polyglot-sql 0.3.7__tar.gz → 0.3.10__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.3.7 → polyglot_sql-0.3.10}/Cargo.lock +5 -5
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/Cargo.toml +1 -1
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/PKG-INFO +1 -1
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/ast_transforms.rs +73 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/mod.rs +201 -5
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/expressions.rs +15 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/generator.rs +91 -4
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/lib.rs +5 -3
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/lineage.rs +10 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +315 -30
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/parser.rs +88 -66
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/scope.rs +10 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/traversal.rs +6 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +9 -9
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/fabric_regression.rs +111 -0
- polyglot_sql-0.3.10/crates/polyglot-sql/tests/fabric_tpch_regression.rs +580 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/transform_regression.rs +130 -2
- polyglot_sql-0.3.10/crates/polyglot-sql/tests/tsql_regression.rs +243 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/expr_types.rs +1 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/lib.rs +3 -0
- polyglot_sql-0.3.10/crates/polyglot-sql-python/src/transforms.rs +121 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_parse.py +19 -0
- polyglot_sql-0.3.10/crates/polyglot-sql-python/tests/test_transforms.py +44 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/python/polyglot_sql/__init__.py +6 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/python/polyglot_sql/__init__.pyi +46 -10
- polyglot_sql-0.3.7/crates/polyglot-sql/tests/tsql_regression.rs +0 -85
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/README.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/README.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/pyproject.toml +0 -0
- {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/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.3.
|
|
608
|
+
version = "0.3.10"
|
|
609
609
|
dependencies = [
|
|
610
610
|
"criterion",
|
|
611
611
|
"once_cell",
|
|
@@ -621,7 +621,7 @@ dependencies = [
|
|
|
621
621
|
|
|
622
622
|
[[package]]
|
|
623
623
|
name = "polyglot-sql-ffi"
|
|
624
|
-
version = "0.3.
|
|
624
|
+
version = "0.3.10"
|
|
625
625
|
dependencies = [
|
|
626
626
|
"cbindgen",
|
|
627
627
|
"polyglot-sql",
|
|
@@ -631,11 +631,11 @@ dependencies = [
|
|
|
631
631
|
|
|
632
632
|
[[package]]
|
|
633
633
|
name = "polyglot-sql-function-catalogs"
|
|
634
|
-
version = "0.3.
|
|
634
|
+
version = "0.3.10"
|
|
635
635
|
|
|
636
636
|
[[package]]
|
|
637
637
|
name = "polyglot-sql-python"
|
|
638
|
-
version = "0.3.
|
|
638
|
+
version = "0.3.10"
|
|
639
639
|
dependencies = [
|
|
640
640
|
"polyglot-sql",
|
|
641
641
|
"pyo3",
|
|
@@ -646,7 +646,7 @@ dependencies = [
|
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "polyglot-sql-wasm"
|
|
649
|
-
version = "0.3.
|
|
649
|
+
version = "0.3.10"
|
|
650
650
|
dependencies = [
|
|
651
651
|
"console_error_panic_hook",
|
|
652
652
|
"js-sys",
|
|
@@ -83,7 +83,7 @@ thiserror = { workspace = true }
|
|
|
83
83
|
unicode-segmentation = { workspace = true }
|
|
84
84
|
stacker = { version = "0.1", optional = true }
|
|
85
85
|
ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
|
|
86
|
-
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.
|
|
86
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.10", optional = true, default-features = false }
|
|
87
87
|
|
|
88
88
|
[dev-dependencies]
|
|
89
89
|
pretty_assertions = "1.4"
|
|
@@ -159,12 +159,61 @@ pub fn rename_columns(expr: Expression, mapping: &HashMap<String, String>) -> Ex
|
|
|
159
159
|
})
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
/// Options for table renaming.
|
|
163
|
+
#[derive(Debug, Clone)]
|
|
164
|
+
pub struct RenameTablesOptions {
|
|
165
|
+
/// Whether renamed table references should receive aliases.
|
|
166
|
+
pub alias_renamed_tables: bool,
|
|
167
|
+
/// Whether existing aliases should be preserved when aliasing renamed tables.
|
|
168
|
+
pub preserve_existing_aliases: bool,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
impl Default for RenameTablesOptions {
|
|
172
|
+
fn default() -> Self {
|
|
173
|
+
Self {
|
|
174
|
+
alias_renamed_tables: false,
|
|
175
|
+
preserve_existing_aliases: true,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
impl RenameTablesOptions {
|
|
181
|
+
pub fn new() -> Self {
|
|
182
|
+
Self::default()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
pub fn with_alias_renamed_tables(mut self, alias: bool) -> Self {
|
|
186
|
+
self.alias_renamed_tables = alias;
|
|
187
|
+
self
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
pub fn with_preserve_existing_aliases(mut self, preserve: bool) -> Self {
|
|
191
|
+
self.preserve_existing_aliases = preserve;
|
|
192
|
+
self
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
162
196
|
/// Rename tables throughout the expression tree using the provided mapping.
|
|
163
197
|
pub fn rename_tables(expr: Expression, mapping: &HashMap<String, String>) -> Expression {
|
|
198
|
+
rename_tables_with_options(expr, mapping, &RenameTablesOptions::default())
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// Rename tables throughout the expression tree using the provided mapping and options.
|
|
202
|
+
pub fn rename_tables_with_options(
|
|
203
|
+
expr: Expression,
|
|
204
|
+
mapping: &HashMap<String, String>,
|
|
205
|
+
options: &RenameTablesOptions,
|
|
206
|
+
) -> Expression {
|
|
164
207
|
xform(expr, |node| match node {
|
|
165
208
|
Expression::Table(mut tbl) => {
|
|
166
209
|
if let Some(new_name) = mapping.get(&tbl.name.name) {
|
|
167
210
|
tbl.name.name = new_name.clone();
|
|
211
|
+
if options.alias_renamed_tables
|
|
212
|
+
&& (!options.preserve_existing_aliases || tbl.alias.is_none())
|
|
213
|
+
{
|
|
214
|
+
tbl.alias = Some(Identifier::new(new_name));
|
|
215
|
+
tbl.alias_explicit_as = true;
|
|
216
|
+
}
|
|
168
217
|
}
|
|
169
218
|
Expression::Table(tbl)
|
|
170
219
|
}
|
|
@@ -701,6 +750,30 @@ mod tests {
|
|
|
701
750
|
assert!(sql.contains("new_table"), "Expected new_table in: {}", sql);
|
|
702
751
|
}
|
|
703
752
|
|
|
753
|
+
#[test]
|
|
754
|
+
fn test_rename_tables_with_alias_renamed_tables() {
|
|
755
|
+
let expr = parse_one("SELECT a FROM old_table");
|
|
756
|
+
let mut mapping = HashMap::new();
|
|
757
|
+
mapping.insert("old_table".to_string(), "new_table".to_string());
|
|
758
|
+
let options = RenameTablesOptions::new().with_alias_renamed_tables(true);
|
|
759
|
+
let result = rename_tables_with_options(expr, &mapping, &options);
|
|
760
|
+
let sql = result.sql();
|
|
761
|
+
|
|
762
|
+
assert_eq!(sql, "SELECT a FROM new_table AS new_table");
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
#[test]
|
|
766
|
+
fn test_rename_tables_with_alias_preserves_existing_alias() {
|
|
767
|
+
let expr = parse_one("SELECT a FROM old_table AS t");
|
|
768
|
+
let mut mapping = HashMap::new();
|
|
769
|
+
mapping.insert("old_table".to_string(), "new_table".to_string());
|
|
770
|
+
let options = RenameTablesOptions::new().with_alias_renamed_tables(true);
|
|
771
|
+
let result = rename_tables_with_options(expr, &mapping, &options);
|
|
772
|
+
let sql = result.sql();
|
|
773
|
+
|
|
774
|
+
assert_eq!(sql, "SELECT a FROM new_table AS t");
|
|
775
|
+
}
|
|
776
|
+
|
|
704
777
|
#[test]
|
|
705
778
|
fn test_set_distinct() {
|
|
706
779
|
let expr = parse_one("SELECT a FROM t");
|
|
@@ -158,7 +158,10 @@ pub use trino::TrinoDialect;
|
|
|
158
158
|
pub use tsql::TSQLDialect;
|
|
159
159
|
|
|
160
160
|
use crate::error::Result;
|
|
161
|
-
use crate::expressions::{
|
|
161
|
+
use crate::expressions::{
|
|
162
|
+
Expression, From, Function, FunctionBody, Identifier, Join, Null, OrderBy, OutputClause,
|
|
163
|
+
TableRef, With,
|
|
164
|
+
};
|
|
162
165
|
use crate::generator::{Generator, GeneratorConfig};
|
|
163
166
|
use crate::parser::Parser;
|
|
164
167
|
use crate::tokens::{Token, TokenType, Tokenizer, TokenizerConfig};
|
|
@@ -1661,6 +1664,122 @@ where
|
|
|
1661
1664
|
}
|
|
1662
1665
|
}
|
|
1663
1666
|
|
|
1667
|
+
fn transform_table_ref_recursive<F>(table: TableRef, transform_fn: &F) -> Result<TableRef>
|
|
1668
|
+
where
|
|
1669
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1670
|
+
{
|
|
1671
|
+
match transform_recursive(Expression::Table(Box::new(table)), transform_fn)? {
|
|
1672
|
+
Expression::Table(table) => Ok(*table),
|
|
1673
|
+
_ => Err(crate::error::Error::parse(
|
|
1674
|
+
"TableRef transformation returned non-table expression",
|
|
1675
|
+
0,
|
|
1676
|
+
0,
|
|
1677
|
+
0,
|
|
1678
|
+
0,
|
|
1679
|
+
)),
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
fn transform_from_recursive<F>(from: From, transform_fn: &F) -> Result<From>
|
|
1684
|
+
where
|
|
1685
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1686
|
+
{
|
|
1687
|
+
match transform_recursive(Expression::From(Box::new(from)), transform_fn)? {
|
|
1688
|
+
Expression::From(from) => Ok(*from),
|
|
1689
|
+
_ => Err(crate::error::Error::parse(
|
|
1690
|
+
"FROM transformation returned non-FROM expression",
|
|
1691
|
+
0,
|
|
1692
|
+
0,
|
|
1693
|
+
0,
|
|
1694
|
+
0,
|
|
1695
|
+
)),
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
fn transform_join_recursive<F>(mut join: Join, transform_fn: &F) -> Result<Join>
|
|
1700
|
+
where
|
|
1701
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1702
|
+
{
|
|
1703
|
+
join.this = transform_recursive(join.this, transform_fn)?;
|
|
1704
|
+
if let Some(on) = join.on.take() {
|
|
1705
|
+
join.on = Some(transform_recursive(on, transform_fn)?);
|
|
1706
|
+
}
|
|
1707
|
+
if let Some(match_condition) = join.match_condition.take() {
|
|
1708
|
+
join.match_condition = Some(transform_recursive(match_condition, transform_fn)?);
|
|
1709
|
+
}
|
|
1710
|
+
join.pivots = join
|
|
1711
|
+
.pivots
|
|
1712
|
+
.into_iter()
|
|
1713
|
+
.map(|pivot| transform_recursive(pivot, transform_fn))
|
|
1714
|
+
.collect::<Result<Vec<_>>>()?;
|
|
1715
|
+
|
|
1716
|
+
match transform_fn(Expression::Join(Box::new(join)))? {
|
|
1717
|
+
Expression::Join(join) => Ok(*join),
|
|
1718
|
+
_ => Err(crate::error::Error::parse(
|
|
1719
|
+
"Join transformation returned non-join expression",
|
|
1720
|
+
0,
|
|
1721
|
+
0,
|
|
1722
|
+
0,
|
|
1723
|
+
0,
|
|
1724
|
+
)),
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
fn transform_output_clause_recursive<F>(
|
|
1729
|
+
mut output: OutputClause,
|
|
1730
|
+
transform_fn: &F,
|
|
1731
|
+
) -> Result<OutputClause>
|
|
1732
|
+
where
|
|
1733
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1734
|
+
{
|
|
1735
|
+
output.columns = output
|
|
1736
|
+
.columns
|
|
1737
|
+
.into_iter()
|
|
1738
|
+
.map(|column| transform_recursive(column, transform_fn))
|
|
1739
|
+
.collect::<Result<Vec<_>>>()?;
|
|
1740
|
+
if let Some(into_table) = output.into_table.take() {
|
|
1741
|
+
output.into_table = Some(transform_recursive(into_table, transform_fn)?);
|
|
1742
|
+
}
|
|
1743
|
+
Ok(output)
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
fn transform_with_recursive<F>(mut with: With, transform_fn: &F) -> Result<With>
|
|
1747
|
+
where
|
|
1748
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1749
|
+
{
|
|
1750
|
+
with.ctes = with
|
|
1751
|
+
.ctes
|
|
1752
|
+
.into_iter()
|
|
1753
|
+
.map(|mut cte| {
|
|
1754
|
+
cte.this = transform_recursive(cte.this, transform_fn)?;
|
|
1755
|
+
Ok(cte)
|
|
1756
|
+
})
|
|
1757
|
+
.collect::<Result<Vec<_>>>()?;
|
|
1758
|
+
if let Some(search) = with.search.take() {
|
|
1759
|
+
with.search = Some(Box::new(transform_recursive(*search, transform_fn)?));
|
|
1760
|
+
}
|
|
1761
|
+
Ok(with)
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
fn transform_order_by_recursive<F>(mut order: OrderBy, transform_fn: &F) -> Result<OrderBy>
|
|
1765
|
+
where
|
|
1766
|
+
F: Fn(Expression) -> Result<Expression>,
|
|
1767
|
+
{
|
|
1768
|
+
order.expressions = order
|
|
1769
|
+
.expressions
|
|
1770
|
+
.into_iter()
|
|
1771
|
+
.map(|mut ordered| {
|
|
1772
|
+
let original = ordered.this.clone();
|
|
1773
|
+
ordered.this = transform_recursive(ordered.this, transform_fn).unwrap_or(original);
|
|
1774
|
+
match transform_fn(Expression::Ordered(Box::new(ordered.clone()))) {
|
|
1775
|
+
Ok(Expression::Ordered(transformed)) => Ok(*transformed),
|
|
1776
|
+
Ok(_) | Err(_) => Ok(ordered),
|
|
1777
|
+
}
|
|
1778
|
+
})
|
|
1779
|
+
.collect::<Result<Vec<_>>>()?;
|
|
1780
|
+
Ok(order)
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1664
1783
|
fn transform_recursive_reference<F>(expr: Expression, transform_fn: &F) -> Result<Expression>
|
|
1665
1784
|
where
|
|
1666
1785
|
F: Fn(Expression) -> Result<Expression>,
|
|
@@ -2377,6 +2496,17 @@ where
|
|
|
2377
2496
|
Expression::Insert(ins)
|
|
2378
2497
|
}
|
|
2379
2498
|
Expression::Update(mut upd) => {
|
|
2499
|
+
upd.table = transform_table_ref_recursive(upd.table, transform_fn)?;
|
|
2500
|
+
upd.extra_tables = upd
|
|
2501
|
+
.extra_tables
|
|
2502
|
+
.into_iter()
|
|
2503
|
+
.map(|table| transform_table_ref_recursive(table, transform_fn))
|
|
2504
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2505
|
+
upd.table_joins = upd
|
|
2506
|
+
.table_joins
|
|
2507
|
+
.into_iter()
|
|
2508
|
+
.map(|join| transform_join_recursive(join, transform_fn))
|
|
2509
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2380
2510
|
upd.set = upd
|
|
2381
2511
|
.set
|
|
2382
2512
|
.into_iter()
|
|
@@ -2385,17 +2515,75 @@ where
|
|
|
2385
2515
|
(id, new_val)
|
|
2386
2516
|
})
|
|
2387
2517
|
.collect();
|
|
2518
|
+
if let Some(from_clause) = upd.from_clause.take() {
|
|
2519
|
+
upd.from_clause = Some(transform_from_recursive(from_clause, transform_fn)?);
|
|
2520
|
+
}
|
|
2521
|
+
upd.from_joins = upd
|
|
2522
|
+
.from_joins
|
|
2523
|
+
.into_iter()
|
|
2524
|
+
.map(|join| transform_join_recursive(join, transform_fn))
|
|
2525
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2388
2526
|
if let Some(mut where_clause) = upd.where_clause.take() {
|
|
2389
2527
|
where_clause.this = transform_recursive(where_clause.this, transform_fn)?;
|
|
2390
2528
|
upd.where_clause = Some(where_clause);
|
|
2391
2529
|
}
|
|
2530
|
+
upd.returning = upd
|
|
2531
|
+
.returning
|
|
2532
|
+
.into_iter()
|
|
2533
|
+
.map(|expr| transform_recursive(expr, transform_fn))
|
|
2534
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2535
|
+
if let Some(output) = upd.output.take() {
|
|
2536
|
+
upd.output = Some(transform_output_clause_recursive(output, transform_fn)?);
|
|
2537
|
+
}
|
|
2538
|
+
if let Some(with) = upd.with.take() {
|
|
2539
|
+
upd.with = Some(transform_with_recursive(with, transform_fn)?);
|
|
2540
|
+
}
|
|
2541
|
+
if let Some(limit) = upd.limit.take() {
|
|
2542
|
+
upd.limit = Some(transform_recursive(limit, transform_fn)?);
|
|
2543
|
+
}
|
|
2544
|
+
if let Some(order_by) = upd.order_by.take() {
|
|
2545
|
+
upd.order_by = Some(transform_order_by_recursive(order_by, transform_fn)?);
|
|
2546
|
+
}
|
|
2392
2547
|
Expression::Update(upd)
|
|
2393
2548
|
}
|
|
2394
2549
|
Expression::Delete(mut del) => {
|
|
2550
|
+
del.table = transform_table_ref_recursive(del.table, transform_fn)?;
|
|
2551
|
+
del.using = del
|
|
2552
|
+
.using
|
|
2553
|
+
.into_iter()
|
|
2554
|
+
.map(|table| transform_table_ref_recursive(table, transform_fn))
|
|
2555
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2395
2556
|
if let Some(mut where_clause) = del.where_clause.take() {
|
|
2396
2557
|
where_clause.this = transform_recursive(where_clause.this, transform_fn)?;
|
|
2397
2558
|
del.where_clause = Some(where_clause);
|
|
2398
2559
|
}
|
|
2560
|
+
if let Some(output) = del.output.take() {
|
|
2561
|
+
del.output = Some(transform_output_clause_recursive(output, transform_fn)?);
|
|
2562
|
+
}
|
|
2563
|
+
if let Some(with) = del.with.take() {
|
|
2564
|
+
del.with = Some(transform_with_recursive(with, transform_fn)?);
|
|
2565
|
+
}
|
|
2566
|
+
if let Some(limit) = del.limit.take() {
|
|
2567
|
+
del.limit = Some(transform_recursive(limit, transform_fn)?);
|
|
2568
|
+
}
|
|
2569
|
+
if let Some(order_by) = del.order_by.take() {
|
|
2570
|
+
del.order_by = Some(transform_order_by_recursive(order_by, transform_fn)?);
|
|
2571
|
+
}
|
|
2572
|
+
del.returning = del
|
|
2573
|
+
.returning
|
|
2574
|
+
.into_iter()
|
|
2575
|
+
.map(|expr| transform_recursive(expr, transform_fn))
|
|
2576
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2577
|
+
del.tables = del
|
|
2578
|
+
.tables
|
|
2579
|
+
.into_iter()
|
|
2580
|
+
.map(|table| transform_table_ref_recursive(table, transform_fn))
|
|
2581
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2582
|
+
del.joins = del
|
|
2583
|
+
.joins
|
|
2584
|
+
.into_iter()
|
|
2585
|
+
.map(|join| transform_join_recursive(join, transform_fn))
|
|
2586
|
+
.collect::<Result<Vec<_>>>()?;
|
|
2399
2587
|
Expression::Delete(del)
|
|
2400
2588
|
}
|
|
2401
2589
|
|
|
@@ -8097,15 +8285,21 @@ impl Dialect {
|
|
|
8097
8285
|
if matches!(target, DialectType::MySQL) && o.nulls_first.is_some() {
|
|
8098
8286
|
Action::MysqlNullsOrdering
|
|
8099
8287
|
} else {
|
|
8100
|
-
// Skip targets that don't support NULLS FIRST/LAST syntax
|
|
8288
|
+
// Skip targets that don't support NULLS FIRST/LAST syntax unless
|
|
8289
|
+
// the generator can preserve semantics with a CASE sort key.
|
|
8290
|
+
let target_rewrites_nulls =
|
|
8291
|
+
matches!(target, DialectType::TSQL | DialectType::Fabric);
|
|
8101
8292
|
let target_supports_nulls = !matches!(
|
|
8102
8293
|
target,
|
|
8103
8294
|
DialectType::MySQL
|
|
8104
8295
|
| DialectType::TSQL
|
|
8296
|
+
| DialectType::Fabric
|
|
8105
8297
|
| DialectType::StarRocks
|
|
8106
8298
|
| DialectType::Doris
|
|
8107
8299
|
);
|
|
8108
|
-
if o.nulls_first.is_none()
|
|
8300
|
+
if o.nulls_first.is_none()
|
|
8301
|
+
&& source != target
|
|
8302
|
+
&& (target_supports_nulls || target_rewrites_nulls)
|
|
8109
8303
|
{
|
|
8110
8304
|
Action::NullsOrdering
|
|
8111
8305
|
} else {
|
|
@@ -32060,7 +32254,7 @@ impl Dialect {
|
|
|
32060
32254
|
match unit.trim().to_ascii_uppercase().as_str() {
|
|
32061
32255
|
"YEAR" | "YEARS" => Some(IntervalUnit::Year),
|
|
32062
32256
|
"QUARTER" | "QUARTERS" => Some(IntervalUnit::Quarter),
|
|
32063
|
-
"MONTH" | "MONTHS" => Some(IntervalUnit::Month),
|
|
32257
|
+
"MONTH" | "MONTHS" | "MON" | "MONS" | "MM" => Some(IntervalUnit::Month),
|
|
32064
32258
|
"WEEK" | "WEEKS" | "ISOWEEK" => Some(IntervalUnit::Week),
|
|
32065
32259
|
"DAY" | "DAYS" => Some(IntervalUnit::Day),
|
|
32066
32260
|
"HOUR" | "HOURS" => Some(IntervalUnit::Hour),
|
|
@@ -36732,7 +36926,9 @@ impl Dialect {
|
|
|
36732
36926
|
match s {
|
|
36733
36927
|
"YEAR" | "YY" | "YYYY" => crate::expressions::IntervalUnit::Year,
|
|
36734
36928
|
"QUARTER" | "QQ" | "Q" => crate::expressions::IntervalUnit::Quarter,
|
|
36735
|
-
"MONTH" | "MM" | "M" =>
|
|
36929
|
+
"MONTH" | "MONTHS" | "MON" | "MONS" | "MM" | "M" => {
|
|
36930
|
+
crate::expressions::IntervalUnit::Month
|
|
36931
|
+
}
|
|
36736
36932
|
"WEEK" | "WK" | "WW" | "ISOWEEK" => crate::expressions::IntervalUnit::Week,
|
|
36737
36933
|
"DAY" | "DD" | "D" | "DY" => crate::expressions::IntervalUnit::Day,
|
|
36738
36934
|
"HOUR" | "HH" => crate::expressions::IntervalUnit::Hour,
|
|
@@ -114,6 +114,7 @@ pub enum Expression {
|
|
|
114
114
|
Copy(Box<CopyStmt>),
|
|
115
115
|
Put(Box<PutStmt>),
|
|
116
116
|
StageReference(Box<StageReference>),
|
|
117
|
+
TryCatch(Box<TryCatch>),
|
|
117
118
|
|
|
118
119
|
// Expressions
|
|
119
120
|
Alias(Box<Alias>),
|
|
@@ -1146,6 +1147,7 @@ impl Expression {
|
|
|
1146
1147
|
| Expression::Copy(_)
|
|
1147
1148
|
| Expression::Put(_)
|
|
1148
1149
|
| Expression::Merge(_)
|
|
1150
|
+
| Expression::TryCatch(_)
|
|
1149
1151
|
|
|
1150
1152
|
// DDL
|
|
1151
1153
|
| Expression::CreateTable(_)
|
|
@@ -2229,6 +2231,7 @@ impl Expression {
|
|
|
2229
2231
|
Expression::Describe(_) => "describe",
|
|
2230
2232
|
Expression::Show(_) => "show",
|
|
2231
2233
|
Expression::Command(_) => "command",
|
|
2234
|
+
Expression::TryCatch(_) => "try_catch",
|
|
2232
2235
|
Expression::Kill(_) => "kill",
|
|
2233
2236
|
Expression::Execute(_) => "execute",
|
|
2234
2237
|
Expression::Raw(_) => "raw",
|
|
@@ -6003,6 +6006,18 @@ pub struct Command {
|
|
|
6003
6006
|
pub this: String,
|
|
6004
6007
|
}
|
|
6005
6008
|
|
|
6009
|
+
/// T-SQL TRY/CATCH block.
|
|
6010
|
+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
6011
|
+
#[cfg_attr(feature = "bindings", derive(TS))]
|
|
6012
|
+
pub struct TryCatch {
|
|
6013
|
+
/// Statements inside BEGIN TRY ... END TRY.
|
|
6014
|
+
#[serde(default)]
|
|
6015
|
+
pub try_body: Vec<Expression>,
|
|
6016
|
+
/// Statements inside BEGIN CATCH ... END CATCH, when present.
|
|
6017
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
6018
|
+
pub catch_body: Option<Vec<Expression>>,
|
|
6019
|
+
}
|
|
6020
|
+
|
|
6006
6021
|
/// EXEC/EXECUTE statement (TSQL stored procedure call)
|
|
6007
6022
|
/// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
|
|
6008
6023
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
@@ -3342,6 +3342,7 @@ impl Generator {
|
|
|
3342
3342
|
Ok(())
|
|
3343
3343
|
}
|
|
3344
3344
|
Expression::CreateTask(task) => self.generate_create_task(task),
|
|
3345
|
+
Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
|
|
3345
3346
|
Expression::Command(cmd) => {
|
|
3346
3347
|
self.write(&cmd.this);
|
|
3347
3348
|
Ok(())
|
|
@@ -4802,7 +4803,10 @@ impl Generator {
|
|
|
4802
4803
|
} else {
|
|
4803
4804
|
self.write_space();
|
|
4804
4805
|
}
|
|
4805
|
-
if matches!(
|
|
4806
|
+
if matches!(
|
|
4807
|
+
self.config.dialect,
|
|
4808
|
+
Some(DialectType::TSQL) | Some(DialectType::Fabric)
|
|
4809
|
+
) {
|
|
4806
4810
|
// SQL Server 2012+ OFFSET ... FETCH syntax
|
|
4807
4811
|
self.write_keyword("OFFSET");
|
|
4808
4812
|
self.write_space();
|
|
@@ -14109,6 +14113,58 @@ impl Generator {
|
|
|
14109
14113
|
Ok(())
|
|
14110
14114
|
}
|
|
14111
14115
|
|
|
14116
|
+
fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
|
|
14117
|
+
self.write_keyword("BEGIN TRY");
|
|
14118
|
+
self.generate_tsql_block_statements(&try_catch.try_body)?;
|
|
14119
|
+
self.write_keyword("END TRY");
|
|
14120
|
+
|
|
14121
|
+
if let Some(catch_body) = &try_catch.catch_body {
|
|
14122
|
+
if self.config.pretty {
|
|
14123
|
+
self.write_newline();
|
|
14124
|
+
self.write_indent();
|
|
14125
|
+
} else {
|
|
14126
|
+
self.write_space();
|
|
14127
|
+
}
|
|
14128
|
+
self.write_keyword("BEGIN CATCH");
|
|
14129
|
+
self.generate_tsql_block_statements(catch_body)?;
|
|
14130
|
+
self.write_keyword("END CATCH");
|
|
14131
|
+
}
|
|
14132
|
+
|
|
14133
|
+
Ok(())
|
|
14134
|
+
}
|
|
14135
|
+
|
|
14136
|
+
fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
|
|
14137
|
+
if statements.is_empty() {
|
|
14138
|
+
self.write_space();
|
|
14139
|
+
return Ok(());
|
|
14140
|
+
}
|
|
14141
|
+
|
|
14142
|
+
if self.config.pretty {
|
|
14143
|
+
self.indent_level += 1;
|
|
14144
|
+
for stmt in statements {
|
|
14145
|
+
self.write_newline();
|
|
14146
|
+
self.write_indent();
|
|
14147
|
+
self.generate_expression(stmt)?;
|
|
14148
|
+
self.write(";");
|
|
14149
|
+
}
|
|
14150
|
+
self.indent_level -= 1;
|
|
14151
|
+
self.write_newline();
|
|
14152
|
+
self.write_indent();
|
|
14153
|
+
} else {
|
|
14154
|
+
self.write_space();
|
|
14155
|
+
for (i, stmt) in statements.iter().enumerate() {
|
|
14156
|
+
if i > 0 {
|
|
14157
|
+
self.write_space();
|
|
14158
|
+
}
|
|
14159
|
+
self.generate_expression(stmt)?;
|
|
14160
|
+
self.write(";");
|
|
14161
|
+
}
|
|
14162
|
+
self.write_space();
|
|
14163
|
+
}
|
|
14164
|
+
|
|
14165
|
+
Ok(())
|
|
14166
|
+
}
|
|
14167
|
+
|
|
14112
14168
|
fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
|
|
14113
14169
|
self.write_keyword("DROP TYPE");
|
|
14114
14170
|
|
|
@@ -18528,7 +18584,7 @@ impl Generator {
|
|
|
18528
18584
|
};
|
|
18529
18585
|
match lower {
|
|
18530
18586
|
"day" | "days" | "d" => "DAY".to_string(),
|
|
18531
|
-
"month" | "months" | "mon" | "mm" => "MONTH".to_string(),
|
|
18587
|
+
"month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
|
|
18532
18588
|
"year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
|
|
18533
18589
|
"week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
|
|
18534
18590
|
"hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
|
|
@@ -23159,6 +23215,36 @@ impl Generator {
|
|
|
23159
23215
|
}
|
|
23160
23216
|
|
|
23161
23217
|
fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
|
|
23218
|
+
let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
|
|
23219
|
+
&& !self.config.null_ordering_supported
|
|
23220
|
+
&& matches!(
|
|
23221
|
+
self.config.dialect,
|
|
23222
|
+
Some(DialectType::TSQL) | Some(DialectType::Fabric)
|
|
23223
|
+
);
|
|
23224
|
+
let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
|
|
23225
|
+
let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
|
|
23226
|
+
let target_default_nulls_first = !ordered.desc;
|
|
23227
|
+
|
|
23228
|
+
unsupported_tsql_null_ordering
|
|
23229
|
+
&& nulls_first != target_default_nulls_first
|
|
23230
|
+
&& !random_ordering
|
|
23231
|
+
} else {
|
|
23232
|
+
false
|
|
23233
|
+
};
|
|
23234
|
+
|
|
23235
|
+
if emulate_tsql_null_ordering {
|
|
23236
|
+
self.write_keyword("CASE WHEN");
|
|
23237
|
+
self.write_space();
|
|
23238
|
+
self.generate_expression(&ordered.this)?;
|
|
23239
|
+
self.write_space();
|
|
23240
|
+
self.write_keyword("IS NULL THEN 1 ELSE 0 END");
|
|
23241
|
+
if ordered.nulls_first == Some(true) {
|
|
23242
|
+
self.write_space();
|
|
23243
|
+
self.write_keyword("DESC");
|
|
23244
|
+
}
|
|
23245
|
+
self.write(", ");
|
|
23246
|
+
}
|
|
23247
|
+
|
|
23162
23248
|
self.generate_expression(&ordered.this)?;
|
|
23163
23249
|
if ordered.desc {
|
|
23164
23250
|
self.write_space();
|
|
@@ -23168,8 +23254,9 @@ impl Generator {
|
|
|
23168
23254
|
self.write_keyword("ASC");
|
|
23169
23255
|
}
|
|
23170
23256
|
if let Some(nulls_first) = ordered.nulls_first {
|
|
23171
|
-
if
|
|
23172
|
-
|
|
23257
|
+
if !unsupported_tsql_null_ordering
|
|
23258
|
+
&& (self.config.null_ordering_supported
|
|
23259
|
+
|| !matches!(self.config.dialect, Some(DialectType::Fabric)))
|
|
23173
23260
|
{
|
|
23174
23261
|
// Determine if we should skip outputting NULLS FIRST/LAST when it's the default
|
|
23175
23262
|
// for the dialect. Different dialects have different NULL ordering defaults:
|
|
@@ -42,8 +42,8 @@ pub use ast_transforms::{
|
|
|
42
42
|
add_select_columns, add_where, get_aggregate_functions, get_column_names, get_functions,
|
|
43
43
|
get_identifiers, get_literals, get_output_column_names, get_subqueries, get_table_names,
|
|
44
44
|
get_window_functions, node_count, qualify_columns, remove_limit_offset, remove_nodes,
|
|
45
|
-
remove_select_columns, remove_where, rename_columns, rename_tables,
|
|
46
|
-
replace_nodes, set_distinct, set_limit, set_offset,
|
|
45
|
+
remove_select_columns, remove_where, rename_columns, rename_tables, rename_tables_with_options,
|
|
46
|
+
replace_by_type, replace_nodes, set_distinct, set_limit, set_offset, RenameTablesOptions,
|
|
47
47
|
};
|
|
48
48
|
pub use dialects::{
|
|
49
49
|
unregister_custom_dialect, CustomDialectBuilder, Dialect, DialectType, TranspileOptions,
|
|
@@ -59,7 +59,9 @@ pub use helper::{
|
|
|
59
59
|
csv, find_new_name, is_date_unit, is_float, is_int, is_iso_date, is_iso_datetime, merge_ranges,
|
|
60
60
|
name_sequence, seq_get, split_num_words, tsort, while_changing, DATE_UNITS,
|
|
61
61
|
};
|
|
62
|
-
pub use optimizer::{
|
|
62
|
+
pub use optimizer::{
|
|
63
|
+
annotate_types, qualify_tables, QualifyTablesOptions, TypeAnnotator, TypeCoercionClass,
|
|
64
|
+
};
|
|
63
65
|
pub use parser::Parser;
|
|
64
66
|
pub use resolver::{is_column_ambiguous, resolve_column, Resolver, ResolverError, ResolverResult};
|
|
65
67
|
pub use schema::{
|
|
@@ -1658,6 +1658,16 @@ fn collect_column_refs(expr: &Expression, refs: &mut Vec<SimpleColumnRef>) {
|
|
|
1658
1658
|
Expression::NamedArgument(n) => {
|
|
1659
1659
|
stack.push(&n.value);
|
|
1660
1660
|
}
|
|
1661
|
+
Expression::TryCatch(t) => {
|
|
1662
|
+
for stmt in &t.try_body {
|
|
1663
|
+
stack.push(stmt);
|
|
1664
|
+
}
|
|
1665
|
+
if let Some(catch_body) = &t.catch_body {
|
|
1666
|
+
for stmt in catch_body {
|
|
1667
|
+
stack.push(stmt);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1661
1671
|
Expression::BracedWildcard(e) | Expression::ReturnStmt(e) => {
|
|
1662
1672
|
stack.push(e);
|
|
1663
1673
|
}
|