sqlglot 26.28.1__tar.gz → 26.29.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-26.28.1 → sqlglot-26.29.0}/CHANGELOG.md +20 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/PKG-INFO +1 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/_version.py +2 -2
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/athena.py +1 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/dialect.py +4 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/duckdb.py +7 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/snowflake.py +38 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/tsql.py +2 -2
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/expressions.py +7 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/generator.py +20 -3
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/annotate_types.py +44 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/qualify_columns.py +7 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/scope.py +14 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/parser.py +155 -72
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.egg-info/PKG-INFO +1 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_athena.py +4 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_duckdb.py +22 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_pipe_syntax.py +120 -48
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_snowflake.py +38 -1
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_tsql.py +4 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/qualify_columns.sql +5 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_optimizer.py +37 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/.gitignore +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/.gitpod.yml +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/.pre-commit-config.yaml +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/CONTRIBUTING.md +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/LICENSE +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/MANIFEST.in +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/Makefile +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/README.md +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/pyproject.toml +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/setup.cfg +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/setup.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/__main__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/_typing.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/bigquery.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/clickhouse.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/doris.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/drill.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/hive.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/materialize.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/mysql.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/oracle.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/postgres.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/presto.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/redshift.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/risingwave.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/spark.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/sqlite.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/starrocks.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/diff.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/errors.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/executor/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/executor/context.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/executor/env.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/executor/python.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/executor/table.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/helper.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/jsonpath.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/lineage.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/canonicalize.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/optimize_joins.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/optimizer.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/planner.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/py.typed +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/schema.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/serde.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/time.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/tokens.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/transforms.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot/trie.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.egg-info/requires.txt +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglot.png +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/Cargo.lock +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/Cargo.toml +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/benches/dialect_settings.json +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/benches/long.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/benches/token_type_settings.json +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/pyproject.toml +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/src/lib.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/src/settings.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/src/token.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/src/tokenizer.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/sqlglotrs/src/trie.rs +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/__init__.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_bigquery.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_clickhouse.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_databricks.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_dialect.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_doris.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_drill.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_druid.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_dune.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_hive.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_mysql.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_oracle.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_postgres.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_presto.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_prql.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_redshift.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_risingwave.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_spark.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_sqlite.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_starrocks.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/dialects/test_trino.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/identity.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/annotate_functions.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/normalize.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/simplify.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/partial.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/gen_fixtures.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/helpers.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_build.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_diff.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_docs.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_executor.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_expressions.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_generator.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_helper.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_jsonpath.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_lineage.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_parser.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_schema.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_serde.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_time.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_tokens.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_transforms.py +0 -0
- {sqlglot-26.28.1 → sqlglot-26.29.0}/tests/test_transpile.py +0 -0
@@ -1,6 +1,25 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
## [v26.28.1] - 2025-06-13
|
5
|
+
### :boom: BREAKING CHANGES
|
6
|
+
- due to [`44297f1`](https://github.com/tobymao/sqlglot/commit/44297f1c5c8c2cb16fe77c318312f417b4281708) - JOIN pipe syntax, Set Operators as CTEs *(PR [#5215](https://github.com/tobymao/sqlglot/pull/5215) by [@geooo109](https://github.com/geooo109))*:
|
7
|
+
|
8
|
+
JOIN pipe syntax, Set Operators as CTEs (#5215)
|
9
|
+
|
10
|
+
|
11
|
+
### :sparkles: New Features
|
12
|
+
- [`44297f1`](https://github.com/tobymao/sqlglot/commit/44297f1c5c8c2cb16fe77c318312f417b4281708) - **parser**: JOIN pipe syntax, Set Operators as CTEs *(PR [#5215](https://github.com/tobymao/sqlglot/pull/5215) by [@geooo109](https://github.com/geooo109))*
|
13
|
+
- [`21cd3eb`](https://github.com/tobymao/sqlglot/commit/21cd3ebf5d0b57f5b102c5aadc3b24a598ebe918) - **parser**: PIVOT/UNPIVOT pipe syntax *(PR [#5222](https://github.com/tobymao/sqlglot/pull/5222) by [@geooo109](https://github.com/geooo109))*
|
14
|
+
|
15
|
+
### :bug: Bug Fixes
|
16
|
+
- [`28fed58`](https://github.com/tobymao/sqlglot/commit/28fed586a39df83aade4792217743a1a859fd039) - **optimizer**: UnboundLocalError in scope module *(commit by [@georgesittas](https://github.com/georgesittas))*
|
17
|
+
- [`809e05a`](https://github.com/tobymao/sqlglot/commit/809e05a743d5a2904a1d6f6813f24ca7549ac7ef) - **snowflake**: preserve STRTOK_TO_ARRAY roundtrip *(commit by [@georgesittas](https://github.com/georgesittas))*
|
18
|
+
|
19
|
+
### :recycle: Refactors
|
20
|
+
- [`aac70aa`](https://github.com/tobymao/sqlglot/commit/aac70aaaa8d840c267129e2307ccb65058cef0c9) - **parser**: simpler _parse_pipe_syntax_select *(commit by [@geooo109](https://github.com/geooo109))*
|
21
|
+
|
22
|
+
|
4
23
|
## [v26.27.0] - 2025-06-12
|
5
24
|
### :boom: BREAKING CHANGES
|
6
25
|
- due to [`ac6555b`](https://github.com/tobymao/sqlglot/commit/ac6555b4d6c162ef7b14b63307d01fd560138ea0) - preserve DIV binary operator, fixes [#5198](https://github.com/tobymao/sqlglot/pull/5198) *(PR [#5199](https://github.com/tobymao/sqlglot/pull/5199) by [@georgesittas](https://github.com/georgesittas))*:
|
@@ -4882,3 +4901,4 @@ Changelog
|
|
4882
4901
|
[v26.25.3]: https://github.com/tobymao/sqlglot/compare/v26.25.2...v26.25.3
|
4883
4902
|
[v26.26.0]: https://github.com/tobymao/sqlglot/compare/v26.25.3...v26.26.0
|
4884
4903
|
[v26.27.0]: https://github.com/tobymao/sqlglot/compare/v26.26.0...v26.27.0
|
4904
|
+
[v26.28.1]: https://github.com/tobymao/sqlglot/compare/v26.27.1...v26.28.1
|
@@ -1621,7 +1621,10 @@ def map_date_part(part, dialect: DialectType = Dialect):
|
|
1621
1621
|
mapped = (
|
1622
1622
|
Dialect.get_or_raise(dialect).DATE_PART_MAPPING.get(part.name.upper()) if part else None
|
1623
1623
|
)
|
1624
|
-
|
1624
|
+
if mapped:
|
1625
|
+
return exp.Literal.string(mapped) if part.is_string else exp.var(mapped)
|
1626
|
+
|
1627
|
+
return part
|
1625
1628
|
|
1626
1629
|
|
1627
1630
|
def no_last_day_sql(self: Generator, expression: exp.LastDay) -> str:
|
@@ -290,6 +290,12 @@ class DuckDB(Dialect):
|
|
290
290
|
# https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
|
291
291
|
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
|
292
292
|
|
293
|
+
DATE_PART_MAPPING = {
|
294
|
+
**Dialect.DATE_PART_MAPPING,
|
295
|
+
"DAYOFWEEKISO": "ISODOW",
|
296
|
+
}
|
297
|
+
DATE_PART_MAPPING.pop("WEEKDAY")
|
298
|
+
|
293
299
|
def to_json_path(self, path: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
|
294
300
|
if isinstance(path, exp.Literal):
|
295
301
|
# DuckDB also supports the JSON pointer syntax, where every path starts with a `/`.
|
@@ -620,6 +626,7 @@ class DuckDB(Dialect):
|
|
620
626
|
PAD_FILL_PATTERN_IS_REQUIRED = True
|
621
627
|
ARRAY_CONCAT_IS_VAR_LEN = False
|
622
628
|
ARRAY_SIZE_DIM_REQUIRED = False
|
629
|
+
NORMALIZE_EXTRACT_DATE_PARTS = True
|
623
630
|
|
624
631
|
TRANSFORMS = {
|
625
632
|
**generator.Generator.TRANSFORMS,
|
@@ -31,6 +31,7 @@ from sqlglot.dialects.dialect import (
|
|
31
31
|
)
|
32
32
|
from sqlglot.generator import unsupported_args
|
33
33
|
from sqlglot.helper import flatten, is_float, is_int, seq_get
|
34
|
+
from sqlglot.optimizer.scope import find_all_in_scope
|
34
35
|
from sqlglot.tokens import TokenType
|
35
36
|
|
36
37
|
if t.TYPE_CHECKING:
|
@@ -333,6 +334,34 @@ def _json_extract_value_array_sql(
|
|
333
334
|
return self.func("TRANSFORM", json_extract, transform_lambda)
|
334
335
|
|
335
336
|
|
337
|
+
def _eliminate_dot_variant_lookup(expression: exp.Expression) -> exp.Expression:
|
338
|
+
if isinstance(expression, exp.Select):
|
339
|
+
# This transformation is used to facilitate transpilation of BigQuery `UNNEST` operations
|
340
|
+
# to Snowflake. It should not affect roundtrip because `Unnest` nodes cannot be produced
|
341
|
+
# by Snowflake's parser.
|
342
|
+
#
|
343
|
+
# Additionally, at the time of writing this, BigQuery is the only dialect that produces a
|
344
|
+
# `TableAlias` node that only fills `columns` and not `this`, due to `UNNEST_COLUMN_ONLY`.
|
345
|
+
unnest_aliases = set()
|
346
|
+
for unnest in find_all_in_scope(expression, exp.Unnest):
|
347
|
+
unnest_alias = unnest.args.get("alias")
|
348
|
+
if (
|
349
|
+
isinstance(unnest_alias, exp.TableAlias)
|
350
|
+
and not unnest_alias.this
|
351
|
+
and len(unnest_alias.columns) == 1
|
352
|
+
):
|
353
|
+
unnest_aliases.add(unnest_alias.columns[0].name)
|
354
|
+
|
355
|
+
if unnest_aliases:
|
356
|
+
for c in find_all_in_scope(expression, exp.Column):
|
357
|
+
if c.table in unnest_aliases:
|
358
|
+
bracket_lhs = c.args["table"]
|
359
|
+
bracket_rhs = exp.Literal.string(c.name)
|
360
|
+
c.replace(exp.Bracket(this=bracket_lhs, expressions=[bracket_rhs]))
|
361
|
+
|
362
|
+
return expression
|
363
|
+
|
364
|
+
|
336
365
|
class Snowflake(Dialect):
|
337
366
|
# https://docs.snowflake.com/en/sql-reference/identifiers-syntax
|
338
367
|
NORMALIZATION_STRATEGY = NormalizationStrategy.UPPERCASE
|
@@ -1096,6 +1125,7 @@ class Snowflake(Dialect):
|
|
1096
1125
|
transforms.explode_projection_to_unnest(),
|
1097
1126
|
transforms.eliminate_semi_and_anti_joins,
|
1098
1127
|
_transform_generate_date_array,
|
1128
|
+
_eliminate_dot_variant_lookup,
|
1099
1129
|
]
|
1100
1130
|
),
|
1101
1131
|
exp.SHA: rename_func("SHA1"),
|
@@ -1314,7 +1344,14 @@ class Snowflake(Dialect):
|
|
1314
1344
|
start = f" START {start}" if start else ""
|
1315
1345
|
increment = expression.args.get("increment")
|
1316
1346
|
increment = f" INCREMENT {increment}" if increment else ""
|
1317
|
-
|
1347
|
+
|
1348
|
+
order = expression.args.get("order")
|
1349
|
+
if order is not None:
|
1350
|
+
order_clause = " ORDER" if order else " NOORDER"
|
1351
|
+
else:
|
1352
|
+
order_clause = ""
|
1353
|
+
|
1354
|
+
return f"AUTOINCREMENT{start}{increment}{order_clause}"
|
1318
1355
|
|
1319
1356
|
def cluster_sql(self, expression: exp.Cluster) -> str:
|
1320
1357
|
return f"CLUSTER BY ({self.expressions(expression, flat=True)})"
|
@@ -1224,8 +1224,6 @@ class TSQL(Dialect):
|
|
1224
1224
|
# to amend the AST by moving the CTEs to the CREATE VIEW statement's query.
|
1225
1225
|
ctas_expression.set("with", with_.pop())
|
1226
1226
|
|
1227
|
-
sql = super().create_sql(expression)
|
1228
|
-
|
1229
1227
|
table = expression.find(exp.Table)
|
1230
1228
|
|
1231
1229
|
# Convert CTAS statement to SELECT .. INTO ..
|
@@ -1243,6 +1241,8 @@ class TSQL(Dialect):
|
|
1243
1241
|
select_into.limit(0, copy=False)
|
1244
1242
|
|
1245
1243
|
sql = self.sql(select_into)
|
1244
|
+
else:
|
1245
|
+
sql = super().create_sql(expression)
|
1246
1246
|
|
1247
1247
|
if exists:
|
1248
1248
|
identifier = self.sql(exp.Literal.string(exp.table_name(table) if table else ""))
|
@@ -1947,6 +1947,7 @@ class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
|
|
1947
1947
|
"minvalue": False,
|
1948
1948
|
"maxvalue": False,
|
1949
1949
|
"cycle": False,
|
1950
|
+
"order": False,
|
1950
1951
|
}
|
1951
1952
|
|
1952
1953
|
|
@@ -7044,6 +7045,12 @@ class Semicolon(Expression):
|
|
7044
7045
|
arg_types = {}
|
7045
7046
|
|
7046
7047
|
|
7048
|
+
# BigQuery allows SELECT t FROM t and treats the projection as a struct value. This expression
|
7049
|
+
# type is intended to be constructed by qualify so that we can properly annotate its type later
|
7050
|
+
class TableColumn(Expression):
|
7051
|
+
pass
|
7052
|
+
|
7053
|
+
|
7047
7054
|
def _norm_arg(arg):
|
7048
7055
|
return arg.lower() if type(arg) is str else arg
|
7049
7056
|
|
@@ -201,6 +201,7 @@ class Generator(metaclass=_Generator):
|
|
201
201
|
exp.StreamingTableProperty: lambda *_: "STREAMING",
|
202
202
|
exp.StrictProperty: lambda *_: "STRICT",
|
203
203
|
exp.SwapTable: lambda self, e: f"SWAP WITH {self.sql(e, 'this')}",
|
204
|
+
exp.TableColumn: lambda self, e: self.sql(e.this),
|
204
205
|
exp.Tags: lambda self, e: f"TAG ({self.expressions(e, flat=True)})",
|
205
206
|
exp.TemporaryProperty: lambda *_: "TEMPORARY",
|
206
207
|
exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}",
|
@@ -463,6 +464,11 @@ class Generator(metaclass=_Generator):
|
|
463
464
|
# Whether to wrap <props> in `AlterSet`, e.g., ALTER ... SET (<props>)
|
464
465
|
ALTER_SET_WRAPPED = False
|
465
466
|
|
467
|
+
# Whether to normalize the date parts in EXTRACT(<date_part> FROM <expr>) into a common representation
|
468
|
+
# For instance, to extract the day of week in ISO semantics, one can use ISODOW, DAYOFWEEKISO etc depending on the dialect.
|
469
|
+
# TODO: The normalization should be done by default once we've tested it across all dialects.
|
470
|
+
NORMALIZE_EXTRACT_DATE_PARTS = False
|
471
|
+
|
466
472
|
# The name to generate for the JSONPath expression. If `None`, only `this` will be generated
|
467
473
|
PARSE_JSON_NAME: t.Optional[str] = "PARSE_JSON"
|
468
474
|
|
@@ -2909,9 +2915,17 @@ class Generator(metaclass=_Generator):
|
|
2909
2915
|
return f"NEXT VALUE FOR {self.sql(expression, 'this')}{order}"
|
2910
2916
|
|
2911
2917
|
def extract_sql(self, expression: exp.Extract) -> str:
|
2912
|
-
|
2918
|
+
from sqlglot.dialects.dialect import map_date_part
|
2919
|
+
|
2920
|
+
this = (
|
2921
|
+
map_date_part(expression.this, self.dialect)
|
2922
|
+
if self.NORMALIZE_EXTRACT_DATE_PARTS
|
2923
|
+
else expression.this
|
2924
|
+
)
|
2925
|
+
this_sql = self.sql(this) if self.EXTRACT_ALLOWS_QUOTES else this.name
|
2913
2926
|
expression_sql = self.sql(expression, "expression")
|
2914
|
-
|
2927
|
+
|
2928
|
+
return f"EXTRACT({this_sql} FROM {expression_sql})"
|
2915
2929
|
|
2916
2930
|
def trim_sql(self, expression: exp.Trim) -> str:
|
2917
2931
|
trim_type = self.sql(expression, "position")
|
@@ -4766,7 +4780,10 @@ class Generator(metaclass=_Generator):
|
|
4766
4780
|
|
4767
4781
|
def detach_sql(self, expression: exp.Detach) -> str:
|
4768
4782
|
this = self.sql(expression, "this")
|
4769
|
-
|
4783
|
+
# the DATABASE keyword is required if IF EXISTS is set
|
4784
|
+
# without it, DuckDB throws an error: Parser Error: syntax error at or near "exists" (Line Number: 1)
|
4785
|
+
# ref: https://duckdb.org/docs/stable/sql/statements/attach.html#detach-syntax
|
4786
|
+
exists_sql = " DATABASE IF EXISTS" if expression.args.get("exists") else ""
|
4770
4787
|
|
4771
4788
|
return f"DETACH{exists_sql} {this}"
|
4772
4789
|
|
@@ -12,7 +12,7 @@ from sqlglot.helper import (
|
|
12
12
|
seq_get,
|
13
13
|
)
|
14
14
|
from sqlglot.optimizer.scope import Scope, traverse_scope
|
15
|
-
from sqlglot.schema import Schema, ensure_schema
|
15
|
+
from sqlglot.schema import MappingSchema, Schema, ensure_schema
|
16
16
|
from sqlglot.dialects.dialect import Dialect
|
17
17
|
|
18
18
|
if t.TYPE_CHECKING:
|
@@ -290,9 +290,52 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
|
|
290
290
|
elif isinstance(source.expression, exp.Unnest):
|
291
291
|
self._set_type(col, source.expression.type)
|
292
292
|
|
293
|
+
if isinstance(self.schema, MappingSchema):
|
294
|
+
for table_column in scope.table_columns:
|
295
|
+
source = scope.sources.get(table_column.name)
|
296
|
+
|
297
|
+
if isinstance(source, exp.Table):
|
298
|
+
schema = self.schema.find(
|
299
|
+
source, raise_on_missing=False, ensure_data_types=True
|
300
|
+
)
|
301
|
+
if not isinstance(schema, dict):
|
302
|
+
continue
|
303
|
+
|
304
|
+
struct_type = exp.DataType(
|
305
|
+
this=exp.DataType.Type.STRUCT,
|
306
|
+
expressions=[
|
307
|
+
exp.ColumnDef(this=exp.to_identifier(c), kind=kind)
|
308
|
+
for c, kind in schema.items()
|
309
|
+
],
|
310
|
+
nested=True,
|
311
|
+
)
|
312
|
+
self._set_type(table_column, struct_type)
|
313
|
+
elif (
|
314
|
+
isinstance(source, Scope)
|
315
|
+
and isinstance(source.expression, exp.Query)
|
316
|
+
and source.expression.is_type(exp.DataType.Type.STRUCT)
|
317
|
+
):
|
318
|
+
self._set_type(table_column, source.expression.type)
|
319
|
+
|
293
320
|
# Then (possibly) annotate the remaining expressions in the scope
|
294
321
|
self._maybe_annotate(scope.expression)
|
295
322
|
|
323
|
+
if self.schema.dialect == "bigquery" and isinstance(scope.expression, exp.Query):
|
324
|
+
struct_type = exp.DataType(
|
325
|
+
this=exp.DataType.Type.STRUCT,
|
326
|
+
expressions=[
|
327
|
+
exp.ColumnDef(this=exp.to_identifier(select.output_name), kind=select.type)
|
328
|
+
for select in scope.expression.selects
|
329
|
+
],
|
330
|
+
nested=True,
|
331
|
+
)
|
332
|
+
if not any(
|
333
|
+
cd.kind.is_type(exp.DataType.Type.UNKNOWN)
|
334
|
+
for cd in struct_type.expressions
|
335
|
+
if cd.kind
|
336
|
+
):
|
337
|
+
self._set_type(scope.expression, struct_type)
|
338
|
+
|
296
339
|
def _maybe_annotate(self, expression: E) -> E:
|
297
340
|
if id(expression) in self._visited:
|
298
341
|
return expression # We've already inferred the expression's type
|
@@ -529,6 +529,13 @@ def _qualify_columns(scope: Scope, resolver: Resolver, allow_partial_qualificati
|
|
529
529
|
column_table = resolver.get_table(column_name)
|
530
530
|
if column_table:
|
531
531
|
column.set("table", column_table)
|
532
|
+
elif (
|
533
|
+
resolver.schema.dialect == "bigquery"
|
534
|
+
and len(column.parts) == 1
|
535
|
+
and column_name in scope.selected_sources
|
536
|
+
):
|
537
|
+
# BigQuery allows tables to be referenced as columns, treating them as structs
|
538
|
+
scope.replace(column, exp.TableColumn(this=column.this))
|
532
539
|
|
533
540
|
for pivot in scope.pivots:
|
534
541
|
for column in pivot.find_all(exp.Column):
|
@@ -88,6 +88,7 @@ class Scope:
|
|
88
88
|
def clear_cache(self):
|
89
89
|
self._collected = False
|
90
90
|
self._raw_columns = None
|
91
|
+
self._table_columns = None
|
91
92
|
self._stars = None
|
92
93
|
self._derived_tables = None
|
93
94
|
self._udtfs = None
|
@@ -125,6 +126,7 @@ class Scope:
|
|
125
126
|
self._derived_tables = []
|
126
127
|
self._udtfs = []
|
127
128
|
self._raw_columns = []
|
129
|
+
self._table_columns = []
|
128
130
|
self._stars = []
|
129
131
|
self._join_hints = []
|
130
132
|
self._semi_anti_join_tables = set()
|
@@ -156,6 +158,8 @@ class Scope:
|
|
156
158
|
self._derived_tables.append(node)
|
157
159
|
elif isinstance(node, exp.UNWRAPPED_QUERIES):
|
158
160
|
self._subqueries.append(node)
|
161
|
+
elif isinstance(node, exp.TableColumn):
|
162
|
+
self._table_columns.append(node)
|
159
163
|
|
160
164
|
self._collected = True
|
161
165
|
|
@@ -309,6 +313,13 @@ class Scope:
|
|
309
313
|
|
310
314
|
return self._columns
|
311
315
|
|
316
|
+
@property
|
317
|
+
def table_columns(self):
|
318
|
+
if self._table_columns is None:
|
319
|
+
self._ensure_collected()
|
320
|
+
|
321
|
+
return self._table_columns
|
322
|
+
|
312
323
|
@property
|
313
324
|
def selected_sources(self):
|
314
325
|
"""
|
@@ -849,12 +860,14 @@ def walk_in_scope(expression, bfs=True, prune=None):
|
|
849
860
|
|
850
861
|
if node is expression:
|
851
862
|
continue
|
863
|
+
|
852
864
|
if (
|
853
865
|
isinstance(node, exp.CTE)
|
854
866
|
or (
|
855
867
|
isinstance(node.parent, (exp.From, exp.Join, exp.Subquery))
|
856
|
-
and
|
868
|
+
and _is_derived_table(node)
|
857
869
|
)
|
870
|
+
or (isinstance(node.parent, exp.UDTF) and isinstance(node, exp.Query))
|
858
871
|
or isinstance(node, exp.UNWRAPPED_QUERIES)
|
859
872
|
):
|
860
873
|
crossed_scope_boundary = True
|