sqlglot 27.28.1__tar.gz → 27.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-27.28.1 → sqlglot-27.29.0}/PKG-INFO +1 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/__init__.py +1 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/_version.py +3 -3
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/bigquery.py +1 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dialect.py +45 -7
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/duckdb.py +17 -3
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/mysql.py +1 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/postgres.py +14 -2
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/snowflake.py +55 -18
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/spark.py +3 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/sqlite.py +1 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/__init__.py +5 -10
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/python.py +1 -29
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/expressions.py +102 -12
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/generator.py +16 -2
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/helper.py +0 -42
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/lineage.py +1 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify.py +5 -5
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify_columns.py +89 -9
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify_tables.py +33 -23
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/simplify.py +12 -7
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/parser.py +16 -8
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/PKG-INFO +1 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_bigquery.py +26 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dialect.py +26 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_duckdb.py +27 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_postgres.py +10 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_snowflake.py +75 -8
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_spark.py +28 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_trino.py +4 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/identity.sql +1 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/annotate_functions.sql +300 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/annotate_types.sql +6 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/normalize.sql +1 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns.sql +7 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +2 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_tables.sql +1 -1
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/simplify.sql +32 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_executor.py +91 -46
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_expressions.py +5 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_lineage.py +46 -4
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_optimizer.py +26 -18
- {sqlglot-27.28.1 → sqlglot-27.29.0}/.gitignore +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/.gitpod.yml +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/.pre-commit-config.yaml +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/CHANGELOG.md +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/CONTRIBUTING.md +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/LICENSE +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/MANIFEST.in +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/Makefile +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/README.md +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/pyproject.toml +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/setup.cfg +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/setup.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/__main__.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/_typing.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/athena.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/clickhouse.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/doris.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dremio.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/drill.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/exasol.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/fabric.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/hive.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/materialize.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/oracle.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/presto.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/redshift.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/risingwave.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/singlestore.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/solr.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/starrocks.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/tsql.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/diff.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/errors.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/context.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/env.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/table.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/jsonpath.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/canonicalize.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/optimize_joins.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/optimizer.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/scope.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/planner.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/py.typed +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/schema.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/serde.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/time.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/tokens.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/transforms.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/trie.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/requires.txt +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.png +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/Cargo.lock +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/Cargo.toml +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/dialect_settings.json +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/long.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/token_type_settings.json +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/pyproject.toml +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/lib.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/settings.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/token.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/tokenizer.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/trie.rs +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/__init__.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/__init__.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_athena.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_clickhouse.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_databricks.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_doris.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dremio.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_drill.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_druid.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dune.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_exasol.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_fabric.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_hive.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_mysql.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_oracle.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_pipe_syntax.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_presto.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_prql.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_redshift.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_risingwave.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_singlestore.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_solr.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_sqlite.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_starrocks.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_tsql.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/partial.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/gen_fixtures.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/helpers.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_build.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_dialect_imports.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_diff.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_docs.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_generator.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_helper.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_jsonpath.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_parser.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_schema.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_serde.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_time.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_tokens.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_transforms.py +0 -0
- {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_transpile.py +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '27.
|
|
32
|
-
__version_tuple__ = version_tuple = (27,
|
|
31
|
+
__version__ = version = '27.29.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (27, 29, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g7f550f22d'
|
|
@@ -44,9 +44,11 @@ DATETIME_DELTA = t.Union[
|
|
|
44
44
|
exp.DatetimeSub,
|
|
45
45
|
exp.TimeAdd,
|
|
46
46
|
exp.TimeSub,
|
|
47
|
+
exp.TimestampAdd,
|
|
47
48
|
exp.TimestampSub,
|
|
48
49
|
exp.TsOrDsAdd,
|
|
49
50
|
]
|
|
51
|
+
DATETIME_ADD = (exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd, exp.TimestampAdd)
|
|
50
52
|
|
|
51
53
|
if t.TYPE_CHECKING:
|
|
52
54
|
from sqlglot._typing import B, E, F
|
|
@@ -539,6 +541,10 @@ class Dialect(metaclass=_Dialect):
|
|
|
539
541
|
# STRING type (Snowflake's case) or can be of any type
|
|
540
542
|
TRY_CAST_REQUIRES_STRING: t.Optional[bool] = None
|
|
541
543
|
|
|
544
|
+
# Whether the double negation can be applied
|
|
545
|
+
# Not safe with MySQL and SQLite due to type coercion (may not return boolean)
|
|
546
|
+
SAFE_TO_ELIMINATE_DOUBLE_NEGATION = True
|
|
547
|
+
|
|
542
548
|
# --- Autofilled ---
|
|
543
549
|
|
|
544
550
|
tokenizer_class = Tokenizer
|
|
@@ -765,8 +771,12 @@ class Dialect(metaclass=_Dialect):
|
|
|
765
771
|
exp.TimeAdd,
|
|
766
772
|
exp.TimeSub,
|
|
767
773
|
},
|
|
774
|
+
exp.DataType.Type.TIMESTAMPLTZ: {
|
|
775
|
+
exp.TimestampLtzFromParts,
|
|
776
|
+
},
|
|
768
777
|
exp.DataType.Type.TIMESTAMPTZ: {
|
|
769
778
|
exp.CurrentTimestampLTZ,
|
|
779
|
+
exp.TimestampTzFromParts,
|
|
770
780
|
},
|
|
771
781
|
exp.DataType.Type.TIMESTAMP: {
|
|
772
782
|
exp.CurrentTimestamp,
|
|
@@ -778,10 +788,17 @@ class Dialect(metaclass=_Dialect):
|
|
|
778
788
|
},
|
|
779
789
|
exp.DataType.Type.TINYINT: {
|
|
780
790
|
exp.Day,
|
|
781
|
-
exp.
|
|
791
|
+
exp.DayOfWeek,
|
|
792
|
+
exp.DayOfWeekIso,
|
|
793
|
+
exp.DayOfMonth,
|
|
794
|
+
exp.DayOfYear,
|
|
782
795
|
exp.Week,
|
|
783
|
-
exp.
|
|
796
|
+
exp.WeekOfYear,
|
|
797
|
+
exp.Month,
|
|
784
798
|
exp.Quarter,
|
|
799
|
+
exp.Year,
|
|
800
|
+
exp.YearOfWeek,
|
|
801
|
+
exp.YearOfWeekIso,
|
|
785
802
|
},
|
|
786
803
|
exp.DataType.Type.VARCHAR: {
|
|
787
804
|
exp.ArrayConcat,
|
|
@@ -1682,11 +1699,7 @@ def date_delta_to_binary_interval_op(
|
|
|
1682
1699
|
def date_delta_to_binary_interval_op_sql(self: Generator, expression: DATETIME_DELTA) -> str:
|
|
1683
1700
|
this = expression.this
|
|
1684
1701
|
unit = unit_to_var(expression)
|
|
1685
|
-
op = (
|
|
1686
|
-
"+"
|
|
1687
|
-
if isinstance(expression, (exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd))
|
|
1688
|
-
else "-"
|
|
1689
|
-
)
|
|
1702
|
+
op = "+" if isinstance(expression, DATETIME_ADD) else "-"
|
|
1690
1703
|
|
|
1691
1704
|
to_type: t.Optional[exp.DATA_TYPE] = None
|
|
1692
1705
|
if cast:
|
|
@@ -1965,6 +1978,15 @@ def sequence_sql(self: Generator, expression: exp.GenerateSeries | exp.GenerateD
|
|
|
1965
1978
|
return self.func("SEQUENCE", start, end, step)
|
|
1966
1979
|
|
|
1967
1980
|
|
|
1981
|
+
def build_like(expr_type: t.Type[E]) -> t.Callable[[t.List], E | exp.Escape]:
|
|
1982
|
+
def _builder(args: t.List) -> E | exp.Escape:
|
|
1983
|
+
like_expr = expr_type(this=seq_get(args, 0), expression=seq_get(args, 1))
|
|
1984
|
+
escape = seq_get(args, 2)
|
|
1985
|
+
return exp.Escape(this=like_expr, expression=escape) if escape else like_expr
|
|
1986
|
+
|
|
1987
|
+
return _builder
|
|
1988
|
+
|
|
1989
|
+
|
|
1968
1990
|
def build_regexp_extract(expr_type: t.Type[E]) -> t.Callable[[t.List, Dialect], E]:
|
|
1969
1991
|
def _builder(args: t.List, dialect: Dialect) -> E:
|
|
1970
1992
|
return expr_type(
|
|
@@ -2075,3 +2097,19 @@ def build_replace_with_optional_replacement(args: t.List) -> exp.Replace:
|
|
|
2075
2097
|
expression=seq_get(args, 1),
|
|
2076
2098
|
replacement=seq_get(args, 2) or exp.Literal.string(""),
|
|
2077
2099
|
)
|
|
2100
|
+
|
|
2101
|
+
|
|
2102
|
+
def regexp_replace_global_modifier(expression: exp.RegexpReplace) -> exp.Expression | None:
|
|
2103
|
+
modifiers = expression.args.get("modifiers")
|
|
2104
|
+
single_replace = expression.args.get("single_replace")
|
|
2105
|
+
occurrence = expression.args.get("occurrence")
|
|
2106
|
+
|
|
2107
|
+
if not single_replace and (not occurrence or (occurrence.is_int and occurrence.to_py() == 0)):
|
|
2108
|
+
if not modifiers or modifiers.is_string:
|
|
2109
|
+
# Append 'g' to the modifiers if they are not provided since
|
|
2110
|
+
# the semantics of REGEXP_REPLACE from the input dialect
|
|
2111
|
+
# is to replace all occurrences of the pattern.
|
|
2112
|
+
value = "" if not modifiers else modifiers.name
|
|
2113
|
+
modifiers = exp.Literal.string(value + "g")
|
|
2114
|
+
|
|
2115
|
+
return modifiers
|
|
@@ -39,6 +39,7 @@ from sqlglot.dialects.dialect import (
|
|
|
39
39
|
explode_to_unnest_sql,
|
|
40
40
|
no_make_interval_sql,
|
|
41
41
|
groupconcat_sql,
|
|
42
|
+
regexp_replace_global_modifier,
|
|
42
43
|
)
|
|
43
44
|
from sqlglot.generator import unsupported_args
|
|
44
45
|
from sqlglot.helper import seq_get
|
|
@@ -414,6 +415,7 @@ class DuckDB(Dialect):
|
|
|
414
415
|
"LIST_SORT": exp.SortArray.from_arg_list,
|
|
415
416
|
"LIST_TRANSFORM": exp.Transform.from_arg_list,
|
|
416
417
|
"LIST_VALUE": lambda args: exp.Array(expressions=args),
|
|
418
|
+
"MAKE_DATE": exp.DateFromParts.from_arg_list,
|
|
417
419
|
"MAKE_TIME": exp.TimeFromParts.from_arg_list,
|
|
418
420
|
"MAKE_TIMESTAMP": _build_make_timestamp,
|
|
419
421
|
"QUANTILE_CONT": exp.PercentileCont.from_arg_list,
|
|
@@ -427,6 +429,7 @@ class DuckDB(Dialect):
|
|
|
427
429
|
expression=seq_get(args, 1),
|
|
428
430
|
replacement=seq_get(args, 2),
|
|
429
431
|
modifiers=seq_get(args, 3),
|
|
432
|
+
single_replace=True,
|
|
430
433
|
),
|
|
431
434
|
"SHA256": lambda args: exp.SHA2(this=seq_get(args, 0), length=exp.Literal.number(256)),
|
|
432
435
|
"STRFTIME": build_formatted_time(exp.TimeToStr, "duckdb"),
|
|
@@ -695,7 +698,6 @@ class DuckDB(Dialect):
|
|
|
695
698
|
exp.BitwiseXorAgg: rename_func("BIT_XOR"),
|
|
696
699
|
exp.CommentColumnConstraint: no_comment_column_constraint_sql,
|
|
697
700
|
exp.CosineDistance: rename_func("LIST_COSINE_DISTANCE"),
|
|
698
|
-
exp.CurrentDate: lambda *_: "CURRENT_DATE",
|
|
699
701
|
exp.CurrentTime: lambda *_: "CURRENT_TIME",
|
|
700
702
|
exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
|
|
701
703
|
exp.DayOfMonth: rename_func("DAYOFMONTH"),
|
|
@@ -754,7 +756,7 @@ class DuckDB(Dialect):
|
|
|
754
756
|
e.this,
|
|
755
757
|
e.expression,
|
|
756
758
|
e.args.get("replacement"),
|
|
757
|
-
e
|
|
759
|
+
regexp_replace_global_modifier(e),
|
|
758
760
|
),
|
|
759
761
|
exp.RegexpLike: rename_func("REGEXP_MATCHES"),
|
|
760
762
|
exp.RegexpILike: lambda self, e: self.func(
|
|
@@ -779,9 +781,11 @@ class DuckDB(Dialect):
|
|
|
779
781
|
exp.Time: no_time_sql,
|
|
780
782
|
exp.TimeDiff: _timediff_sql,
|
|
781
783
|
exp.Timestamp: no_timestamp_sql,
|
|
784
|
+
exp.TimestampAdd: date_delta_to_binary_interval_op(),
|
|
782
785
|
exp.TimestampDiff: lambda self, e: self.func(
|
|
783
786
|
"DATE_DIFF", exp.Literal.string(e.unit), e.expression, e.this
|
|
784
787
|
),
|
|
788
|
+
exp.TimestampSub: date_delta_to_binary_interval_op(),
|
|
785
789
|
exp.TimestampTrunc: timestamptrunc_sql(),
|
|
786
790
|
exp.TimeStrToDate: lambda self, e: self.sql(exp.cast(e.this, exp.DataType.Type.DATE)),
|
|
787
791
|
exp.TimeStrToTime: timestrtotime_sql,
|
|
@@ -799,7 +803,7 @@ class DuckDB(Dialect):
|
|
|
799
803
|
exp.cast(e.expression, exp.DataType.Type.TIMESTAMP),
|
|
800
804
|
exp.cast(e.this, exp.DataType.Type.TIMESTAMP),
|
|
801
805
|
),
|
|
802
|
-
exp.UnixMicros:
|
|
806
|
+
exp.UnixMicros: lambda self, e: self.func("EPOCH_US", _implicit_datetime_cast(e.this)),
|
|
803
807
|
exp.UnixToStr: lambda self, e: self.func(
|
|
804
808
|
"STRFTIME", self.func("TO_TIMESTAMP", e.this), self.format_time(e)
|
|
805
809
|
),
|
|
@@ -989,6 +993,16 @@ class DuckDB(Dialect):
|
|
|
989
993
|
return f"CAST({self.func('TRY_STRPTIME', expression.this, formatted_time)} AS DATE)"
|
|
990
994
|
return f"CAST({str_to_time_sql(self, expression)} AS DATE)"
|
|
991
995
|
|
|
996
|
+
def currentdate_sql(self, expression: exp.CurrentDate) -> str:
|
|
997
|
+
if not expression.this:
|
|
998
|
+
return "CURRENT_DATE"
|
|
999
|
+
|
|
1000
|
+
expr = exp.Cast(
|
|
1001
|
+
this=exp.AtTimeZone(this=exp.CurrentTimestamp(), zone=expression.this),
|
|
1002
|
+
to=exp.DataType(this=exp.DataType.Type.DATE),
|
|
1003
|
+
)
|
|
1004
|
+
return self.sql(expr)
|
|
1005
|
+
|
|
992
1006
|
def parsejson_sql(self, expression: exp.ParseJSON) -> str:
|
|
993
1007
|
arg = expression.this
|
|
994
1008
|
if expression.args.get("safe"):
|
|
@@ -163,6 +163,7 @@ class MySQL(Dialect):
|
|
|
163
163
|
SUPPORTS_USER_DEFINED_TYPES = False
|
|
164
164
|
SUPPORTS_SEMI_ANTI_JOIN = False
|
|
165
165
|
SAFE_DIVISION = True
|
|
166
|
+
SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
|
|
166
167
|
|
|
167
168
|
# https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions
|
|
168
169
|
TIME_MAPPING = {
|
|
@@ -37,6 +37,7 @@ from sqlglot.dialects.dialect import (
|
|
|
37
37
|
count_if_to_sum,
|
|
38
38
|
groupconcat_sql,
|
|
39
39
|
Version,
|
|
40
|
+
regexp_replace_global_modifier,
|
|
40
41
|
)
|
|
41
42
|
from sqlglot.generator import unsupported_args
|
|
42
43
|
from sqlglot.helper import is_int, seq_get
|
|
@@ -203,6 +204,7 @@ def _build_regexp_replace(args: t.List, dialect: DialectType = None) -> exp.Rege
|
|
|
203
204
|
# Any one of `start`, `N` and `flags` can be column references, meaning that
|
|
204
205
|
# unless we can statically see that the last argument is a non-integer string
|
|
205
206
|
# (eg. not '0'), then it's not possible to construct the correct AST
|
|
207
|
+
regexp_replace = None
|
|
206
208
|
if len(args) > 3:
|
|
207
209
|
last = args[-1]
|
|
208
210
|
if not is_int(last.name):
|
|
@@ -214,9 +216,10 @@ def _build_regexp_replace(args: t.List, dialect: DialectType = None) -> exp.Rege
|
|
|
214
216
|
if last.is_type(*exp.DataType.TEXT_TYPES):
|
|
215
217
|
regexp_replace = exp.RegexpReplace.from_arg_list(args[:-1])
|
|
216
218
|
regexp_replace.set("modifiers", last)
|
|
217
|
-
return regexp_replace
|
|
218
219
|
|
|
219
|
-
|
|
220
|
+
regexp_replace = regexp_replace or exp.RegexpReplace.from_arg_list(args)
|
|
221
|
+
regexp_replace.set("single_replace", True)
|
|
222
|
+
return regexp_replace
|
|
220
223
|
|
|
221
224
|
|
|
222
225
|
def _unix_to_time_sql(self: Postgres.Generator, expression: exp.UnixToTime) -> str:
|
|
@@ -651,6 +654,15 @@ class Postgres(Dialect):
|
|
|
651
654
|
exp.Rand: rename_func("RANDOM"),
|
|
652
655
|
exp.RegexpLike: lambda self, e: self.binary(e, "~"),
|
|
653
656
|
exp.RegexpILike: lambda self, e: self.binary(e, "~*"),
|
|
657
|
+
exp.RegexpReplace: lambda self, e: self.func(
|
|
658
|
+
"REGEXP_REPLACE",
|
|
659
|
+
e.this,
|
|
660
|
+
e.expression,
|
|
661
|
+
e.args.get("replacement"),
|
|
662
|
+
e.args.get("position"),
|
|
663
|
+
e.args.get("occurrence"),
|
|
664
|
+
regexp_replace_global_modifier(e),
|
|
665
|
+
),
|
|
654
666
|
exp.Select: transforms.preprocess(
|
|
655
667
|
[
|
|
656
668
|
transforms.eliminate_semi_and_anti_joins,
|
|
@@ -8,10 +8,10 @@ from sqlglot.dialects.dialect import (
|
|
|
8
8
|
NormalizationStrategy,
|
|
9
9
|
annotate_with_type_lambda,
|
|
10
10
|
build_timetostr_or_tochar,
|
|
11
|
+
build_like,
|
|
11
12
|
binary_from_function,
|
|
12
13
|
build_default_decimal_type,
|
|
13
14
|
build_replace_with_optional_replacement,
|
|
14
|
-
build_timestamp_from_parts,
|
|
15
15
|
date_delta_sql,
|
|
16
16
|
date_trunc_to_time,
|
|
17
17
|
datestrtodate_sql,
|
|
@@ -362,15 +362,6 @@ def _build_regexp_extract(expr_type: t.Type[E]) -> t.Callable[[t.List], E]:
|
|
|
362
362
|
return _builder
|
|
363
363
|
|
|
364
364
|
|
|
365
|
-
def _build_like(expr_type: t.Type[E]) -> t.Callable[[t.List], E | exp.Escape]:
|
|
366
|
-
def _builder(args: t.List) -> E | exp.Escape:
|
|
367
|
-
like_expr = expr_type(this=args[0], expression=args[1])
|
|
368
|
-
escape = seq_get(args, 2)
|
|
369
|
-
return exp.Escape(this=like_expr, expression=escape) if escape else like_expr
|
|
370
|
-
|
|
371
|
-
return _builder
|
|
372
|
-
|
|
373
|
-
|
|
374
365
|
def _regexpextract_sql(self, expression: exp.RegexpExtract | exp.RegexpExtractAll) -> str:
|
|
375
366
|
# Other dialects don't support all of the following parameters, so we need to
|
|
376
367
|
# generate default values as necessary to ensure the transpilation is correct
|
|
@@ -551,6 +542,34 @@ def _annotate_reverse(self: TypeAnnotator, expression: exp.Reverse) -> exp.Rever
|
|
|
551
542
|
return expression
|
|
552
543
|
|
|
553
544
|
|
|
545
|
+
def _annotate_timestamp_from_parts(
|
|
546
|
+
self: TypeAnnotator, expression: exp.TimestampFromParts
|
|
547
|
+
) -> exp.TimestampFromParts:
|
|
548
|
+
"""Annotate TimestampFromParts with correct type based on arguments.
|
|
549
|
+
TIMESTAMP_FROM_PARTS with time_zone -> TIMESTAMPTZ
|
|
550
|
+
TIMESTAMP_FROM_PARTS without time_zone -> TIMESTAMP (defaults to TIMESTAMP_NTZ)
|
|
551
|
+
"""
|
|
552
|
+
self._annotate_args(expression)
|
|
553
|
+
|
|
554
|
+
if expression.args.get("zone"):
|
|
555
|
+
self._set_type(expression, exp.DataType.Type.TIMESTAMPTZ)
|
|
556
|
+
else:
|
|
557
|
+
self._set_type(expression, exp.DataType.Type.TIMESTAMP)
|
|
558
|
+
|
|
559
|
+
return expression
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def _build_timestamp_from_parts(args: t.List) -> exp.Func:
|
|
563
|
+
"""Build TimestampFromParts with support for both syntaxes:
|
|
564
|
+
1. TIMESTAMP_FROM_PARTS(year, month, day, hour, minute, second [, nanosecond] [, time_zone])
|
|
565
|
+
2. TIMESTAMP_FROM_PARTS(date_expr, time_expr) - Snowflake specific
|
|
566
|
+
"""
|
|
567
|
+
if len(args) == 2:
|
|
568
|
+
return exp.TimestampFromParts(this=seq_get(args, 0), expression=seq_get(args, 1))
|
|
569
|
+
|
|
570
|
+
return exp.TimestampFromParts.from_arg_list(args)
|
|
571
|
+
|
|
572
|
+
|
|
554
573
|
def _annotate_date_or_time_add(self: TypeAnnotator, expression: E) -> E:
|
|
555
574
|
self._annotate_args(expression)
|
|
556
575
|
|
|
@@ -588,6 +607,8 @@ class Snowflake(Dialect):
|
|
|
588
607
|
exp.Degrees,
|
|
589
608
|
exp.Exp,
|
|
590
609
|
exp.MonthsBetween,
|
|
610
|
+
exp.RegrValx,
|
|
611
|
+
exp.RegrValy,
|
|
591
612
|
exp.Sin,
|
|
592
613
|
exp.Sinh,
|
|
593
614
|
exp.Tan,
|
|
@@ -680,6 +701,10 @@ class Snowflake(Dialect):
|
|
|
680
701
|
exp.DataType.Type.BOOLEAN: {
|
|
681
702
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BOOLEAN],
|
|
682
703
|
exp.Boolnot,
|
|
704
|
+
exp.Booland,
|
|
705
|
+
exp.Boolor,
|
|
706
|
+
exp.EqualNull,
|
|
707
|
+
exp.IsNullValue,
|
|
683
708
|
exp.Search,
|
|
684
709
|
},
|
|
685
710
|
exp.DataType.Type.DATE: {
|
|
@@ -734,8 +759,11 @@ class Snowflake(Dialect):
|
|
|
734
759
|
else exp.DataType.Type.TIMESTAMPTZ,
|
|
735
760
|
),
|
|
736
761
|
exp.DateAdd: _annotate_date_or_time_add,
|
|
737
|
-
exp.Reverse: _annotate_reverse,
|
|
738
762
|
exp.TimeAdd: _annotate_date_or_time_add,
|
|
763
|
+
exp.GreatestIgnoreNulls: lambda self, e: self._annotate_by_args(e, "expressions"),
|
|
764
|
+
exp.LeastIgnoreNulls: lambda self, e: self._annotate_by_args(e, "expressions"),
|
|
765
|
+
exp.Reverse: _annotate_reverse,
|
|
766
|
+
exp.TimestampFromParts: _annotate_timestamp_from_parts,
|
|
739
767
|
}
|
|
740
768
|
|
|
741
769
|
TIME_MAPPING = {
|
|
@@ -889,10 +917,10 @@ class Snowflake(Dialect):
|
|
|
889
917
|
"TIMEDIFF": _build_datediff,
|
|
890
918
|
"TIMESTAMPADD": _build_date_time_add(exp.DateAdd),
|
|
891
919
|
"TIMESTAMPDIFF": _build_datediff,
|
|
892
|
-
"TIMESTAMPFROMPARTS":
|
|
893
|
-
"TIMESTAMP_FROM_PARTS":
|
|
894
|
-
"TIMESTAMPNTZFROMPARTS":
|
|
895
|
-
"TIMESTAMP_NTZ_FROM_PARTS":
|
|
920
|
+
"TIMESTAMPFROMPARTS": _build_timestamp_from_parts,
|
|
921
|
+
"TIMESTAMP_FROM_PARTS": _build_timestamp_from_parts,
|
|
922
|
+
"TIMESTAMPNTZFROMPARTS": _build_timestamp_from_parts,
|
|
923
|
+
"TIMESTAMP_NTZ_FROM_PARTS": _build_timestamp_from_parts,
|
|
896
924
|
"TRY_PARSE_JSON": lambda args: exp.ParseJSON(this=seq_get(args, 0), safe=True),
|
|
897
925
|
"TRY_TO_DATE": _build_datetime("TRY_TO_DATE", exp.DataType.Type.DATE, safe=True),
|
|
898
926
|
"TRY_TO_TIME": _build_datetime("TRY_TO_TIME", exp.DataType.Type.TIME, safe=True),
|
|
@@ -916,9 +944,11 @@ class Snowflake(Dialect):
|
|
|
916
944
|
"TO_JSON": exp.JSONFormat.from_arg_list,
|
|
917
945
|
"VECTOR_L2_DISTANCE": exp.EuclideanDistance.from_arg_list,
|
|
918
946
|
"ZEROIFNULL": _build_if_from_zeroifnull,
|
|
919
|
-
"LIKE":
|
|
920
|
-
"ILIKE":
|
|
947
|
+
"LIKE": build_like(exp.Like),
|
|
948
|
+
"ILIKE": build_like(exp.ILike),
|
|
921
949
|
"SEARCH": _build_search,
|
|
950
|
+
"WEEKISO": exp.WeekOfYear.from_arg_list,
|
|
951
|
+
"WEEKOFYEAR": exp.Week.from_arg_list,
|
|
922
952
|
}
|
|
923
953
|
FUNCTIONS.pop("PREDICT")
|
|
924
954
|
|
|
@@ -1624,9 +1654,16 @@ class Snowflake(Dialect):
|
|
|
1624
1654
|
exp.UnixToTime: rename_func("TO_TIMESTAMP"),
|
|
1625
1655
|
exp.Uuid: rename_func("UUID_STRING"),
|
|
1626
1656
|
exp.VarMap: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),
|
|
1627
|
-
exp.
|
|
1657
|
+
exp.Booland: rename_func("BOOLAND"),
|
|
1658
|
+
exp.Boolor: rename_func("BOOLOR"),
|
|
1659
|
+
exp.WeekOfYear: rename_func("WEEKISO"),
|
|
1660
|
+
exp.YearOfWeek: rename_func("YEAROFWEEK"),
|
|
1661
|
+
exp.YearOfWeekIso: rename_func("YEAROFWEEKISO"),
|
|
1628
1662
|
exp.Xor: rename_func("BOOLXOR"),
|
|
1629
1663
|
exp.ByteLength: rename_func("OCTET_LENGTH"),
|
|
1664
|
+
exp.ArrayConcatAgg: lambda self, e: self.func(
|
|
1665
|
+
"ARRAY_FLATTEN", exp.ArrayAgg(this=e.this)
|
|
1666
|
+
),
|
|
1630
1667
|
}
|
|
1631
1668
|
|
|
1632
1669
|
SUPPORTED_JSON_PATH_PARTS = {
|
|
@@ -6,6 +6,7 @@ from sqlglot import exp
|
|
|
6
6
|
from sqlglot.dialects.dialect import (
|
|
7
7
|
Version,
|
|
8
8
|
rename_func,
|
|
9
|
+
build_like,
|
|
9
10
|
unit_to_var,
|
|
10
11
|
timestampdiff_sql,
|
|
11
12
|
build_date_delta,
|
|
@@ -147,6 +148,8 @@ class Spark(Spark2):
|
|
|
147
148
|
offset=1,
|
|
148
149
|
safe=True,
|
|
149
150
|
),
|
|
151
|
+
"LIKE": build_like(exp.Like),
|
|
152
|
+
"ILIKE": build_like(exp.ILike),
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
PLACEHOLDER_PARSERS = {
|
|
@@ -31,7 +31,6 @@ if t.TYPE_CHECKING:
|
|
|
31
31
|
def execute(
|
|
32
32
|
sql: str | Expression,
|
|
33
33
|
schema: t.Optional[t.Dict | Schema] = None,
|
|
34
|
-
read: DialectType = None,
|
|
35
34
|
dialect: DialectType = None,
|
|
36
35
|
tables: t.Optional[t.Dict] = None,
|
|
37
36
|
) -> Table:
|
|
@@ -45,15 +44,13 @@ def execute(
|
|
|
45
44
|
1. {table: {col: type}}
|
|
46
45
|
2. {db: {table: {col: type}}}
|
|
47
46
|
3. {catalog: {db: {table: {col: type}}}}
|
|
48
|
-
|
|
49
|
-
dialect: the SQL dialect (alias for read).
|
|
47
|
+
dialect: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
|
|
50
48
|
tables: additional tables to register.
|
|
51
49
|
|
|
52
50
|
Returns:
|
|
53
51
|
Simple columnar data structure.
|
|
54
52
|
"""
|
|
55
|
-
|
|
56
|
-
tables_ = ensure_tables(tables, dialect=read)
|
|
53
|
+
tables_ = ensure_tables(tables, dialect=dialect)
|
|
57
54
|
|
|
58
55
|
if not schema:
|
|
59
56
|
schema = {}
|
|
@@ -66,19 +63,17 @@ def execute(
|
|
|
66
63
|
for column in table.columns:
|
|
67
64
|
value = table[0][column]
|
|
68
65
|
column_type = (
|
|
69
|
-
annotate_types(exp.convert(value), dialect=
|
|
66
|
+
annotate_types(exp.convert(value), dialect=dialect).type or type(value).__name__
|
|
70
67
|
)
|
|
71
68
|
nested_set(schema, [*keys, column], column_type)
|
|
72
69
|
|
|
73
|
-
schema = ensure_schema(schema, dialect=
|
|
70
|
+
schema = ensure_schema(schema, dialect=dialect)
|
|
74
71
|
|
|
75
72
|
if tables_.supported_table_args and tables_.supported_table_args != schema.supported_table_args:
|
|
76
73
|
raise ExecuteError("Tables must support the same table args as schema")
|
|
77
74
|
|
|
78
75
|
now = time.time()
|
|
79
|
-
expression = optimize(
|
|
80
|
-
sql, schema, leave_tables_isolated=True, infer_csv_schemas=True, dialect=read
|
|
81
|
-
)
|
|
76
|
+
expression = optimize(sql, schema, leave_tables_isolated=True, dialect=dialect)
|
|
82
77
|
|
|
83
78
|
logger.debug("Optimization finished: %f", time.time() - now)
|
|
84
79
|
logger.debug("Optimized SQL: %s", expression.sql(pretty=True))
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import ast
|
|
2
1
|
import collections
|
|
3
2
|
import itertools
|
|
4
3
|
import math
|
|
@@ -9,7 +8,7 @@ from sqlglot.errors import ExecuteError
|
|
|
9
8
|
from sqlglot.executor.context import Context
|
|
10
9
|
from sqlglot.executor.env import ENV
|
|
11
10
|
from sqlglot.executor.table import RowReader, Table
|
|
12
|
-
from sqlglot.helper import
|
|
11
|
+
from sqlglot.helper import subclasses
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class PythonExecutor:
|
|
@@ -97,9 +96,6 @@ class PythonExecutor:
|
|
|
97
96
|
if not step.projections and not step.condition:
|
|
98
97
|
return self.context({step.name: context.tables[source]})
|
|
99
98
|
table_iter = context.table_iter(source)
|
|
100
|
-
elif isinstance(step.source, exp.Table) and isinstance(step.source.this, exp.ReadCSV):
|
|
101
|
-
table_iter = self.scan_csv(step)
|
|
102
|
-
context = next(table_iter)
|
|
103
99
|
else:
|
|
104
100
|
context, table_iter = self.scan_table(step)
|
|
105
101
|
|
|
@@ -132,30 +128,6 @@ class PythonExecutor:
|
|
|
132
128
|
context = self.context({step.source.alias_or_name: table})
|
|
133
129
|
return context, iter(table)
|
|
134
130
|
|
|
135
|
-
def scan_csv(self, step):
|
|
136
|
-
alias = step.source.alias
|
|
137
|
-
source = step.source.this
|
|
138
|
-
|
|
139
|
-
with csv_reader(source) as reader:
|
|
140
|
-
columns = next(reader)
|
|
141
|
-
table = Table(columns)
|
|
142
|
-
context = self.context({alias: table})
|
|
143
|
-
yield context
|
|
144
|
-
types = []
|
|
145
|
-
for row in reader:
|
|
146
|
-
if not types:
|
|
147
|
-
for v in row:
|
|
148
|
-
try:
|
|
149
|
-
types.append(type(ast.literal_eval(v)))
|
|
150
|
-
except (ValueError, SyntaxError):
|
|
151
|
-
types.append(str)
|
|
152
|
-
|
|
153
|
-
# We can't cast empty values ('') to non-string types, so we convert them to None instead
|
|
154
|
-
context.set_row(
|
|
155
|
-
tuple(None if (t is not str and v == "") else t(v) for t, v in zip(types, row))
|
|
156
|
-
)
|
|
157
|
-
yield context.table.reader
|
|
158
|
-
|
|
159
131
|
def join(self, step, context):
|
|
160
132
|
source = step.source_name
|
|
161
133
|
|