sqlglot 30.4.2__tar.gz → 30.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sqlglot-30.4.2 → sqlglot-30.5.0}/CHANGELOG.md +12 -0
- {sqlglot-30.4.2/sqlglot.egg-info → sqlglot-30.5.0}/PKG-INFO +3 -3
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/_typing.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/_version.py +3 -3
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/bigquery.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/dialect.py +8 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/duckdb.py +2 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/exasol.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/constraints.py +4 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/ddl.py +4 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/dml.py +4 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/functions.py +18 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/math.py +6 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/string.py +1 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generator.py +33 -5
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/bigquery.py +3 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/clickhouse.py +26 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/duckdb.py +122 -3
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/oracle.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/snowflake.py +5 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/spark.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/starrocks.py +8 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parser.py +27 -2
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/bigquery.py +3 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/clickhouse.py +18 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/databricks.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/doris.py +5 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/duckdb.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/mysql.py +10 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/snowflake.py +22 -9
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/spark.py +1 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/starrocks.py +10 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/bigquery.py +21 -10
- {sqlglot-30.4.2 → sqlglot-30.5.0/sqlglot.egg-info}/PKG-INFO +3 -3
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot.egg-info/requires.txt +2 -2
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_bigquery.py +26 -4
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_clickhouse.py +41 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_databricks.py +31 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_dialect.py +1 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_doris.py +13 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_duckdb.py +34 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_exasol.py +4 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_mysql.py +35 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_oracle.py +15 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_snowflake.py +11 -9
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_spark.py +15 -1
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_starrocks.py +28 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_parser.py +26 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/.gitignore +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/.gitmodules +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/.gitpod.yml +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/.pre-commit-config.yaml +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/AGENTS.md +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/CLAUDE.md +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/CONTRIBUTING.md +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/LICENSE +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/MANIFEST.in +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/Makefile +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/README.md +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/pyproject.toml +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/setup.cfg +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/setup.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/__main__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/athena.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/clickhouse.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/doris.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/dremio.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/drill.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/fabric.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/hive.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/materialize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/mysql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/oracle.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/postgres.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/presto.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/redshift.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/risingwave.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/singlestore.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/snowflake.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/solr.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/spark.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/sqlite.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/starrocks.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/dialects/tsql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/diff.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/errors.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/executor/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/executor/context.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/executor/env.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/executor/python.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/executor/table.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/aggregate.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/array.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/builders.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/core.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/json.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/properties.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/query.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/athena.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/databricks.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/doris.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/drill.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/druid.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/dune.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/fabric.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/hive.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/mysql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/postgres.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/presto.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/prql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/singlestore.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/solr.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/spark2.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/sqlite.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/teradata.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/trino.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/generators/tsql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/helper.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/jsonpath.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/lineage.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/canonicalize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/optimize_joins.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/optimizer.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/qualify_columns.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/resolver.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/scope.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/athena.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/base.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/hive.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/oracle.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/postgres.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/redshift.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/spark2.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/sqlite.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/teradata.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/trino.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/parsers/tsql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/planner.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/py.typed +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/schema.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/serde.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/time.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/tokenizer_core.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/tokens.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/transforms.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/trie.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/clickhouse.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/duckdb.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/hive.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/mysql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/presto.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/redshift.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/snowflake.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/spark.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/spark2.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot/typing/tsql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglot.png +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglotc/MANIFEST.in +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglotc/pyproject.toml +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/sqlglotc/setup.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_athena.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_dremio.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_drill.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_druid.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_dune.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_fabric.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_hive.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_pipe_syntax.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_postgres.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_presto.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_prql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_redshift.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_risingwave.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_singlestore.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_solr.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_sqlite.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_trino.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/dialects/test_tsql.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/identity.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/annotate_functions.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/normalize.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/simplify.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/partial.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/gen_fixtures.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/helpers.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/sqlglot/__init__.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_build.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_dialect_entry_points.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_dialect_imports.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_diff.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_docs.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_errors.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_executor.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_expressions.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_generator.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_helper.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_integration_loader.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_jsonpath.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_lineage.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_optimizer.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_schema.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_serde.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_time.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_tokens.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_transforms.py +0 -0
- {sqlglot-30.4.2 → sqlglot-30.5.0}/tests/test_transpile.py +0 -0
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [v30.4.3] - 2026-04-13
|
|
5
|
+
### :bug: Bug Fixes
|
|
6
|
+
- [`713e95f`](https://github.com/tobymao/sqlglot/commit/713e95fb9bca5fa6ac0aa660f599a4be632872e2) - **snowflake**: parse GET_DDL #unknown_policy in ROW ACCESS POLICY [CLAUDE] *(PR [#7491](https://github.com/tobymao/sqlglot/pull/7491) by [@eakmanrq](https://github.com/eakmanrq))*
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## [v30.4.2] - 2026-04-08
|
|
10
|
+
### :bug: Bug Fixes
|
|
11
|
+
- [`d04595e`](https://github.com/tobymao/sqlglot/commit/d04595e1ba91a778e4b76f3f84dcb41649594e32) - incomplete `ColumnMapping` type hint *(commit by [@georgesittas](https://github.com/georgesittas))*
|
|
12
|
+
|
|
13
|
+
|
|
4
14
|
## [v30.4.0] - 2026-04-08
|
|
5
15
|
### :sparkles: New Features
|
|
6
16
|
- [`24ff8bb`](https://github.com/tobymao/sqlglot/commit/24ff8bb6c1d94a03f6611d4353e210108c25a6a6) - **duckdb**: Add transpilation support for COLLATE function *(PR [#7461](https://github.com/tobymao/sqlglot/pull/7461) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
@@ -14137,3 +14147,5 @@ pip install "sqlglot[c]" # compiled — faster, but no subclassing
|
|
|
14137
14147
|
[v30.2.1]: https://github.com/tobymao/sqlglot/compare/v30.2.0...v30.2.1
|
|
14138
14148
|
[v30.3.0]: https://github.com/tobymao/sqlglot/compare/v30.2.1...v30.3.0
|
|
14139
14149
|
[v30.4.0]: https://github.com/tobymao/sqlglot/compare/v30.3.0...v30.4.0
|
|
14150
|
+
[v30.4.2]: https://github.com/tobymao/sqlglot/compare/v30.4.1...v30.4.2
|
|
14151
|
+
[v30.4.3]: https://github.com/tobymao/sqlglot/compare/v30.4.2...v30.4.3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglot
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.5.0
|
|
4
4
|
Summary: An easily customizable SQL parser and transpiler
|
|
5
5
|
Author-email: Toby Mao <toby.mao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,10 +33,10 @@ Requires-Dist: types-pytz; extra == "dev"
|
|
|
33
33
|
Requires-Dist: typing_extensions; extra == "dev"
|
|
34
34
|
Requires-Dist: pyperf; extra == "dev"
|
|
35
35
|
Provides-Extra: c
|
|
36
|
-
Requires-Dist: sqlglotc==30.
|
|
36
|
+
Requires-Dist: sqlglotc==30.5.0; extra == "c"
|
|
37
37
|
Provides-Extra: rs
|
|
38
38
|
Requires-Dist: sqlglotrs==0.13.0; extra == "rs"
|
|
39
|
-
Requires-Dist: sqlglotc==30.
|
|
39
|
+
Requires-Dist: sqlglotc==30.5.0; extra == "rs"
|
|
40
40
|
Dynamic: license-file
|
|
41
41
|
Dynamic: provides-extra
|
|
42
42
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '30.
|
|
22
|
-
__version_tuple__ = version_tuple = (30,
|
|
21
|
+
__version__ = version = '30.5.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (30, 5, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g64d385f36'
|
|
@@ -183,6 +183,7 @@ class BigQuery(Dialect):
|
|
|
183
183
|
"EXCEPTION": TokenType.COMMAND,
|
|
184
184
|
"EXPORT": TokenType.EXPORT,
|
|
185
185
|
"FLOAT64": TokenType.DOUBLE,
|
|
186
|
+
"FOR SYSTEM TIME": TokenType.TIMESTAMP_SNAPSHOT,
|
|
186
187
|
"FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
|
|
187
188
|
"LOOP": TokenType.COMMAND,
|
|
188
189
|
"MODEL": TokenType.MODEL,
|
|
@@ -1598,6 +1598,7 @@ def build_date_delta(
|
|
|
1598
1598
|
|
|
1599
1599
|
def build_date_delta_with_interval(
|
|
1600
1600
|
expression_class: Type[E],
|
|
1601
|
+
default_unit: str | None = None,
|
|
1601
1602
|
) -> t.Callable[[BuilderArgs], E | None]:
|
|
1602
1603
|
def _builder(args: BuilderArgs) -> E | None:
|
|
1603
1604
|
if len(args) < 2:
|
|
@@ -1606,7 +1607,13 @@ def build_date_delta_with_interval(
|
|
|
1606
1607
|
interval = args[1]
|
|
1607
1608
|
|
|
1608
1609
|
if not isinstance(interval, exp.Interval):
|
|
1609
|
-
|
|
1610
|
+
if default_unit is None:
|
|
1611
|
+
raise ParseError(f"INTERVAL expression expected but got '{interval}'")
|
|
1612
|
+
return expression_class(
|
|
1613
|
+
this=args[0],
|
|
1614
|
+
expression=interval,
|
|
1615
|
+
unit=exp.Literal.string(default_unit),
|
|
1616
|
+
)
|
|
1610
1617
|
|
|
1611
1618
|
return expression_class(this=args[0], expression=interval.this, unit=unit_to_str(interval))
|
|
1612
1619
|
|
|
@@ -79,6 +79,7 @@ class Delete(Expression, DML):
|
|
|
79
79
|
"limit": False,
|
|
80
80
|
"tables": False, # Multiple-Table Syntax (MySQL)
|
|
81
81
|
"cluster": False, # Clickhouse
|
|
82
|
+
"hint": False,
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
def delete(
|
|
@@ -282,7 +283,8 @@ class LoadData(Expression):
|
|
|
282
283
|
"this": True,
|
|
283
284
|
"local": False,
|
|
284
285
|
"overwrite": False,
|
|
285
|
-
"inpath":
|
|
286
|
+
"inpath": False,
|
|
287
|
+
"files": False,
|
|
286
288
|
"partition": False,
|
|
287
289
|
"input_format": False,
|
|
288
290
|
"serde": False,
|
|
@@ -300,6 +302,7 @@ class Update(Expression, DML):
|
|
|
300
302
|
"order": False,
|
|
301
303
|
"limit": False,
|
|
302
304
|
"options": False,
|
|
305
|
+
"hint": False,
|
|
303
306
|
}
|
|
304
307
|
|
|
305
308
|
def table(
|
|
@@ -321,6 +321,24 @@ class AIClassify(Expression, Func):
|
|
|
321
321
|
_sql_names = ["AI_CLASSIFY"]
|
|
322
322
|
|
|
323
323
|
|
|
324
|
+
class AIEmbed(Expression, Func):
|
|
325
|
+
arg_types = {"expressions": True}
|
|
326
|
+
is_var_len_args = True
|
|
327
|
+
_sql_names = ["AI_EMBED"]
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class AISimilarity(Expression, Func):
|
|
331
|
+
arg_types = {"expressions": True}
|
|
332
|
+
is_var_len_args = True
|
|
333
|
+
_sql_names = ["AI_SIMILARITY"]
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class AIGenerate(Expression, Func):
|
|
337
|
+
arg_types = {"expressions": True}
|
|
338
|
+
is_var_len_args = True
|
|
339
|
+
_sql_names = ["AI_GENERATE"]
|
|
340
|
+
|
|
341
|
+
|
|
324
342
|
class FeaturesAtTime(Expression, Func):
|
|
325
343
|
arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
|
|
326
344
|
|
|
@@ -108,7 +108,12 @@ class EuclideanDistance(Expression, Func):
|
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
class JarowinklerSimilarity(Expression, Func):
|
|
111
|
-
arg_types = {
|
|
111
|
+
arg_types = {
|
|
112
|
+
"this": True,
|
|
113
|
+
"expression": True,
|
|
114
|
+
"case_insensitive": False,
|
|
115
|
+
"integer_scale": False,
|
|
116
|
+
}
|
|
112
117
|
|
|
113
118
|
|
|
114
119
|
class ManhattanDistance(Expression, Func):
|
|
@@ -220,7 +220,7 @@ class Stuff(Expression, Func):
|
|
|
220
220
|
|
|
221
221
|
class Substring(Expression, Func):
|
|
222
222
|
_sql_names = ["SUBSTRING", "SUBSTR"]
|
|
223
|
-
arg_types = {"this": True, "start": False, "length": False}
|
|
223
|
+
arg_types = {"this": True, "start": False, "length": False, "zero_start": False}
|
|
224
224
|
|
|
225
225
|
|
|
226
226
|
class SubstringIndex(Expression, Func):
|
|
@@ -234,6 +234,7 @@ class Generator:
|
|
|
234
234
|
exp.ProjectionPolicyColumnConstraint: lambda self, e: (
|
|
235
235
|
f"PROJECTION POLICY {self.sql(e, 'this')}"
|
|
236
236
|
),
|
|
237
|
+
exp.InvisibleColumnConstraint: lambda self, e: "INVISIBLE",
|
|
237
238
|
exp.ZeroFillColumnConstraint: lambda self, e: "ZEROFILL",
|
|
238
239
|
exp.Put: lambda self, e: self.get_put_sql(e),
|
|
239
240
|
exp.RemoteWithConnectionModelProperty: lambda self, e: (
|
|
@@ -320,6 +321,9 @@ class Generator:
|
|
|
320
321
|
# Whether MERGE ... WHEN MATCHED BY SOURCE is allowed
|
|
321
322
|
MATCHED_BY_SOURCE = True
|
|
322
323
|
|
|
324
|
+
# Whether MERGE ... WHEN MATCHED/NOT MATCHED THEN UPDATE/INSERT ... WHERE is supported
|
|
325
|
+
SUPPORTS_MERGE_WHERE = False
|
|
326
|
+
|
|
323
327
|
# Whether the INTERVAL expression works only with values like '1 day'
|
|
324
328
|
SINGLE_STRING_INTERVAL = False
|
|
325
329
|
|
|
@@ -1681,6 +1685,7 @@ class Generator:
|
|
|
1681
1685
|
return f"{local}DIRECTORY {self.sql(expression, 'this')}{row_format}"
|
|
1682
1686
|
|
|
1683
1687
|
def delete_sql(self, expression: exp.Delete) -> str:
|
|
1688
|
+
hint = self.sql(expression, "hint")
|
|
1684
1689
|
this = self.sql(expression, "this")
|
|
1685
1690
|
this = f" FROM {this}" if this else ""
|
|
1686
1691
|
using = self.expressions(expression, key="using")
|
|
@@ -1697,7 +1702,7 @@ class Generator:
|
|
|
1697
1702
|
expression_sql = f"{this}{using}{cluster}{where}{returning}{order}{limit}"
|
|
1698
1703
|
else:
|
|
1699
1704
|
expression_sql = f"{returning}{this}{using}{cluster}{where}{order}{limit}"
|
|
1700
|
-
return self.prepend_ctes(expression, f"DELETE{tables}{expression_sql}")
|
|
1705
|
+
return self.prepend_ctes(expression, f"DELETE{hint}{tables}{expression_sql}")
|
|
1701
1706
|
|
|
1702
1707
|
def drop_sql(self, expression: exp.Drop) -> str:
|
|
1703
1708
|
this = self.sql(expression, "this")
|
|
@@ -2463,6 +2468,7 @@ class Generator:
|
|
|
2463
2468
|
return (join_sql, "")
|
|
2464
2469
|
|
|
2465
2470
|
def update_sql(self, expression: exp.Update) -> str:
|
|
2471
|
+
hint = self.sql(expression, "hint")
|
|
2466
2472
|
this = self.sql(expression, "this")
|
|
2467
2473
|
join_sql, from_sql = self._update_from_joins_sql(expression)
|
|
2468
2474
|
set_sql = self.expressions(expression, flat=True)
|
|
@@ -2476,7 +2482,7 @@ class Generator:
|
|
|
2476
2482
|
expression_sql = f"{returning}{from_sql}{where_sql}"
|
|
2477
2483
|
options = self.expressions(expression, key="options")
|
|
2478
2484
|
options = f" OPTION({options})" if options else ""
|
|
2479
|
-
sql = f"UPDATE {this}{join_sql} SET {set_sql}{expression_sql}{order}{limit}{options}"
|
|
2485
|
+
sql = f"UPDATE{hint} {this}{join_sql} SET {set_sql}{expression_sql}{order}{limit}{options}"
|
|
2480
2486
|
return self.prepend_ctes(expression, sql)
|
|
2481
2487
|
|
|
2482
2488
|
def values_sql(self, expression: exp.Values, values_as_table: bool = True) -> str:
|
|
@@ -2811,10 +2817,20 @@ class Generator:
|
|
|
2811
2817
|
return self._replace_line_breaks(text).replace(delimiter, escaped_delimiter)
|
|
2812
2818
|
|
|
2813
2819
|
def loaddata_sql(self, expression: exp.LoadData) -> str:
|
|
2820
|
+
is_overwrite = expression.args.get("overwrite")
|
|
2821
|
+
overwrite = " OVERWRITE" if is_overwrite else ""
|
|
2822
|
+
this = self.sql(expression, "this")
|
|
2823
|
+
|
|
2824
|
+
files = expression.args.get("files")
|
|
2825
|
+
if files:
|
|
2826
|
+
files_sql = self.expressions(files, flat=True)
|
|
2827
|
+
files_sql = f"FILES{self.wrap(files_sql)}"
|
|
2828
|
+
this = f" {this}" if is_overwrite else f" INTO TABLE {this}"
|
|
2829
|
+
return f"LOAD DATA{overwrite}{this} FROM {files_sql}"
|
|
2830
|
+
|
|
2814
2831
|
local = " LOCAL" if expression.args.get("local") else ""
|
|
2815
2832
|
inpath = f" INPATH {self.sql(expression, 'inpath')}"
|
|
2816
|
-
|
|
2817
|
-
this = f" INTO TABLE {self.sql(expression, 'this')}"
|
|
2833
|
+
this = f" INTO TABLE {this}"
|
|
2818
2834
|
partition = self.sql(expression, "partition")
|
|
2819
2835
|
partition = f" {partition}" if partition else ""
|
|
2820
2836
|
input_format = self.sql(expression, "input_format")
|
|
@@ -4448,9 +4464,16 @@ class Generator:
|
|
|
4448
4464
|
else:
|
|
4449
4465
|
expressions_sql = self.expressions(then_expression)
|
|
4450
4466
|
then = f"UPDATE SET{self.sep()}{expressions_sql}" if expressions_sql else "UPDATE"
|
|
4451
|
-
|
|
4452
4467
|
else:
|
|
4453
4468
|
then = self.sql(then_expression)
|
|
4469
|
+
|
|
4470
|
+
if isinstance(then_expression, (exp.Insert, exp.Update)):
|
|
4471
|
+
where = self.sql(then_expression, "where")
|
|
4472
|
+
if where and not self.SUPPORTS_MERGE_WHERE:
|
|
4473
|
+
kind = "INSERT" if isinstance(then_expression, exp.Insert) else "UPDATE"
|
|
4474
|
+
self.unsupported(f"WHERE clause in MERGE {kind} is not supported")
|
|
4475
|
+
where = ""
|
|
4476
|
+
then = f"{then}{where}"
|
|
4454
4477
|
return f"WHEN {matched}{source}{condition} THEN {then}"
|
|
4455
4478
|
|
|
4456
4479
|
def whens_sql(self, expression: exp.Whens) -> str:
|
|
@@ -5899,3 +5922,8 @@ class Generator:
|
|
|
5899
5922
|
def usingproperty_sql(self, expression: exp.UsingProperty) -> str:
|
|
5900
5923
|
kind = expression.args.get("kind")
|
|
5901
5924
|
return f"USING {kind} {self.sql(expression, 'this')}"
|
|
5925
|
+
|
|
5926
|
+
def renameindex_sql(self, expression: exp.RenameIndex) -> str:
|
|
5927
|
+
this = self.sql(expression, "this")
|
|
5928
|
+
to = self.sql(expression, "to")
|
|
5929
|
+
return f"RENAME INDEX {this} TO {to}"
|
|
@@ -272,6 +272,9 @@ class BigQueryGenerator(generator.Generator):
|
|
|
272
272
|
|
|
273
273
|
TRANSFORMS = {
|
|
274
274
|
**generator.Generator.TRANSFORMS,
|
|
275
|
+
exp.AIEmbed: rename_func("EMBED"),
|
|
276
|
+
exp.AIGenerate: rename_func("GENERATE"),
|
|
277
|
+
exp.AISimilarity: rename_func("SIMILARITY"),
|
|
275
278
|
exp.ApproxTopK: rename_func("APPROX_TOP_COUNT"),
|
|
276
279
|
exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
|
|
277
280
|
exp.ArgMax: arg_max_or_min_no_count("MAX_BY"),
|
|
@@ -416,6 +416,32 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
416
416
|
exp.DType.MULTIPOLYGON,
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
def groupconcat_sql(self, expression: exp.GroupConcat) -> str:
|
|
420
|
+
this = expression.this
|
|
421
|
+
separator = expression.args.get("separator")
|
|
422
|
+
|
|
423
|
+
if isinstance(this, exp.Limit) and this.this:
|
|
424
|
+
limit = this
|
|
425
|
+
this = limit.this.pop()
|
|
426
|
+
return self.sql(
|
|
427
|
+
exp.ParameterizedAgg(
|
|
428
|
+
this="groupConcat",
|
|
429
|
+
params=[this],
|
|
430
|
+
expressions=[separator, limit.expression],
|
|
431
|
+
)
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
if separator:
|
|
435
|
+
return self.sql(
|
|
436
|
+
exp.ParameterizedAgg(
|
|
437
|
+
this="groupConcat",
|
|
438
|
+
params=[this],
|
|
439
|
+
expressions=[separator],
|
|
440
|
+
)
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
return self.func("groupConcat", this)
|
|
444
|
+
|
|
419
445
|
def offset_sql(self, expression: exp.Offset) -> str:
|
|
420
446
|
offset = super().offset_sql(expression)
|
|
421
447
|
|
|
@@ -24,7 +24,6 @@ from sqlglot.dialects.dialect import (
|
|
|
24
24
|
getbit_sql,
|
|
25
25
|
groupconcat_sql,
|
|
26
26
|
inline_array_unless_query,
|
|
27
|
-
jarowinkler_similarity,
|
|
28
27
|
months_between_sql,
|
|
29
28
|
no_datetime_sql,
|
|
30
29
|
no_comment_column_constraint_sql,
|
|
@@ -1537,7 +1536,6 @@ class DuckDBGenerator(generator.Generator):
|
|
|
1537
1536
|
exp.BitwiseOrAgg: _bitwise_agg_sql,
|
|
1538
1537
|
exp.BitwiseRightShift: _bitshift_sql,
|
|
1539
1538
|
exp.BitwiseXorAgg: _bitwise_agg_sql,
|
|
1540
|
-
exp.ByteLength: lambda self, e: self.func("OCTET_LENGTH", e.this),
|
|
1541
1539
|
exp.CommentColumnConstraint: no_comment_column_constraint_sql,
|
|
1542
1540
|
exp.Corr: lambda self, e: self._corr_sql(e),
|
|
1543
1541
|
exp.CosineDistance: rename_func("LIST_COSINE_DISTANCE"),
|
|
@@ -1609,7 +1607,6 @@ class DuckDBGenerator(generator.Generator):
|
|
|
1609
1607
|
),
|
|
1610
1608
|
exp.Ceil: _ceil_floor,
|
|
1611
1609
|
exp.Floor: _ceil_floor,
|
|
1612
|
-
exp.JarowinklerSimilarity: jarowinkler_similarity("JARO_WINKLER_SIMILARITY"),
|
|
1613
1610
|
exp.JSONBExists: rename_func("JSON_EXISTS"),
|
|
1614
1611
|
exp.JSONExtract: _arrow_json_extract_sql,
|
|
1615
1612
|
exp.JSONExtractArray: _json_extract_value_array_sql,
|
|
@@ -2259,6 +2256,47 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2259
2256
|
self.unsupported("DuckDB does not support the COMPRESS() function")
|
|
2260
2257
|
return self.function_fallback_sql(expression)
|
|
2261
2258
|
|
|
2259
|
+
def encrypt_sql(self, expression: exp.Encrypt) -> str:
|
|
2260
|
+
self.unsupported("ENCRYPT is not supported in DuckDB")
|
|
2261
|
+
return self.function_fallback_sql(expression)
|
|
2262
|
+
|
|
2263
|
+
def decrypt_sql(self, expression: exp.Decrypt) -> str:
|
|
2264
|
+
func_name = "TRY_DECRYPT" if expression.args.get("safe") else "DECRYPT"
|
|
2265
|
+
self.unsupported(f"{func_name} is not supported in DuckDB")
|
|
2266
|
+
return self.function_fallback_sql(expression)
|
|
2267
|
+
|
|
2268
|
+
def decryptraw_sql(self, expression: exp.DecryptRaw) -> str:
|
|
2269
|
+
func_name = "TRY_DECRYPT_RAW" if expression.args.get("safe") else "DECRYPT_RAW"
|
|
2270
|
+
self.unsupported(f"{func_name} is not supported in DuckDB")
|
|
2271
|
+
return self.function_fallback_sql(expression)
|
|
2272
|
+
|
|
2273
|
+
def encryptraw_sql(self, expression: exp.EncryptRaw) -> str:
|
|
2274
|
+
self.unsupported("ENCRYPT_RAW is not supported in DuckDB")
|
|
2275
|
+
return self.function_fallback_sql(expression)
|
|
2276
|
+
|
|
2277
|
+
def parseurl_sql(self, expression: exp.ParseUrl) -> str:
|
|
2278
|
+
self.unsupported("PARSE_URL is not supported in DuckDB")
|
|
2279
|
+
return self.function_fallback_sql(expression)
|
|
2280
|
+
|
|
2281
|
+
def parseip_sql(self, expression: exp.ParseIp) -> str:
|
|
2282
|
+
self.unsupported("PARSE_IP is not supported in DuckDB")
|
|
2283
|
+
return self.function_fallback_sql(expression)
|
|
2284
|
+
|
|
2285
|
+
def jarowinklersimilarity_sql(self, expression: exp.JarowinklerSimilarity) -> str:
|
|
2286
|
+
this = expression.this
|
|
2287
|
+
expr = expression.expression
|
|
2288
|
+
|
|
2289
|
+
if expression.args.get("case_insensitive"):
|
|
2290
|
+
this = exp.Upper(this=this)
|
|
2291
|
+
expr = exp.Upper(this=expr)
|
|
2292
|
+
|
|
2293
|
+
result = exp.func("JARO_WINKLER_SIMILARITY", this, expr)
|
|
2294
|
+
|
|
2295
|
+
if expression.args.get("integer_scale"):
|
|
2296
|
+
result = exp.cast(result * 100, "INTEGER")
|
|
2297
|
+
|
|
2298
|
+
return self.sql(result)
|
|
2299
|
+
|
|
2262
2300
|
def nthvalue_sql(self, expression: exp.NthValue) -> str:
|
|
2263
2301
|
from_first = expression.args.get("from_first", True)
|
|
2264
2302
|
if not from_first:
|
|
@@ -2293,6 +2331,17 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2293
2331
|
replacements = {"seed": seed_value, "length": length}
|
|
2294
2332
|
return f"({self.sql(exp.replace_placeholders(self.RANDSTR_TEMPLATE, **replacements))})"
|
|
2295
2333
|
|
|
2334
|
+
@unsupported_args("finish")
|
|
2335
|
+
def reduce_sql(self, expression: exp.Reduce) -> str:
|
|
2336
|
+
array_arg = expression.this
|
|
2337
|
+
initial_value = expression.args.get("initial")
|
|
2338
|
+
merge_lambda = expression.args.get("merge")
|
|
2339
|
+
|
|
2340
|
+
if merge_lambda:
|
|
2341
|
+
merge_lambda.set("colon", True)
|
|
2342
|
+
|
|
2343
|
+
return self.func("list_reduce", array_arg, merge_lambda, initial_value)
|
|
2344
|
+
|
|
2296
2345
|
def zipf_sql(self, expression: exp.Zipf) -> str:
|
|
2297
2346
|
"""
|
|
2298
2347
|
Transpile Snowflake's ZIPF to DuckDB using CDF-based inverse sampling.
|
|
@@ -2431,6 +2480,10 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2431
2480
|
from_ = f" FROM {from_}" if from_ else ""
|
|
2432
2481
|
return f"SHOW {expression.name}{from_}"
|
|
2433
2482
|
|
|
2483
|
+
def soundex_sql(self, expression: exp.Soundex) -> str:
|
|
2484
|
+
self.unsupported("SOUNDEX is not supported in DuckDB")
|
|
2485
|
+
return self.func("SOUNDEX", expression.this)
|
|
2486
|
+
|
|
2434
2487
|
def sortarray_sql(self, expression: exp.SortArray) -> str:
|
|
2435
2488
|
arr = expression.this
|
|
2436
2489
|
asc = expression.args.get("asc")
|
|
@@ -2504,6 +2557,20 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2504
2557
|
|
|
2505
2558
|
return strposition_sql(self, expression)
|
|
2506
2559
|
|
|
2560
|
+
def substring_sql(self, expression: exp.Substring) -> str:
|
|
2561
|
+
if expression.args.get("zero_start"):
|
|
2562
|
+
start = expression.args.get("start")
|
|
2563
|
+
length = expression.args.get("length")
|
|
2564
|
+
|
|
2565
|
+
if start := expression.args.get("start"):
|
|
2566
|
+
start = exp.If(this=start.eq(0), true=exp.Literal.number(1), false=start)
|
|
2567
|
+
if length := expression.args.get("length"):
|
|
2568
|
+
length = exp.If(this=length < 0, true=exp.Literal.number(0), false=length)
|
|
2569
|
+
|
|
2570
|
+
return self.func("SUBSTRING", expression.this, start, length)
|
|
2571
|
+
|
|
2572
|
+
return self.function_fallback_sql(expression)
|
|
2573
|
+
|
|
2507
2574
|
def strtotime_sql(self, expression: exp.StrToTime) -> str:
|
|
2508
2575
|
# Check if target_type requires TIMESTAMPTZ (for LTZ/TZ variants)
|
|
2509
2576
|
target_type = expression.args.get("target_type")
|
|
@@ -3229,6 +3296,10 @@ class DuckDBGenerator(generator.Generator):
|
|
|
3229
3296
|
)
|
|
3230
3297
|
)
|
|
3231
3298
|
|
|
3299
|
+
def arrayunionagg_sql(self, expression: exp.ArrayUnionAgg) -> str:
|
|
3300
|
+
self.unsupported("ARRAY_UNION_AGG is not supported in DuckDB")
|
|
3301
|
+
return self.function_fallback_sql(expression)
|
|
3302
|
+
|
|
3232
3303
|
def arraydistinct_sql(self, expression: exp.ArrayDistinct) -> str:
|
|
3233
3304
|
arr = expression.this
|
|
3234
3305
|
func = self.func("LIST_DISTINCT", arr)
|
|
@@ -3396,6 +3467,44 @@ class DuckDBGenerator(generator.Generator):
|
|
|
3396
3467
|
def rtrimmedlength_sql(self, expression: exp.RtrimmedLength) -> str:
|
|
3397
3468
|
return self.func("LENGTH", exp.Trim(this=expression.this, position="TRAILING"))
|
|
3398
3469
|
|
|
3470
|
+
def stuff_sql(self, expression: exp.Stuff) -> str:
|
|
3471
|
+
base = expression.this
|
|
3472
|
+
start = expression.args["start"]
|
|
3473
|
+
length = expression.args["length"]
|
|
3474
|
+
insertion = expression.expression
|
|
3475
|
+
is_binary = _is_binary(base)
|
|
3476
|
+
|
|
3477
|
+
if is_binary:
|
|
3478
|
+
# DuckDB's SUBSTRING doesn't accept BLOB; operate on the HEX string instead
|
|
3479
|
+
# (each byte = 2 hex chars), then UNHEX back to BLOB
|
|
3480
|
+
base = exp.Hex(this=base)
|
|
3481
|
+
insertion = exp.Hex(this=insertion)
|
|
3482
|
+
left = exp.Substring(
|
|
3483
|
+
this=base.copy(),
|
|
3484
|
+
start=exp.Literal.number(1),
|
|
3485
|
+
length=(start.copy() - exp.Literal.number(1)) * exp.Literal.number(2),
|
|
3486
|
+
)
|
|
3487
|
+
right = exp.Substring(
|
|
3488
|
+
this=base.copy(),
|
|
3489
|
+
start=((start + length) - exp.Literal.number(1)) * exp.Literal.number(2)
|
|
3490
|
+
+ exp.Literal.number(1),
|
|
3491
|
+
)
|
|
3492
|
+
else:
|
|
3493
|
+
left = exp.Substring(
|
|
3494
|
+
this=base.copy(),
|
|
3495
|
+
start=exp.Literal.number(1),
|
|
3496
|
+
length=start.copy() - exp.Literal.number(1),
|
|
3497
|
+
)
|
|
3498
|
+
right = exp.Substring(this=base.copy(), start=start + length)
|
|
3499
|
+
result: exp.Expr = exp.DPipe(
|
|
3500
|
+
this=exp.DPipe(this=left, expression=insertion), expression=right
|
|
3501
|
+
)
|
|
3502
|
+
|
|
3503
|
+
if is_binary:
|
|
3504
|
+
result = exp.Unhex(this=result)
|
|
3505
|
+
|
|
3506
|
+
return self.sql(result)
|
|
3507
|
+
|
|
3399
3508
|
def rand_sql(self, expression: exp.Rand) -> str:
|
|
3400
3509
|
seed = expression.this
|
|
3401
3510
|
if seed is not None:
|
|
@@ -3416,6 +3525,16 @@ class DuckDBGenerator(generator.Generator):
|
|
|
3416
3525
|
# Default DuckDB behavior - just return RANDOM() as float
|
|
3417
3526
|
return "RANDOM()"
|
|
3418
3527
|
|
|
3528
|
+
def bytelength_sql(self, expression: exp.ByteLength) -> str:
|
|
3529
|
+
arg = expression.this
|
|
3530
|
+
|
|
3531
|
+
# Check if it's a text type (handles both literals and annotated expressions)
|
|
3532
|
+
if arg.is_type(*exp.DataType.TEXT_TYPES):
|
|
3533
|
+
return self.func("OCTET_LENGTH", exp.Encode(this=arg))
|
|
3534
|
+
|
|
3535
|
+
# Default: pass through as-is (conservative for DuckDB, handles binary and unannotated)
|
|
3536
|
+
return self.func("OCTET_LENGTH", arg)
|
|
3537
|
+
|
|
3419
3538
|
def base64encode_sql(self, expression: exp.Base64Encode) -> str:
|
|
3420
3539
|
# DuckDB TO_BASE64 requires BLOB input
|
|
3421
3540
|
# Snowflake BASE64_ENCODE accepts both VARCHAR and BINARY - for VARCHAR it implicitly
|
|
@@ -497,6 +497,9 @@ class SnowflakeGenerator(generator.Generator):
|
|
|
497
497
|
exp.GetExtract: rename_func("GET"),
|
|
498
498
|
exp.GroupConcat: lambda self, e: groupconcat_sql(self, e, sep=""),
|
|
499
499
|
exp.If: if_sql(name="IFF", false_value="NULL"),
|
|
500
|
+
exp.JSONArray: lambda self, e: self.func(
|
|
501
|
+
"TO_VARIANT", self.func("ARRAY_CONSTRUCT", *e.expressions)
|
|
502
|
+
),
|
|
500
503
|
exp.JSONExtractArray: _json_extract_value_array_sql,
|
|
501
504
|
exp.JSONExtractScalar: lambda self, e: self.func(
|
|
502
505
|
"JSON_EXTRACT_PATH_TEXT", e.this, e.expression
|
|
@@ -640,6 +643,7 @@ class SnowflakeGenerator(generator.Generator):
|
|
|
640
643
|
TYPE_MAPPING = {
|
|
641
644
|
**generator.Generator.TYPE_MAPPING,
|
|
642
645
|
exp.DType.BIGDECIMAL: "DOUBLE",
|
|
646
|
+
exp.DType.JSON: "VARIANT",
|
|
643
647
|
exp.DType.NESTED: "OBJECT",
|
|
644
648
|
exp.DType.STRUCT: "OBJECT",
|
|
645
649
|
exp.DType.TEXT: "VARCHAR",
|
|
@@ -863,7 +867,7 @@ class SnowflakeGenerator(generator.Generator):
|
|
|
863
867
|
def rowaccessproperty_sql(self, expression: exp.RowAccessProperty) -> str:
|
|
864
868
|
if not expression.this:
|
|
865
869
|
return "ROW ACCESS"
|
|
866
|
-
on = f" ON ({self.expressions(expression, flat=True)})"
|
|
870
|
+
on = f" ON ({self.expressions(expression, flat=True)})" if expression.expressions else ""
|
|
867
871
|
return f"WITH ROW ACCESS POLICY {self.sql(expression, 'this')}{on}"
|
|
868
872
|
|
|
869
873
|
def describe_sql(self, expression: exp.Describe) -> str:
|
|
@@ -119,6 +119,7 @@ class SparkGenerator(Spark2Generator):
|
|
|
119
119
|
f"PARTITIONED BY {self.wrap(self.expressions(sqls=[_normalize_partition(e) for e in e.this.expressions], skip_first=True))}"
|
|
120
120
|
),
|
|
121
121
|
exp.SafeAdd: rename_func("TRY_ADD"),
|
|
122
|
+
exp.SafeDivide: rename_func("TRY_DIVIDE"),
|
|
122
123
|
exp.SafeMultiply: rename_func("TRY_MULTIPLY"),
|
|
123
124
|
exp.SafeSubtract: rename_func("TRY_SUBTRACT"),
|
|
124
125
|
exp.StartsWith: rename_func("STARTSWITH"),
|
|
@@ -100,6 +100,14 @@ class StarRocksGenerator(MySQLGenerator):
|
|
|
100
100
|
exp.JSONExtract: arrow_json_extract_sql,
|
|
101
101
|
exp.Property: property_sql,
|
|
102
102
|
exp.RegexpLike: rename_func("REGEXP"),
|
|
103
|
+
# Inherited from MySQL, minus operations StarRocks supports natively
|
|
104
|
+
# (QUALIFY, FULL OUTER JOIN, SEMI/ANTI JOIN)
|
|
105
|
+
exp.Select: transforms.preprocess(
|
|
106
|
+
[
|
|
107
|
+
transforms.eliminate_distinct_on,
|
|
108
|
+
transforms.unnest_generate_date_array_using_recursive_cte,
|
|
109
|
+
]
|
|
110
|
+
),
|
|
103
111
|
exp.SchemaCommentProperty: lambda self, e: self.naked_property(e),
|
|
104
112
|
exp.SqlSecurityProperty: lambda self, e: f"SECURITY {self.sql(e.this)}",
|
|
105
113
|
exp.StDistance: st_distance_sphere,
|