polyglot-sql 0.9.0__tar.gz → 0.9.2__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.
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/Cargo.lock +6 -6
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/Cargo.toml +1 -1
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/PKG-INFO +1 -1
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/Cargo.toml +2 -2
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/README.md +1 -1
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/ast_transforms.rs +82 -23
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/builder/mod.rs +22 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/duckdb.rs +25 -8
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/mod.rs +23 -58
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +89 -9
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/mod.rs +5 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/operators.rs +13 -16
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/expressions.rs +23 -4
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/function_registry.rs +187 -5
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/generator.rs +376 -56
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/lib.rs +13 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/lineage.rs +462 -16
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/openlineage.rs +2 -57
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/annotate_types.rs +155 -6
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/mod.rs +26 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +535 -48
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +29 -1
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/parser.rs +182 -43
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/planner.rs +12 -85
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/query_analysis.rs +167 -30
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/resolver.rs +68 -0
- polyglot_sql-0.9.2/crates/polyglot-sql/src/set_operation.rs +475 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/traversal.rs +70 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/validation/tests.rs +39 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/validation.rs +4 -1
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/dialect_matrix.rs +30 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/fabric_regression.rs +56 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/query_analysis.rs +243 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/tsql_regression.rs +56 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-ast-derive/src/lib.rs +51 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_lineage.py +19 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/README.md +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/allocation_hotspots.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/ast_traversal.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/lineage.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/performance_hotspots.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/ast_children.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/ast_json.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/builder/engine.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/builder/plan.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/collections.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/json.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/postgres_interval.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/scalar.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/statements.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/temporal.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/types.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/format_tokens.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/guard.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/scope.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/create_view_security_comment_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/oracle_data_types_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/postgres_explain_options.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/postgres_regexp_clickhouse.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-ast-derive/Cargo.toml +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/builders.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_builders.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_query_analysis.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/pyproject.toml +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/python/polyglot_sql/py.typed +0 -0
|
@@ -605,7 +605,7 @@ dependencies = [
|
|
|
605
605
|
|
|
606
606
|
[[package]]
|
|
607
607
|
name = "polyglot-sql"
|
|
608
|
-
version = "0.9.
|
|
608
|
+
version = "0.9.2"
|
|
609
609
|
dependencies = [
|
|
610
610
|
"criterion",
|
|
611
611
|
"once_cell",
|
|
@@ -623,7 +623,7 @@ dependencies = [
|
|
|
623
623
|
|
|
624
624
|
[[package]]
|
|
625
625
|
name = "polyglot-sql-ast-derive"
|
|
626
|
-
version = "0.9.
|
|
626
|
+
version = "0.9.2"
|
|
627
627
|
dependencies = [
|
|
628
628
|
"proc-macro2",
|
|
629
629
|
"quote",
|
|
@@ -632,7 +632,7 @@ dependencies = [
|
|
|
632
632
|
|
|
633
633
|
[[package]]
|
|
634
634
|
name = "polyglot-sql-ffi"
|
|
635
|
-
version = "0.9.
|
|
635
|
+
version = "0.9.2"
|
|
636
636
|
dependencies = [
|
|
637
637
|
"cbindgen",
|
|
638
638
|
"polyglot-sql",
|
|
@@ -642,11 +642,11 @@ dependencies = [
|
|
|
642
642
|
|
|
643
643
|
[[package]]
|
|
644
644
|
name = "polyglot-sql-function-catalogs"
|
|
645
|
-
version = "0.9.
|
|
645
|
+
version = "0.9.2"
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "polyglot-sql-python"
|
|
649
|
-
version = "0.9.
|
|
649
|
+
version = "0.9.2"
|
|
650
650
|
dependencies = [
|
|
651
651
|
"polyglot-sql",
|
|
652
652
|
"pyo3",
|
|
@@ -657,7 +657,7 @@ dependencies = [
|
|
|
657
657
|
|
|
658
658
|
[[package]]
|
|
659
659
|
name = "polyglot-sql-wasm"
|
|
660
|
-
version = "0.9.
|
|
660
|
+
version = "0.9.2"
|
|
661
661
|
dependencies = [
|
|
662
662
|
"console_error_panic_hook",
|
|
663
663
|
"js-sys",
|
|
@@ -100,14 +100,14 @@ function-catalog-all-dialects = [
|
|
|
100
100
|
]
|
|
101
101
|
|
|
102
102
|
[dependencies]
|
|
103
|
-
polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.9.
|
|
103
|
+
polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.9.2" }
|
|
104
104
|
serde = { workspace = true }
|
|
105
105
|
serde_json = { workspace = true }
|
|
106
106
|
thiserror = { workspace = true }
|
|
107
107
|
unicode-segmentation = { workspace = true }
|
|
108
108
|
stacker = { version = "0.1", optional = true }
|
|
109
109
|
ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
|
|
110
|
-
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.9.
|
|
110
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.9.2", optional = true, default-features = false }
|
|
111
111
|
|
|
112
112
|
[dev-dependencies]
|
|
113
113
|
pretty_assertions = "1.4"
|
|
@@ -25,7 +25,7 @@ By default, `polyglot-sql` enables the full public API. Parser-only consumers ca
|
|
|
25
25
|
disable default features and opt into only the dialect parsers they need:
|
|
26
26
|
|
|
27
27
|
```toml
|
|
28
|
-
polyglot-sql = { version = "0.9.
|
|
28
|
+
polyglot-sql = { version = "0.9.2", default-features = false }
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
```toml
|
|
@@ -11,7 +11,7 @@ use std::collections::{HashMap, HashSet};
|
|
|
11
11
|
|
|
12
12
|
use crate::builder::engine;
|
|
13
13
|
use crate::expressions::*;
|
|
14
|
-
use crate::traversal::ExpressionWalk;
|
|
14
|
+
use crate::traversal::{is_aggregate, ExpressionWalk};
|
|
15
15
|
|
|
16
16
|
/// Apply a bottom-up transformation to every node in the tree.
|
|
17
17
|
/// Wraps `crate::traversal::transform` with a simpler signature for this module.
|
|
@@ -336,6 +336,26 @@ pub fn get_output_column_names(expr: &Expression) -> Vec<String> {
|
|
|
336
336
|
output_column_names_from_query(expr)
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
+
/// Collect projected output column names using dialect-specific set-operation
|
|
340
|
+
/// alignment rules.
|
|
341
|
+
///
|
|
342
|
+
/// This differs from [`get_output_column_names`] only for name-aligned set
|
|
343
|
+
/// operations. When an output shape is not statically knowable (for example an
|
|
344
|
+
/// unresolved wildcard), it preserves the existing leftmost-branch behavior.
|
|
345
|
+
pub fn get_output_column_names_for_dialect(
|
|
346
|
+
expr: &Expression,
|
|
347
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
348
|
+
) -> Vec<String> {
|
|
349
|
+
crate::set_operation::query_output_identifiers(expr, dialect)
|
|
350
|
+
.map(|identifiers| {
|
|
351
|
+
identifiers
|
|
352
|
+
.into_iter()
|
|
353
|
+
.map(|identifier| identifier.name)
|
|
354
|
+
.collect()
|
|
355
|
+
})
|
|
356
|
+
.unwrap_or_else(|_| output_column_names_from_query(expr))
|
|
357
|
+
}
|
|
358
|
+
|
|
339
359
|
fn output_column_names_from_query(expr: &Expression) -> Vec<String> {
|
|
340
360
|
match expr {
|
|
341
361
|
Expression::Select(select) => select_output_column_names(select),
|
|
@@ -540,22 +560,7 @@ pub fn get_subqueries(expr: &Expression) -> Vec<&Expression> {
|
|
|
540
560
|
/// Includes typed aggregates (`Count`, `Sum`, `Avg`, `Min`, `Max`, etc.)
|
|
541
561
|
/// and generic `AggregateFunction` nodes.
|
|
542
562
|
pub fn get_aggregate_functions(expr: &Expression) -> Vec<&Expression> {
|
|
543
|
-
expr.find_all(
|
|
544
|
-
matches!(
|
|
545
|
-
e,
|
|
546
|
-
Expression::AggregateFunction(_)
|
|
547
|
-
| Expression::Count(_)
|
|
548
|
-
| Expression::Sum(_)
|
|
549
|
-
| Expression::Avg(_)
|
|
550
|
-
| Expression::Min(_)
|
|
551
|
-
| Expression::Max(_)
|
|
552
|
-
| Expression::ApproxDistinct(_)
|
|
553
|
-
| Expression::ArrayAgg(_)
|
|
554
|
-
| Expression::GroupConcat(_)
|
|
555
|
-
| Expression::StringAgg(_)
|
|
556
|
-
| Expression::ListAgg(_)
|
|
557
|
-
)
|
|
558
|
-
})
|
|
563
|
+
expr.find_all(is_aggregate)
|
|
559
564
|
}
|
|
560
565
|
|
|
561
566
|
/// Collect all window function nodes in the expression tree.
|
|
@@ -695,6 +700,37 @@ mod tests {
|
|
|
695
700
|
assert_eq!(names, vec!["c1".to_string(), "c2".to_string()]);
|
|
696
701
|
}
|
|
697
702
|
|
|
703
|
+
#[test]
|
|
704
|
+
fn test_get_output_column_names_uses_dialect_by_name_layout() {
|
|
705
|
+
for dialect in [
|
|
706
|
+
crate::dialects::DialectType::DuckDB,
|
|
707
|
+
crate::dialects::DialectType::Snowflake,
|
|
708
|
+
] {
|
|
709
|
+
let expr = crate::parse_one(
|
|
710
|
+
"SELECT 1 AS left_value UNION ALL BY NAME SELECT 2 AS right_value",
|
|
711
|
+
dialect,
|
|
712
|
+
)
|
|
713
|
+
.expect("parse");
|
|
714
|
+
assert_eq!(
|
|
715
|
+
get_output_column_names_for_dialect(&expr, Some(dialect)),
|
|
716
|
+
vec!["left_value", "right_value"]
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
let expr = crate::parse_one(
|
|
721
|
+
"SELECT 1 AS a, 2 AS b UNION ALL BY NAME SELECT 3 AS b, 4 AS a",
|
|
722
|
+
crate::dialects::DialectType::BigQuery,
|
|
723
|
+
)
|
|
724
|
+
.expect("parse");
|
|
725
|
+
assert_eq!(
|
|
726
|
+
get_output_column_names_for_dialect(
|
|
727
|
+
&expr,
|
|
728
|
+
Some(crate::dialects::DialectType::BigQuery),
|
|
729
|
+
),
|
|
730
|
+
vec!["a", "b"]
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
|
|
698
734
|
#[test]
|
|
699
735
|
fn test_get_column_names_union_still_returns_all_references() {
|
|
700
736
|
let expr =
|
|
@@ -851,12 +887,35 @@ mod tests {
|
|
|
851
887
|
|
|
852
888
|
#[test]
|
|
853
889
|
fn test_get_aggregate_functions() {
|
|
854
|
-
let expr = parse_one(
|
|
890
|
+
let expr = crate::parse_one(
|
|
891
|
+
"SELECT COUNT_IF(numeric_value > 0), MEDIAN(numeric_value), FIRST(numeric_value) FROM source_table",
|
|
892
|
+
crate::dialects::DialectType::DuckDB,
|
|
893
|
+
)
|
|
894
|
+
.unwrap();
|
|
855
895
|
let aggs = get_aggregate_functions(&expr);
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
896
|
+
let aggregate_types: Vec<_> = aggs.iter().map(|agg| agg.variant_name()).collect();
|
|
897
|
+
|
|
898
|
+
assert_eq!(aggregate_types, vec!["count_if", "median", "first"]);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
#[test]
|
|
902
|
+
fn test_get_duckdb_null_preserving_arg_extrema() {
|
|
903
|
+
let expr = crate::parse_one(
|
|
904
|
+
"SELECT ARG_MAX_NULL(label, score), ARG_MIN_NULL(label, score) FROM source_table",
|
|
905
|
+
crate::dialects::DialectType::DuckDB,
|
|
906
|
+
)
|
|
907
|
+
.unwrap();
|
|
908
|
+
let aggregates = get_aggregate_functions(&expr);
|
|
909
|
+
|
|
910
|
+
assert_eq!(aggregates.len(), 2);
|
|
911
|
+
for (aggregate, expected_name) in
|
|
912
|
+
aggregates.into_iter().zip(["ARG_MAX_NULL", "ARG_MIN_NULL"])
|
|
913
|
+
{
|
|
914
|
+
let Expression::AggregateFunction(function) = aggregate else {
|
|
915
|
+
panic!("expected a generic aggregate node, got {aggregate:?}");
|
|
916
|
+
};
|
|
917
|
+
assert_eq!(function.name, expected_name);
|
|
918
|
+
assert_eq!(function.args.len(), 2);
|
|
919
|
+
}
|
|
861
920
|
}
|
|
862
921
|
}
|
|
@@ -186,6 +186,7 @@ pub fn col(name: &str) -> Expr {
|
|
|
186
186
|
expr = Expression::Dot(Box::new(DotAccess {
|
|
187
187
|
this: expr,
|
|
188
188
|
field: builder_identifier(field),
|
|
189
|
+
inferred_type: None,
|
|
189
190
|
}));
|
|
190
191
|
}
|
|
191
192
|
|
|
@@ -2783,6 +2784,27 @@ mod tests {
|
|
|
2783
2784
|
assert_eq!(sql, "SELECT price * quantity AS total FROM items");
|
|
2784
2785
|
}
|
|
2785
2786
|
|
|
2787
|
+
#[test]
|
|
2788
|
+
fn test_nested_operator_grouping() {
|
|
2789
|
+
assert_eq!(
|
|
2790
|
+
or(col("a").eq(lit(1)), col("b").eq(lit(2)))
|
|
2791
|
+
.and(col("c").eq(lit(3)))
|
|
2792
|
+
.to_sql(),
|
|
2793
|
+
"(a = 1 OR b = 2) AND c = 3"
|
|
2794
|
+
);
|
|
2795
|
+
assert_eq!(
|
|
2796
|
+
col("a")
|
|
2797
|
+
.eq(lit(1))
|
|
2798
|
+
.and(or(col("b").eq(lit(2)), col("c").eq(lit(3))))
|
|
2799
|
+
.to_sql(),
|
|
2800
|
+
"a = 1 AND (b = 2 OR c = 3)"
|
|
2801
|
+
);
|
|
2802
|
+
assert_eq!(col("a").add(col("b")).mul(col("c")).to_sql(), "(a + b) * c");
|
|
2803
|
+
assert_eq!(col("a").mul(col("b").add(col("c"))).to_sql(), "a * (b + c)");
|
|
2804
|
+
assert_eq!(col("a").sub(col("b").sub(col("c"))).to_sql(), "a - (b - c)");
|
|
2805
|
+
assert_eq!(col("a").div(col("b").div(col("c"))).to_sql(), "a / (b / c)");
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2786
2808
|
#[test]
|
|
2787
2809
|
fn test_cast() {
|
|
2788
2810
|
let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
|
|
@@ -6120,14 +6120,12 @@ impl DuckDBDialect {
|
|
|
6120
6120
|
trailing_comments: Vec::new(),
|
|
6121
6121
|
inferred_type: None,
|
|
6122
6122
|
}));
|
|
6123
|
-
let two_pi_u2 = Expression::
|
|
6124
|
-
|
|
6125
|
-
right
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
inferred_type: None,
|
|
6130
|
-
}));
|
|
6123
|
+
let two_pi_u2 = if let Expression::Div(div) = u2 {
|
|
6124
|
+
let numerator = Expression::Mul(Box::new(BinaryOp::new(two_pi, div.left)));
|
|
6125
|
+
Expression::Div(Box::new(BinaryOp::new(numerator, div.right)))
|
|
6126
|
+
} else {
|
|
6127
|
+
Expression::Mul(Box::new(BinaryOp::new(two_pi, u2)))
|
|
6128
|
+
};
|
|
6131
6129
|
let cos_part = Expression::Function(Box::new(Function::new(
|
|
6132
6130
|
"COS".to_string(),
|
|
6133
6131
|
vec![two_pi_u2],
|
|
@@ -6328,6 +6326,7 @@ impl DuckDBDialect {
|
|
|
6328
6326
|
let x_value = Expression::Dot(Box::new(crate::expressions::DotAccess {
|
|
6329
6327
|
this: x_ref,
|
|
6330
6328
|
field: Identifier::new("value"),
|
|
6329
|
+
inferred_type: None,
|
|
6331
6330
|
}));
|
|
6332
6331
|
let x_value_is_null = Expression::IsNull(Box::new(crate::expressions::IsNull {
|
|
6333
6332
|
this: x_value,
|
|
@@ -7212,6 +7211,24 @@ impl DuckDBDialect {
|
|
|
7212
7211
|
) -> Result<Expression> {
|
|
7213
7212
|
let name_upper = f.name.to_uppercase();
|
|
7214
7213
|
match name_upper.as_str() {
|
|
7214
|
+
// Keep the established canonical transpilation for a plain DuckDB
|
|
7215
|
+
// LIST aggregate now that the parser represents it as an aggregate
|
|
7216
|
+
// node. Modifier-bearing LIST calls retain their aggregate shape so
|
|
7217
|
+
// DISTINCT, ORDER BY, FILTER, and LIMIT are not discarded.
|
|
7218
|
+
"LIST"
|
|
7219
|
+
if f.args.len() == 1
|
|
7220
|
+
&& !f.distinct
|
|
7221
|
+
&& f.filter.is_none()
|
|
7222
|
+
&& f.order_by.is_empty()
|
|
7223
|
+
&& f.limit.is_none()
|
|
7224
|
+
&& f.ignore_nulls.is_none() =>
|
|
7225
|
+
{
|
|
7226
|
+
Ok(Expression::Function(Box::new(Function::new(
|
|
7227
|
+
"ARRAY_AGG".to_string(),
|
|
7228
|
+
f.args,
|
|
7229
|
+
))))
|
|
7230
|
+
}
|
|
7231
|
+
|
|
7215
7232
|
// GROUP_CONCAT -> LISTAGG
|
|
7216
7233
|
"GROUP_CONCAT" if !f.args.is_empty() => Ok(Expression::Function(Box::new(
|
|
7217
7234
|
Function::new("LISTAGG".to_string(), f.args),
|
|
@@ -188,7 +188,7 @@ use crate::parser::Parser;
|
|
|
188
188
|
use crate::tokens::TokenType;
|
|
189
189
|
use crate::tokens::{Token, Tokenizer, TokenizerConfig};
|
|
190
190
|
#[cfg(feature = "transpile")]
|
|
191
|
-
use crate::traversal::ExpressionWalk;
|
|
191
|
+
use crate::traversal::{is_aggregate, ExpressionWalk};
|
|
192
192
|
use serde::{Deserialize, Serialize};
|
|
193
193
|
use std::collections::HashMap;
|
|
194
194
|
#[cfg(feature = "transpile")]
|
|
@@ -4561,6 +4561,12 @@ impl Dialect {
|
|
|
4561
4561
|
"qualified whole-row aggregate arguments",
|
|
4562
4562
|
);
|
|
4563
4563
|
}
|
|
4564
|
+
if Self::node_has_subquery_in_aggregate_argument(node) {
|
|
4565
|
+
Self::push_unsupported_diagnostic(
|
|
4566
|
+
&mut diagnostics,
|
|
4567
|
+
"aggregate arguments containing subqueries",
|
|
4568
|
+
);
|
|
4569
|
+
}
|
|
4564
4570
|
}
|
|
4565
4571
|
|
|
4566
4572
|
if !Self::target_supports_distinct_on(target) && Self::node_has_distinct_on(node) {
|
|
@@ -5368,63 +5374,7 @@ impl Dialect {
|
|
|
5368
5374
|
}
|
|
5369
5375
|
|
|
5370
5376
|
fn node_is_aggregate_function(expr: &Expression) -> bool {
|
|
5371
|
-
|
|
5372
|
-
expr,
|
|
5373
|
-
Expression::AggregateFunction(_)
|
|
5374
|
-
| Expression::Count(_)
|
|
5375
|
-
| Expression::Sum(_)
|
|
5376
|
-
| Expression::Avg(_)
|
|
5377
|
-
| Expression::Min(_)
|
|
5378
|
-
| Expression::Max(_)
|
|
5379
|
-
| Expression::GroupConcat(_)
|
|
5380
|
-
| Expression::StringAgg(_)
|
|
5381
|
-
| Expression::ListAgg(_)
|
|
5382
|
-
| Expression::ArrayAgg(_)
|
|
5383
|
-
| Expression::CountIf(_)
|
|
5384
|
-
| Expression::SumIf(_)
|
|
5385
|
-
| Expression::Stddev(_)
|
|
5386
|
-
| Expression::StddevPop(_)
|
|
5387
|
-
| Expression::StddevSamp(_)
|
|
5388
|
-
| Expression::Variance(_)
|
|
5389
|
-
| Expression::VarPop(_)
|
|
5390
|
-
| Expression::VarSamp(_)
|
|
5391
|
-
| Expression::Median(_)
|
|
5392
|
-
| Expression::Mode(_)
|
|
5393
|
-
| Expression::First(_)
|
|
5394
|
-
| Expression::Last(_)
|
|
5395
|
-
| Expression::AnyValue(_)
|
|
5396
|
-
| Expression::ApproxDistinct(_)
|
|
5397
|
-
| Expression::ApproxCountDistinct(_)
|
|
5398
|
-
| Expression::ApproxPercentile(_)
|
|
5399
|
-
| Expression::Percentile(_)
|
|
5400
|
-
| Expression::LogicalAnd(_)
|
|
5401
|
-
| Expression::LogicalOr(_)
|
|
5402
|
-
| Expression::Skewness(_)
|
|
5403
|
-
| Expression::BitwiseCount(_)
|
|
5404
|
-
| Expression::BitwiseAndAgg(_)
|
|
5405
|
-
| Expression::BitwiseOrAgg(_)
|
|
5406
|
-
| Expression::BitwiseXorAgg(_)
|
|
5407
|
-
| Expression::ArrayConcatAgg(_)
|
|
5408
|
-
| Expression::ArrayUniqueAgg(_)
|
|
5409
|
-
| Expression::BoolXorAgg(_)
|
|
5410
|
-
| Expression::JsonArrayAgg(_)
|
|
5411
|
-
| Expression::JsonObjectAgg(_)
|
|
5412
|
-
| Expression::ParameterizedAgg(_)
|
|
5413
|
-
| Expression::ArgMax(_)
|
|
5414
|
-
| Expression::ArgMin(_)
|
|
5415
|
-
| Expression::ApproxTopK(_)
|
|
5416
|
-
| Expression::ApproxTopKAccumulate(_)
|
|
5417
|
-
| Expression::ApproxTopKCombine(_)
|
|
5418
|
-
| Expression::ApproxTopKEstimate(_)
|
|
5419
|
-
| Expression::ApproxTopSum(_)
|
|
5420
|
-
| Expression::ApproxQuantiles(_)
|
|
5421
|
-
| Expression::AnonymousAggFunc(_)
|
|
5422
|
-
| Expression::CombinedAggFunc(_)
|
|
5423
|
-
| Expression::CombinedParameterizedAgg(_)
|
|
5424
|
-
| Expression::HashAgg(_)
|
|
5425
|
-
| Expression::ObjectAgg(_)
|
|
5426
|
-
| Expression::AIAgg(_)
|
|
5427
|
-
)
|
|
5377
|
+
is_aggregate(expr)
|
|
5428
5378
|
}
|
|
5429
5379
|
|
|
5430
5380
|
fn node_has_qualified_whole_row_aggregate_argument(expr: &Expression) -> bool {
|
|
@@ -5446,6 +5396,21 @@ impl Dialect {
|
|
|
5446
5396
|
&& expr.children().into_iter().any(contains_qualified_star)
|
|
5447
5397
|
}
|
|
5448
5398
|
|
|
5399
|
+
fn node_has_subquery_in_aggregate_argument(expr: &Expression) -> bool {
|
|
5400
|
+
fn contains_query(expr: &Expression) -> bool {
|
|
5401
|
+
matches!(
|
|
5402
|
+
expr,
|
|
5403
|
+
Expression::Select(_)
|
|
5404
|
+
| Expression::Subquery(_)
|
|
5405
|
+
| Expression::Union(_)
|
|
5406
|
+
| Expression::Intersect(_)
|
|
5407
|
+
| Expression::Except(_)
|
|
5408
|
+
) || expr.children().into_iter().any(contains_query)
|
|
5409
|
+
}
|
|
5410
|
+
|
|
5411
|
+
Self::node_is_aggregate_function(expr) && expr.children().into_iter().any(contains_query)
|
|
5412
|
+
}
|
|
5413
|
+
|
|
5449
5414
|
fn tsql_apply_has_invalid_outer_aggregate(expr: &Expression) -> bool {
|
|
5450
5415
|
// SQL Server error 8124: if an aggregate expression contains an outer
|
|
5451
5416
|
// reference, that reference must be the only column used by the expression.
|
|
@@ -32,6 +32,7 @@ pub(super) enum Action {
|
|
|
32
32
|
CollectListToArrayAgg,
|
|
33
33
|
CollectSetConvert,
|
|
34
34
|
PercentileConvert,
|
|
35
|
+
DuckDBQuantileConvert,
|
|
35
36
|
CorrIsnanWrap,
|
|
36
37
|
FirstToAnyValue,
|
|
37
38
|
PercentileContConvert,
|
|
@@ -191,10 +192,16 @@ pub(super) fn rewrite(
|
|
|
191
192
|
} else {
|
|
192
193
|
"ARG_MIN_NULL"
|
|
193
194
|
};
|
|
194
|
-
Ok(Expression::
|
|
195
|
-
func_name.to_string(),
|
|
196
|
-
vec![agg.this, *having_expr],
|
|
197
|
-
|
|
195
|
+
Ok(Expression::AggregateFunction(Box::new(AggregateFunction {
|
|
196
|
+
name: func_name.to_string(),
|
|
197
|
+
args: vec![agg.this, *having_expr],
|
|
198
|
+
distinct: agg.distinct,
|
|
199
|
+
filter: agg.filter,
|
|
200
|
+
order_by: agg.order_by,
|
|
201
|
+
limit: agg.limit,
|
|
202
|
+
ignore_nulls: agg.ignore_nulls,
|
|
203
|
+
inferred_type: agg.inferred_type,
|
|
204
|
+
})))
|
|
198
205
|
} else {
|
|
199
206
|
Ok(Expression::AnyValue(agg))
|
|
200
207
|
}
|
|
@@ -247,11 +254,10 @@ pub(super) fn rewrite(
|
|
|
247
254
|
expressions: quantiles,
|
|
248
255
|
}));
|
|
249
256
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
Ok(Expression::Function(Box::new(new_func)))
|
|
257
|
+
let mut new_agg = *agg;
|
|
258
|
+
new_agg.name = "APPROX_QUANTILE".to_string();
|
|
259
|
+
new_agg.args = vec![x_expr, array_expr];
|
|
260
|
+
Ok(Expression::AggregateFunction(Box::new(new_agg)))
|
|
255
261
|
} else {
|
|
256
262
|
Ok(Expression::AggregateFunction(agg))
|
|
257
263
|
}
|
|
@@ -1146,6 +1152,80 @@ pub(super) fn rewrite(
|
|
|
1146
1152
|
}
|
|
1147
1153
|
}
|
|
1148
1154
|
|
|
1155
|
+
Action::DuckDBQuantileConvert => {
|
|
1156
|
+
let mut aggregate = if let Expression::AggregateFunction(aggregate) = e {
|
|
1157
|
+
*aggregate
|
|
1158
|
+
} else {
|
|
1159
|
+
unreachable!("action only triggered for AggregateFunction expressions")
|
|
1160
|
+
};
|
|
1161
|
+
let name = aggregate.name.to_ascii_uppercase();
|
|
1162
|
+
|
|
1163
|
+
match name.as_str() {
|
|
1164
|
+
"QUANTILE" => {
|
|
1165
|
+
aggregate.name = match target {
|
|
1166
|
+
DialectType::Spark | DialectType::Databricks | DialectType::Hive => {
|
|
1167
|
+
"PERCENTILE"
|
|
1168
|
+
}
|
|
1169
|
+
DialectType::Presto | DialectType::Trino => "APPROX_PERCENTILE",
|
|
1170
|
+
DialectType::BigQuery => "PERCENTILE_CONT",
|
|
1171
|
+
_ => "QUANTILE",
|
|
1172
|
+
}
|
|
1173
|
+
.to_string();
|
|
1174
|
+
Ok(Expression::AggregateFunction(Box::new(aggregate)))
|
|
1175
|
+
}
|
|
1176
|
+
"APPROX_QUANTILE" => {
|
|
1177
|
+
if matches!(target, DialectType::Snowflake) {
|
|
1178
|
+
aggregate.name = "APPROX_PERCENTILE".to_string();
|
|
1179
|
+
}
|
|
1180
|
+
Ok(Expression::AggregateFunction(Box::new(aggregate)))
|
|
1181
|
+
}
|
|
1182
|
+
"QUANTILE_CONT" | "QUANTILE_DISC"
|
|
1183
|
+
if aggregate.args.len() == 2
|
|
1184
|
+
&& matches!(
|
|
1185
|
+
target,
|
|
1186
|
+
DialectType::PostgreSQL
|
|
1187
|
+
| DialectType::Redshift
|
|
1188
|
+
| DialectType::Snowflake
|
|
1189
|
+
) =>
|
|
1190
|
+
{
|
|
1191
|
+
// DISTINCT, an inner ORDER BY, LIMIT, and explicit null
|
|
1192
|
+
// handling cannot be represented by these targets' ordered-set
|
|
1193
|
+
// aggregate syntax. Keep the original aggregate intact rather
|
|
1194
|
+
// than silently dropping any of those modifiers.
|
|
1195
|
+
if aggregate.distinct
|
|
1196
|
+
|| !aggregate.order_by.is_empty()
|
|
1197
|
+
|| aggregate.limit.is_some()
|
|
1198
|
+
|| aggregate.ignore_nulls.is_some()
|
|
1199
|
+
{
|
|
1200
|
+
return Ok(Expression::AggregateFunction(Box::new(aggregate)));
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
let mut args = aggregate.args;
|
|
1204
|
+
let column = args.remove(0);
|
|
1205
|
+
let percentile = args.remove(0);
|
|
1206
|
+
let percentile = PercentileFunc {
|
|
1207
|
+
this: column.clone(),
|
|
1208
|
+
percentile,
|
|
1209
|
+
order_by: Some(vec![Ordered {
|
|
1210
|
+
this: column,
|
|
1211
|
+
desc: false,
|
|
1212
|
+
nulls_first: None,
|
|
1213
|
+
explicit_asc: false,
|
|
1214
|
+
with_fill: None,
|
|
1215
|
+
}]),
|
|
1216
|
+
filter: aggregate.filter,
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
if name == "QUANTILE_CONT" {
|
|
1220
|
+
Ok(Expression::PercentileCont(Box::new(percentile)))
|
|
1221
|
+
} else {
|
|
1222
|
+
Ok(Expression::PercentileDisc(Box::new(percentile)))
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
_ => Ok(Expression::AggregateFunction(Box::new(aggregate))),
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1149
1229
|
Action::CorrIsnanWrap => {
|
|
1150
1230
|
// CORR(a, b) -> CASE WHEN ISNAN(CORR(a, b)) THEN NULL ELSE CORR(a, b) END
|
|
1151
1231
|
// The CORR expression could be AggregateFunction, WindowFunction, or Filter-wrapped
|
{polyglot_sql-0.9.0 → polyglot_sql-0.9.2}/crates/polyglot-sql/src/dialects/normalization/mod.rs
RENAMED
|
@@ -2294,6 +2294,11 @@ pub(super) fn normalize(
|
|
|
2294
2294
|
{
|
|
2295
2295
|
Action::Aggregates(aggregates::Action::BigQueryPercentileContToDuckDB)
|
|
2296
2296
|
}
|
|
2297
|
+
"QUANTILE" | "QUANTILE_CONT" | "QUANTILE_DISC" | "APPROX_QUANTILE"
|
|
2298
|
+
if matches!(source, DialectType::DuckDB) =>
|
|
2299
|
+
{
|
|
2300
|
+
Action::Aggregates(aggregates::Action::DuckDBQuantileConvert)
|
|
2301
|
+
}
|
|
2297
2302
|
_ => Action::None,
|
|
2298
2303
|
}
|
|
2299
2304
|
}
|
|
@@ -1418,26 +1418,23 @@ pub(super) fn rewrite(
|
|
|
1418
1418
|
],
|
|
1419
1419
|
)));
|
|
1420
1420
|
|
|
1421
|
-
//
|
|
1422
|
-
let
|
|
1421
|
+
// ELSE base: 1 + split_sum + extract_sum
|
|
1422
|
+
let else_base = Expression::Add(Box::new(BinaryOp::new(
|
|
1423
|
+
Expression::Add(Box::new(BinaryOp::new(Expression::number(1), split_sum))),
|
|
1424
|
+
extract_sum,
|
|
1425
|
+
)));
|
|
1426
|
+
|
|
1427
|
+
// Append the position offset as a left-associated `+ pos - 1` chain.
|
|
1428
|
+
let else_expr = if !is_pos_1 {
|
|
1423
1429
|
let pos = position.clone().unwrap_or(Expression::number(1));
|
|
1424
|
-
Expression::Sub(Box::new(BinaryOp::new(
|
|
1430
|
+
Expression::Sub(Box::new(BinaryOp::new(
|
|
1431
|
+
Expression::Add(Box::new(BinaryOp::new(else_base, pos))),
|
|
1432
|
+
Expression::number(1),
|
|
1433
|
+
)))
|
|
1425
1434
|
} else {
|
|
1426
|
-
Expression::number(0)
|
|
1435
|
+
Expression::Add(Box::new(BinaryOp::new(else_base, Expression::number(0))))
|
|
1427
1436
|
};
|
|
1428
1437
|
|
|
1429
|
-
// ELSE: 1 + split_sum + extract_sum + pos_offset
|
|
1430
|
-
let else_expr = Expression::Add(Box::new(BinaryOp::new(
|
|
1431
|
-
Expression::Add(Box::new(BinaryOp::new(
|
|
1432
|
-
Expression::Add(Box::new(BinaryOp::new(
|
|
1433
|
-
Expression::number(1),
|
|
1434
|
-
split_sum,
|
|
1435
|
-
))),
|
|
1436
|
-
extract_sum,
|
|
1437
|
-
))),
|
|
1438
|
-
pos_offset,
|
|
1439
|
-
)));
|
|
1440
|
-
|
|
1441
1438
|
Ok(Expression::Case(Box::new(Case {
|
|
1442
1439
|
operand: None,
|
|
1443
1440
|
whens: vec![
|