sqlglot 27.19.0__tar.gz → 27.21.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.19.0 → sqlglot-27.21.0}/CHANGELOG.md +98 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/Makefile +8 -2
- {sqlglot-27.19.0 → sqlglot-27.21.0}/PKG-INFO +4 -2
- {sqlglot-27.19.0 → sqlglot-27.21.0}/README.md +2 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/_version.py +3 -3
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/bigquery.py +2 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/dialect.py +4 -2
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/duckdb.py +3 -4
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/hive.py +0 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/oracle.py +0 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/presto.py +0 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/risingwave.py +14 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/snowflake.py +102 -3
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/spark.py +0 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/sqlite.py +9 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/starrocks.py +3 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/expressions.py +124 -28
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/generator.py +3 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/helper.py +0 -18
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/canonicalize.py +1 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/merge_subqueries.py +2 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/parser.py +26 -27
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/tokens.py +5 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/transforms.py +0 -33
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.egg-info/PKG-INFO +4 -2
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.egg-info/requires.txt +1 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/Cargo.lock +1 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/Cargo.toml +1 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/src/tokenizer.rs +6 -15
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_bigquery.py +20 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_databricks.py +2 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_dialect.py +19 -12
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_duckdb.py +20 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_hive.py +1 -1
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_postgres.py +6 -4
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_redshift.py +2 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_snowflake.py +120 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_sqlite.py +1 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_starrocks.py +3 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_tsql.py +1 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/identity.sql +1 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/annotate_functions.sql +216 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/merge_subqueries.sql +28 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/optimizer.sql +12 -7
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +22 -12
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_expressions.py +8 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_transforms.py +0 -33
- {sqlglot-27.19.0 → sqlglot-27.21.0}/.gitignore +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/.gitpod.yml +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/.pre-commit-config.yaml +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/CONTRIBUTING.md +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/LICENSE +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/MANIFEST.in +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/pyproject.toml +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/setup.cfg +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/setup.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/__main__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/_typing.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/athena.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/clickhouse.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/databricks.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/doris.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/dremio.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/drill.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/druid.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/dune.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/exasol.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/fabric.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/materialize.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/mysql.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/postgres.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/prql.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/redshift.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/singlestore.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/solr.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/spark2.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/tableau.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/teradata.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/trino.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/dialects/tsql.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/diff.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/errors.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/executor/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/executor/context.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/executor/env.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/executor/python.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/executor/table.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/jsonpath.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/lineage.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/annotate_types.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/normalize.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/optimize_joins.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/optimizer.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/qualify_columns.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/scope.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/simplify.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/planner.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/py.typed +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/schema.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/serde.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/time.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot/trie.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.egg-info/SOURCES.txt +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.egg-info/dependency_links.txt +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.egg-info/top_level.txt +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglot.png +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/benches/dialect_settings.json +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/benches/long.rs +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/benches/token_type_settings.json +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/pyproject.toml +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/src/lib.rs +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/src/settings.rs +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/src/token.rs +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/sqlglotrs/src/trie.rs +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/__init__.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_athena.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_clickhouse.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_doris.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_dremio.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_drill.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_druid.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_dune.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_exasol.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_fabric.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_materialize.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_mysql.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_oracle.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_pipe_syntax.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_presto.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_prql.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_risingwave.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_singlestore.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_solr.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_spark.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_tableau.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_teradata.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/dialects/test_trino.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/jsonpath/LICENSE +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/jsonpath/cts.json +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/normalize.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/simplify.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/partial.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/fixtures/pretty.sql +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/gen_fixtures.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/helpers.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_build.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_dialect_imports.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_diff.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_docs.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_executor.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_generator.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_helper.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_jsonpath.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_lineage.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_optimizer.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_parser.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_schema.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_serde.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_time.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_tokens.py +0 -0
- {sqlglot-27.19.0 → sqlglot-27.21.0}/tests/test_transpile.py +0 -0
|
@@ -1,6 +1,102 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [v27.20.0] - 2025-09-30
|
|
5
|
+
### :boom: BREAKING CHANGES
|
|
6
|
+
- due to [`13a30df`](https://github.com/tobymao/sqlglot/commit/13a30dfa37096df5bfc2c31538325c40a49f7917) - Annotate type for snowflake TRY_BASE64_DECODE_BINARY function *(PR [#5972](https://github.com/tobymao/sqlglot/pull/5972) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
7
|
+
|
|
8
|
+
Annotate type for snowflake TRY_BASE64_DECODE_BINARY function (#5972)
|
|
9
|
+
|
|
10
|
+
- due to [`1f5fdd7`](https://github.com/tobymao/sqlglot/commit/1f5fdd799c047de167a4572f7ac26b7ad92167f2) - Annotate type for snowflake TRY_BASE64_DECODE_STRING function *(PR [#5974](https://github.com/tobymao/sqlglot/pull/5974) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
11
|
+
|
|
12
|
+
Annotate type for snowflake TRY_BASE64_DECODE_STRING function (#5974)
|
|
13
|
+
|
|
14
|
+
- due to [`324e82f`](https://github.com/tobymao/sqlglot/commit/324e82fe1fb11722f91341010602a743b151e055) - Annotate type for snowflake TRY_HEX_DECODE_BINARY function *(PR [#5975](https://github.com/tobymao/sqlglot/pull/5975) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
15
|
+
|
|
16
|
+
Annotate type for snowflake TRY_HEX_DECODE_BINARY function (#5975)
|
|
17
|
+
|
|
18
|
+
- due to [`6caf99d`](https://github.com/tobymao/sqlglot/commit/6caf99d556a3357ffaa6c294a9babcd30dd5fac5) - Annotate type for snowflake TRY_HEX_DECODE_STRING function *(PR [#5976](https://github.com/tobymao/sqlglot/pull/5976) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
19
|
+
|
|
20
|
+
Annotate type for snowflake TRY_HEX_DECODE_STRING function (#5976)
|
|
21
|
+
|
|
22
|
+
- due to [`73186a8`](https://github.com/tobymao/sqlglot/commit/73186a812ce422c108ee81b3de11da6ee9a9e902) - annotate type for Snowflake REGEXP_COUNT function *(PR [#5963](https://github.com/tobymao/sqlglot/pull/5963) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
|
|
23
|
+
|
|
24
|
+
annotate type for Snowflake REGEXP_COUNT function (#5963)
|
|
25
|
+
|
|
26
|
+
- due to [`c3bdb3c`](https://github.com/tobymao/sqlglot/commit/c3bdb3cd1af1809ed82be0ae40744d9fffc8ce18) - array start index is 1, support array_flatten, fixes [#5983](https://github.com/tobymao/sqlglot/pull/5983) *(commit by [@georgesittas](https://github.com/georgesittas))*:
|
|
27
|
+
|
|
28
|
+
array start index is 1, support array_flatten, fixes #5983
|
|
29
|
+
|
|
30
|
+
- due to [`244fb48`](https://github.com/tobymao/sqlglot/commit/244fb48fc9c4776f427c08b825d139b1c172fd26) - annotate type for Snowflake SPLIT_PART function *(PR [#5988](https://github.com/tobymao/sqlglot/pull/5988) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
|
|
31
|
+
|
|
32
|
+
annotate type for Snowflake SPLIT_PART function (#5988)
|
|
33
|
+
|
|
34
|
+
- due to [`0d772e0`](https://github.com/tobymao/sqlglot/commit/0d772e0b9d687b24d49203c05d7a90cc1dce02d5) - add ast node for `DIRECTORY` source *(PR [#5990](https://github.com/tobymao/sqlglot/pull/5990) by [@georgesittas](https://github.com/georgesittas))*:
|
|
35
|
+
|
|
36
|
+
add ast node for `DIRECTORY` source (#5990)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### :sparkles: New Features
|
|
40
|
+
- [`13a30df`](https://github.com/tobymao/sqlglot/commit/13a30dfa37096df5bfc2c31538325c40a49f7917) - **optimizer**: Annotate type for snowflake TRY_BASE64_DECODE_BINARY function *(PR [#5972](https://github.com/tobymao/sqlglot/pull/5972) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
41
|
+
- [`1f5fdd7`](https://github.com/tobymao/sqlglot/commit/1f5fdd799c047de167a4572f7ac26b7ad92167f2) - **optimizer**: Annotate type for snowflake TRY_BASE64_DECODE_STRING function *(PR [#5974](https://github.com/tobymao/sqlglot/pull/5974) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
42
|
+
- [`324e82f`](https://github.com/tobymao/sqlglot/commit/324e82fe1fb11722f91341010602a743b151e055) - **optimizer**: Annotate type for snowflake TRY_HEX_DECODE_BINARY function *(PR [#5975](https://github.com/tobymao/sqlglot/pull/5975) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
43
|
+
- [`6caf99d`](https://github.com/tobymao/sqlglot/commit/6caf99d556a3357ffaa6c294a9babcd30dd5fac5) - **optimizer**: Annotate type for snowflake TRY_HEX_DECODE_STRING function *(PR [#5976](https://github.com/tobymao/sqlglot/pull/5976) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
44
|
+
- [`73186a8`](https://github.com/tobymao/sqlglot/commit/73186a812ce422c108ee81b3de11da6ee9a9e902) - **optimizer**: annotate type for Snowflake REGEXP_COUNT function *(PR [#5963](https://github.com/tobymao/sqlglot/pull/5963) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
45
|
+
- [`6124de7`](https://github.com/tobymao/sqlglot/commit/6124de76fa6d6725e844cd37e09ebfe99469b0ec) - **optimizer**: Annotate type for snowflake SOUNDEX function *(PR [#5986](https://github.com/tobymao/sqlglot/pull/5986) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
46
|
+
- [`244fb48`](https://github.com/tobymao/sqlglot/commit/244fb48fc9c4776f427c08b825d139b1c172fd26) - **optimizer**: annotate type for Snowflake SPLIT_PART function *(PR [#5988](https://github.com/tobymao/sqlglot/pull/5988) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
47
|
+
- [`0d772e0`](https://github.com/tobymao/sqlglot/commit/0d772e0b9d687b24d49203c05d7a90cc1dce02d5) - **snowflake**: add ast node for `DIRECTORY` source *(PR [#5990](https://github.com/tobymao/sqlglot/pull/5990) by [@georgesittas](https://github.com/georgesittas))*
|
|
48
|
+
|
|
49
|
+
### :bug: Bug Fixes
|
|
50
|
+
- [`7a3744f`](https://github.com/tobymao/sqlglot/commit/7a3744f203b93211e5dd97e6730b6bf59d6d96e0) - **sqlite**: support `RANGE CURRENT ROW` in window spec *(commit by [@georgesittas](https://github.com/georgesittas))*
|
|
51
|
+
- [`c3bdb3c`](https://github.com/tobymao/sqlglot/commit/c3bdb3cd1af1809ed82be0ae40744d9fffc8ce18) - **starrocks**: array start index is 1, support array_flatten, fixes [#5983](https://github.com/tobymao/sqlglot/pull/5983) *(commit by [@georgesittas](https://github.com/georgesittas))*
|
|
52
|
+
|
|
53
|
+
### :recycle: Refactors
|
|
54
|
+
- [`d425ba2`](https://github.com/tobymao/sqlglot/commit/d425ba26b96b368801f8f486fa375cd75105993d) - make hash and eq non recursive *(PR [#5966](https://github.com/tobymao/sqlglot/pull/5966) by [@tobymao](https://github.com/tobymao))*
|
|
55
|
+
|
|
56
|
+
### :wrench: Chores
|
|
57
|
+
- [`345c6a1`](https://github.com/tobymao/sqlglot/commit/345c6a153481a22d6df1b12ef1863e2133688fdf) - add uv support to Makefile *(PR [#5973](https://github.com/tobymao/sqlglot/pull/5973) by [@eakmanrq](https://github.com/eakmanrq))*
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## [v27.19.0] - 2025-09-26
|
|
61
|
+
### :boom: BREAKING CHANGES
|
|
62
|
+
- due to [`68473ac`](https://github.com/tobymao/sqlglot/commit/68473ac3ec8dc76512dc76819892a1b0324c7ddc) - Annotate type for snowflake PARSE_URL function *(PR [#5962](https://github.com/tobymao/sqlglot/pull/5962) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
63
|
+
|
|
64
|
+
Annotate type for snowflake PARSE_URL function (#5962)
|
|
65
|
+
|
|
66
|
+
- due to [`b015a9d`](https://github.com/tobymao/sqlglot/commit/b015a9d944d0a87069a7750ad74953c399d7da34) - annotate type for Snowflake REGEXP_INSTR function *(commit by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
|
|
67
|
+
|
|
68
|
+
annotate type for Snowflake REGEXP_INSTR function
|
|
69
|
+
|
|
70
|
+
- due to [`1f29ba7`](https://github.com/tobymao/sqlglot/commit/1f29ba710f4213beb1a2f993244d7d824f3536ce) - annotate type for Snowflake PARSE_IP function *(PR [#5961](https://github.com/tobymao/sqlglot/pull/5961) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
|
|
71
|
+
|
|
72
|
+
annotate type for Snowflake PARSE_IP function (#5961)
|
|
73
|
+
|
|
74
|
+
- due to [`bf45d5d`](https://github.com/tobymao/sqlglot/commit/bf45d5d3cb0c0f380824019eb32ec29049268a61) - annotate types for Snowflake RTRIMMED_LENGTH function *(PR [#5968](https://github.com/tobymao/sqlglot/pull/5968) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
|
|
75
|
+
|
|
76
|
+
annotate types for Snowflake RTRIMMED_LENGTH function (#5968)
|
|
77
|
+
|
|
78
|
+
- due to [`13caa69`](https://github.com/tobymao/sqlglot/commit/13caa6991f003ad7abb590073451e591b6fd888c) - Annotate type for snowflake POSITION function *(PR [#5964](https://github.com/tobymao/sqlglot/pull/5964) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
79
|
+
|
|
80
|
+
Annotate type for snowflake POSITION function (#5964)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### :sparkles: New Features
|
|
84
|
+
- [`88e4e4c`](https://github.com/tobymao/sqlglot/commit/88e4e4c55f3a113127eb3c82c0be46c29bcf15ab) - **optimizer**: Annotate type for OCTET_LENGTH function *(PR [#5960](https://github.com/tobymao/sqlglot/pull/5960) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
85
|
+
- [`68473ac`](https://github.com/tobymao/sqlglot/commit/68473ac3ec8dc76512dc76819892a1b0324c7ddc) - **optimizer**: Annotate type for snowflake PARSE_URL function *(PR [#5962](https://github.com/tobymao/sqlglot/pull/5962) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
86
|
+
- [`b015a9d`](https://github.com/tobymao/sqlglot/commit/b015a9d944d0a87069a7750ad74953c399d7da34) - **optimizer**: annotate type for Snowflake REGEXP_INSTR function *(commit by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
87
|
+
- [`1f29ba7`](https://github.com/tobymao/sqlglot/commit/1f29ba710f4213beb1a2f993244d7d824f3536ce) - **optimizer**: annotate type for Snowflake PARSE_IP function *(PR [#5961](https://github.com/tobymao/sqlglot/pull/5961) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
88
|
+
- [`bf45d5d`](https://github.com/tobymao/sqlglot/commit/bf45d5d3cb0c0f380824019eb32ec29049268a61) - **optimizer**: annotate types for Snowflake RTRIMMED_LENGTH function *(PR [#5968](https://github.com/tobymao/sqlglot/pull/5968) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
89
|
+
- [`13caa69`](https://github.com/tobymao/sqlglot/commit/13caa6991f003ad7abb590073451e591b6fd888c) - **optimizer**: Annotate type for snowflake POSITION function *(PR [#5964](https://github.com/tobymao/sqlglot/pull/5964) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
90
|
+
- [`1471306`](https://github.com/tobymao/sqlglot/commit/1471306ed317830c294e3654075f55424d14bf5a) - support parse into grant principal and privilege *(PR [#5971](https://github.com/tobymao/sqlglot/pull/5971) by [@eakmanrq](https://github.com/eakmanrq))*
|
|
91
|
+
|
|
92
|
+
### :bug: Bug Fixes
|
|
93
|
+
- [`5432976`](https://github.com/tobymao/sqlglot/commit/543297680755344185e0f306843bc4909f4f75ed) - **bigquery**: allow GRANT as an id var *(PR [#5965](https://github.com/tobymao/sqlglot/pull/5965) by [@treysp](https://github.com/treysp))*
|
|
94
|
+
|
|
95
|
+
### :wrench: Chores
|
|
96
|
+
- [`1514bc6`](https://github.com/tobymao/sqlglot/commit/1514bc640ec129a96aedd9e89bfd5d61e832d6b1) - **optimizer**: add type inference tests for Snowflake RPAD function *(PR [#5967](https://github.com/tobymao/sqlglot/pull/5967) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
|
|
97
|
+
- [`050b89d`](https://github.com/tobymao/sqlglot/commit/050b89deb9be842f2ddd07c78ea201ec4eae4779) - **optimizer**: Annotate type for snowflake regexp function *(PR [#5970](https://github.com/tobymao/sqlglot/pull/5970) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
|
|
98
|
+
|
|
99
|
+
|
|
4
100
|
## [v27.18.0] - 2025-09-25
|
|
5
101
|
### :boom: BREAKING CHANGES
|
|
6
102
|
- due to [`7f13eaf`](https://github.com/tobymao/sqlglot/commit/7f13eaf7769a3381a56c9209af590835be2f95cd) - Annotate type for snowflake DECOMPRESS_BINARY function *(PR [#5945](https://github.com/tobymao/sqlglot/pull/5945) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
|
|
@@ -7520,3 +7616,5 @@ Changelog
|
|
|
7520
7616
|
[v27.16.3]: https://github.com/tobymao/sqlglot/compare/v27.16.2...v27.16.3
|
|
7521
7617
|
[v27.17.0]: https://github.com/tobymao/sqlglot/compare/v27.16.3...v27.17.0
|
|
7522
7618
|
[v27.18.0]: https://github.com/tobymao/sqlglot/compare/v27.17.0...v27.18.0
|
|
7619
|
+
[v27.19.0]: https://github.com/tobymao/sqlglot/compare/v27.18.0...v27.19.0
|
|
7620
|
+
[v27.20.0]: https://github.com/tobymao/sqlglot/compare/v27.19.0...v27.20.0
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
.PHONY: install install-dev install-pre-commit test unit style check docs docs-serve
|
|
2
2
|
|
|
3
|
+
ifdef UV
|
|
4
|
+
PIP := uv pip
|
|
5
|
+
else
|
|
6
|
+
PIP := pip
|
|
7
|
+
endif
|
|
8
|
+
|
|
3
9
|
install:
|
|
4
|
-
|
|
10
|
+
$(PIP) install -e .
|
|
5
11
|
|
|
6
12
|
bench: install-dev-rs-release
|
|
7
13
|
python -m benchmarks.bench
|
|
@@ -17,7 +23,7 @@ install-dev-rs:
|
|
|
17
23
|
cd sqlglotrs/ && python -m maturin develop
|
|
18
24
|
|
|
19
25
|
install-dev-core:
|
|
20
|
-
|
|
26
|
+
$(PIP) install -e ".[dev]"
|
|
21
27
|
|
|
22
28
|
install-dev: install-dev-core install-dev-rs
|
|
23
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglot
|
|
3
|
-
Version: 27.
|
|
3
|
+
Version: 27.21.0
|
|
4
4
|
Summary: An easily customizable SQL parser and transpiler
|
|
5
5
|
Author-email: Toby Mao <toby.mao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,7 +33,7 @@ Requires-Dist: typing_extensions; extra == "dev"
|
|
|
33
33
|
Requires-Dist: maturin<2.0,>=1.4; extra == "dev"
|
|
34
34
|
Requires-Dist: pyperf; extra == "dev"
|
|
35
35
|
Provides-Extra: rs
|
|
36
|
-
Requires-Dist: sqlglotrs==0.
|
|
36
|
+
Requires-Dist: sqlglotrs==0.7.0; extra == "rs"
|
|
37
37
|
Dynamic: license-file
|
|
38
38
|
Dynamic: provides-extra
|
|
39
39
|
|
|
@@ -89,12 +89,14 @@ pip3 install "sqlglot[rs]"
|
|
|
89
89
|
Or with a local checkout:
|
|
90
90
|
|
|
91
91
|
```
|
|
92
|
+
# Optionally prefix with UV=1 to use uv for the installation
|
|
92
93
|
make install
|
|
93
94
|
```
|
|
94
95
|
|
|
95
96
|
Requirements for development (optional):
|
|
96
97
|
|
|
97
98
|
```
|
|
99
|
+
# Optionally prefix with UV=1 to use uv for the installation
|
|
98
100
|
make install-dev
|
|
99
101
|
```
|
|
100
102
|
|
|
@@ -50,12 +50,14 @@ pip3 install "sqlglot[rs]"
|
|
|
50
50
|
Or with a local checkout:
|
|
51
51
|
|
|
52
52
|
```
|
|
53
|
+
# Optionally prefix with UV=1 to use uv for the installation
|
|
53
54
|
make install
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
Requirements for development (optional):
|
|
57
58
|
|
|
58
59
|
```
|
|
60
|
+
# Optionally prefix with UV=1 to use uv for the installation
|
|
59
61
|
make install-dev
|
|
60
62
|
```
|
|
61
63
|
|
|
@@ -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.21.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (27, 21, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g5dd2ed3c6'
|
|
@@ -867,6 +867,8 @@ class BigQuery(Dialect):
|
|
|
867
867
|
"FROM_HEX": exp.Unhex.from_arg_list,
|
|
868
868
|
"WEEK": lambda args: exp.WeekStart(this=exp.var(seq_get(args, 0))),
|
|
869
869
|
}
|
|
870
|
+
# Remove SEARCH to avoid parameter routing issues - let it fall back to Anonymous function
|
|
871
|
+
FUNCTIONS.pop("SEARCH")
|
|
870
872
|
|
|
871
873
|
FUNCTION_PARSERS = {
|
|
872
874
|
**parser.Parser.FUNCTION_PARSERS,
|
|
@@ -1715,7 +1715,7 @@ def unit_to_str(expression: exp.Expression, default: str = "DAY") -> t.Optional[
|
|
|
1715
1715
|
def unit_to_var(expression: exp.Expression, default: str = "DAY") -> t.Optional[exp.Expression]:
|
|
1716
1716
|
unit = expression.args.get("unit")
|
|
1717
1717
|
|
|
1718
|
-
if isinstance(unit, (exp.Var, exp.Placeholder, exp.WeekStart)):
|
|
1718
|
+
if isinstance(unit, (exp.Var, exp.Placeholder, exp.WeekStart, exp.Column)):
|
|
1719
1719
|
return unit
|
|
1720
1720
|
|
|
1721
1721
|
value = unit.name if unit else default
|
|
@@ -1736,7 +1736,9 @@ def map_date_part(
|
|
|
1736
1736
|
|
|
1737
1737
|
def map_date_part(part, dialect: DialectType = Dialect):
|
|
1738
1738
|
mapped = (
|
|
1739
|
-
Dialect.get_or_raise(dialect).DATE_PART_MAPPING.get(part.name.upper())
|
|
1739
|
+
Dialect.get_or_raise(dialect).DATE_PART_MAPPING.get(part.name.upper())
|
|
1740
|
+
if part and not (isinstance(part, exp.Column) and len(part.parts) != 1)
|
|
1741
|
+
else None
|
|
1740
1742
|
)
|
|
1741
1743
|
if mapped:
|
|
1742
1744
|
return exp.Literal.string(mapped) if part.is_string else exp.var(mapped)
|
|
@@ -311,6 +311,7 @@ class DuckDB(Dialect):
|
|
|
311
311
|
"PIVOT_WIDER": TokenType.PIVOT,
|
|
312
312
|
"POSITIONAL": TokenType.POSITIONAL,
|
|
313
313
|
"RESET": TokenType.COMMAND,
|
|
314
|
+
"ROW": TokenType.STRUCT,
|
|
314
315
|
"SIGNED": TokenType.INT,
|
|
315
316
|
"STRING": TokenType.TEXT,
|
|
316
317
|
"SUMMARIZE": TokenType.SUMMARIZE,
|
|
@@ -337,16 +338,14 @@ class DuckDB(Dialect):
|
|
|
337
338
|
class Parser(parser.Parser):
|
|
338
339
|
MAP_KEYS_ARE_ARBITRARY_EXPRESSIONS = True
|
|
339
340
|
|
|
340
|
-
BITWISE =
|
|
341
|
-
**parser.Parser.BITWISE,
|
|
342
|
-
TokenType.TILDA: exp.RegexpLike,
|
|
343
|
-
}
|
|
341
|
+
BITWISE = parser.Parser.BITWISE.copy()
|
|
344
342
|
BITWISE.pop(TokenType.CARET)
|
|
345
343
|
|
|
346
344
|
RANGE_PARSERS = {
|
|
347
345
|
**parser.Parser.RANGE_PARSERS,
|
|
348
346
|
TokenType.DAMP: binary_range_parser(exp.ArrayOverlaps),
|
|
349
347
|
TokenType.CARET_AT: binary_range_parser(exp.StartsWith),
|
|
348
|
+
TokenType.TILDA: binary_range_parser(exp.RegexpFullMatch),
|
|
350
349
|
}
|
|
351
350
|
|
|
352
351
|
EXPONENT = {
|
|
@@ -531,7 +531,6 @@ class Hive(Dialect):
|
|
|
531
531
|
|
|
532
532
|
TRANSFORMS = {
|
|
533
533
|
**generator.Generator.TRANSFORMS,
|
|
534
|
-
exp.Group: transforms.preprocess([transforms.unalias_group]),
|
|
535
534
|
exp.Property: property_sql,
|
|
536
535
|
exp.AnyValue: rename_func("FIRST"),
|
|
537
536
|
exp.ApproxDistinct: approx_count_distinct_sql,
|
|
@@ -307,7 +307,6 @@ class Oracle(Dialect):
|
|
|
307
307
|
),
|
|
308
308
|
exp.DateTrunc: lambda self, e: self.func("TRUNC", e.this, e.unit),
|
|
309
309
|
exp.EuclideanDistance: rename_func("L2_DISTANCE"),
|
|
310
|
-
exp.Group: transforms.preprocess([transforms.unalias_group]),
|
|
311
310
|
exp.ILike: no_ilike_sql,
|
|
312
311
|
exp.LogicalOr: rename_func("MAX"),
|
|
313
312
|
exp.LogicalAnd: rename_func("MIN"),
|
|
@@ -475,7 +475,6 @@ class Presto(Dialect):
|
|
|
475
475
|
e: f"WITH_TIMEZONE({self.sql(e, 'this')}, {self.sql(e, 'zone')}) AT TIME ZONE 'UTC'",
|
|
476
476
|
exp.GenerateSeries: sequence_sql,
|
|
477
477
|
exp.GenerateDateArray: sequence_sql,
|
|
478
|
-
exp.Group: transforms.preprocess([transforms.unalias_group]),
|
|
479
478
|
exp.If: if_sql(),
|
|
480
479
|
exp.ILike: no_ilike_sql,
|
|
481
480
|
exp.Initcap: _initcap_sql,
|
|
@@ -25,6 +25,20 @@ class RisingWave(Postgres):
|
|
|
25
25
|
"KEY": lambda self: self._parse_encode_property(key=True),
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
CONSTRAINT_PARSERS = {
|
|
29
|
+
**Postgres.Parser.CONSTRAINT_PARSERS,
|
|
30
|
+
"WATERMARK": lambda self: self.expression(
|
|
31
|
+
exp.WatermarkColumnConstraint,
|
|
32
|
+
this=self._match(TokenType.FOR) and self._parse_column(),
|
|
33
|
+
expression=self._match(TokenType.ALIAS) and self._parse_disjunction(),
|
|
34
|
+
),
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
SCHEMA_UNNAMED_CONSTRAINTS = {
|
|
38
|
+
*Postgres.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
|
|
39
|
+
"WATERMARK",
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
def _parse_table_hints(self) -> t.Optional[t.List[exp.Expression]]:
|
|
29
43
|
# There is no hint in risingwave.
|
|
30
44
|
# Do nothing here to avoid WITH keywords conflict in CREATE SINK statement.
|
|
@@ -41,7 +41,18 @@ if t.TYPE_CHECKING:
|
|
|
41
41
|
from sqlglot._typing import E, B
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
def _build_strtok(args: t.List) -> exp.SplitPart:
|
|
45
|
+
# Add default delimiter (space) if missing - per Snowflake docs
|
|
46
|
+
if len(args) == 1:
|
|
47
|
+
args.append(exp.Literal.string(" "))
|
|
48
|
+
|
|
49
|
+
# Add default part_index (1) if missing
|
|
50
|
+
if len(args) == 2:
|
|
51
|
+
args.append(exp.Literal.number(1))
|
|
52
|
+
|
|
53
|
+
return exp.SplitPart.from_arg_list(args)
|
|
54
|
+
|
|
55
|
+
|
|
45
56
|
def _build_datetime(
|
|
46
57
|
name: str, kind: exp.DataType.Type, safe: bool = False
|
|
47
58
|
) -> t.Callable[[t.List], exp.Func]:
|
|
@@ -137,12 +148,35 @@ def _build_if_from_div0(args: t.List) -> exp.If:
|
|
|
137
148
|
return exp.If(this=cond, true=true, false=false)
|
|
138
149
|
|
|
139
150
|
|
|
151
|
+
# https://docs.snowflake.com/en/sql-reference/functions/div0null
|
|
152
|
+
def _build_if_from_div0null(args: t.List) -> exp.If:
|
|
153
|
+
lhs = exp._wrap(seq_get(args, 0), exp.Binary)
|
|
154
|
+
rhs = exp._wrap(seq_get(args, 1), exp.Binary)
|
|
155
|
+
|
|
156
|
+
# Returns 0 when divisor is 0 OR NULL
|
|
157
|
+
cond = exp.EQ(this=rhs, expression=exp.Literal.number(0)).or_(
|
|
158
|
+
exp.Is(this=rhs, expression=exp.null())
|
|
159
|
+
)
|
|
160
|
+
true = exp.Literal.number(0)
|
|
161
|
+
false = exp.Div(this=lhs, expression=rhs)
|
|
162
|
+
return exp.If(this=cond, true=true, false=false)
|
|
163
|
+
|
|
164
|
+
|
|
140
165
|
# https://docs.snowflake.com/en/sql-reference/functions/zeroifnull
|
|
141
166
|
def _build_if_from_zeroifnull(args: t.List) -> exp.If:
|
|
142
167
|
cond = exp.Is(this=seq_get(args, 0), expression=exp.Null())
|
|
143
168
|
return exp.If(this=cond, true=exp.Literal.number(0), false=seq_get(args, 0))
|
|
144
169
|
|
|
145
170
|
|
|
171
|
+
def _build_search(args: t.List) -> exp.Search:
|
|
172
|
+
kwargs = {
|
|
173
|
+
"this": seq_get(args, 0),
|
|
174
|
+
"expression": seq_get(args, 1),
|
|
175
|
+
**{arg.name.lower(): arg for arg in args[2:] if isinstance(arg, exp.Kwarg)},
|
|
176
|
+
}
|
|
177
|
+
return exp.Search(**kwargs)
|
|
178
|
+
|
|
179
|
+
|
|
146
180
|
# https://docs.snowflake.com/en/sql-reference/functions/zeroifnull
|
|
147
181
|
def _build_if_from_nullifzero(args: t.List) -> exp.If:
|
|
148
182
|
cond = exp.EQ(this=seq_get(args, 0), expression=exp.Literal.number(0))
|
|
@@ -529,6 +563,16 @@ class Snowflake(Dialect):
|
|
|
529
563
|
|
|
530
564
|
TYPE_TO_EXPRESSIONS = {
|
|
531
565
|
**Dialect.TYPE_TO_EXPRESSIONS,
|
|
566
|
+
exp.DataType.Type.DOUBLE: {
|
|
567
|
+
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.DOUBLE],
|
|
568
|
+
exp.Cos,
|
|
569
|
+
exp.Cosh,
|
|
570
|
+
exp.Cot,
|
|
571
|
+
exp.Degrees,
|
|
572
|
+
exp.Exp,
|
|
573
|
+
exp.Sin,
|
|
574
|
+
exp.Tan,
|
|
575
|
+
},
|
|
532
576
|
exp.DataType.Type.INT: {
|
|
533
577
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.INT],
|
|
534
578
|
exp.Ascii,
|
|
@@ -539,10 +583,12 @@ class Snowflake(Dialect):
|
|
|
539
583
|
exp.Levenshtein,
|
|
540
584
|
exp.JarowinklerSimilarity,
|
|
541
585
|
exp.StrPosition,
|
|
586
|
+
exp.Unicode,
|
|
542
587
|
},
|
|
543
588
|
exp.DataType.Type.VARCHAR: {
|
|
544
589
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.VARCHAR],
|
|
545
590
|
exp.Base64DecodeString,
|
|
591
|
+
exp.TryBase64DecodeString,
|
|
546
592
|
exp.Base64Encode,
|
|
547
593
|
exp.DecompressString,
|
|
548
594
|
exp.MD5,
|
|
@@ -553,6 +599,7 @@ class Snowflake(Dialect):
|
|
|
553
599
|
exp.Collate,
|
|
554
600
|
exp.Collation,
|
|
555
601
|
exp.HexDecodeString,
|
|
602
|
+
exp.TryHexDecodeString,
|
|
556
603
|
exp.HexEncode,
|
|
557
604
|
exp.Initcap,
|
|
558
605
|
exp.RegexpExtract,
|
|
@@ -561,12 +608,18 @@ class Snowflake(Dialect):
|
|
|
561
608
|
exp.Replace,
|
|
562
609
|
exp.SHA,
|
|
563
610
|
exp.SHA2,
|
|
611
|
+
exp.Soundex,
|
|
612
|
+
exp.SoundexP123,
|
|
564
613
|
exp.Space,
|
|
614
|
+
exp.SplitPart,
|
|
615
|
+
exp.Translate,
|
|
565
616
|
exp.Uuid,
|
|
566
617
|
},
|
|
567
618
|
exp.DataType.Type.BINARY: {
|
|
568
619
|
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BINARY],
|
|
569
620
|
exp.Base64DecodeBinary,
|
|
621
|
+
exp.TryBase64DecodeBinary,
|
|
622
|
+
exp.TryHexDecodeBinary,
|
|
570
623
|
exp.Compress,
|
|
571
624
|
exp.DecompressBinary,
|
|
572
625
|
exp.MD5Digest,
|
|
@@ -581,11 +634,20 @@ class Snowflake(Dialect):
|
|
|
581
634
|
},
|
|
582
635
|
exp.DataType.Type.ARRAY: {
|
|
583
636
|
exp.Split,
|
|
637
|
+
exp.RegexpExtractAll,
|
|
638
|
+
exp.StringToArray,
|
|
584
639
|
},
|
|
585
640
|
exp.DataType.Type.OBJECT: {
|
|
586
641
|
exp.ParseUrl,
|
|
587
642
|
exp.ParseIp,
|
|
588
643
|
},
|
|
644
|
+
exp.DataType.Type.DECIMAL: {
|
|
645
|
+
exp.RegexpCount,
|
|
646
|
+
},
|
|
647
|
+
exp.DataType.Type.BOOLEAN: {
|
|
648
|
+
*Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BOOLEAN],
|
|
649
|
+
exp.Search,
|
|
650
|
+
},
|
|
589
651
|
}
|
|
590
652
|
|
|
591
653
|
ANNOTATORS = {
|
|
@@ -605,6 +667,15 @@ class Snowflake(Dialect):
|
|
|
605
667
|
exp.Substring,
|
|
606
668
|
)
|
|
607
669
|
},
|
|
670
|
+
**{
|
|
671
|
+
expr_type: lambda self, e: self._annotate_with_type(
|
|
672
|
+
e, exp.DataType.build("NUMBER", dialect="snowflake")
|
|
673
|
+
)
|
|
674
|
+
for expr_type in (
|
|
675
|
+
exp.RegexpCount,
|
|
676
|
+
exp.RegexpInstr,
|
|
677
|
+
)
|
|
678
|
+
},
|
|
608
679
|
exp.ConcatWs: lambda self, e: self._annotate_by_args(e, "expressions"),
|
|
609
680
|
exp.Reverse: _annotate_reverse,
|
|
610
681
|
}
|
|
@@ -679,7 +750,7 @@ class Snowflake(Dialect):
|
|
|
679
750
|
"APPROX_PERCENTILE": exp.ApproxQuantile.from_arg_list,
|
|
680
751
|
"ARRAY_CONSTRUCT": lambda args: exp.Array(expressions=args),
|
|
681
752
|
"ARRAY_CONTAINS": lambda args: exp.ArrayContains(
|
|
682
|
-
this=seq_get(args, 1), expression=seq_get(args, 0)
|
|
753
|
+
this=seq_get(args, 1), expression=seq_get(args, 0), ensure_variant=False
|
|
683
754
|
),
|
|
684
755
|
"ARRAY_GENERATE_RANGE": lambda args: exp.GenerateSeries(
|
|
685
756
|
# ARRAY_GENERATE_RANGE has an exlusive end; we normalize it to be inclusive
|
|
@@ -715,6 +786,7 @@ class Snowflake(Dialect):
|
|
|
715
786
|
"DATEDIFF": _build_datediff,
|
|
716
787
|
"DAYOFWEEKISO": exp.DayOfWeekIso.from_arg_list,
|
|
717
788
|
"DIV0": _build_if_from_div0,
|
|
789
|
+
"DIV0NULL": _build_if_from_div0null,
|
|
718
790
|
"EDITDISTANCE": lambda args: exp.Levenshtein(
|
|
719
791
|
this=seq_get(args, 0), expression=seq_get(args, 1), max_dist=seq_get(args, 2)
|
|
720
792
|
),
|
|
@@ -753,6 +825,7 @@ class Snowflake(Dialect):
|
|
|
753
825
|
"SHA2_BINARY": exp.SHA2Digest.from_arg_list,
|
|
754
826
|
"SHA2_HEX": exp.SHA2.from_arg_list,
|
|
755
827
|
"SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
|
|
828
|
+
"STRTOK": _build_strtok,
|
|
756
829
|
"TABLE": lambda args: exp.TableFromRows(this=seq_get(args, 0)),
|
|
757
830
|
"TIMEADD": _build_date_time_add(exp.TimeAdd),
|
|
758
831
|
"TIMEDIFF": _build_datediff,
|
|
@@ -787,12 +860,14 @@ class Snowflake(Dialect):
|
|
|
787
860
|
"ZEROIFNULL": _build_if_from_zeroifnull,
|
|
788
861
|
"LIKE": _build_like(exp.Like),
|
|
789
862
|
"ILIKE": _build_like(exp.ILike),
|
|
863
|
+
"SEARCH": _build_search,
|
|
790
864
|
}
|
|
791
865
|
FUNCTIONS.pop("PREDICT")
|
|
792
866
|
|
|
793
867
|
FUNCTION_PARSERS = {
|
|
794
868
|
**parser.Parser.FUNCTION_PARSERS,
|
|
795
869
|
"DATE_PART": lambda self: self._parse_date_part(),
|
|
870
|
+
"DIRECTORY": lambda self: self._parse_directory(),
|
|
796
871
|
"OBJECT_CONSTRUCT_KEEP_NULL": lambda self: self._parse_json_object(),
|
|
797
872
|
"LISTAGG": lambda self: self._parse_string_agg(),
|
|
798
873
|
"SEMANTIC_VIEW": lambda self: self._parse_semantic_view(),
|
|
@@ -902,6 +977,14 @@ class Snowflake(Dialect):
|
|
|
902
977
|
),
|
|
903
978
|
}
|
|
904
979
|
|
|
980
|
+
def _parse_directory(self) -> exp.DirectoryStage:
|
|
981
|
+
table = self._parse_table_parts()
|
|
982
|
+
|
|
983
|
+
if isinstance(table, exp.Table):
|
|
984
|
+
table = table.this
|
|
985
|
+
|
|
986
|
+
return self.expression(exp.DirectoryStage, this=table)
|
|
987
|
+
|
|
905
988
|
def _parse_use(self) -> exp.Use:
|
|
906
989
|
if self._match_text_seq("SECONDARY", "ROLES"):
|
|
907
990
|
this = self._match_texts(("ALL", "NONE")) and exp.var(self._prev.text.upper())
|
|
@@ -1343,7 +1426,13 @@ class Snowflake(Dialect):
|
|
|
1343
1426
|
exp.ArgMax: rename_func("MAX_BY"),
|
|
1344
1427
|
exp.ArgMin: rename_func("MIN_BY"),
|
|
1345
1428
|
exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
|
|
1346
|
-
exp.ArrayContains: lambda self, e: self.func(
|
|
1429
|
+
exp.ArrayContains: lambda self, e: self.func(
|
|
1430
|
+
"ARRAY_CONTAINS",
|
|
1431
|
+
e.expression
|
|
1432
|
+
if e.args.get("ensure_variant") is False
|
|
1433
|
+
else exp.cast(e.expression, exp.DataType.Type.VARIANT, copy=False),
|
|
1434
|
+
e.this,
|
|
1435
|
+
),
|
|
1347
1436
|
exp.ArrayIntersect: rename_func("ARRAY_INTERSECTION"),
|
|
1348
1437
|
exp.AtTimeZone: lambda self, e: self.func(
|
|
1349
1438
|
"CONVERT_TIMEZONE", e.args.get("zone"), e.this
|
|
@@ -1873,3 +1962,13 @@ class Snowflake(Dialect):
|
|
|
1873
1962
|
return self.func("TO_CHAR", expression.expressions[0])
|
|
1874
1963
|
|
|
1875
1964
|
return self.function_fallback_sql(expression)
|
|
1965
|
+
|
|
1966
|
+
def splitpart_sql(self, expression: exp.SplitPart) -> str:
|
|
1967
|
+
# Set part_index to 1 if missing
|
|
1968
|
+
if not expression.args.get("delimiter"):
|
|
1969
|
+
expression.set("delimiter", exp.Literal.string(" "))
|
|
1970
|
+
|
|
1971
|
+
if not expression.args.get("part_index"):
|
|
1972
|
+
expression.set("part_index", exp.Literal.number(1))
|
|
1973
|
+
|
|
1974
|
+
return rename_func("SPLIT_PART")(self, expression)
|
|
@@ -342,3 +342,12 @@ class SQLite(Dialect):
|
|
|
342
342
|
|
|
343
343
|
def respectnulls_sql(self, expression: exp.RespectNulls) -> str:
|
|
344
344
|
return self.sql(expression.this)
|
|
345
|
+
|
|
346
|
+
def windowspec_sql(self, expression: exp.WindowSpec) -> str:
|
|
347
|
+
if (
|
|
348
|
+
expression.text("kind").upper() == "RANGE"
|
|
349
|
+
and expression.text("start").upper() == "CURRENT ROW"
|
|
350
|
+
):
|
|
351
|
+
return "RANGE CURRENT ROW"
|
|
352
|
+
|
|
353
|
+
return super().windowspec_sql(expression)
|
|
@@ -32,6 +32,7 @@ def st_distance_sphere(self, expression: exp.StDistance) -> str:
|
|
|
32
32
|
|
|
33
33
|
class StarRocks(MySQL):
|
|
34
34
|
STRICT_JSON_PATH_SYNTAX = False
|
|
35
|
+
INDEX_OFFSET = 1
|
|
35
36
|
|
|
36
37
|
class Tokenizer(MySQL.Tokenizer):
|
|
37
38
|
KEYWORDS = {
|
|
@@ -49,6 +50,7 @@ class StarRocks(MySQL):
|
|
|
49
50
|
"DATE_DIFF": lambda args: exp.DateDiff(
|
|
50
51
|
this=seq_get(args, 1), expression=seq_get(args, 2), unit=seq_get(args, 0)
|
|
51
52
|
),
|
|
53
|
+
"ARRAY_FLATTEN": exp.Flatten.from_arg_list,
|
|
52
54
|
"REGEXP": exp.RegexpLike.from_arg_list,
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -152,6 +154,7 @@ class StarRocks(MySQL):
|
|
|
152
154
|
exp.DateDiff: lambda self, e: self.func(
|
|
153
155
|
"DATE_DIFF", unit_to_str(e), e.this, e.expression
|
|
154
156
|
),
|
|
157
|
+
exp.Flatten: rename_func("ARRAY_FLATTEN"),
|
|
155
158
|
exp.JSONExtractScalar: arrow_json_extract_sql,
|
|
156
159
|
exp.JSONExtract: arrow_json_extract_sql,
|
|
157
160
|
exp.Property: property_sql,
|