polyglot-sql 0.13.1__tar.gz → 0.13.3__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.1 → polyglot_sql-0.13.3}/Cargo.lock +6 -6
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/Cargo.toml +1 -1
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/PKG-INFO +1 -1
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/Cargo.toml +2 -2
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/README.md +4 -4
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/duckdb.rs +2 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/mod.rs +246 -4
- polyglot_sql-0.13.3/crates/polyglot-sql/src/dialects/normalization/duckdb.rs +272 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/mod.rs +1 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/scalar.rs +2 -1
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/generator.rs +158 -28
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/parser.rs +22 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/transforms.rs +48 -2
- polyglot_sql-0.13.3/crates/polyglot-sql/tests/duckdb_integer_division.rs +572 -0
- polyglot_sql-0.13.3/crates/polyglot-sql/tests/duckdb_order_by_all.rs +517 -0
- polyglot_sql-0.13.3/crates/polyglot-sql/tests/mod_precedence.rs +176 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/README.md +1 -1
- polyglot_sql-0.13.3/crates/polyglot-sql-python/tests/test_duckdb_datafusion_execution.py +102 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/README.md +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/allocation_hotspots.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/ast_traversal.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/common/mod.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/lineage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/performance_hotspots.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/ast_children.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/ast_json.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/ast_mutation.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/binding.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/builder/mod.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/builder/plan.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/hana.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/collections.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/hana.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/json.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/operators.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/postgres_interval.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/statements.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/temporal.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/normalization/vertica.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/dialects/vertica.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/format_tokens.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/guard.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/lib.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/lineage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/set_operation_types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/query_analysis/column_uses.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/query_analysis.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/scope.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/set_operation.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/traversal.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/validation/semantics.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/create_view_security_comment_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/dml.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/functions.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/identity.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/select.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/hana/types.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/vertica/identity.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/vertica/transpilation.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/custom_fixtures/vertica/types.json +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/oracle_data_types_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/postgres_explain_options.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/postgres_regexp_clickhouse.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/query_analysis.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-ast-derive/Cargo.toml +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-ast-derive/src/lib.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/builders.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_builders.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_query_analysis.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/pyproject.toml +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/python/polyglot_sql/analysis_types.py +0 -0
- {polyglot_sql-0.13.1 → polyglot_sql-0.13.3}/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.3"
|
|
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.3"
|
|
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.3"
|
|
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.3"
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "polyglot-sql-python"
|
|
649
|
-
version = "0.13.
|
|
649
|
+
version = "0.13.3"
|
|
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.3"
|
|
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.3" }
|
|
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.3", 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.3", default-features = false }
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
```toml
|
|
32
32
|
polyglot-sql = {
|
|
33
|
-
version = "0.13.
|
|
33
|
+
version = "0.13.3",
|
|
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.3",
|
|
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.3",
|
|
55
55
|
default-features = false,
|
|
56
56
|
features = ["transpile", "dialect-clickhouse", "dialect-postgresql"],
|
|
57
57
|
}
|
|
@@ -103,6 +103,8 @@ impl DialectImpl for DuckDBDialect {
|
|
|
103
103
|
config.nested_comments = true;
|
|
104
104
|
// DuckDB allows underscores as digit separators in numeric literals
|
|
105
105
|
config.numbers_can_be_underscore_separated = true;
|
|
106
|
+
// `//` is integer division (same tokenizer-level recognition as Vertica)
|
|
107
|
+
config.double_slash_int_div = true;
|
|
106
108
|
config
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -298,6 +298,20 @@ impl DialectType {
|
|
|
298
298
|
DialectType::TSQL | DialectType::Fabric | DialectType::MySQL | DialectType::SQLite
|
|
299
299
|
) || (matches!(self, DialectType::DuckDB) && explicit_as)
|
|
300
300
|
}
|
|
301
|
+
|
|
302
|
+
/// Whether this dialect natively accepts DuckDB-style `ORDER BY ALL`
|
|
303
|
+
/// (a bare `ALL` keyword meaning "every projected column, in order").
|
|
304
|
+
/// Other targets need it rewritten to positional `ORDER BY 1, 2, ...`.
|
|
305
|
+
pub(crate) const fn supports_order_by_all(self) -> bool {
|
|
306
|
+
matches!(
|
|
307
|
+
self,
|
|
308
|
+
DialectType::DuckDB
|
|
309
|
+
| DialectType::Snowflake
|
|
310
|
+
| DialectType::ClickHouse
|
|
311
|
+
| DialectType::Databricks
|
|
312
|
+
| DialectType::Spark
|
|
313
|
+
)
|
|
314
|
+
}
|
|
301
315
|
}
|
|
302
316
|
|
|
303
317
|
impl Default for DialectType {
|
|
@@ -648,6 +662,189 @@ fn is_default_presto_date_format(fmt: &str) -> bool {
|
|
|
648
662
|
fmt == "%Y-%m-%d" || fmt == "%F"
|
|
649
663
|
}
|
|
650
664
|
|
|
665
|
+
/// The parser marks the ORDER BY ALL keyword as a Var, never an identifier.
|
|
666
|
+
#[cfg(feature = "generate")]
|
|
667
|
+
pub(crate) fn is_order_by_all_marker(e: &Expression) -> bool {
|
|
668
|
+
matches!(e, Expression::Var(v) if v.this.eq_ignore_ascii_case("all"))
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
#[cfg(feature = "transpile")]
|
|
672
|
+
fn is_order_by_all(order_by: &Option<crate::expressions::OrderBy>) -> bool {
|
|
673
|
+
order_by.as_ref().is_some_and(|ob| {
|
|
674
|
+
ob.expressions.len() == 1 && is_order_by_all_marker(&ob.expressions[0].this)
|
|
675
|
+
})
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/// Whether `e` is a projection item that can produce more or fewer than one
|
|
679
|
+
/// output column (`*`, or DuckDB's `COLUMNS(...)` macro), making the output
|
|
680
|
+
/// column count unknowable from the AST alone.
|
|
681
|
+
#[cfg(feature = "transpile")]
|
|
682
|
+
fn has_unknown_column_count(e: &Expression) -> bool {
|
|
683
|
+
use crate::expressions::Expression as E;
|
|
684
|
+
let mut inner = e;
|
|
685
|
+
loop {
|
|
686
|
+
inner = match inner {
|
|
687
|
+
E::Alias(a) => &a.this,
|
|
688
|
+
E::Paren(p) => &p.this,
|
|
689
|
+
_ => break,
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
if matches!(inner, E::Star(_)) {
|
|
693
|
+
return true;
|
|
694
|
+
}
|
|
695
|
+
// COLUMNS still expands inside arithmetic, casts and aggregate/function
|
|
696
|
+
// arguments. COUNT(*) and scalar subqueries, however, produce one column.
|
|
697
|
+
contains_in_projection(inner, |node| match node {
|
|
698
|
+
E::Columns(_) => true,
|
|
699
|
+
E::Function(f) => {
|
|
700
|
+
!f.quoted && f.qualified_name.is_empty() && f.name.eq_ignore_ascii_case("COLUMNS")
|
|
701
|
+
}
|
|
702
|
+
E::MethodCall(m) => m.method.name.eq_ignore_ascii_case("COLUMNS"),
|
|
703
|
+
_ => false,
|
|
704
|
+
})
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
#[cfg(feature = "transpile")]
|
|
708
|
+
pub(crate) fn contains_in_projection(
|
|
709
|
+
e: &Expression,
|
|
710
|
+
predicate: impl Fn(&Expression) -> bool,
|
|
711
|
+
) -> bool {
|
|
712
|
+
let mut pending = vec![e];
|
|
713
|
+
while let Some(node) = pending.pop() {
|
|
714
|
+
if matches!(
|
|
715
|
+
node,
|
|
716
|
+
Expression::Subquery(_) | Expression::Select(_) | Expression::Exists(_)
|
|
717
|
+
) {
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
if predicate(node) {
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
crate::ast_children::for_each_child_untracked(node, |child| pending.push(child));
|
|
724
|
+
}
|
|
725
|
+
false
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/// The number of columns a query block projects, when that count is known
|
|
729
|
+
/// statically from the AST. Compound queries (UNION/INTERSECT/EXCEPT) take
|
|
730
|
+
/// their width from the left-hand operand, per standard SQL set-operation
|
|
731
|
+
/// rules (both sides must already agree on column count).
|
|
732
|
+
#[cfg(feature = "transpile")]
|
|
733
|
+
fn query_output_width(e: &Expression) -> Option<usize> {
|
|
734
|
+
use crate::expressions::Expression as E;
|
|
735
|
+
match e {
|
|
736
|
+
E::Select(sel) => {
|
|
737
|
+
if sel.expressions.is_empty() || sel.expressions.iter().any(has_unknown_column_count) {
|
|
738
|
+
None
|
|
739
|
+
} else {
|
|
740
|
+
Some(sel.expressions.len())
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
E::Paren(p) => query_output_width(&p.this),
|
|
744
|
+
E::Subquery(s) => query_output_width(&s.this),
|
|
745
|
+
E::Union(u) if !u.by_name => query_output_width(&u.left),
|
|
746
|
+
E::Intersect(i) => query_output_width(&i.left),
|
|
747
|
+
E::Except(ex) => query_output_width(&ex.left),
|
|
748
|
+
_ => None,
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/// Rewrite an `ORDER BY ALL` clause into positional `ORDER BY 1..n` over
|
|
753
|
+
/// `width` columns, in place. No-op if `order_by` isn't the ALL marker.
|
|
754
|
+
/// Errors if the marker is present but `width` is unknown (e.g. a `*` or
|
|
755
|
+
/// `COLUMNS(...)` projection, where positional ordinals can't be derived).
|
|
756
|
+
///
|
|
757
|
+
/// The source's explicit direction and NULL order (if any) carry over to each
|
|
758
|
+
/// positional entry unchanged; the later cross-dialect NULL-ordering pass
|
|
759
|
+
/// fills in the source dialect's implied default where the target's differs.
|
|
760
|
+
/// MySQL is the exception: it has no NULLS FIRST/LAST syntax and is skipped by
|
|
761
|
+
/// that pass, so compare every supported source's default against MySQL here.
|
|
762
|
+
#[cfg(feature = "transpile")]
|
|
763
|
+
fn expand_order_by_all(
|
|
764
|
+
order_by: &mut Option<crate::expressions::OrderBy>,
|
|
765
|
+
width: Option<usize>,
|
|
766
|
+
source: DialectType,
|
|
767
|
+
target: DialectType,
|
|
768
|
+
) -> Result<()> {
|
|
769
|
+
use crate::expressions::Expression as E;
|
|
770
|
+
if !is_order_by_all(order_by) {
|
|
771
|
+
return Ok(());
|
|
772
|
+
}
|
|
773
|
+
let Some(n) = width else {
|
|
774
|
+
return Err(crate::error::Error::unsupported(
|
|
775
|
+
"ORDER BY ALL over a projection with an unknown column count (*, COLUMNS(...), or UNION BY NAME) cannot be expanded to positional ORDER BY",
|
|
776
|
+
target.to_string(),
|
|
777
|
+
));
|
|
778
|
+
};
|
|
779
|
+
let ob = order_by.as_mut().unwrap();
|
|
780
|
+
let (desc, nulls_first) = (ob.expressions[0].desc, ob.expressions[0].nulls_first);
|
|
781
|
+
|
|
782
|
+
// An ordinal cannot be used inside a CASE expression to emulate NULL
|
|
783
|
+
// placement: it would become a constant instead of a column reference.
|
|
784
|
+
if matches!(target, DialectType::MySQL) {
|
|
785
|
+
let required_nulls_first = nulls_first.unwrap_or(match source {
|
|
786
|
+
DialectType::DuckDB | DialectType::ClickHouse => false,
|
|
787
|
+
DialectType::Snowflake => desc,
|
|
788
|
+
DialectType::Spark | DialectType::Databricks => !desc,
|
|
789
|
+
_ => unreachable!("ORDER BY ALL source capability must be checked"),
|
|
790
|
+
});
|
|
791
|
+
if required_nulls_first != !desc {
|
|
792
|
+
return Err(crate::error::Error::unsupported(
|
|
793
|
+
"ORDER BY ALL's NULL ordering (MySQL's default NULL placement does not match and cannot be emulated with positional ordering)",
|
|
794
|
+
target.to_string(),
|
|
795
|
+
));
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
ob.expressions = (1..=n as i64)
|
|
800
|
+
.map(|i| {
|
|
801
|
+
let mut o = ob.expressions[0].clone();
|
|
802
|
+
o.this = E::number(i);
|
|
803
|
+
if target == DialectType::MySQL {
|
|
804
|
+
// Matching explicit NULL placement is redundant and MySQL
|
|
805
|
+
// cannot print the NULLS FIRST/LAST syntax.
|
|
806
|
+
o.nulls_first = None;
|
|
807
|
+
}
|
|
808
|
+
o
|
|
809
|
+
})
|
|
810
|
+
.collect();
|
|
811
|
+
Ok(())
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/// Expand when the target lacks ALL, or when a native target cannot use it
|
|
815
|
+
/// for this query (aggregate projections in Snowflake, DISTINCT ON emulation).
|
|
816
|
+
#[cfg(feature = "transpile")]
|
|
817
|
+
fn expand_select_order_by_all(
|
|
818
|
+
mut sel: Box<crate::expressions::Select>,
|
|
819
|
+
source: DialectType,
|
|
820
|
+
target: DialectType,
|
|
821
|
+
) -> Result<Box<crate::expressions::Select>> {
|
|
822
|
+
if !is_order_by_all(&sel.order_by) {
|
|
823
|
+
return Ok(sel);
|
|
824
|
+
}
|
|
825
|
+
let emulate_distinct = sel
|
|
826
|
+
.distinct_on
|
|
827
|
+
.as_ref()
|
|
828
|
+
.is_some_and(|cols| !cols.is_empty())
|
|
829
|
+
&& !Dialect::target_supports_distinct_on(target);
|
|
830
|
+
let snowflake_aggregate = target == DialectType::Snowflake
|
|
831
|
+
&& sel
|
|
832
|
+
.expressions
|
|
833
|
+
.iter()
|
|
834
|
+
.any(|e| contains_in_projection(e, crate::traversal::is_aggregate));
|
|
835
|
+
if target.supports_order_by_all() && !emulate_distinct && !snowflake_aggregate {
|
|
836
|
+
return Ok(sel);
|
|
837
|
+
}
|
|
838
|
+
let width =
|
|
839
|
+
if sel.expressions.is_empty() || sel.expressions.iter().any(has_unknown_column_count) {
|
|
840
|
+
None
|
|
841
|
+
} else {
|
|
842
|
+
Some(sel.expressions.len())
|
|
843
|
+
};
|
|
844
|
+
expand_order_by_all(&mut sel.order_by, width, source, target)?;
|
|
845
|
+
Ok(sel)
|
|
846
|
+
}
|
|
847
|
+
|
|
651
848
|
/// Applies a dialect transform bottom-up through selected syntax children.
|
|
652
849
|
///
|
|
653
850
|
/// The public entrypoint uses an explicit task stack for the recursion-heavy shapes
|
|
@@ -708,6 +905,7 @@ where
|
|
|
708
905
|
Expression::Union(set_op) => set_op.with.is_none() && set_op.order_by.is_none(),
|
|
709
906
|
Expression::Intersect(set_op) => set_op.with.is_none() && set_op.order_by.is_none(),
|
|
710
907
|
Expression::Except(set_op) => set_op.with.is_none() && set_op.order_by.is_none(),
|
|
908
|
+
Expression::Subquery(subquery) => subquery.order_by.is_none(),
|
|
711
909
|
Expression::Vertica(_)
|
|
712
910
|
| Expression::Literal(_)
|
|
713
911
|
| Expression::Boolean(_)
|
|
@@ -725,7 +923,6 @@ where
|
|
|
725
923
|
| Expression::IsNull(_)
|
|
726
924
|
| Expression::IsTrue(_)
|
|
727
925
|
| Expression::IsFalse(_)
|
|
728
|
-
| Expression::Subquery(_)
|
|
729
926
|
| Expression::Exists(_)
|
|
730
927
|
| Expression::Any(_)
|
|
731
928
|
| Expression::All(_)
|
|
@@ -736,6 +933,7 @@ where
|
|
|
736
933
|
| Expression::Sub(_)
|
|
737
934
|
| Expression::Mul(_)
|
|
738
935
|
| Expression::Div(_)
|
|
936
|
+
| Expression::IntDiv(_)
|
|
739
937
|
| Expression::Eq(_)
|
|
740
938
|
| Expression::NullSafeEq(_)
|
|
741
939
|
| Expression::NullSafeNeq(_)
|
|
@@ -1596,6 +1794,9 @@ where
|
|
|
1596
1794
|
// ===== Subquery expressions =====
|
|
1597
1795
|
Expression::Subquery(mut s) => {
|
|
1598
1796
|
s.this = transform_recursive(s.this, transform_fn)?;
|
|
1797
|
+
if let Some(order_by) = s.order_by.take() {
|
|
1798
|
+
s.order_by = Some(transform_order_by_recursive(order_by, transform_fn)?);
|
|
1799
|
+
}
|
|
1599
1800
|
Expression::Subquery(s)
|
|
1600
1801
|
}
|
|
1601
1802
|
Expression::Exists(mut e) => {
|
|
@@ -3515,16 +3716,57 @@ impl Dialect {
|
|
|
3515
3716
|
let expr =
|
|
3516
3717
|
normalization::vertica::prepare_conversion(expr, self.dialect_type, target)?;
|
|
3517
3718
|
normalization::vertica::validate_conversion(&expr, self.dialect_type, target)?;
|
|
3719
|
+
let expr = normalization::duckdb::prepare_integer_division(
|
|
3720
|
+
expr,
|
|
3721
|
+
self.dialect_type,
|
|
3722
|
+
target,
|
|
3723
|
+
)?;
|
|
3518
3724
|
// DuckDB source: normalize VARCHAR/CHAR to TEXT (DuckDB doesn't support
|
|
3519
3725
|
// VARCHAR length constraints). This emulates Python sqlglot's DuckDB parser
|
|
3520
3726
|
// where VARCHAR_LENGTH = None and VARCHAR maps to TEXT.
|
|
3521
|
-
|
|
3727
|
+
//
|
|
3728
|
+
// Any source with native `ORDER BY ALL`: expand it to positional
|
|
3729
|
+
// `ORDER BY 1..n` for targets without it, on both plain SELECTs and
|
|
3730
|
+
// compound queries (whose ORDER BY lives on the set-op node).
|
|
3731
|
+
let source = self.dialect_type;
|
|
3732
|
+
let is_duckdb = matches!(source, DialectType::DuckDB);
|
|
3733
|
+
let expand_all = source.supports_order_by_all() && !target.supports_order_by_all();
|
|
3734
|
+
let expr = if source.supports_order_by_all() {
|
|
3522
3735
|
use crate::expressions::DataType as DT;
|
|
3523
3736
|
transform_recursive(expr, &|e| match e {
|
|
3524
|
-
Expression::DataType(DT::VarChar { .. }) => {
|
|
3737
|
+
Expression::DataType(DT::VarChar { .. }) if is_duckdb => {
|
|
3738
|
+
Ok(Expression::DataType(DT::Text))
|
|
3739
|
+
}
|
|
3740
|
+
Expression::DataType(DT::Char { .. }) if is_duckdb => {
|
|
3525
3741
|
Ok(Expression::DataType(DT::Text))
|
|
3526
3742
|
}
|
|
3527
|
-
Expression::
|
|
3743
|
+
Expression::Select(sel) => {
|
|
3744
|
+
expand_select_order_by_all(sel, source, target).map(Expression::Select)
|
|
3745
|
+
}
|
|
3746
|
+
Expression::Subquery(mut subquery) if expand_all => {
|
|
3747
|
+
let width = query_output_width(&subquery.this);
|
|
3748
|
+
expand_order_by_all(&mut subquery.order_by, width, source, target)?;
|
|
3749
|
+
Ok(Expression::Subquery(subquery))
|
|
3750
|
+
}
|
|
3751
|
+
Expression::Union(mut u) if expand_all => {
|
|
3752
|
+
let width = if u.by_name {
|
|
3753
|
+
None
|
|
3754
|
+
} else {
|
|
3755
|
+
query_output_width(&u.left)
|
|
3756
|
+
};
|
|
3757
|
+
expand_order_by_all(&mut u.order_by, width, source, target)?;
|
|
3758
|
+
Ok(Expression::Union(u))
|
|
3759
|
+
}
|
|
3760
|
+
Expression::Intersect(mut i) if expand_all => {
|
|
3761
|
+
let width = query_output_width(&i.left);
|
|
3762
|
+
expand_order_by_all(&mut i.order_by, width, source, target)?;
|
|
3763
|
+
Ok(Expression::Intersect(i))
|
|
3764
|
+
}
|
|
3765
|
+
Expression::Except(mut ex) if expand_all => {
|
|
3766
|
+
let width = query_output_width(&ex.left);
|
|
3767
|
+
expand_order_by_all(&mut ex.order_by, width, source, target)?;
|
|
3768
|
+
Ok(Expression::Except(ex))
|
|
3769
|
+
}
|
|
3528
3770
|
_ => Ok(e),
|
|
3529
3771
|
})?
|
|
3530
3772
|
} else {
|