sqlglot 27.3.1__tar.gz → 27.4.1__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-27.3.1 → sqlglot-27.4.1}/CHANGELOG.md +41 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/PKG-INFO +1 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/_version.py +2 -2
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/bigquery.py +28 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/exasol.py +24 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/snowflake.py +14 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/sqlite.py +22 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/expressions.py +1 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/generator.py +3 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/annotate_types.py +8 -3
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/optimize_joins.py +2 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/parser.py +5 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.egg-info/PKG-INFO +1 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_bigquery.py +8 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_exasol.py +82 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_hive.py +15 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_sqlite.py +16 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/optimize_joins.sql +6 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_optimizer.py +6 -1
- {sqlglot-27.3.1 → sqlglot-27.4.1}/.gitignore +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/.gitpod.yml +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/.pre-commit-config.yaml +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/CONTRIBUTING.md +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/LICENSE +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/MANIFEST.in +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/Makefile +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/README.md +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/pyproject.toml +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/setup.cfg +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/setup.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/__main__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/_typing.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/athena.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/clickhouse.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/dialect.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/doris.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/dremio.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/drill.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/duckdb.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/fabric.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/hive.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/materialize.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/mysql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/oracle.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/postgres.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/presto.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/redshift.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/risingwave.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/singlestore.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/spark.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/starrocks.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/dialects/tsql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/diff.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/errors.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/executor/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/executor/context.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/executor/env.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/executor/python.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/executor/table.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/helper.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/jsonpath.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/lineage.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/canonicalize.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/merge_subqueries.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/optimizer.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/pushdown_predicates.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/qualify_columns.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/scope.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/planner.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/py.typed +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/schema.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/serde.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/time.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/tokens.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/transforms.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot/trie.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.egg-info/requires.txt +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglot.png +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/Cargo.lock +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/Cargo.toml +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/benches/dialect_settings.json +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/benches/long.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/benches/token_type_settings.json +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/benches/tokenizer_settings.json +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/pyproject.toml +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/src/lib.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/src/settings.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/src/token.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/src/tokenizer.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/sqlglotrs/src/trie.rs +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/__init__.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_athena.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_clickhouse.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_databricks.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_dialect.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_doris.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_dremio.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_drill.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_druid.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_duckdb.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_dune.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_fabric.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_mysql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_oracle.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_pipe_syntax.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_postgres.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_presto.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_prql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_redshift.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_risingwave.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_singlestore.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_snowflake.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_spark.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_starrocks.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_trino.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/dialects/test_tsql.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/identity.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/annotate_functions.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/annotate_types.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/normalize.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/optimizer.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/simplify.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/partial.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/gen_fixtures.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/helpers.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_build.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_dialect_imports.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_diff.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_docs.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_executor.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_expressions.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_generator.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_helper.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_jsonpath.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_lineage.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_parser.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_schema.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_serde.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_time.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_tokens.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_transforms.py +0 -0
- {sqlglot-27.3.1 → sqlglot-27.4.1}/tests/test_transpile.py +0 -0
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [v27.4.0] - 2025-07-25
|
|
5
|
+
### :boom: BREAKING CHANGES
|
|
6
|
+
- due to [`4f348bd`](https://github.com/tobymao/sqlglot/commit/4f348bddda21b18841fd2d728fe486e95cdaa549) - store Query schemas in meta dict instead of type attr *(PR [#5480](https://github.com/tobymao/sqlglot/pull/5480) by [@georgesittas](https://github.com/georgesittas))*:
|
|
7
|
+
|
|
8
|
+
store Query schemas in meta dict instead of type attr (#5480)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### :sparkles: New Features
|
|
12
|
+
- [`7961ece`](https://github.com/tobymao/sqlglot/commit/7961ece058f3771364aad5beedba9484e3a2e27c) - **exasol**: Add support for HASH_SHA1 function *(PR [#5468](https://github.com/tobymao/sqlglot/pull/5468) by [@nnamdi16](https://github.com/nnamdi16))*
|
|
13
|
+
- [`406815d`](https://github.com/tobymao/sqlglot/commit/406815de21f0fdc9874ff46155d4ee0274aa6337) - **exasol**: support HASH_SHA1 *(commit by [@georgesittas](https://github.com/georgesittas))*
|
|
14
|
+
- [`e6f4fc9`](https://github.com/tobymao/sqlglot/commit/e6f4fc9c6d59d96777b2a2ec5dcc360e53639f8d) - **sqlite**: support ATTACH/DETACH DATABASE *(PR [#5469](https://github.com/tobymao/sqlglot/pull/5469) by [@geooo109](https://github.com/geooo109))*
|
|
15
|
+
- :arrow_lower_right: *addresses issue [#5459](https://github.com/tobymao/sqlglot/issues/5459) opened by [@mariofox](https://github.com/mariofox)*
|
|
16
|
+
- [`8aa3498`](https://github.com/tobymao/sqlglot/commit/8aa349890673dccdd4daa0aea6ca5fcb9fdaf46f) - **hive, spark**: Add support for LOCATION in ADD PARTITION *(PR [#5472](https://github.com/tobymao/sqlglot/pull/5472) by [@VaggelisD](https://github.com/VaggelisD))*
|
|
17
|
+
- :arrow_lower_right: *addresses issue [#5457](https://github.com/tobymao/sqlglot/issues/5457) opened by [@tsamaras](https://github.com/tsamaras)*
|
|
18
|
+
- [`44adfc0`](https://github.com/tobymao/sqlglot/commit/44adfc0e74da9d1b05a5a8a67b81fb7c67634c70) - **exasol**: add HASH_MD5 functionality to exasol dialect *(PR [#5473](https://github.com/tobymao/sqlglot/pull/5473) by [@nnamdi16](https://github.com/nnamdi16))*
|
|
19
|
+
- [`05e1c4d`](https://github.com/tobymao/sqlglot/commit/05e1c4dbf795915448173a894a89a33b289a3b5b) - **snowflake**: Transpile BQ's `STRUCT` dot access *(PR [#5471](https://github.com/tobymao/sqlglot/pull/5471) by [@VaggelisD](https://github.com/VaggelisD))*
|
|
20
|
+
- [`3c5ecdf`](https://github.com/tobymao/sqlglot/commit/3c5ecdf7f27629c01f0f3402e64a9dedf0583851) - **exasol**: Add HASHTYPE_MD5 functions to Exasol dialect *(PR [#5474](https://github.com/tobymao/sqlglot/pull/5474) by [@nnamdi16](https://github.com/nnamdi16))*
|
|
21
|
+
- [`1d640d2`](https://github.com/tobymao/sqlglot/commit/1d640d2278288b9a39a65b2532a13bc17e06c4e8) - **exasol**: add support for HASH_SHA256 and HASH_SHA512 hashing *(PR [#5475](https://github.com/tobymao/sqlglot/pull/5475) by [@nnamdi16](https://github.com/nnamdi16))*
|
|
22
|
+
|
|
23
|
+
### :bug: Bug Fixes
|
|
24
|
+
- [`e1819d6`](https://github.com/tobymao/sqlglot/commit/e1819d6451fec0eb3a1f77c90fd8d5c5b0d89889) - only strip kind from joins when it is inner|outer *(PR [#5477](https://github.com/tobymao/sqlglot/pull/5477) by [@themattmorris](https://github.com/themattmorris))*
|
|
25
|
+
- :arrow_lower_right: *fixes issue [#5470](https://github.com/tobymao/sqlglot/issues/5470) opened by [@themattmorris](https://github.com/themattmorris)*
|
|
26
|
+
- [`4f348bd`](https://github.com/tobymao/sqlglot/commit/4f348bddda21b18841fd2d728fe486e95cdaa549) - **bigquery**: store Query schemas in meta dict instead of type attr *(PR [#5480](https://github.com/tobymao/sqlglot/pull/5480) by [@georgesittas](https://github.com/georgesittas))*
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## [v27.3.1] - 2025-07-24
|
|
30
|
+
### :boom: BREAKING CHANGES
|
|
31
|
+
- due to [`48703c4`](https://github.com/tobymao/sqlglot/commit/48703c4fadd9f24de151a63d1bfa74f4b8e71133) - temporarily move VARCHAR length inference logic to Fabric *(commit by [@georgesittas](https://github.com/georgesittas))*:
|
|
32
|
+
|
|
33
|
+
temporarily move VARCHAR length inference logic to Fabric
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### :sparkles: New Features
|
|
37
|
+
- [`4cc321c`](https://github.com/tobymao/sqlglot/commit/4cc321cc1995d538ab0c48a7a0a473c31e76ddff) - **singlestore**: Added initial implementation of SingleStore dialect *(PR [#5447](https://github.com/tobymao/sqlglot/pull/5447) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
|
|
38
|
+
|
|
39
|
+
### :wrench: Chores
|
|
40
|
+
- [`48703c4`](https://github.com/tobymao/sqlglot/commit/48703c4fadd9f24de151a63d1bfa74f4b8e71133) - **tsql**: temporarily move VARCHAR length inference logic to Fabric *(commit by [@georgesittas](https://github.com/georgesittas))*
|
|
41
|
+
|
|
42
|
+
|
|
4
43
|
## [v27.3.0] - 2025-07-24
|
|
5
44
|
### :boom: BREAKING CHANGES
|
|
6
45
|
- due to [`d7ccb48`](https://github.com/tobymao/sqlglot/commit/d7ccb48e542c49258e31cc4df45f49beebc2e238) - week/quarter support *(PR [#5374](https://github.com/tobymao/sqlglot/pull/5374) by [@eakmanrq](https://github.com/eakmanrq))*:
|
|
@@ -6291,3 +6330,5 @@ Changelog
|
|
|
6291
6330
|
[v27.1.0]: https://github.com/tobymao/sqlglot/compare/v26.31.2...v27.1.0
|
|
6292
6331
|
[v27.2.0]: https://github.com/tobymao/sqlglot/compare/v27.1.0...v27.2.0
|
|
6293
6332
|
[v27.3.0]: https://github.com/tobymao/sqlglot/compare/v27.0.1...v27.3.0
|
|
6333
|
+
[v27.3.1]: https://github.com/tobymao/sqlglot/compare/v27.3.0...v27.3.1
|
|
6334
|
+
[v27.4.0]: https://github.com/tobymao/sqlglot/compare/v27.3.1...v27.4.0
|
|
@@ -365,6 +365,33 @@ def _annotate_concat(self: TypeAnnotator, expression: exp.Concat) -> exp.Concat:
|
|
|
365
365
|
return annotated
|
|
366
366
|
|
|
367
367
|
|
|
368
|
+
def _annotate_array(self: TypeAnnotator, expression: exp.Array) -> exp.Array:
|
|
369
|
+
array_args = expression.expressions
|
|
370
|
+
|
|
371
|
+
# BigQuery behaves as follows:
|
|
372
|
+
#
|
|
373
|
+
# SELECT t, TYPEOF(t) FROM (SELECT 'foo') AS t -- foo, STRUCT<STRING>
|
|
374
|
+
# SELECT ARRAY(SELECT 'foo'), TYPEOF(ARRAY(SELECT 'foo')) -- foo, ARRAY<STRING>
|
|
375
|
+
if (
|
|
376
|
+
len(array_args) == 1
|
|
377
|
+
and isinstance(select := array_args[0].unnest(), exp.Select)
|
|
378
|
+
and (query_type := select.meta.get("query_type")) is not None
|
|
379
|
+
and query_type.is_type(exp.DataType.Type.STRUCT)
|
|
380
|
+
and len(query_type.expressions) == 1
|
|
381
|
+
and isinstance(col_def := query_type.expressions[0], exp.ColumnDef)
|
|
382
|
+
and (projection_type := col_def.kind) is not None
|
|
383
|
+
and not projection_type.is_type(exp.DataType.Type.UNKNOWN)
|
|
384
|
+
):
|
|
385
|
+
array_type = exp.DataType(
|
|
386
|
+
this=exp.DataType.Type.ARRAY,
|
|
387
|
+
expressions=[projection_type.copy()],
|
|
388
|
+
nested=True,
|
|
389
|
+
)
|
|
390
|
+
return self._annotate_with_type(expression, array_type)
|
|
391
|
+
|
|
392
|
+
return self._annotate_by_args(expression, "expressions", array=True)
|
|
393
|
+
|
|
394
|
+
|
|
368
395
|
class BigQuery(Dialect):
|
|
369
396
|
WEEK_OFFSET = -1
|
|
370
397
|
UNNEST_COLUMN_ONLY = True
|
|
@@ -445,6 +472,7 @@ class BigQuery(Dialect):
|
|
|
445
472
|
exp.Substring,
|
|
446
473
|
)
|
|
447
474
|
},
|
|
475
|
+
exp.Array: _annotate_array,
|
|
448
476
|
exp.ArrayConcat: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
|
|
449
477
|
exp.Ascii: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
450
478
|
exp.BitwiseAndAgg: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
|
|
@@ -13,6 +13,12 @@ from sqlglot.generator import unsupported_args
|
|
|
13
13
|
from sqlglot.tokens import TokenType
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def _sha2_sql(self: Exasol.Generator, expression: exp.SHA2) -> str:
|
|
17
|
+
length = expression.text("length")
|
|
18
|
+
func_name = "HASH_SHA256" if length == "256" else "HASH_SHA512"
|
|
19
|
+
return self.func(func_name, expression.this)
|
|
20
|
+
|
|
21
|
+
|
|
16
22
|
class Exasol(Dialect):
|
|
17
23
|
TIME_MAPPING = {
|
|
18
24
|
"yyyy": "%Y",
|
|
@@ -59,6 +65,10 @@ class Exasol(Dialect):
|
|
|
59
65
|
"BIT_RSHIFT": binary_from_function(exp.BitwiseRightShift),
|
|
60
66
|
"EVERY": lambda args: exp.All(this=seq_get(args, 0)),
|
|
61
67
|
"EDIT_DISTANCE": exp.Levenshtein.from_arg_list,
|
|
68
|
+
"HASH_SHA": exp.SHA.from_arg_list,
|
|
69
|
+
"HASH_SHA1": exp.SHA.from_arg_list,
|
|
70
|
+
"HASH_MD5": exp.MD5.from_arg_list,
|
|
71
|
+
"HASHTYPE_MD5": exp.MD5Digest.from_arg_list,
|
|
62
72
|
"REGEXP_REPLACE": lambda args: exp.RegexpReplace(
|
|
63
73
|
this=seq_get(args, 0),
|
|
64
74
|
expression=seq_get(args, 1),
|
|
@@ -66,6 +76,12 @@ class Exasol(Dialect):
|
|
|
66
76
|
position=seq_get(args, 3),
|
|
67
77
|
occurrence=seq_get(args, 4),
|
|
68
78
|
),
|
|
79
|
+
"HASH_SHA256": lambda args: exp.SHA2(
|
|
80
|
+
this=seq_get(args, 0), length=exp.Literal.number(256)
|
|
81
|
+
),
|
|
82
|
+
"HASH_SHA512": lambda args: exp.SHA2(
|
|
83
|
+
this=seq_get(args, 0), length=exp.Literal.number(512)
|
|
84
|
+
),
|
|
69
85
|
"VAR_POP": exp.VariancePop.from_arg_list,
|
|
70
86
|
"APPROXIMATE_COUNT_DISTINCT": exp.ApproxDistinct.from_arg_list,
|
|
71
87
|
"TO_CHAR": build_formatted_time(exp.ToChar, "exasol"),
|
|
@@ -173,6 +189,14 @@ class Exasol(Dialect):
|
|
|
173
189
|
self, e, func_name="INSTR", supports_position=True, supports_occurrence=True
|
|
174
190
|
)
|
|
175
191
|
),
|
|
192
|
+
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha%5B1%5D.htm#HASH_SHA%5B1%5D
|
|
193
|
+
exp.SHA: rename_func("HASH_SHA"),
|
|
194
|
+
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha256.htm
|
|
195
|
+
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hash_sha512.htm
|
|
196
|
+
exp.SHA2: _sha2_sql,
|
|
197
|
+
exp.MD5: rename_func("HASH_MD5"),
|
|
198
|
+
# https://docs.exasol.com/db/latest/sql_references/functions/alphabeticallistfunctions/hashtype_md5.htm
|
|
199
|
+
exp.MD5Digest: rename_func("HASHTYPE_MD5"),
|
|
176
200
|
# https://docs.exasol.com/db/latest/sql/create_view.htm
|
|
177
201
|
exp.CommentColumnConstraint: lambda self, e: f"COMMENT IS {self.sql(e, 'this')}",
|
|
178
202
|
}
|
|
@@ -1673,3 +1673,17 @@ class Snowflake(Dialect):
|
|
|
1673
1673
|
to=exp.DataType(this=exp.DataType.Type.DATE),
|
|
1674
1674
|
)
|
|
1675
1675
|
return self.sql(expr)
|
|
1676
|
+
|
|
1677
|
+
def dot_sql(self, expression: exp.Dot) -> str:
|
|
1678
|
+
this = expression.this
|
|
1679
|
+
|
|
1680
|
+
if not this.type:
|
|
1681
|
+
from sqlglot.optimizer.annotate_types import annotate_types
|
|
1682
|
+
|
|
1683
|
+
this = annotate_types(this, dialect=self.dialect)
|
|
1684
|
+
|
|
1685
|
+
if not isinstance(this, exp.Dot) and this.is_type(exp.DataType.Type.STRUCT):
|
|
1686
|
+
# Generate colon notation for the top level STRUCT
|
|
1687
|
+
return f"{self.sql(this)}:{self.sql(expression, 'expression')}"
|
|
1688
|
+
|
|
1689
|
+
return super().dot_sql(expression)
|
|
@@ -96,7 +96,12 @@ class SQLite(Dialect):
|
|
|
96
96
|
|
|
97
97
|
NESTED_COMMENTS = False
|
|
98
98
|
|
|
99
|
-
KEYWORDS =
|
|
99
|
+
KEYWORDS = {
|
|
100
|
+
**tokens.Tokenizer.KEYWORDS,
|
|
101
|
+
"ATTACH": TokenType.ATTACH,
|
|
102
|
+
"DETACH": TokenType.DETACH,
|
|
103
|
+
}
|
|
104
|
+
|
|
100
105
|
KEYWORDS.pop("/*+")
|
|
101
106
|
|
|
102
107
|
COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE}
|
|
@@ -114,6 +119,12 @@ class SQLite(Dialect):
|
|
|
114
119
|
"TIME": lambda args: exp.Anonymous(this="TIME", expressions=args),
|
|
115
120
|
}
|
|
116
121
|
|
|
122
|
+
STATEMENT_PARSERS = {
|
|
123
|
+
**parser.Parser.STATEMENT_PARSERS,
|
|
124
|
+
TokenType.ATTACH: lambda self: self._parse_attach_detach(),
|
|
125
|
+
TokenType.DETACH: lambda self: self._parse_attach_detach(is_attach=False),
|
|
126
|
+
}
|
|
127
|
+
|
|
117
128
|
def _parse_unique(self) -> exp.UniqueColumnConstraint:
|
|
118
129
|
# Do not consume more tokens if UNIQUE is used as a standalone constraint, e.g:
|
|
119
130
|
# CREATE TABLE foo (bar TEXT UNIQUE REFERENCES baz ...)
|
|
@@ -122,6 +133,16 @@ class SQLite(Dialect):
|
|
|
122
133
|
|
|
123
134
|
return super()._parse_unique()
|
|
124
135
|
|
|
136
|
+
def _parse_attach_detach(self, is_attach=True) -> exp.Attach | exp.Detach:
|
|
137
|
+
self._match(TokenType.DATABASE)
|
|
138
|
+
this = self._parse_expression()
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
self.expression(exp.Attach, this=this)
|
|
142
|
+
if is_attach
|
|
143
|
+
else self.expression(exp.Detach, this=this)
|
|
144
|
+
)
|
|
145
|
+
|
|
125
146
|
class Generator(generator.Generator):
|
|
126
147
|
JOIN_HINTS = False
|
|
127
148
|
TABLE_HINTS = False
|
|
@@ -3549,7 +3549,9 @@ class Generator(metaclass=_Generator):
|
|
|
3549
3549
|
|
|
3550
3550
|
def addpartition_sql(self, expression: exp.AddPartition) -> str:
|
|
3551
3551
|
exists = "IF NOT EXISTS " if expression.args.get("exists") else ""
|
|
3552
|
-
|
|
3552
|
+
location = self.sql(expression, "location")
|
|
3553
|
+
location = f" {location}" if location else ""
|
|
3554
|
+
return f"ADD {exists}{self.sql(expression.this)}{location}"
|
|
3553
3555
|
|
|
3554
3556
|
def distinct_sql(self, expression: exp.Distinct) -> str:
|
|
3555
3557
|
this = self.expressions(expression, flat=True)
|
|
@@ -313,9 +313,11 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
|
|
|
313
313
|
elif (
|
|
314
314
|
isinstance(source, Scope)
|
|
315
315
|
and isinstance(source.expression, exp.Query)
|
|
316
|
-
and
|
|
316
|
+
and (
|
|
317
|
+
source.expression.meta.get("query_type") or exp.DataType.build("UNKNOWN")
|
|
318
|
+
).is_type(exp.DataType.Type.STRUCT)
|
|
317
319
|
):
|
|
318
|
-
self._set_type(table_column, source.expression.
|
|
320
|
+
self._set_type(table_column, source.expression.meta["query_type"])
|
|
319
321
|
|
|
320
322
|
# Then (possibly) annotate the remaining expressions in the scope
|
|
321
323
|
self._maybe_annotate(scope.expression)
|
|
@@ -335,7 +337,10 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
|
|
|
335
337
|
for cd in struct_type.expressions
|
|
336
338
|
if cd.kind
|
|
337
339
|
):
|
|
338
|
-
|
|
340
|
+
# We don't use `_set_type` on purpose here. If we annotated the query directly, then
|
|
341
|
+
# using it in other contexts (e.g., ARRAY(<query>)) could result in incorrect type
|
|
342
|
+
# annotations, i.e., it shouldn't be interpreted as a STRUCT value.
|
|
343
|
+
scope.expression.meta["query_type"] = struct_type
|
|
339
344
|
|
|
340
345
|
def _maybe_annotate(self, expression: E) -> E:
|
|
341
346
|
if id(expression) in self._visited:
|
|
@@ -79,7 +79,8 @@ def normalize(expression):
|
|
|
79
79
|
if join.kind == "CROSS":
|
|
80
80
|
join.set("on", None)
|
|
81
81
|
else:
|
|
82
|
-
join.
|
|
82
|
+
if join.kind in ("INNER", "OUTER"):
|
|
83
|
+
join.set("kind", None)
|
|
83
84
|
|
|
84
85
|
if not join.args.get("on") and not join.args.get("using"):
|
|
85
86
|
join.set("on", exp.true())
|
|
@@ -7394,7 +7394,11 @@ class Parser(metaclass=_Parser):
|
|
|
7394
7394
|
exists = self._parse_exists(not_=True)
|
|
7395
7395
|
if self._match_pair(TokenType.PARTITION, TokenType.L_PAREN, advance=False):
|
|
7396
7396
|
return self.expression(
|
|
7397
|
-
exp.AddPartition,
|
|
7397
|
+
exp.AddPartition,
|
|
7398
|
+
exists=exists,
|
|
7399
|
+
this=self._parse_field(any_token=True),
|
|
7400
|
+
location=self._match_text_seq("LOCATION", advance=False)
|
|
7401
|
+
and self._parse_property(),
|
|
7398
7402
|
)
|
|
7399
7403
|
|
|
7400
7404
|
return None
|
|
@@ -1762,6 +1762,14 @@ WHERE
|
|
|
1762
1762
|
self.validate_identity("ARRAY_LAST(['a', 'b'])")
|
|
1763
1763
|
self.validate_identity("JSON_TYPE(PARSE_JSON('1'))")
|
|
1764
1764
|
|
|
1765
|
+
self.validate_all(
|
|
1766
|
+
"SELECT CAST(col AS STRUCT<fld1 STRUCT<fld2 INT>>).fld1.fld2",
|
|
1767
|
+
write={
|
|
1768
|
+
"bigquery": "SELECT CAST(col AS STRUCT<fld1 STRUCT<fld2 INT64>>).fld1.fld2",
|
|
1769
|
+
"snowflake": "SELECT CAST(col AS OBJECT(fld1 OBJECT(fld2 INT))):fld1.fld2",
|
|
1770
|
+
},
|
|
1771
|
+
)
|
|
1772
|
+
|
|
1765
1773
|
def test_errors(self):
|
|
1766
1774
|
with self.assertRaises(ParseError):
|
|
1767
1775
|
self.parse_one("SELECT * FROM a - b.c.d2")
|
|
@@ -398,3 +398,85 @@ class TestExasol(Validator):
|
|
|
398
398
|
"exasol": 'CREATE OR REPLACE VIEW "schema"."v" ("col" COMMENT IS \'desc\') AS SELECT "src_col" AS "col"',
|
|
399
399
|
},
|
|
400
400
|
)
|
|
401
|
+
self.validate_all(
|
|
402
|
+
"HASH_SHA(x)",
|
|
403
|
+
read={
|
|
404
|
+
"clickhouse": "SHA1(x)",
|
|
405
|
+
"exasol": "HASH_SHA1(x)",
|
|
406
|
+
"presto": "SHA1(x)",
|
|
407
|
+
"trino": "SHA1(x)",
|
|
408
|
+
},
|
|
409
|
+
write={
|
|
410
|
+
"exasol": "HASH_SHA(x)",
|
|
411
|
+
"clickhouse": "SHA1(x)",
|
|
412
|
+
"bigquery": "SHA1(x)",
|
|
413
|
+
"": "SHA(x)",
|
|
414
|
+
"presto": "SHA1(x)",
|
|
415
|
+
"trino": "SHA1(x)",
|
|
416
|
+
},
|
|
417
|
+
)
|
|
418
|
+
self.validate_all(
|
|
419
|
+
"HASH_MD5(x)",
|
|
420
|
+
write={
|
|
421
|
+
"exasol": "HASH_MD5(x)",
|
|
422
|
+
"": "MD5(x)",
|
|
423
|
+
"bigquery": "TO_HEX(MD5(x))",
|
|
424
|
+
"clickhouse": "LOWER(HEX(MD5(x)))",
|
|
425
|
+
"hive": "MD5(x)",
|
|
426
|
+
"presto": "LOWER(TO_HEX(MD5(x)))",
|
|
427
|
+
"spark": "MD5(x)",
|
|
428
|
+
"trino": "LOWER(TO_HEX(MD5(x)))",
|
|
429
|
+
},
|
|
430
|
+
)
|
|
431
|
+
self.validate_all(
|
|
432
|
+
"HASHTYPE_MD5(x)",
|
|
433
|
+
write={
|
|
434
|
+
"exasol": "HASHTYPE_MD5(x)",
|
|
435
|
+
"": "MD5_DIGEST(x)",
|
|
436
|
+
"bigquery": "MD5(x)",
|
|
437
|
+
"clickhouse": "MD5(x)",
|
|
438
|
+
"hive": "UNHEX(MD5(x))",
|
|
439
|
+
"presto": "MD5(x)",
|
|
440
|
+
"spark": "UNHEX(MD5(x))",
|
|
441
|
+
"trino": "MD5(x)",
|
|
442
|
+
},
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
self.validate_all(
|
|
446
|
+
"HASH_SHA256(x)",
|
|
447
|
+
read={
|
|
448
|
+
"clickhouse": "SHA256(x)",
|
|
449
|
+
"presto": "SHA256(x)",
|
|
450
|
+
"trino": "SHA256(x)",
|
|
451
|
+
"postgres": "SHA256(x)",
|
|
452
|
+
"duckdb": "SHA256(x)",
|
|
453
|
+
},
|
|
454
|
+
write={
|
|
455
|
+
"exasol": "HASH_SHA256(x)",
|
|
456
|
+
"bigquery": "SHA256(x)",
|
|
457
|
+
"spark2": "SHA2(x, 256)",
|
|
458
|
+
"clickhouse": "SHA256(x)",
|
|
459
|
+
"postgres": "SHA256(x)",
|
|
460
|
+
"presto": "SHA256(x)",
|
|
461
|
+
"redshift": "SHA2(x, 256)",
|
|
462
|
+
"trino": "SHA256(x)",
|
|
463
|
+
"duckdb": "SHA256(x)",
|
|
464
|
+
"snowflake": "SHA2(x, 256)",
|
|
465
|
+
},
|
|
466
|
+
)
|
|
467
|
+
self.validate_all(
|
|
468
|
+
"HASH_SHA512(x)",
|
|
469
|
+
read={
|
|
470
|
+
"clickhouse": "SHA512(x)",
|
|
471
|
+
"presto": "SHA512(x)",
|
|
472
|
+
"trino": "SHA512(x)",
|
|
473
|
+
},
|
|
474
|
+
write={
|
|
475
|
+
"exasol": "HASH_SHA512(x)",
|
|
476
|
+
"clickhouse": "SHA512(x)",
|
|
477
|
+
"bigquery": "SHA512(x)",
|
|
478
|
+
"spark2": "SHA2(x, 512)",
|
|
479
|
+
"presto": "SHA512(x)",
|
|
480
|
+
"trino": "SHA512(x)",
|
|
481
|
+
},
|
|
482
|
+
)
|
|
@@ -216,6 +216,21 @@ class TestHive(Validator):
|
|
|
216
216
|
},
|
|
217
217
|
)
|
|
218
218
|
|
|
219
|
+
self.validate_all(
|
|
220
|
+
"ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
221
|
+
read={
|
|
222
|
+
"spark2": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
223
|
+
"spark": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
224
|
+
"databricks": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
225
|
+
},
|
|
226
|
+
write={
|
|
227
|
+
"hive": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
228
|
+
"spark2": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
229
|
+
"spark": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
230
|
+
"databricks": "ALTER TABLE db.example_table ADD PARTITION(col_a = 'a') LOCATION 'b'",
|
|
231
|
+
},
|
|
232
|
+
)
|
|
233
|
+
|
|
219
234
|
def test_lateral_view(self):
|
|
220
235
|
self.validate_all(
|
|
221
236
|
"SELECT a, b FROM x LATERAL VIEW EXPLODE(y) t AS a LATERAL VIEW EXPLODE(z) u AS b",
|
|
@@ -122,6 +122,22 @@ class TestSQLite(Validator):
|
|
|
122
122
|
'CREATE TABLE "foo t" ("foo t id" TEXT NOT NULL PRIMARY KEY)',
|
|
123
123
|
)
|
|
124
124
|
self.validate_identity("REPLACE INTO foo (x, y) VALUES (1, 2)", check_command_warning=True)
|
|
125
|
+
self.validate_identity(
|
|
126
|
+
"ATTACH DATABASE 'foo' AS schema_name", "ATTACH 'foo' AS schema_name"
|
|
127
|
+
)
|
|
128
|
+
self.validate_identity(
|
|
129
|
+
"ATTACH DATABASE NOT EXISTS(SELECT 1) AS schema_name",
|
|
130
|
+
"ATTACH NOT EXISTS(SELECT 1) AS schema_name",
|
|
131
|
+
)
|
|
132
|
+
self.validate_identity(
|
|
133
|
+
"ATTACH DATABASE IIF(NOT EXISTS(SELECT 1), 'foo1', 'foo2') AS schema_name",
|
|
134
|
+
"ATTACH IIF(NOT EXISTS(SELECT 1), 'foo1', 'foo2') AS schema_name",
|
|
135
|
+
)
|
|
136
|
+
self.validate_identity(
|
|
137
|
+
"ATTACH DATABASE 'foo' || '.foo2' AS schema_name",
|
|
138
|
+
"ATTACH 'foo' || '.foo2' AS schema_name",
|
|
139
|
+
)
|
|
140
|
+
self.validate_identity("DETACH DATABASE schema_name", "DETACH schema_name")
|
|
125
141
|
|
|
126
142
|
def test_strftime(self):
|
|
127
143
|
self.validate_identity("SELECT STRFTIME('%Y/%m/%d', 'now')")
|
|
@@ -36,3 +36,9 @@ SELECT * FROM x JOIN z USING (id);
|
|
|
36
36
|
|
|
37
37
|
SELECT * FROM x CROSS JOIN z ON TRUE;
|
|
38
38
|
SELECT * FROM x CROSS JOIN z;
|
|
39
|
+
|
|
40
|
+
SELECT * FROM x LEFT ANTI JOIN y ON x.a = y.a;
|
|
41
|
+
SELECT * FROM x LEFT ANTI JOIN y ON x.a = y.a;
|
|
42
|
+
|
|
43
|
+
SELECT * FROM x LEFT SEMI JOIN y ON x.a = y.a;
|
|
44
|
+
SELECT * FROM x LEFT SEMI JOIN y ON x.a = y.a;
|
|
@@ -1589,7 +1589,7 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
|
|
|
1589
1589
|
schema = {"d": {"s": {"t": {"c1": "int64", "c2": "struct<f1 int64, f2 string>"}}}}
|
|
1590
1590
|
|
|
1591
1591
|
def _annotate(query: str) -> exp.Expression:
|
|
1592
|
-
expression = parse_one(
|
|
1592
|
+
expression = parse_one(query, dialect=dialect)
|
|
1593
1593
|
qual = optimizer.qualify.qualify(expression, schema=schema, dialect=dialect)
|
|
1594
1594
|
return optimizer.annotate_types.annotate_types(qual, schema=schema, dialect=dialect)
|
|
1595
1595
|
|
|
@@ -1620,3 +1620,8 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
|
|
|
1620
1620
|
annotated = _annotate(example_query)
|
|
1621
1621
|
|
|
1622
1622
|
self.assertTrue(annotated.selects[0].is_type("UNKNOWN"))
|
|
1623
|
+
|
|
1624
|
+
for query in ("SELECT 'foo'", "(SELECT 'foo')"):
|
|
1625
|
+
query = f"SELECT ARRAY({query})"
|
|
1626
|
+
with self.subTest(f"Annotating '{query}' in BigQuery"):
|
|
1627
|
+
self.assertTrue(_annotate(query).selects[0].is_type("ARRAY<VARCHAR>"))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|