polyglot-sql 0.13.4__tar.gz → 0.13.5__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.13.4 → polyglot_sql-0.13.5}/Cargo.lock +6 -6
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/Cargo.toml +1 -1
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/PKG-INFO +1 -1
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/Cargo.toml +2 -2
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/README.md +4 -4
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/mod.rs +18 -10
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/mod.rs +6 -46
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/operators.rs +0 -52
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/scalar.rs +0 -52
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/starrocks.rs +1 -1
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/expressions.rs +180 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/generator.rs +179 -16
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/lineage.rs +280 -19
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/openlineage.rs +406 -45
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +99 -27
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/parser.rs +84 -43
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/query_analysis/column_uses.rs +16 -2
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/query_analysis.rs +283 -28
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/resolver.rs +8 -2
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/scope.rs +155 -8
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/transforms.rs +477 -306
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/clickhouse_regression.rs +134 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/common/known_failures.rs +8 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_dialect_tests.rs +23 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +22 -22
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/vertica/identity.json +3 -3
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/dialect_matrix.rs +216 -7
- polyglot_sql-0.13.5/crates/polyglot-sql/tests/duckdb_decimal_precision.rs +80 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/query_analysis.rs +847 -2
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/transform_regression.rs +130 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/README.md +1 -1
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/python/polyglot_sql/analysis_types.py +6 -1
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/README.md +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/allocation_hotspots.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/ast_traversal.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/common/mod.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/lineage.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/performance_hotspots.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/ast_children.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/ast_json.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/ast_mutation.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/binding.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/builder/mod.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/builder/plan.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/hana.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/collections.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/duckdb.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/hana.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/json.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/postgres_interval.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/statements.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/temporal.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/vertica.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/vertica.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/format_tokens.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/guard.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/lib.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/set_operation_types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/set_operation.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/traversal.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/validation/semantics.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/create_view_security_comment_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/dml.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/functions.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/identity.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/select.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/hana/types.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/vertica/transpilation.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/custom_fixtures/vertica/types.json +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/duckdb_integer_division.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/duckdb_json_arrow_context.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/duckdb_order_by_all.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/duckdb_unreserved_relation_aliases.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/is_predicate_precedence.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/mod_precedence.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/numeric_exponent_boundaries.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/oracle_data_types_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/postgres_explain_options.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/postgres_regexp_clickhouse.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/quoted_relation_columns.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-ast-derive/Cargo.toml +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-ast-derive/src/lib.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/builders.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_builders.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_duckdb_datafusion_execution.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_query_analysis.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/pyproject.toml +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/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.13.
|
|
608
|
+
version = "0.13.5"
|
|
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.13.
|
|
626
|
+
version = "0.13.5"
|
|
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.13.
|
|
635
|
+
version = "0.13.5"
|
|
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.13.
|
|
645
|
+
version = "0.13.5"
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "polyglot-sql-python"
|
|
649
|
-
version = "0.13.
|
|
649
|
+
version = "0.13.5"
|
|
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.13.
|
|
660
|
+
version = "0.13.5"
|
|
661
661
|
dependencies = [
|
|
662
662
|
"console_error_panic_hook",
|
|
663
663
|
"js-sys",
|
|
@@ -103,14 +103,14 @@ function-catalog-all-dialects = [
|
|
|
103
103
|
]
|
|
104
104
|
|
|
105
105
|
[dependencies]
|
|
106
|
-
polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.13.
|
|
106
|
+
polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.13.5" }
|
|
107
107
|
serde = { workspace = true }
|
|
108
108
|
serde_json = { workspace = true }
|
|
109
109
|
thiserror = { workspace = true }
|
|
110
110
|
unicode-segmentation = { workspace = true }
|
|
111
111
|
stacker = { version = "0.1", optional = true }
|
|
112
112
|
ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
|
|
113
|
-
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.13.
|
|
113
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.13.5", optional = true, default-features = false }
|
|
114
114
|
|
|
115
115
|
[dev-dependencies]
|
|
116
116
|
pretty_assertions = "1.4"
|
|
@@ -25,12 +25,12 @@ 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.13.
|
|
28
|
+
polyglot-sql = { version = "0.13.5", default-features = false }
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
```toml
|
|
32
32
|
polyglot-sql = {
|
|
33
|
-
version = "0.13.
|
|
33
|
+
version = "0.13.5",
|
|
34
34
|
default-features = false,
|
|
35
35
|
features = ["dialect-clickhouse"],
|
|
36
36
|
}
|
|
@@ -44,14 +44,14 @@ Examples:
|
|
|
44
44
|
```toml
|
|
45
45
|
# Parse and generate SQL for one dialect.
|
|
46
46
|
polyglot-sql = {
|
|
47
|
-
version = "0.13.
|
|
47
|
+
version = "0.13.5",
|
|
48
48
|
default-features = false,
|
|
49
49
|
features = ["generate", "dialect-clickhouse"],
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
# Cross-dialect transpilation.
|
|
53
53
|
polyglot-sql = {
|
|
54
|
-
version = "0.13.
|
|
54
|
+
version = "0.13.5",
|
|
55
55
|
default-features = false,
|
|
56
56
|
features = ["transpile", "dialect-clickhouse", "dialect-postgresql"],
|
|
57
57
|
}
|
|
@@ -757,8 +757,8 @@ fn query_output_width(e: &Expression) -> Option<usize> {
|
|
|
757
757
|
/// The source's explicit direction and NULL order (if any) carry over to each
|
|
758
758
|
/// positional entry unchanged; the later cross-dialect NULL-ordering pass
|
|
759
759
|
/// fills in the source dialect's implied default where the target's differs.
|
|
760
|
-
/// MySQL
|
|
761
|
-
/// that
|
|
760
|
+
/// MySQL additionally checks placement here because a known width alone does
|
|
761
|
+
/// not establish that every generated ordinal can be resolved to an expression.
|
|
762
762
|
#[cfg(feature = "transpile")]
|
|
763
763
|
fn expand_order_by_all(
|
|
764
764
|
order_by: &mut Option<crate::expressions::OrderBy>,
|
|
@@ -800,11 +800,8 @@ fn expand_order_by_all(
|
|
|
800
800
|
.map(|i| {
|
|
801
801
|
let mut o = ob.expressions[0].clone();
|
|
802
802
|
o.this = E::number(i);
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
// cannot print the NULLS FIRST/LAST syntax.
|
|
806
|
-
o.nulls_first = None;
|
|
807
|
-
}
|
|
803
|
+
// Keep explicit placement until generation. Clearing it here would
|
|
804
|
+
// make normalization substitute the source dialect's implicit default.
|
|
808
805
|
o
|
|
809
806
|
})
|
|
810
807
|
.collect();
|
|
@@ -3440,6 +3437,7 @@ impl Dialect {
|
|
|
3440
3437
|
feature = "dialect-sqlite",
|
|
3441
3438
|
feature = "dialect-trino",
|
|
3442
3439
|
feature = "dialect-presto",
|
|
3440
|
+
feature = "dialect-athena",
|
|
3443
3441
|
feature = "dialect-duckdb",
|
|
3444
3442
|
feature = "dialect-redshift",
|
|
3445
3443
|
feature = "dialect-starrocks",
|
|
@@ -3583,6 +3581,12 @@ impl Dialect {
|
|
|
3583
3581
|
let expr = transforms::explode_projection_to_unnest(expr, DialectType::Presto)?;
|
|
3584
3582
|
Ok(expr)
|
|
3585
3583
|
}
|
|
3584
|
+
#[cfg(feature = "dialect-athena")]
|
|
3585
|
+
DialectType::Athena => {
|
|
3586
|
+
let expr = transforms::eliminate_qualify(expr)?;
|
|
3587
|
+
let expr = transforms::eliminate_window_clause(expr)?;
|
|
3588
|
+
transforms::explode_projection_to_unnest(expr, DialectType::Athena)
|
|
3589
|
+
}
|
|
3586
3590
|
// DuckDB supports QUALIFY - no elimination needed
|
|
3587
3591
|
// Expand POSEXPLODE to GENERATE_SUBSCRIPTS + UNNEST
|
|
3588
3592
|
// Expand LIKE ANY / ILIKE ANY to OR chains (DuckDB doesn't support quantifiers)
|
|
@@ -3592,15 +3596,14 @@ impl Dialect {
|
|
|
3592
3596
|
let expr = transforms::expand_like_any(expr)?;
|
|
3593
3597
|
Ok(expr)
|
|
3594
3598
|
}
|
|
3595
|
-
// Redshift
|
|
3599
|
+
// Redshift supports QUALIFY, but not WINDOW or GENERATE_DATE_ARRAY.
|
|
3596
3600
|
#[cfg(feature = "dialect-redshift")]
|
|
3597
3601
|
DialectType::Redshift => {
|
|
3598
|
-
let expr = transforms::eliminate_qualify(expr)?;
|
|
3599
3602
|
let expr = transforms::eliminate_window_clause(expr)?;
|
|
3600
3603
|
let expr = transforms::unnest_generate_date_array_using_recursive_cte(expr)?;
|
|
3601
3604
|
Ok(expr)
|
|
3602
3605
|
}
|
|
3603
|
-
// StarRocks
|
|
3606
|
+
// StarRocks supports only restricted QUALIFY forms; lower the general form.
|
|
3604
3607
|
#[cfg(feature = "dialect-starrocks")]
|
|
3605
3608
|
DialectType::StarRocks => {
|
|
3606
3609
|
let expr = transforms::eliminate_qualify(expr)?;
|
|
@@ -4333,6 +4336,11 @@ impl Dialect {
|
|
|
4333
4336
|
normalized
|
|
4334
4337
|
};
|
|
4335
4338
|
|
|
4339
|
+
let normalized = crate::transforms::lower_set_operations_by_name(
|
|
4340
|
+
normalized,
|
|
4341
|
+
self.dialect_type,
|
|
4342
|
+
target,
|
|
4343
|
+
)?;
|
|
4336
4344
|
let transformed =
|
|
4337
4345
|
target_dialect.transform_with_guard(normalized, opts.complexity_guard)?;
|
|
4338
4346
|
|
{polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/mod.rs
RENAMED
|
@@ -2746,33 +2746,13 @@ pub(super) fn normalize(
|
|
|
2746
2746
|
// When nulls_first is not specified, fill in the source dialect's implied
|
|
2747
2747
|
// default so the target generator can correctly add/strip NULLS FIRST/LAST.
|
|
2748
2748
|
Expression::Ordered(o) => {
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2749
|
+
if o.nulls_first.is_none()
|
|
2750
|
+
&& source != target
|
|
2751
|
+
&& source != DialectType::Vertica
|
|
2752
|
+
{
|
|
2753
|
+
Action::Operators(operators::Action::NullsOrdering)
|
|
2752
2754
|
} else {
|
|
2753
|
-
|
|
2754
|
-
// the generator can preserve semantics with a CASE sort key.
|
|
2755
|
-
let target_rewrites_nulls =
|
|
2756
|
-
matches!(target, DialectType::TSQL | DialectType::Fabric);
|
|
2757
|
-
let target_supports_nulls = !matches!(
|
|
2758
|
-
target,
|
|
2759
|
-
DialectType::MySQL
|
|
2760
|
-
| DialectType::TSQL
|
|
2761
|
-
| DialectType::Fabric
|
|
2762
|
-
| DialectType::StarRocks
|
|
2763
|
-
| DialectType::Doris
|
|
2764
|
-
);
|
|
2765
|
-
// Vertica's implicit NULL placement depends on the sort key's data
|
|
2766
|
-
// type (NULLS AUTO), so there is no source default to make explicit.
|
|
2767
|
-
if o.nulls_first.is_none()
|
|
2768
|
-
&& source != target
|
|
2769
|
-
&& source != DialectType::Vertica
|
|
2770
|
-
&& (target_supports_nulls || target_rewrites_nulls)
|
|
2771
|
-
{
|
|
2772
|
-
Action::Operators(operators::Action::NullsOrdering)
|
|
2773
|
-
} else {
|
|
2774
|
-
Action::None
|
|
2775
|
-
}
|
|
2755
|
+
Action::None
|
|
2776
2756
|
}
|
|
2777
2757
|
}
|
|
2778
2758
|
// BigQuery data types: convert INT64, BYTES, NUMERIC etc. to standard types
|
|
@@ -3556,7 +3536,6 @@ pub(super) fn normalize(
|
|
|
3556
3536
|
Action::Collections(collections::Action::ArrayIndexConvert)
|
|
3557
3537
|
}
|
|
3558
3538
|
// ANY_VALUE IGNORE NULLS detection moved to the AnyValue arm above
|
|
3559
|
-
// MysqlNullsOrdering for Ordered is now handled in the Ordered arm above
|
|
3560
3539
|
// RESPECT NULLS handling for SQLite (strip it, add NULLS LAST to ORDER BY)
|
|
3561
3540
|
// and for MySQL (rewrite ORDER BY with CASE WHEN for null ordering)
|
|
3562
3541
|
Expression::WindowFunction(ref wf) => {
|
|
@@ -3569,25 +3548,7 @@ pub(super) fn normalize(
|
|
|
3569
3548
|
&& wf.over.order_by.iter().any(|o| o.nulls_first.is_some())
|
|
3570
3549
|
{
|
|
3571
3550
|
Action::Operators(operators::Action::BigQueryNullsOrdering)
|
|
3572
|
-
// DuckDB -> MySQL: Add CASE WHEN for NULLS LAST simulation in window ORDER BY
|
|
3573
|
-
// But NOT when frame is RANGE/GROUPS, since adding CASE WHEN would break value-based frames
|
|
3574
3551
|
} else {
|
|
3575
|
-
let source_nulls_last = matches!(source, DialectType::DuckDB);
|
|
3576
|
-
let has_range_frame = wf.over.frame.as_ref().map_or(false, |f| {
|
|
3577
|
-
matches!(
|
|
3578
|
-
f.kind,
|
|
3579
|
-
crate::expressions::WindowFrameKind::Range
|
|
3580
|
-
| crate::expressions::WindowFrameKind::Groups
|
|
3581
|
-
)
|
|
3582
|
-
});
|
|
3583
|
-
if source_nulls_last
|
|
3584
|
-
&& matches!(target, DialectType::MySQL)
|
|
3585
|
-
&& !wf.over.order_by.is_empty()
|
|
3586
|
-
&& wf.over.order_by.iter().any(|o| !o.desc)
|
|
3587
|
-
&& !has_range_frame
|
|
3588
|
-
{
|
|
3589
|
-
Action::Scalar(scalar::Action::MysqlNullsLastRewrite)
|
|
3590
|
-
} else {
|
|
3591
3552
|
// Check for Snowflake window frame handling for FIRST_VALUE/LAST_VALUE/NTH_VALUE
|
|
3592
3553
|
let is_ranking_window_func = matches!(
|
|
3593
3554
|
&wf.this,
|
|
@@ -3639,7 +3600,6 @@ pub(super) fn normalize(
|
|
|
3639
3600
|
_ => Action::None,
|
|
3640
3601
|
}
|
|
3641
3602
|
}
|
|
3642
|
-
}
|
|
3643
3603
|
}
|
|
3644
3604
|
}
|
|
3645
3605
|
// CREATE TABLE a LIKE b -> dialect-specific transformations
|
|
@@ -20,7 +20,6 @@ pub(super) enum Action {
|
|
|
20
20
|
DollarParamConvert,
|
|
21
21
|
AnyToExists,
|
|
22
22
|
RespectNullsConvert,
|
|
23
|
-
MysqlNullsOrdering,
|
|
24
23
|
BigQueryNullsOrdering,
|
|
25
24
|
PipeConcatToConcat,
|
|
26
25
|
PostgresPipeConcatToTsql,
|
|
@@ -691,57 +690,6 @@ pub(super) fn rewrite(
|
|
|
691
690
|
}
|
|
692
691
|
}
|
|
693
692
|
|
|
694
|
-
Action::MysqlNullsOrdering => {
|
|
695
|
-
// MySQL doesn't support NULLS FIRST/LAST - strip or rewrite
|
|
696
|
-
if let Expression::Ordered(mut o) = e {
|
|
697
|
-
let nulls_last = o.nulls_first == Some(false);
|
|
698
|
-
let desc = o.desc;
|
|
699
|
-
// MySQL default: ASC -> NULLS LAST, DESC -> NULLS FIRST
|
|
700
|
-
// If requested ordering matches default, just strip NULLS clause
|
|
701
|
-
let matches_default = if desc {
|
|
702
|
-
// DESC default is NULLS FIRST, so nulls_first=true matches
|
|
703
|
-
o.nulls_first == Some(true)
|
|
704
|
-
} else {
|
|
705
|
-
// ASC default is NULLS LAST, so nulls_first=false matches
|
|
706
|
-
nulls_last
|
|
707
|
-
};
|
|
708
|
-
if matches_default {
|
|
709
|
-
o.nulls_first = None;
|
|
710
|
-
Ok(Expression::Ordered(o))
|
|
711
|
-
} else {
|
|
712
|
-
// Need CASE WHEN x IS NULL THEN 0/1 ELSE 0/1 END, x
|
|
713
|
-
// For ASC NULLS FIRST: ORDER BY CASE WHEN x IS NULL THEN 0 ELSE 1 END, x ASC
|
|
714
|
-
// For DESC NULLS LAST: ORDER BY CASE WHEN x IS NULL THEN 1 ELSE 0 END, x DESC
|
|
715
|
-
let null_val = if desc { 1 } else { 0 };
|
|
716
|
-
let non_null_val = if desc { 0 } else { 1 };
|
|
717
|
-
let _case_expr = Expression::Case(Box::new(Case {
|
|
718
|
-
operand: None,
|
|
719
|
-
whens: vec![(
|
|
720
|
-
Expression::IsNull(Box::new(crate::expressions::IsNull {
|
|
721
|
-
this: o.this.clone(),
|
|
722
|
-
not: false,
|
|
723
|
-
postfix_form: false,
|
|
724
|
-
})),
|
|
725
|
-
Expression::number(null_val),
|
|
726
|
-
)],
|
|
727
|
-
else_: Some(Expression::number(non_null_val)),
|
|
728
|
-
comments: Vec::new(),
|
|
729
|
-
inferred_type: None,
|
|
730
|
-
}));
|
|
731
|
-
o.nulls_first = None;
|
|
732
|
-
// Return a tuple of [case_expr, ordered_expr]
|
|
733
|
-
// We need to return both as part of the ORDER BY
|
|
734
|
-
// But since transform_recursive processes individual expressions,
|
|
735
|
-
// we can't easily add extra ORDER BY items here.
|
|
736
|
-
// Instead, strip the nulls_first
|
|
737
|
-
o.nulls_first = None;
|
|
738
|
-
Ok(Expression::Ordered(o))
|
|
739
|
-
}
|
|
740
|
-
} else {
|
|
741
|
-
Ok(e)
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
|
|
745
693
|
Action::BigQueryNullsOrdering => {
|
|
746
694
|
// BigQuery doesn't support NULLS FIRST/LAST in window function ORDER BY
|
|
747
695
|
if let Expression::WindowFunction(mut wf) = e {
|
{polyglot_sql-0.13.4 → polyglot_sql-0.13.5}/crates/polyglot-sql/src/dialects/normalization/scalar.rs
RENAMED
|
@@ -73,7 +73,6 @@ pub(super) enum Action {
|
|
|
73
73
|
CurrentUserParens,
|
|
74
74
|
EscapeStringNormalize,
|
|
75
75
|
SnowflakeIntervalFormat,
|
|
76
|
-
MysqlNullsLastRewrite,
|
|
77
76
|
FilterToIff,
|
|
78
77
|
StrPositionExpand,
|
|
79
78
|
CurrentUserSparkParens,
|
|
@@ -11247,57 +11246,6 @@ pub(super) fn rewrite(
|
|
|
11247
11246
|
}
|
|
11248
11247
|
}
|
|
11249
11248
|
|
|
11250
|
-
Action::MysqlNullsLastRewrite => {
|
|
11251
|
-
// DuckDB -> MySQL: Add CASE WHEN IS NULL THEN 1 ELSE 0 END to ORDER BY
|
|
11252
|
-
// to simulate NULLS LAST for ASC ordering
|
|
11253
|
-
if let Expression::WindowFunction(mut wf) = e {
|
|
11254
|
-
let mut new_order_by = Vec::new();
|
|
11255
|
-
for o in wf.over.order_by {
|
|
11256
|
-
if !o.desc {
|
|
11257
|
-
// ASC: DuckDB has NULLS LAST, MySQL has NULLS FIRST
|
|
11258
|
-
// Add CASE WHEN expr IS NULL THEN 1 ELSE 0 END before expr
|
|
11259
|
-
let case_expr = Expression::Case(Box::new(Case {
|
|
11260
|
-
operand: None,
|
|
11261
|
-
whens: vec![(
|
|
11262
|
-
Expression::IsNull(Box::new(crate::expressions::IsNull {
|
|
11263
|
-
this: o.this.clone(),
|
|
11264
|
-
not: false,
|
|
11265
|
-
postfix_form: false,
|
|
11266
|
-
})),
|
|
11267
|
-
Expression::Literal(Box::new(Literal::Number("1".to_string()))),
|
|
11268
|
-
)],
|
|
11269
|
-
else_: Some(Expression::Literal(Box::new(Literal::Number(
|
|
11270
|
-
"0".to_string(),
|
|
11271
|
-
)))),
|
|
11272
|
-
comments: Vec::new(),
|
|
11273
|
-
inferred_type: None,
|
|
11274
|
-
}));
|
|
11275
|
-
new_order_by.push(crate::expressions::Ordered {
|
|
11276
|
-
nulls_auto: false,
|
|
11277
|
-
this: case_expr,
|
|
11278
|
-
desc: false,
|
|
11279
|
-
nulls_first: None,
|
|
11280
|
-
explicit_asc: false,
|
|
11281
|
-
with_fill: None,
|
|
11282
|
-
});
|
|
11283
|
-
let mut ordered = o;
|
|
11284
|
-
ordered.nulls_first = None;
|
|
11285
|
-
new_order_by.push(ordered);
|
|
11286
|
-
} else {
|
|
11287
|
-
// DESC: DuckDB has NULLS LAST, MySQL also has NULLS LAST (NULLs smallest in DESC)
|
|
11288
|
-
// No change needed
|
|
11289
|
-
let mut ordered = o;
|
|
11290
|
-
ordered.nulls_first = None;
|
|
11291
|
-
new_order_by.push(ordered);
|
|
11292
|
-
}
|
|
11293
|
-
}
|
|
11294
|
-
wf.over.order_by = new_order_by;
|
|
11295
|
-
Ok(Expression::WindowFunction(wf))
|
|
11296
|
-
} else {
|
|
11297
|
-
Ok(e)
|
|
11298
|
-
}
|
|
11299
|
-
}
|
|
11300
|
-
|
|
11301
11249
|
Action::FilterToIff => {
|
|
11302
11250
|
// FILTER(WHERE cond) -> rewrite aggregate: AGG(IFF(cond, val, NULL))
|
|
11303
11251
|
if let Expression::Filter(f) = e {
|
|
@@ -50,7 +50,7 @@ impl DialectImpl for StarRocksDialect {
|
|
|
50
50
|
// StarRocks: PROPERTIES prefix for WITH properties
|
|
51
51
|
with_properties_prefix: "PROPERTIES",
|
|
52
52
|
// StarRocks uses MySQL-style settings
|
|
53
|
-
null_ordering_supported:
|
|
53
|
+
null_ordering_supported: true,
|
|
54
54
|
limit_only_literals: true,
|
|
55
55
|
semi_anti_join_with_side: false,
|
|
56
56
|
supports_table_alias_columns: false,
|
|
@@ -3681,6 +3681,186 @@ pub struct Star {
|
|
|
3681
3681
|
pub span: Option<Span>,
|
|
3682
3682
|
}
|
|
3683
3683
|
|
|
3684
|
+
impl Star {
|
|
3685
|
+
/// Apply EXCEPT, REPLACE, and RENAME to the expanded `column` named `name`.
|
|
3686
|
+
/// Returns `None` when EXCEPT removes the column.
|
|
3687
|
+
#[cfg(feature = "semantic")]
|
|
3688
|
+
pub(crate) fn expand_column(
|
|
3689
|
+
&self,
|
|
3690
|
+
name: &str,
|
|
3691
|
+
column: Expression,
|
|
3692
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3693
|
+
) -> Option<Expression> {
|
|
3694
|
+
if self.excludes(name, dialect) {
|
|
3695
|
+
return None;
|
|
3696
|
+
}
|
|
3697
|
+
let renamed = self.renamed(name, dialect);
|
|
3698
|
+
if let Some(replacement) = self.replacement(name, dialect) {
|
|
3699
|
+
let mut replacement = replacement.clone();
|
|
3700
|
+
if let Some(alias) = renamed {
|
|
3701
|
+
replacement.alias = alias;
|
|
3702
|
+
}
|
|
3703
|
+
return Some(Expression::Alias(Box::new(replacement)));
|
|
3704
|
+
}
|
|
3705
|
+
Some(match renamed {
|
|
3706
|
+
Some(alias) => Expression::Alias(Box::new(Alias::new(column, alias))),
|
|
3707
|
+
None => column,
|
|
3708
|
+
})
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
/// Whether EXCEPT holds a ClickHouse pattern string (`EXCEPT ('re')`).
|
|
3712
|
+
/// The columns it removes are not known, so the star stays unexpanded.
|
|
3713
|
+
#[cfg(any(feature = "semantic", test))]
|
|
3714
|
+
pub(crate) fn has_except_pattern(&self) -> bool {
|
|
3715
|
+
self.except.iter().flatten().any(is_except_pattern)
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
/// Whether EXCEPT / EXCLUDE removes the column `name`.
|
|
3719
|
+
#[cfg(feature = "semantic")]
|
|
3720
|
+
pub(crate) fn excludes(
|
|
3721
|
+
&self,
|
|
3722
|
+
name: &str,
|
|
3723
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3724
|
+
) -> bool {
|
|
3725
|
+
self.except
|
|
3726
|
+
.iter()
|
|
3727
|
+
.flatten()
|
|
3728
|
+
.any(|column| star_modifier_matches(column, name, dialect))
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
/// The new name RENAME gives to the column `name`. With a known dialect,
|
|
3732
|
+
/// the name gets the identifier normalization that schema columns get.
|
|
3733
|
+
#[cfg(feature = "semantic")]
|
|
3734
|
+
pub(crate) fn renamed(
|
|
3735
|
+
&self,
|
|
3736
|
+
name: &str,
|
|
3737
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3738
|
+
) -> Option<Identifier> {
|
|
3739
|
+
let (_, new) = self
|
|
3740
|
+
.rename
|
|
3741
|
+
.iter()
|
|
3742
|
+
.flatten()
|
|
3743
|
+
.find(|(old, _)| star_modifier_matches(old, name, dialect))?;
|
|
3744
|
+
Some(match dialect {
|
|
3745
|
+
Some(_) => crate::optimizer::normalize_identifiers::normalize_identifier(
|
|
3746
|
+
new.clone(),
|
|
3747
|
+
crate::optimizer::normalize_identifiers::get_normalization_strategy(dialect),
|
|
3748
|
+
),
|
|
3749
|
+
None => new.clone(),
|
|
3750
|
+
})
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3753
|
+
/// The REPLACE expression for the column `name`.
|
|
3754
|
+
#[cfg(feature = "semantic")]
|
|
3755
|
+
pub(crate) fn replacement(
|
|
3756
|
+
&self,
|
|
3757
|
+
name: &str,
|
|
3758
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3759
|
+
) -> Option<&Alias> {
|
|
3760
|
+
self.replace
|
|
3761
|
+
.iter()
|
|
3762
|
+
.flatten()
|
|
3763
|
+
.find(|replacement| star_modifier_matches(&replacement.alias, name, dialect))
|
|
3764
|
+
}
|
|
3765
|
+
|
|
3766
|
+
/// The source column that the star outputs as `output`, after RENAME and
|
|
3767
|
+
/// EXCEPT. Returns `None` when the star does not output `output`.
|
|
3768
|
+
#[cfg(feature = "semantic")]
|
|
3769
|
+
pub(crate) fn source_column(
|
|
3770
|
+
&self,
|
|
3771
|
+
output: &str,
|
|
3772
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3773
|
+
) -> Option<String> {
|
|
3774
|
+
let renames = self.rename.iter().flatten();
|
|
3775
|
+
let column = match renames
|
|
3776
|
+
.clone()
|
|
3777
|
+
.find(|(_, new)| star_modifier_matches(new, output, dialect))
|
|
3778
|
+
{
|
|
3779
|
+
Some((old, _)) => old.name.clone(),
|
|
3780
|
+
None if renames
|
|
3781
|
+
.clone()
|
|
3782
|
+
.any(|(old, _)| star_modifier_matches(old, output, dialect)) =>
|
|
3783
|
+
{
|
|
3784
|
+
return None
|
|
3785
|
+
}
|
|
3786
|
+
None => output.to_string(),
|
|
3787
|
+
};
|
|
3788
|
+
(!self.excludes(&column, dialect)).then_some(column)
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3792
|
+
/// A pattern string keeps its quotes in the name (see `parse_star_except_name`).
|
|
3793
|
+
#[cfg(any(feature = "semantic", test))]
|
|
3794
|
+
fn is_except_pattern(identifier: &Identifier) -> bool {
|
|
3795
|
+
!identifier.quoted && identifier.name.starts_with('\'')
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
/// Match a modifier name to the column `name`. A quoted name matches with
|
|
3799
|
+
/// its case, unless the dialect ignores case. An unquoted name ignores case,
|
|
3800
|
+
/// unless the dialect is case sensitive. A qualified name such as `t.col`
|
|
3801
|
+
/// matches on its column part, as in sqlglot. A pattern string never matches.
|
|
3802
|
+
#[cfg(feature = "semantic")]
|
|
3803
|
+
fn star_modifier_matches(
|
|
3804
|
+
identifier: &Identifier,
|
|
3805
|
+
name: &str,
|
|
3806
|
+
dialect: Option<crate::dialects::DialectType>,
|
|
3807
|
+
) -> bool {
|
|
3808
|
+
use crate::optimizer::normalize_identifiers::{
|
|
3809
|
+
get_normalization_strategy, NormalizationStrategy,
|
|
3810
|
+
};
|
|
3811
|
+
use std::borrow::Cow;
|
|
3812
|
+
if is_except_pattern(identifier) {
|
|
3813
|
+
return false;
|
|
3814
|
+
}
|
|
3815
|
+
let text = identifier.name.as_str();
|
|
3816
|
+
let (column, quoted) = if identifier.quoted {
|
|
3817
|
+
(Cow::Borrowed(text), true)
|
|
3818
|
+
} else if let Some(quote) = text.chars().last().filter(|c| matches!(c, '"' | '`')) {
|
|
3819
|
+
// A qualified name keeps the quotes of its parts: `t."col"`.
|
|
3820
|
+
let body = &text[..text.len() - 1];
|
|
3821
|
+
let mut chars = body.char_indices().rev().peekable();
|
|
3822
|
+
let mut opening = None;
|
|
3823
|
+
while let Some((index, ch)) = chars.next() {
|
|
3824
|
+
if ch == quote {
|
|
3825
|
+
if chars.peek().is_some_and(|(_, next)| *next == quote) {
|
|
3826
|
+
chars.next(); // Skip an escaped quote inside the identifier.
|
|
3827
|
+
} else {
|
|
3828
|
+
opening = Some(index);
|
|
3829
|
+
break;
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
match opening {
|
|
3834
|
+
Some(open) => (
|
|
3835
|
+
Cow::Owned(
|
|
3836
|
+
body[open + 1..].replace(&format!("{quote}{quote}"), "e.to_string()),
|
|
3837
|
+
),
|
|
3838
|
+
true,
|
|
3839
|
+
),
|
|
3840
|
+
None => (Cow::Borrowed(text), false),
|
|
3841
|
+
}
|
|
3842
|
+
} else {
|
|
3843
|
+
(
|
|
3844
|
+
Cow::Borrowed(text.rsplit_once('.').map_or(text, |(_, column)| column)),
|
|
3845
|
+
false,
|
|
3846
|
+
)
|
|
3847
|
+
};
|
|
3848
|
+
let strategy = dialect.map(|dialect| get_normalization_strategy(Some(dialect)));
|
|
3849
|
+
let exact = match strategy {
|
|
3850
|
+
Some(NormalizationStrategy::CaseSensitive) => true,
|
|
3851
|
+
Some(
|
|
3852
|
+
NormalizationStrategy::CaseInsensitive
|
|
3853
|
+
| NormalizationStrategy::CaseInsensitiveUppercase,
|
|
3854
|
+
) => false,
|
|
3855
|
+
_ => quoted,
|
|
3856
|
+
};
|
|
3857
|
+
if exact {
|
|
3858
|
+
column == name
|
|
3859
|
+
} else {
|
|
3860
|
+
column.eq_ignore_ascii_case(name)
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3684
3864
|
/// Represent a complete SELECT statement.
|
|
3685
3865
|
///
|
|
3686
3866
|
/// This is the most feature-rich AST node, covering the full surface area of
|