sqlglot 30.21.0__tar.gz → 30.22.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.21.0 → sqlglot-30.22.0}/CHANGELOG.md +55 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/Makefile +1 -1
- {sqlglot-30.21.0/sqlglot.egg-info → sqlglot-30.22.0}/PKG-INFO +22 -10
- {sqlglot-30.21.0 → sqlglot-30.22.0}/README.md +18 -6
- {sqlglot-30.21.0 → sqlglot-30.22.0}/setup.py +3 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/__init__.py +5 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/_version.py +3 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/bigquery.py +9 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/clickhouse.py +11 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dialect.py +118 -11
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/doris.py +4 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/drill.py +2 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/duckdb.py +8 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/hive.py +13 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/materialize.py +5 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/mysql.py +15 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/postgres.py +11 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/redshift.py +5 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/risingwave.py +2 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/snowflake.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/spark.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/sqlite.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/starrocks.py +5 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/tsql.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/env.py +10 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/array.py +15 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/builders.py +1 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/ddl.py +1 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/properties.py +3 -5
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/query.py +28 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/string.py +4 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generator.py +114 -33
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/bigquery.py +4 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/clickhouse.py +20 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/doris.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dremio.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/drill.py +7 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/duckdb.py +76 -9
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/hive.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/materialize.py +6 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/mysql.py +25 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/oracle.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/postgres.py +15 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/presto.py +9 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/redshift.py +8 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/risingwave.py +2 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/singlestore.py +5 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/snowflake.py +5 -48
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/sqlite.py +2 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/starrocks.py +8 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/trino.py +1 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/tsql.py +12 -4
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/lineage.py +19 -6
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/optimizer.py +5 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/pushdown_predicates.py +24 -18
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify.py +0 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify_columns.py +93 -22
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify_tables.py +32 -8
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/resolver.py +29 -25
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/scope.py +31 -13
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/simplify.py +9 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parser.py +243 -75
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/clickhouse.py +14 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/doris.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/duckdb.py +3 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/mysql.py +30 -5
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/postgres.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/snowflake.py +11 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/spark.py +4 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/spark2.py +6 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/starrocks.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/trino.py +25 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/tsql.py +72 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/planner.py +1 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/schema.py +0 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/tokenizer_core.py +99 -20
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/tokens.py +25 -7
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/transforms.py +7 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/__init__.py +49 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/bigquery.py +2 -20
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/duckdb.py +15 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/hive.py +18 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/postgres.py +21 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/presto.py +0 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/redshift.py +17 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/snowflake.py +19 -3
- sqlglot-30.22.0/sqlglot/typing/tsql.py +64 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0/sqlglot.egg-info}/PKG-INFO +22 -10
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/requires.txt +3 -3
- sqlglot-30.22.0/sqlglot.egg-info/scm_version.json +8 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/pyproject.toml +2 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/setup.py +0 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_bigquery.py +47 -7
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_clickhouse.py +104 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_databricks.py +2 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dialect.py +33 -12
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_duckdb.py +185 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_hive.py +87 -6
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_mysql.py +301 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_oracle.py +26 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_postgres.py +87 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_presto.py +28 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_redshift.py +62 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_risingwave.py +3 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_singlestore.py +19 -4
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_snowflake.py +79 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_spark.py +17 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_starrocks.py +6 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_trino.py +51 -6
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_tsql.py +124 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/annotate_functions.sql +15 -3
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/canonicalize_internal_names.sql +1 -1
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/optimizer.sql +18 -4
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_projections.sql +6 -6
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns.sql +71 -7
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_tables.sql +8 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/simplify.sql +39 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_build.py +6 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_executor.py +37 -2
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_lineage.py +98 -28
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_optimizer.py +179 -98
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_parser.py +6 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_schema.py +31 -1
- sqlglot-30.21.0/sqlglot/typing/tsql.py +0 -37
- sqlglot-30.21.0/sqlglot.egg-info/scm_version.json +0 -8
- {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitignore +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitmodules +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitpod.yml +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/.pre-commit-config.yaml +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/AGENTS.md +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/CLAUDE.md +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/CONTRIBUTING.md +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/LICENSE +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/MANIFEST.in +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/pyproject.toml +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/setup.cfg +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/__main__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/_typing.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/anonymize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/athena.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dax.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dremio.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/exasol.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/fabric.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/oracle.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/presto.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/singlestore.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/solr.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/diff.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/errors.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/context.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/python.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/table.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/aggregate.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/constraints.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/core.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/dml.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/functions.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/json.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/math.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/athena.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/databricks.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dax.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/druid.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dune.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/fabric.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/prql.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/python.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/solr.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/spark.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/spark2.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/teradata.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/helper.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/jsonpath.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/canonicalize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/helpers.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/journal.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/optimize_joins.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/athena.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/base.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/bigquery.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/databricks.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dax.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/hive.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/oracle.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/redshift.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/sqlite.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/teradata.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/py.typed +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/serde.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/time.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/trie.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/clickhouse.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/databricks.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/mysql.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/spark.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/spark2.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/scm_file_list.json +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.png +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/MANIFEST.in +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_athena.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dax.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_doris.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dremio.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_drill.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_druid.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dune.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_exasol.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_fabric.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_pipe_syntax.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_prql.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_solr.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_sqlite.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/identity.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/normalize.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/partial.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/gen_fixtures.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/helpers.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/leakcheck.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/sqlglot/__init__.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_anonymize.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_dialect_entry_points.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_dialect_imports.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_diff.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_docs.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_errors.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_expressions.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_generator.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_helper.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_integration_loader.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_jsonpath.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_serde.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_time.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_tokens.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_transforms.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_transpile.py +0 -0
- {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_typing.py +0 -0
|
@@ -1,6 +1,60 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [v30.21.0] - 2026-09-30
|
|
5
|
+
### :boom: BREAKING CHANGES
|
|
6
|
+
- due to [`2be1e0e`](https://github.com/tobymao/sqlglot/commit/2be1e0e2addc0ef01cfa3fd3cf2ef751cdbf411d) - annotate `bit_xor` for duckdb *(PR [#8452](https://github.com/tobymao/sqlglot/pull/8452) by [@opencode13241-eng](https://github.com/opencode13241-eng))*:
|
|
7
|
+
|
|
8
|
+
annotate `bit_xor` for duckdb (#8452)
|
|
9
|
+
|
|
10
|
+
- due to [`65a0e22`](https://github.com/tobymao/sqlglot/commit/65a0e22447fcca9ea4a89f6167954fbb872c8e6d) - new projection pushdown algorithm *(PR [#8440](https://github.com/tobymao/sqlglot/pull/8440) by [@georgesittas](https://github.com/georgesittas))*:
|
|
11
|
+
|
|
12
|
+
new projection pushdown algorithm (#8440)
|
|
13
|
+
|
|
14
|
+
- due to [`e3f71dc`](https://github.com/tobymao/sqlglot/commit/e3f71dc1a1186ada4b017a5f2498b8c2b0a8a25b) - decode backslash escape sequences in string literals *(PR [#8456](https://github.com/tobymao/sqlglot/pull/8456) by [@georgesittas](https://github.com/georgesittas))*:
|
|
15
|
+
|
|
16
|
+
decode backslash escape sequences in string literals (#8456)
|
|
17
|
+
|
|
18
|
+
- due to [`b4d9e37`](https://github.com/tobymao/sqlglot/commit/b4d9e37d84a61eeb78e8d652f697e2e0d4d57869) - inherit Trino dialect, parser and generator defaults *(PR [#8464](https://github.com/tobymao/sqlglot/pull/8464) by [@georgesittas](https://github.com/georgesittas))*:
|
|
19
|
+
|
|
20
|
+
inherit Trino dialect, parser and generator defaults (#8464)
|
|
21
|
+
|
|
22
|
+
- due to [`d84f7f3`](https://github.com/tobymao/sqlglot/commit/d84f7f3ee1ff50778c93970b086d59692714dcdc) - preserve BD literal semantics in Hive and Spark *(PR [#8455](https://github.com/tobymao/sqlglot/pull/8455) by [@georgesittas](https://github.com/georgesittas))*:
|
|
23
|
+
|
|
24
|
+
preserve BD literal semantics in Hive and Spark (#8455)
|
|
25
|
+
|
|
26
|
+
- due to [`1122046`](https://github.com/tobymao/sqlglot/commit/11220460d0e78a3c83f14b006239f636e4ddde71) - convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] *(PR [#8460](https://github.com/tobymao/sqlglot/pull/8460) by [@anishmehta24](https://github.com/anishmehta24))*:
|
|
27
|
+
|
|
28
|
+
convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] (#8460)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### :sparkles: New Features
|
|
32
|
+
- [`2be1e0e`](https://github.com/tobymao/sqlglot/commit/2be1e0e2addc0ef01cfa3fd3cf2ef751cdbf411d) - **optimizer**: annotate `bit_xor` for duckdb *(PR [#8452](https://github.com/tobymao/sqlglot/pull/8452) by [@opencode13241-eng](https://github.com/opencode13241-eng))*
|
|
33
|
+
- [`7e48d16`](https://github.com/tobymao/sqlglot/commit/7e48d16936216f9f93d7a52baef0e482e3fb14e7) - **optimizer**: add #schema fixture directive *(PR [#8435](https://github.com/tobymao/sqlglot/pull/8435) by [@fivetran-kwoodbeck](https://github.com/fivetran-kwoodbeck))*
|
|
34
|
+
|
|
35
|
+
### :bug: Bug Fixes
|
|
36
|
+
- [`1d40af1`](https://github.com/tobymao/sqlglot/commit/1d40af146d77dcf890ae18c1a59e649bf0862db3) - **optimizer**: unqualified semi/anti join column bound to table joined *(PR [#8430](https://github.com/tobymao/sqlglot/pull/8430) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
37
|
+
- [`d9b2b96`](https://github.com/tobymao/sqlglot/commit/d9b2b9660be8a6b77a0bb0475f6bf0509c6c6aa0) - **parser**: constraint parsing fixup *(PR [#8457](https://github.com/tobymao/sqlglot/pull/8457) by [@georgesittas](https://github.com/georgesittas))*
|
|
38
|
+
- [`e3f71dc`](https://github.com/tobymao/sqlglot/commit/e3f71dc1a1186ada4b017a5f2498b8c2b0a8a25b) - **snowflake**: decode backslash escape sequences in string literals *(PR [#8456](https://github.com/tobymao/sqlglot/pull/8456) by [@georgesittas](https://github.com/georgesittas))*
|
|
39
|
+
- :arrow_lower_right: *fixes issue [#4344](https://github.com/tobymao/sqlglot/issues/4344) opened by [@dylanscott](https://github.com/dylanscott)*
|
|
40
|
+
- :arrow_lower_right: *fixes issue [#8441](https://github.com/tobymao/sqlglot/issues/8441) opened by [@yvonne-chou-1](https://github.com/yvonne-chou-1)*
|
|
41
|
+
- [`b4d9e37`](https://github.com/tobymao/sqlglot/commit/b4d9e37d84a61eeb78e8d652f697e2e0d4d57869) - **athena**: inherit Trino dialect, parser and generator defaults *(PR [#8464](https://github.com/tobymao/sqlglot/pull/8464) by [@georgesittas](https://github.com/georgesittas))*
|
|
42
|
+
- :arrow_lower_right: *fixes issue [#8458](https://github.com/tobymao/sqlglot/issues/8458) opened by [@deepyaman](https://github.com/deepyaman)*
|
|
43
|
+
- [`d84f7f3`](https://github.com/tobymao/sqlglot/commit/d84f7f3ee1ff50778c93970b086d59692714dcdc) - preserve BD literal semantics in Hive and Spark *(PR [#8455](https://github.com/tobymao/sqlglot/pull/8455) by [@georgesittas](https://github.com/georgesittas))*
|
|
44
|
+
- [`1122046`](https://github.com/tobymao/sqlglot/commit/11220460d0e78a3c83f14b006239f636e4ddde71) - **spark**: convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] *(PR [#8460](https://github.com/tobymao/sqlglot/pull/8460) by [@anishmehta24](https://github.com/anishmehta24))*
|
|
45
|
+
- [`18520e2`](https://github.com/tobymao/sqlglot/commit/18520e2b5bfa3f1d7ed1a261d1bd463132054db1) - **clickhouse**: generate varPop for VariancePop [CLAUDE] *(PR [#8469](https://github.com/tobymao/sqlglot/pull/8469) by [@ekut](https://github.com/ekut))*
|
|
46
|
+
- [`2960bdd`](https://github.com/tobymao/sqlglot/commit/2960bdd7470f1c21518710ed468466b9bab4bb7b) - **optimizer**: preserve tautological aggregate filters [CODEX] *(PR [#8466](https://github.com/tobymao/sqlglot/pull/8466) by [@Boulea7](https://github.com/Boulea7))*
|
|
47
|
+
- [`840b482`](https://github.com/tobymao/sqlglot/commit/840b4823e649e380e1dda30cf21907baebb6c58c) - **postgres**: keep WITH ORDINALITY alias columns on LATERAL UNNEST [GROK] *(PR [#8463](https://github.com/tobymao/sqlglot/pull/8463) by [@00200200](https://github.com/00200200))*
|
|
48
|
+
- :arrow_lower_right: *fixes issue [#8462](https://github.com/tobymao/sqlglot/issues/8462) opened by [@SoTrx](https://github.com/SoTrx)*
|
|
49
|
+
- [`aa70202`](https://github.com/tobymao/sqlglot/commit/aa702020725f4d1591cfb2d308c72937a38e8fd4) - **optimizer**: qualify struct paths with conflicting aliases [CODEX] *(PR [#8467](https://github.com/tobymao/sqlglot/pull/8467) by [@tobymao](https://github.com/tobymao))*
|
|
50
|
+
- [`b54d32f`](https://github.com/tobymao/sqlglot/commit/b54d32f036d4c1158bb889324f4ac6d2846d2701) - **optimizer**: stop struct lookup at nearest alias [CODEX] *(commit by [@tobymao](https://github.com/tobymao))*
|
|
51
|
+
- [`5d16fa8`](https://github.com/tobymao/sqlglot/commit/5d16fa83bfb8f3582eaffa4b99c7d05a061d8a76) - **ci**: publish sqlglot independently of sqlglotc [CODEX] *(commit by [@tobymao](https://github.com/tobymao))*
|
|
52
|
+
|
|
53
|
+
### :recycle: Refactors
|
|
54
|
+
- [`65a0e22`](https://github.com/tobymao/sqlglot/commit/65a0e22447fcca9ea4a89f6167954fbb872c8e6d) - **optimizer**: new projection pushdown algorithm *(PR [#8440](https://github.com/tobymao/sqlglot/pull/8440) by [@georgesittas](https://github.com/georgesittas))*
|
|
55
|
+
- [`ac940f0`](https://github.com/tobymao/sqlglot/commit/ac940f016a1d398137b4d666db0f191e6c4b6d1f) - **tokenizer**: generalize backslash escape handling, report unterminated escapes *(PR [#8470](https://github.com/tobymao/sqlglot/pull/8470) by [@georgesittas](https://github.com/georgesittas))*
|
|
56
|
+
|
|
57
|
+
|
|
4
58
|
## [v30.20.0] - 2026-09-27
|
|
5
59
|
### :boom: BREAKING CHANGES
|
|
6
60
|
- due to [`1d0e3f3`](https://github.com/tobymao/sqlglot/commit/1d0e3f34864037c54cf6bdf45af594db62ad7319) - Fix mysql roundtrip for DATE_ADD and DATE_SUB *(PR [#8417](https://github.com/tobymao/sqlglot/pull/8417) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
@@ -15990,3 +16044,4 @@ pip install "sqlglot[c]" # compiled — faster, but no subclassing
|
|
|
15990
16044
|
[v30.18.0]: https://github.com/tobymao/sqlglot/compare/v30.17.0...v30.18.0
|
|
15991
16045
|
[v30.19.0]: https://github.com/tobymao/sqlglot/compare/v30.18.0...v30.19.0
|
|
15992
16046
|
[v30.20.0]: https://github.com/tobymao/sqlglot/compare/v30.19.0...v30.20.0
|
|
16047
|
+
[v30.21.0]: https://github.com/tobymao/sqlglot/compare/v30.20.0...v30.21.0
|
|
@@ -42,7 +42,7 @@ install-dev:
|
|
|
42
42
|
fi; \
|
|
43
43
|
fi
|
|
44
44
|
|
|
45
|
-
# sqlglotc requires Python 3.10+ (
|
|
45
|
+
# sqlglotc requires Python 3.10+ (mypy 2.4+ dropped 3.9). On 3.9
|
|
46
46
|
# we skip the C build; tests fall back to pure-Python sqlglot.
|
|
47
47
|
PY_GE_310 := $(shell python -c "import sys; print(int(sys.version_info >= (3, 10)))")
|
|
48
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglot
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.22.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
|
|
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
|
|
|
19
19
|
License-File: LICENSE
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: duckdb>=0.6; extra == "dev"
|
|
22
|
-
Requires-Dist:
|
|
22
|
+
Requires-Dist: mypy>=2.4.0; python_version >= "3.10" and extra == "dev"
|
|
23
23
|
Requires-Dist: mypy; python_version < "3.10" and extra == "dev"
|
|
24
24
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
25
25
|
Requires-Dist: pandas; extra == "dev"
|
|
@@ -34,10 +34,10 @@ Requires-Dist: types-pytz; extra == "dev"
|
|
|
34
34
|
Requires-Dist: typing_extensions; extra == "dev"
|
|
35
35
|
Requires-Dist: pyperf; extra == "dev"
|
|
36
36
|
Provides-Extra: c
|
|
37
|
-
Requires-Dist: sqlglotc==30.
|
|
37
|
+
Requires-Dist: sqlglotc==30.22.0; python_version >= "3.10" and extra == "c"
|
|
38
38
|
Provides-Extra: rs
|
|
39
39
|
Requires-Dist: sqlglotrs==0.13.0; extra == "rs"
|
|
40
|
-
Requires-Dist: sqlglotc==30.
|
|
40
|
+
Requires-Dist: sqlglotc==30.22.0; python_version >= "3.10" and extra == "rs"
|
|
41
41
|
Dynamic: license-file
|
|
42
42
|
Dynamic: provides-extra
|
|
43
43
|
|
|
@@ -87,11 +87,13 @@ From PyPI:
|
|
|
87
87
|
# Pure python version
|
|
88
88
|
pip3 install sqlglot
|
|
89
89
|
|
|
90
|
-
# C extensions compiled with mypyc
|
|
90
|
+
# C extensions compiled with mypyc (Python 3.10+)
|
|
91
91
|
# prebuilt wheel if available for your platform, otherwise builds from source
|
|
92
92
|
pip3 install "sqlglot[c]"
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
On Python 3.9, `sqlglot[c]` installs the pure Python version.
|
|
96
|
+
|
|
95
97
|
Or with a local checkout:
|
|
96
98
|
|
|
97
99
|
```
|
|
@@ -581,12 +583,12 @@ make docs-serve
|
|
|
581
583
|
## Run Tests and Lint
|
|
582
584
|
|
|
583
585
|
```
|
|
584
|
-
make style #
|
|
586
|
+
make style # Format, lint, and type-check
|
|
585
587
|
make unit # Only unit tests (pure Python)
|
|
586
588
|
make test # Unit and integration tests (pure Python)
|
|
587
589
|
make unitc # Only unit tests (mypyc compiled)
|
|
588
590
|
make testc # Unit and integration tests (mypyc compiled)
|
|
589
|
-
make check # Full test suite
|
|
591
|
+
make check # Full test suite, formatting, linting, and type checks
|
|
590
592
|
make clean # Remove compiled C artifacts (.so files, build dirs)
|
|
591
593
|
```
|
|
592
594
|
|
|
@@ -616,18 +618,28 @@ sqlglot, sqltree, sqlparse, and sqlfluff are python based whereas sqloxide and p
|
|
|
616
618
|
| many_numbers | 0.103898 (1.00) | 0.024483 (0.24) | 0.120119 (1.16) | N/A | N/A | 0.031667 (0.30) | 0.026880 (0.26) |
|
|
617
619
|
|
|
618
620
|
```
|
|
619
|
-
make bench # Run parsing
|
|
621
|
+
make bench # Run parsing, transpilation, and optimization benchmarks
|
|
622
|
+
make bench-parse # Run parsing benchmark
|
|
623
|
+
make bench-transpile # Run transpilation benchmark
|
|
620
624
|
make bench-optimize # Run optimization benchmark
|
|
621
625
|
```
|
|
622
626
|
|
|
623
627
|
## Optional Dependencies
|
|
624
628
|
|
|
625
|
-
SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify
|
|
629
|
+
SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify constant date and interval arithmetic. With dateutil installed, the optimizer simplifies:
|
|
630
|
+
|
|
631
|
+
```sql
|
|
632
|
+
DATE '2021-01-01' + INTERVAL '1' MONTH
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
to:
|
|
626
636
|
|
|
627
637
|
```sql
|
|
628
|
-
|
|
638
|
+
CAST('2021-02-01' AS DATE)
|
|
629
639
|
```
|
|
630
640
|
|
|
641
|
+
Without dateutil, the optimizer leaves this arithmetic unevaluated.
|
|
642
|
+
|
|
631
643
|
## Supported Dialects
|
|
632
644
|
|
|
633
645
|
| Dialect | Support Level |
|
|
@@ -44,11 +44,13 @@ From PyPI:
|
|
|
44
44
|
# Pure python version
|
|
45
45
|
pip3 install sqlglot
|
|
46
46
|
|
|
47
|
-
# C extensions compiled with mypyc
|
|
47
|
+
# C extensions compiled with mypyc (Python 3.10+)
|
|
48
48
|
# prebuilt wheel if available for your platform, otherwise builds from source
|
|
49
49
|
pip3 install "sqlglot[c]"
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
On Python 3.9, `sqlglot[c]` installs the pure Python version.
|
|
53
|
+
|
|
52
54
|
Or with a local checkout:
|
|
53
55
|
|
|
54
56
|
```
|
|
@@ -538,12 +540,12 @@ make docs-serve
|
|
|
538
540
|
## Run Tests and Lint
|
|
539
541
|
|
|
540
542
|
```
|
|
541
|
-
make style #
|
|
543
|
+
make style # Format, lint, and type-check
|
|
542
544
|
make unit # Only unit tests (pure Python)
|
|
543
545
|
make test # Unit and integration tests (pure Python)
|
|
544
546
|
make unitc # Only unit tests (mypyc compiled)
|
|
545
547
|
make testc # Unit and integration tests (mypyc compiled)
|
|
546
|
-
make check # Full test suite
|
|
548
|
+
make check # Full test suite, formatting, linting, and type checks
|
|
547
549
|
make clean # Remove compiled C artifacts (.so files, build dirs)
|
|
548
550
|
```
|
|
549
551
|
|
|
@@ -573,18 +575,28 @@ sqlglot, sqltree, sqlparse, and sqlfluff are python based whereas sqloxide and p
|
|
|
573
575
|
| many_numbers | 0.103898 (1.00) | 0.024483 (0.24) | 0.120119 (1.16) | N/A | N/A | 0.031667 (0.30) | 0.026880 (0.26) |
|
|
574
576
|
|
|
575
577
|
```
|
|
576
|
-
make bench # Run parsing
|
|
578
|
+
make bench # Run parsing, transpilation, and optimization benchmarks
|
|
579
|
+
make bench-parse # Run parsing benchmark
|
|
580
|
+
make bench-transpile # Run transpilation benchmark
|
|
577
581
|
make bench-optimize # Run optimization benchmark
|
|
578
582
|
```
|
|
579
583
|
|
|
580
584
|
## Optional Dependencies
|
|
581
585
|
|
|
582
|
-
SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify
|
|
586
|
+
SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify constant date and interval arithmetic. With dateutil installed, the optimizer simplifies:
|
|
587
|
+
|
|
588
|
+
```sql
|
|
589
|
+
DATE '2021-01-01' + INTERVAL '1' MONTH
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
to:
|
|
583
593
|
|
|
584
594
|
```sql
|
|
585
|
-
|
|
595
|
+
CAST('2021-02-01' AS DATE)
|
|
586
596
|
```
|
|
587
597
|
|
|
598
|
+
Without dateutil, the optimizer leaves this arithmetic unevaluated.
|
|
599
|
+
|
|
588
600
|
## Supported Dialects
|
|
589
601
|
|
|
590
602
|
| Dialect | Support Level |
|
|
@@ -7,9 +7,9 @@ setup(
|
|
|
7
7
|
extras_require={
|
|
8
8
|
"dev": [
|
|
9
9
|
"duckdb>=0.6",
|
|
10
|
-
#
|
|
10
|
+
# mypy 2.4+ is the build dep for sqlglotc and only ships
|
|
11
11
|
# for py3.10+; on py3.9 just use upstream mypy for type checking.
|
|
12
|
-
"
|
|
12
|
+
"mypy >= 2.4.0; python_version >= '3.10'",
|
|
13
13
|
"mypy; python_version < '3.10'",
|
|
14
14
|
"setuptools_scm",
|
|
15
15
|
"pandas",
|
|
@@ -25,7 +25,7 @@ setup(
|
|
|
25
25
|
"pyperf",
|
|
26
26
|
],
|
|
27
27
|
# Compiles from source on the user's machine. Requires Python 3.10+
|
|
28
|
-
# because the build dep (
|
|
28
|
+
# because the build dep (mypy 2.4+) dropped 3.9; on 3.9
|
|
29
29
|
# `pip install sqlglot[c]` is a no-op and you just get pure-Python sqlglot.
|
|
30
30
|
"c": [f"sqlglotc=={version}; python_version >= '3.10'"],
|
|
31
31
|
# Deprecated: the Rust tokenizer has been replaced by sqlglotc.
|
|
@@ -81,6 +81,7 @@ def tokenize(sql: str, read: DialectType = None, dialect: DialectType = None) ->
|
|
|
81
81
|
Args:
|
|
82
82
|
sql: the SQL code string to tokenize.
|
|
83
83
|
read: the SQL dialect to apply during tokenizing (eg. "spark", "hive", "presto", "mysql").
|
|
84
|
+
See `sqlglot.dialects.Dialects` for options.
|
|
84
85
|
dialect: the SQL dialect (alias for read).
|
|
85
86
|
|
|
86
87
|
Returns:
|
|
@@ -101,6 +102,7 @@ def parse(
|
|
|
101
102
|
Args:
|
|
102
103
|
sql: the SQL code string to parse.
|
|
103
104
|
read: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
|
|
105
|
+
See `sqlglot.dialects.Dialects` for options.
|
|
104
106
|
dialect: the SQL dialect (alias for read).
|
|
105
107
|
**opts: other `sqlglot.parser.Parser` options.
|
|
106
108
|
|
|
@@ -144,6 +146,7 @@ def parse_one(
|
|
|
144
146
|
Args:
|
|
145
147
|
sql: the SQL code string to parse.
|
|
146
148
|
read: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
|
|
149
|
+
See `sqlglot.dialects.Dialects` for options.
|
|
147
150
|
dialect: the SQL dialect (alias for read)
|
|
148
151
|
into: the SQLGlot Expr to parse into.
|
|
149
152
|
**opts: other `sqlglot.parser.Parser` options.
|
|
@@ -180,7 +183,9 @@ def transpile(
|
|
|
180
183
|
Args:
|
|
181
184
|
sql: the SQL code string to transpile.
|
|
182
185
|
read: the source dialect used to parse the input string (eg. "spark", "hive", "presto", "mysql").
|
|
186
|
+
See `sqlglot.dialects.Dialects` for options.
|
|
183
187
|
write: the target dialect into which the input should be transformed (eg. "spark", "hive", "presto", "mysql").
|
|
188
|
+
See `sqlglot.dialects.Dialects` for options.
|
|
184
189
|
identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:
|
|
185
190
|
the source and the target dialect.
|
|
186
191
|
error_level: the desired error level of the parser.
|
|
@@ -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.22.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (30, 22, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gb8333a81f'
|
|
@@ -29,7 +29,7 @@ class BigQuery(Dialect):
|
|
|
29
29
|
HEX_LOWERCASE = True
|
|
30
30
|
FORCE_EARLY_ALIAS_REF_EXPANSION = True
|
|
31
31
|
EXPAND_ONLY_GROUP_ALIAS_REF = True
|
|
32
|
-
|
|
32
|
+
ORIGINAL_NAME_META_KEY = "bigquery_name"
|
|
33
33
|
HEX_STRING_IS_INTEGER_TYPE = True
|
|
34
34
|
BYTE_STRING_IS_BYTES_TYPE = True
|
|
35
35
|
UUID_IS_STRING_TYPE = True
|
|
@@ -168,6 +168,14 @@ class BigQuery(Dialect):
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
class Tokenizer(tokens.Tokenizer):
|
|
171
|
+
NUMERIC_ESCAPES = {
|
|
172
|
+
"x": (16, 2, 2, 0xFF),
|
|
173
|
+
"X": (16, 2, 2, 0xFF),
|
|
174
|
+
"u": (16, 4, 4, 0xFFFF),
|
|
175
|
+
"U": (16, 8, 8, 0x10FFFF),
|
|
176
|
+
"0": (8, 3, 3, 0xFF),
|
|
177
|
+
}
|
|
178
|
+
DROP_UNKNOWN_ESCAPES = True
|
|
171
179
|
QUOTES = ["'", '"', '"""', "'''"]
|
|
172
180
|
COMMENTS = ["--", "#", ("/*", "*/")]
|
|
173
181
|
IDENTIFIERS = ["`"]
|
|
@@ -19,7 +19,7 @@ class ClickHouse(Dialect):
|
|
|
19
19
|
SUPPORTS_USER_DEFINED_TYPES = False
|
|
20
20
|
LOG_BASE_FIRST: bool | None = None
|
|
21
21
|
FORCE_EARLY_ALIAS_REF_EXPANSION = True
|
|
22
|
-
|
|
22
|
+
ORIGINAL_NAME_META_KEY = "clickhouse_name"
|
|
23
23
|
NUMBERS_CAN_BE_UNDERSCORE_SEPARATED = True
|
|
24
24
|
IDENTIFIERS_CAN_START_WITH_DIGIT = True
|
|
25
25
|
HEX_STRING_IS_INTEGER_TYPE = True
|
|
@@ -31,6 +31,13 @@ class ClickHouse(Dialect):
|
|
|
31
31
|
|
|
32
32
|
UNESCAPED_SEQUENCES = {
|
|
33
33
|
"\\0": "\0",
|
|
34
|
+
"\\e": "\x1b",
|
|
35
|
+
"\\N": "",
|
|
36
|
+
"\\/": "/",
|
|
37
|
+
'\\"': '"',
|
|
38
|
+
"\\=": "=",
|
|
39
|
+
"\\`": "`",
|
|
40
|
+
**{"\\" + chr(i): chr(i) for i in range(1, 32)},
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
CREATABLE_KIND_MAPPING = {"DATABASE": "SCHEMA"}
|
|
@@ -68,7 +75,10 @@ class ClickHouse(Dialect):
|
|
|
68
75
|
return column_aliases
|
|
69
76
|
|
|
70
77
|
class Tokenizer(tokens.Tokenizer):
|
|
78
|
+
NUMERIC_ESCAPES = {"x": (16, 2, 2, 0xFF)}
|
|
79
|
+
NUMERIC_ESCAPES_ARE_BYTES = True
|
|
71
80
|
COMMENTS = ["--", "#", "#!", ("/*", "*/")]
|
|
81
|
+
COMMENTS_TERMINATE_AT_NEWLINE_ONLY = True
|
|
72
82
|
IDENTIFIERS = ['"', "`"]
|
|
73
83
|
IDENTIFIER_ESCAPES = ["\\"]
|
|
74
84
|
STRING_ESCAPES = ["'", "\\"]
|
|
@@ -140,6 +140,19 @@ class NormalizationStrategy(str, AutoName):
|
|
|
140
140
|
"""Always case-insensitive (uppercase), regardless of quotes."""
|
|
141
141
|
|
|
142
142
|
|
|
143
|
+
class UsingColumnOrder(str, AutoName):
|
|
144
|
+
"""Where star expansion places the columns of a `USING` or `NATURAL` join."""
|
|
145
|
+
|
|
146
|
+
USING_LIST = auto()
|
|
147
|
+
"""First, in the order they're listed in USING (SQL standard, e.g. Postgres)."""
|
|
148
|
+
|
|
149
|
+
LEFT_TABLE = auto()
|
|
150
|
+
"""First, in the order they appear in the left table (e.g. MySQL)."""
|
|
151
|
+
|
|
152
|
+
IN_PLACE = auto()
|
|
153
|
+
"""Where the left table has them (e.g. DuckDB)."""
|
|
154
|
+
|
|
155
|
+
|
|
143
156
|
# "Strict" dialects (e.g. modern Hive, Spark 3+) map their zero-padded MM/dd/HH/hh/mm/ss to these in
|
|
144
157
|
# TIME_MAPPING so they roundtrip, since a lax %m/%d renders non-padded there for parse expressions
|
|
145
158
|
# (see HiveGenerator.format_time).
|
|
@@ -343,7 +356,15 @@ class _Dialect(type):
|
|
|
343
356
|
# The filter is necessary because of `\\a -> a` in Snowflake; we can't replace `a` with `\a`.
|
|
344
357
|
v: k
|
|
345
358
|
for k, v in klass.UNESCAPED_SEQUENCES.items()
|
|
346
|
-
|
|
359
|
+
# Sequences that only drop the backslash (e.g. "\\\n" -> "\n") aren't needed for generation
|
|
360
|
+
if v == "\\" or (not v.isprintable() and k[1:] != v)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
identifier_escapes = klass.tokenizer_class.IDENTIFIER_ESCAPES
|
|
364
|
+
klass.IDENTIFIER_ESCAPED_SEQUENCES = {
|
|
365
|
+
v: k
|
|
366
|
+
for k, v in klass.UNESCAPED_SEQUENCES.items()
|
|
367
|
+
if k[0] in identifier_escapes and v in identifier_escapes
|
|
347
368
|
}
|
|
348
369
|
|
|
349
370
|
# Prefer hex, then octal, then Unicode for numeric control-character escapes.
|
|
@@ -428,11 +449,11 @@ class Dialect(metaclass=_Dialect):
|
|
|
428
449
|
False: Disables function name normalization.
|
|
429
450
|
"""
|
|
430
451
|
|
|
431
|
-
|
|
452
|
+
ORIGINAL_NAME_META_KEY: str | None = None
|
|
432
453
|
"""
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
e.g JSON_VALUE vs JSON_EXTRACT_SCALAR in BigQuery
|
|
454
|
+
Dialect-specific metadata key for preserving original function names, or None to disable.
|
|
455
|
+
Only generators using the same key reuse these names, allowing round trips of aliases
|
|
456
|
+
that share an AST node, e.g. JSON_VALUE vs JSON_EXTRACT_SCALAR in BigQuery.
|
|
436
457
|
"""
|
|
437
458
|
|
|
438
459
|
LOG_BASE_FIRST: bool | None = True
|
|
@@ -490,6 +511,9 @@ class Dialect(metaclass=_Dialect):
|
|
|
490
511
|
BYTE_STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = False
|
|
491
512
|
"""Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES."""
|
|
492
513
|
|
|
514
|
+
IDENTIFIER_ESCAPED_SEQUENCES: dict[str, str] = {}
|
|
515
|
+
"""Mapping of an identifier escape char (`\\`) to its escaped version (`\\\\`). Set by the metaclass based on the tokenizer's IDENTIFIER_ESCAPES."""
|
|
516
|
+
|
|
493
517
|
INVERSE_VECTOR_TYPE_ALIASES: dict[str, str] = {}
|
|
494
518
|
"""Mapping of vector type aliases back to their canonical names. Overridden by dialects like SingleStore."""
|
|
495
519
|
|
|
@@ -651,6 +675,19 @@ class Dialect(metaclass=_Dialect):
|
|
|
651
675
|
they must be explicitly selected.
|
|
652
676
|
"""
|
|
653
677
|
|
|
678
|
+
USING_COLUMN_ORDER = UsingColumnOrder.USING_LIST
|
|
679
|
+
"""
|
|
680
|
+
Where star expansion places the columns of a `USING` or `NATURAL` join.
|
|
681
|
+
|
|
682
|
+
Given `a(a_id, k1, k2)` and `b(k2, b_id, k1)`, `SELECT * FROM a JOIN b USING (k2, k1)` returns:
|
|
683
|
+
- `USING_LIST`: `k2, k1, a_id, b_id`
|
|
684
|
+
- `LEFT_TABLE`: `k1, k2, a_id, b_id`
|
|
685
|
+
- `IN_PLACE`: `a_id, k1, k2, b_id`
|
|
686
|
+
|
|
687
|
+
When join columns come first, this applies at every join: each USING join moves its columns
|
|
688
|
+
ahead of all the columns to its left.
|
|
689
|
+
"""
|
|
690
|
+
|
|
654
691
|
QUERY_RESULTS_ARE_STRUCTS = False
|
|
655
692
|
"""
|
|
656
693
|
Whether query results are typed as structs in metadata for type inference.
|
|
@@ -774,6 +811,9 @@ class Dialect(metaclass=_Dialect):
|
|
|
774
811
|
# Whether ADD is present for each column added by ALTER TABLE
|
|
775
812
|
ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN = True
|
|
776
813
|
|
|
814
|
+
# Whether DROP is present for each column dropped by ALTER TABLE
|
|
815
|
+
ALTER_TABLE_DROP_REQUIRED_FOR_EACH_COLUMN = True
|
|
816
|
+
|
|
777
817
|
# Whether the value/LHS of the TRY_CAST(<value> AS <type>) should strictly be a
|
|
778
818
|
# STRING type (Snowflake's case) or can be of any type
|
|
779
819
|
TRY_CAST_REQUIRES_STRING: bool | None = None
|
|
@@ -1305,7 +1345,13 @@ def inline_array_sql(self: Generator, expression: exp.Expr) -> str:
|
|
|
1305
1345
|
|
|
1306
1346
|
def inline_array_unless_query(self: Generator, expression: exp.Expr) -> str:
|
|
1307
1347
|
elem = seq_get(expression.expressions, 0)
|
|
1308
|
-
if
|
|
1348
|
+
if (
|
|
1349
|
+
len(expression.expressions) == 1
|
|
1350
|
+
and isinstance(elem, exp.Query)
|
|
1351
|
+
# value_constructor=True keeps scalar subqueries as array elements. In [(SELECT …)], the
|
|
1352
|
+
# subquery supplies one scalar value; in ARRAY(SELECT …) (BigQuery), the query supplies rows.
|
|
1353
|
+
and not expression.args.get("value_constructor")
|
|
1354
|
+
):
|
|
1309
1355
|
return self.func("ARRAY", elem)
|
|
1310
1356
|
return inline_array_sql(self, expression)
|
|
1311
1357
|
|
|
@@ -1358,6 +1404,71 @@ def no_map_from_entries_sql(self: Generator, expression: exp.MapFromEntries) ->
|
|
|
1358
1404
|
return ""
|
|
1359
1405
|
|
|
1360
1406
|
|
|
1407
|
+
def no_filter_sql(self: Generator, expression: exp.Filter) -> str:
|
|
1408
|
+
# Rewrite `AGG(x) FILTER (WHERE cond)` into an equivalent conditional aggregation, i.e. wrap
|
|
1409
|
+
# the input values in an IF, which works because aggregate functions skip NULLs
|
|
1410
|
+
agg = expression.this
|
|
1411
|
+
# IGNORE NULLS can wrap the aggregate, but the condition still belongs to its arguments
|
|
1412
|
+
if isinstance(agg, exp.IgnoreNulls):
|
|
1413
|
+
agg = agg.this
|
|
1414
|
+
|
|
1415
|
+
agg_arg = seq_get(agg.expressions, 0) if isinstance(agg, exp.Anonymous) else agg.this
|
|
1416
|
+
cond = expression.expression.this
|
|
1417
|
+
|
|
1418
|
+
if isinstance(agg, exp.WithinGroup):
|
|
1419
|
+
# Ordered-set aggregates take their input from the ORDER BY key, so the
|
|
1420
|
+
# condition has to wrap that instead of the aggregate's own argument
|
|
1421
|
+
if isinstance(agg_arg, (exp.Mode, *exp.PERCENTILES)):
|
|
1422
|
+
for ordered in agg.expression.expressions:
|
|
1423
|
+
key = ordered.this
|
|
1424
|
+
key.replace(exp.If(this=cond.copy(), true=key.copy(), false=exp.null()))
|
|
1425
|
+
|
|
1426
|
+
return self.sql(expression.this)
|
|
1427
|
+
|
|
1428
|
+
# Besides the ordered-set aggregates, these are the only functions that take WITHIN GROUP
|
|
1429
|
+
# and the input values as arguments, so anything else can't be rewritten correctly
|
|
1430
|
+
if isinstance(agg_arg, (exp.ArrayAgg, exp.GroupConcat)):
|
|
1431
|
+
agg_arg = agg_arg.this
|
|
1432
|
+
else:
|
|
1433
|
+
self.unsupported("Unable to rewrite FILTER into the aggregate's arguments")
|
|
1434
|
+
return self.sql(expression.this)
|
|
1435
|
+
|
|
1436
|
+
# Folding the condition into COUNT_IF's predicate avoids an IF that returns a predicate, which
|
|
1437
|
+
# dialects without a boolean type (e.g. T-SQL) reject
|
|
1438
|
+
if isinstance(agg, exp.CountIf) and not isinstance(agg_arg, exp.Distinct):
|
|
1439
|
+
return self.sql(exp.CountIf(this=exp.and_(cond, agg_arg)))
|
|
1440
|
+
|
|
1441
|
+
# `COUNT(*/t.*) FILTER (WHERE cond)` counts qualifying rows, but a star can't be an IF
|
|
1442
|
+
# argument: `IF(cond, *, NULL)` expands to multiple columns once the table has 2+ of
|
|
1443
|
+
# them. Each dialect generates CountIf in its own way instead, e.g. COUNT_IF or COUNTIF.
|
|
1444
|
+
if isinstance(agg, exp.Count) and (agg_arg is None or agg_arg.is_star):
|
|
1445
|
+
return self.sql(exp.CountIf(this=cond))
|
|
1446
|
+
|
|
1447
|
+
# `DISTINCT` and `ORDER BY` are part of the aggregate's own argument list, so the
|
|
1448
|
+
# condition has to wrap the values underneath them rather than the whole clause --
|
|
1449
|
+
# `IF(cond, DISTINCT x, NULL)` is not a call any dialect accepts.
|
|
1450
|
+
if isinstance(agg_arg, exp.Order):
|
|
1451
|
+
agg_arg = agg_arg.this
|
|
1452
|
+
|
|
1453
|
+
if isinstance(agg_arg, exp.Distinct):
|
|
1454
|
+
targets = agg_arg.expressions
|
|
1455
|
+
else:
|
|
1456
|
+
targets = [agg_arg]
|
|
1457
|
+
|
|
1458
|
+
for target in targets:
|
|
1459
|
+
target.replace(exp.If(this=cond.copy(), true=target.copy(), false=exp.null()))
|
|
1460
|
+
|
|
1461
|
+
# In dialects where ARRAY_AGG keeps NULLs (e.g. BigQuery, which even fails on them), the
|
|
1462
|
+
# rows that don't satisfy the condition have to be dropped explicitly
|
|
1463
|
+
if isinstance(agg, exp.ArrayAgg) and self.dialect.ARRAY_AGG_INCLUDES_NULLS:
|
|
1464
|
+
# IGNORE NULLS already drops them, so no extra FILTER (WHERE x IS NOT NULL) is needed
|
|
1465
|
+
agg.set("nulls_excluded", None)
|
|
1466
|
+
if agg is expression.this:
|
|
1467
|
+
return self.sql(exp.IgnoreNulls(this=agg))
|
|
1468
|
+
|
|
1469
|
+
return self.sql(expression.this)
|
|
1470
|
+
|
|
1471
|
+
|
|
1361
1472
|
def property_sql(self: Generator, expression: exp.Property) -> str:
|
|
1362
1473
|
return f"{self.property_name(expression, string_key=True)}={self.sql(expression, 'value')}"
|
|
1363
1474
|
|
|
@@ -1648,11 +1759,7 @@ def build_formatted_time(
|
|
|
1648
1759
|
"""
|
|
1649
1760
|
|
|
1650
1761
|
def _builder(args: BuilderArgs, dialect: Dialect) -> E:
|
|
1651
|
-
target_dialect = (
|
|
1652
|
-
t.cast(Dialect, Dialect[dialect_override])
|
|
1653
|
-
if isinstance(dialect_override, str)
|
|
1654
|
-
else dialect
|
|
1655
|
-
)
|
|
1762
|
+
target_dialect = Dialect[dialect_override] if isinstance(dialect_override, str) else dialect
|
|
1656
1763
|
|
|
1657
1764
|
fmt = seq_get(args, 1)
|
|
1658
1765
|
if not fmt:
|
|
@@ -10,6 +10,10 @@ class Doris(MySQL):
|
|
|
10
10
|
DATEINT_FORMAT = "'yyyyMMdd'"
|
|
11
11
|
TIME_FORMAT = "'yyyy-MM-dd HH:mm:ss'"
|
|
12
12
|
|
|
13
|
+
class Tokenizer(MySQL.Tokenizer):
|
|
14
|
+
DASH_COMMENT_REQUIRES_BOUNDARY = False
|
|
15
|
+
COMMENTS_TERMINATE_AT_NEWLINE_ONLY = False
|
|
16
|
+
|
|
13
17
|
Parser = DorisParser
|
|
14
18
|
|
|
15
19
|
Generator = DorisGenerator
|
|
@@ -9,7 +9,7 @@ from sqlglot.parsers.drill import DrillParser
|
|
|
9
9
|
|
|
10
10
|
class Drill(Dialect):
|
|
11
11
|
NORMALIZE_FUNCTIONS: bool | str = False
|
|
12
|
-
|
|
12
|
+
ORIGINAL_NAME_META_KEY = "drill_name"
|
|
13
13
|
NULL_ORDERING = "nulls_are_last"
|
|
14
14
|
DATE_FORMAT = "'yyyy-MM-dd'"
|
|
15
15
|
DATEINT_FORMAT = "'yyyyMMdd'"
|
|
@@ -53,7 +53,7 @@ class Drill(Dialect):
|
|
|
53
53
|
|
|
54
54
|
class Tokenizer(tokens.Tokenizer):
|
|
55
55
|
IDENTIFIERS = ["`"]
|
|
56
|
-
STRING_ESCAPES = ["
|
|
56
|
+
STRING_ESCAPES = ["'"]
|
|
57
57
|
|
|
58
58
|
KEYWORDS = tokens.Tokenizer.KEYWORDS.copy()
|
|
59
59
|
KEYWORDS.pop("/*+")
|
|
@@ -6,6 +6,7 @@ from sqlglot import exp, tokens
|
|
|
6
6
|
from sqlglot.dialects.dialect import (
|
|
7
7
|
Dialect,
|
|
8
8
|
NormalizationStrategy,
|
|
9
|
+
UsingColumnOrder,
|
|
9
10
|
)
|
|
10
11
|
from sqlglot.generators.duckdb import DuckDBGenerator, WS_CONTROL_CHARS_TO_DUCK # noqa: F401
|
|
11
12
|
from sqlglot.parsers.duckdb import DuckDBParser
|
|
@@ -22,9 +23,11 @@ class DuckDB(Dialect):
|
|
|
22
23
|
SUPPORTS_ORDER_BY_ALL = True
|
|
23
24
|
SUPPORTS_LIMIT_ALL = True
|
|
24
25
|
SUPPORTS_FIXED_SIZE_ARRAYS = True
|
|
26
|
+
TABLES_REFERENCEABLE_AS_COLUMNS = True
|
|
25
27
|
STRICT_JSON_PATH_SYNTAX = False
|
|
26
28
|
NUMBERS_CAN_BE_UNDERSCORE_SEPARATED = True
|
|
27
29
|
UUID_IS_STRING_TYPE = False
|
|
30
|
+
USING_COLUMN_ORDER = UsingColumnOrder.IN_PLACE
|
|
28
31
|
|
|
29
32
|
# https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
|
|
30
33
|
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
|
|
@@ -66,7 +69,12 @@ class DuckDB(Dialect):
|
|
|
66
69
|
|
|
67
70
|
return super().to_json_path(path)
|
|
68
71
|
|
|
72
|
+
UNESCAPED_SEQUENCES = {"\\a": "a", "\\v": "v"}
|
|
73
|
+
|
|
69
74
|
class Tokenizer(tokens.Tokenizer):
|
|
75
|
+
NUMERIC_ESCAPES = {"x": (16, 1, 2, 0xFF), "0": (8, 1, 3, 0o777)}
|
|
76
|
+
NUMERIC_ESCAPES_ARE_BYTES = True
|
|
77
|
+
DROP_UNKNOWN_ESCAPES = True
|
|
70
78
|
BYTE_STRINGS = [("e'", "'"), ("E'", "'")]
|
|
71
79
|
BYTE_STRING_ESCAPES = ["'", "\\"]
|
|
72
80
|
HEREDOC_STRINGS = ["$"]
|
|
@@ -88,7 +88,20 @@ class Hive(Dialect):
|
|
|
88
88
|
TokenType.DASH,
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
UNESCAPED_SEQUENCES = {
|
|
92
|
+
"\\0": "\0",
|
|
93
|
+
"\\Z": "\x1a",
|
|
94
|
+
"\\%": "\\%",
|
|
95
|
+
"\\_": "\\_",
|
|
96
|
+
"\\a": "a",
|
|
97
|
+
"\\f": "f",
|
|
98
|
+
"\\v": "v",
|
|
99
|
+
}
|
|
100
|
+
|
|
91
101
|
class Tokenizer(tokens.Tokenizer):
|
|
102
|
+
NUMERIC_ESCAPES = {"u": (16, 4, 4, 0xFFFF), "0": (8, 3, 3, 0x7F)}
|
|
103
|
+
DROP_UNKNOWN_ESCAPES = True
|
|
104
|
+
LONE_SURROGATE_REPLACEMENT = "?"
|
|
92
105
|
QUOTES = ["'", '"']
|
|
93
106
|
IDENTIFIERS = ["`"]
|
|
94
107
|
STRING_ESCAPES = ["\\"]
|
|
@@ -8,6 +8,11 @@ from sqlglot.parsers.materialize import MaterializeParser
|
|
|
8
8
|
class Materialize(Postgres):
|
|
9
9
|
NORMALIZE_NOT_NULL = True
|
|
10
10
|
|
|
11
|
+
UNESCAPED_SEQUENCES = {"\\a": "a", "\\v": "v"}
|
|
12
|
+
|
|
13
|
+
class Tokenizer(Postgres.Tokenizer):
|
|
14
|
+
NUMERIC_ESCAPES = {"u": (16, 4, 4, 0xFFFF), "U": (16, 8, 8, 0x10FFFF)}
|
|
15
|
+
|
|
11
16
|
Parser = MaterializeParser
|
|
12
17
|
|
|
13
18
|
Generator = MaterializeGenerator
|