polyglot-sql 0.4.4__tar.gz → 0.5.1__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.4.4 → polyglot_sql-0.5.1}/Cargo.lock +5 -5
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/Cargo.toml +1 -1
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/PKG-INFO +31 -1
- {polyglot_sql-0.4.4/crates/polyglot-sql-python → polyglot_sql-0.5.1}/README.md +30 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/README.md +39 -4
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/mod.rs +278 -16
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/postgres.rs +13 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/generator.rs +12 -4
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/lib.rs +35 -2
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/lineage.rs +330 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/parser.rs +35 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/src/query_analysis.rs +769 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/scope.rs +28 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/tests/data_type_api.rs +86 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/tests/issue226_regression_test.rs +48 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +181 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/tests/query_analysis.rs +143 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/snowflake_regression_test.rs +66 -1
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/tsql_regression.rs +53 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1/crates/polyglot-sql-python}/README.md +30 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/docs/api.md +31 -2
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/docs/index.md +25 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/helpers.rs +31 -8
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/lib.rs +3 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/parse.rs +32 -2
- polyglot_sql-0.5.1/crates/polyglot-sql-python/src/query_analysis.rs +33 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/transpile.rs +14 -3
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_parse.py +26 -0
- polyglot_sql-0.5.1/crates/polyglot-sql-python/tests/test_query_analysis.py +45 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_transpile.py +33 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/python/polyglot_sql/__init__.py +4 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/python/polyglot_sql/__init__.pyi +62 -4
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/traversal.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/pyproject.toml +0 -0
- {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/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.
|
|
608
|
+
version = "0.5.1"
|
|
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.
|
|
624
|
+
version = "0.5.1"
|
|
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.
|
|
634
|
+
version = "0.5.1"
|
|
635
635
|
|
|
636
636
|
[[package]]
|
|
637
637
|
name = "polyglot-sql-python"
|
|
638
|
-
version = "0.
|
|
638
|
+
version = "0.5.1"
|
|
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.
|
|
649
|
+
version = "0.5.1"
|
|
650
650
|
dependencies = [
|
|
651
651
|
"console_error_panic_hook",
|
|
652
652
|
"js-sys",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: polyglot-sql
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -55,6 +55,15 @@ ast = polyglot_sql.parse_one("SELECT 1 + 2", dialect="postgres")
|
|
|
55
55
|
polyglot_sql.generate(ast, dialect="mysql")
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
```python
|
|
59
|
+
data_type = polyglot_sql.parse_data_type("DECIMAL(10, 2)", dialect="duckdb")
|
|
60
|
+
data_type.sql("postgres")
|
|
61
|
+
# "DECIMAL(10, 2)"
|
|
62
|
+
|
|
63
|
+
# SQLGlot-compatible narrow form for data types only:
|
|
64
|
+
polyglot_sql.parse_one("VARCHAR(255)", dialect="duckdb", into=polyglot_sql.DataType)
|
|
65
|
+
```
|
|
66
|
+
|
|
58
67
|
```python
|
|
59
68
|
polyglot_sql.format_sql("SELECT a,b FROM t WHERE x=1", dialect="postgres")
|
|
60
69
|
```
|
|
@@ -114,6 +123,24 @@ print(payload["facet"]["fields"])
|
|
|
114
123
|
OpenLineage helpers only produce compatible payloads. Transport and client
|
|
115
124
|
emission are intentionally out of scope.
|
|
116
125
|
|
|
126
|
+
```python
|
|
127
|
+
analysis = polyglot_sql.analyze_query(
|
|
128
|
+
"SELECT CAST(total AS TEXT) AS total_text FROM orders",
|
|
129
|
+
{
|
|
130
|
+
"dialect": "generic",
|
|
131
|
+
"schema": {
|
|
132
|
+
"tables": [
|
|
133
|
+
{
|
|
134
|
+
"name": "orders",
|
|
135
|
+
"columns": [{"name": "total", "type": "INT"}],
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
)
|
|
141
|
+
print(analysis["projections"][0]["transformKind"]) # "cast"
|
|
142
|
+
```
|
|
143
|
+
|
|
117
144
|
## API Reference
|
|
118
145
|
|
|
119
146
|
All functions are exported from `polyglot_sql`.
|
|
@@ -121,6 +148,8 @@ All functions are exported from `polyglot_sql`.
|
|
|
121
148
|
- `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
122
149
|
- `parse(sql: str, dialect: str = "generic") -> list[dict]`
|
|
123
150
|
- `parse_one(sql: str, dialect: str = "generic") -> dict`
|
|
151
|
+
- `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
|
|
152
|
+
- `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
|
|
124
153
|
- `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
125
154
|
- `format_sql(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str`
|
|
126
155
|
- `format(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str` (alias of `format_sql`)
|
|
@@ -128,6 +157,7 @@ All functions are exported from `polyglot_sql`.
|
|
|
128
157
|
- `optimize(sql: str, dialect: str = "generic") -> str`
|
|
129
158
|
- `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
|
|
130
159
|
- `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
|
|
160
|
+
- `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
|
|
131
161
|
- `openlineage_column_lineage(sql: str, options: dict) -> dict`
|
|
132
162
|
- `openlineage_job_event(sql: str, options: dict) -> dict`
|
|
133
163
|
- `openlineage_run_event(sql: str, options: dict) -> dict`
|
|
@@ -28,6 +28,15 @@ ast = polyglot_sql.parse_one("SELECT 1 + 2", dialect="postgres")
|
|
|
28
28
|
polyglot_sql.generate(ast, dialect="mysql")
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
```python
|
|
32
|
+
data_type = polyglot_sql.parse_data_type("DECIMAL(10, 2)", dialect="duckdb")
|
|
33
|
+
data_type.sql("postgres")
|
|
34
|
+
# "DECIMAL(10, 2)"
|
|
35
|
+
|
|
36
|
+
# SQLGlot-compatible narrow form for data types only:
|
|
37
|
+
polyglot_sql.parse_one("VARCHAR(255)", dialect="duckdb", into=polyglot_sql.DataType)
|
|
38
|
+
```
|
|
39
|
+
|
|
31
40
|
```python
|
|
32
41
|
polyglot_sql.format_sql("SELECT a,b FROM t WHERE x=1", dialect="postgres")
|
|
33
42
|
```
|
|
@@ -87,6 +96,24 @@ print(payload["facet"]["fields"])
|
|
|
87
96
|
OpenLineage helpers only produce compatible payloads. Transport and client
|
|
88
97
|
emission are intentionally out of scope.
|
|
89
98
|
|
|
99
|
+
```python
|
|
100
|
+
analysis = polyglot_sql.analyze_query(
|
|
101
|
+
"SELECT CAST(total AS TEXT) AS total_text FROM orders",
|
|
102
|
+
{
|
|
103
|
+
"dialect": "generic",
|
|
104
|
+
"schema": {
|
|
105
|
+
"tables": [
|
|
106
|
+
{
|
|
107
|
+
"name": "orders",
|
|
108
|
+
"columns": [{"name": "total", "type": "INT"}],
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
)
|
|
114
|
+
print(analysis["projections"][0]["transformKind"]) # "cast"
|
|
115
|
+
```
|
|
116
|
+
|
|
90
117
|
## API Reference
|
|
91
118
|
|
|
92
119
|
All functions are exported from `polyglot_sql`.
|
|
@@ -94,6 +121,8 @@ All functions are exported from `polyglot_sql`.
|
|
|
94
121
|
- `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
95
122
|
- `parse(sql: str, dialect: str = "generic") -> list[dict]`
|
|
96
123
|
- `parse_one(sql: str, dialect: str = "generic") -> dict`
|
|
124
|
+
- `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
|
|
125
|
+
- `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
|
|
97
126
|
- `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
98
127
|
- `format_sql(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str`
|
|
99
128
|
- `format(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str` (alias of `format_sql`)
|
|
@@ -101,6 +130,7 @@ All functions are exported from `polyglot_sql`.
|
|
|
101
130
|
- `optimize(sql: str, dialect: str = "generic") -> str`
|
|
102
131
|
- `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
|
|
103
132
|
- `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
|
|
133
|
+
- `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
|
|
104
134
|
- `openlineage_column_lineage(sql: str, options: dict) -> dict`
|
|
105
135
|
- `openlineage_job_event(sql: str, options: dict) -> dict`
|
|
106
136
|
- `openlineage_run_event(sql: str, options: dict) -> dict`
|
|
@@ -106,7 +106,7 @@ thiserror = { workspace = true }
|
|
|
106
106
|
unicode-segmentation = { workspace = true }
|
|
107
107
|
stacker = { version = "0.1", optional = true }
|
|
108
108
|
ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
|
|
109
|
-
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.
|
|
109
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.5.1", optional = true, default-features = false }
|
|
110
110
|
|
|
111
111
|
[dev-dependencies]
|
|
112
112
|
pretty_assertions = "1.4"
|
|
@@ -7,6 +7,7 @@ Part of the [Polyglot](https://github.com/tobilg/polyglot) project.
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **Parse** SQL into a fully-typed AST with 200+ expression types
|
|
10
|
+
- **Parse standalone data types** such as `DECIMAL(10, 2)` without a statement wrapper
|
|
10
11
|
- **Generate** SQL from AST nodes for any target dialect
|
|
11
12
|
- **Transpile** between any pair of 32 dialects in one call
|
|
12
13
|
- **Format** / pretty-print SQL
|
|
@@ -14,6 +15,7 @@ Part of the [Polyglot](https://github.com/tobilg/polyglot) project.
|
|
|
14
15
|
- **AST traversal** utilities (DFS/BFS iterators, transform, walk)
|
|
15
16
|
- **Validation** with syntax checking and error location reporting
|
|
16
17
|
- **Schema** module for column resolution and type annotation
|
|
18
|
+
- **Compact query analysis** for projection, relation, CTE, set-operation, and upstream-reference facts
|
|
17
19
|
|
|
18
20
|
## Usage
|
|
19
21
|
|
|
@@ -23,12 +25,12 @@ By default, `polyglot-sql` enables the full public API. Parser-only consumers ca
|
|
|
23
25
|
disable default features and opt into only the dialect parsers they need:
|
|
24
26
|
|
|
25
27
|
```toml
|
|
26
|
-
polyglot-sql = { version = "0.
|
|
28
|
+
polyglot-sql = { version = "0.5", default-features = false }
|
|
27
29
|
```
|
|
28
30
|
|
|
29
31
|
```toml
|
|
30
32
|
polyglot-sql = {
|
|
31
|
-
version = "0.
|
|
33
|
+
version = "0.5",
|
|
32
34
|
default-features = false,
|
|
33
35
|
features = ["dialect-clickhouse"],
|
|
34
36
|
}
|
|
@@ -42,14 +44,14 @@ Examples:
|
|
|
42
44
|
```toml
|
|
43
45
|
# Parse and generate SQL for one dialect.
|
|
44
46
|
polyglot-sql = {
|
|
45
|
-
version = "0.
|
|
47
|
+
version = "0.5",
|
|
46
48
|
default-features = false,
|
|
47
49
|
features = ["generate", "dialect-clickhouse"],
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
# Cross-dialect transpilation.
|
|
51
53
|
polyglot-sql = {
|
|
52
|
-
version = "0.
|
|
54
|
+
version = "0.5",
|
|
53
55
|
default-features = false,
|
|
54
56
|
features = ["transpile", "dialect-clickhouse", "dialect-postgresql"],
|
|
55
57
|
}
|
|
@@ -103,6 +105,19 @@ let sql = generate(&ast[0], DialectType::Postgres).unwrap();
|
|
|
103
105
|
assert_eq!(sql, "SELECT 1 + 2");
|
|
104
106
|
```
|
|
105
107
|
|
|
108
|
+
### Standalone Data Types
|
|
109
|
+
|
|
110
|
+
```rust
|
|
111
|
+
use polyglot_sql::{generate_data_type, parse_data_type, DialectType};
|
|
112
|
+
|
|
113
|
+
let data_type = parse_data_type("DECIMAL(10, 2)", DialectType::DuckDB).unwrap();
|
|
114
|
+
let sql = generate_data_type(&data_type, DialectType::Postgres).unwrap();
|
|
115
|
+
assert_eq!(sql, "DECIMAL(10, 2)");
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`parse_data_type` parses exactly one type string and rejects trailing SQL. Type
|
|
119
|
+
rendering requires the `generate` feature, which is enabled by default.
|
|
120
|
+
|
|
106
121
|
### Format With Guard Options
|
|
107
122
|
|
|
108
123
|
Formatting is protected by guard limits by default:
|
|
@@ -295,6 +310,26 @@ Schema-aware validation emits stable codes such as:
|
|
|
295
310
|
- `E210-E217` and `W210-W216` for type checks
|
|
296
311
|
- `E220`, `E221`, `W220`, `W221`, `W222` for reference/FK checks
|
|
297
312
|
|
|
313
|
+
### Compact Query Analysis
|
|
314
|
+
|
|
315
|
+
Use `analyze_query` when you need high-level facts without consuming the full AST
|
|
316
|
+
or full lineage graph:
|
|
317
|
+
|
|
318
|
+
```rust
|
|
319
|
+
use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
|
|
320
|
+
|
|
321
|
+
let analysis = analyze_query(
|
|
322
|
+
"SELECT o.total AS total FROM orders o",
|
|
323
|
+
AnalyzeQueryOptions {
|
|
324
|
+
dialect: DialectType::Generic,
|
|
325
|
+
schema: None,
|
|
326
|
+
},
|
|
327
|
+
).unwrap();
|
|
328
|
+
|
|
329
|
+
assert_eq!(analysis.shape, QueryShape::Select);
|
|
330
|
+
assert_eq!(analysis.projections[0].name.as_deref(), Some("total"));
|
|
331
|
+
```
|
|
332
|
+
|
|
298
333
|
### Tokenize
|
|
299
334
|
|
|
300
335
|
Access the raw token stream with full source position spans. Each token carries a `Span` with byte offsets and line/column numbers.
|
|
@@ -158,9 +158,9 @@ pub use trino::TrinoDialect;
|
|
|
158
158
|
pub use tsql::TSQLDialect;
|
|
159
159
|
|
|
160
160
|
use crate::error::Result;
|
|
161
|
-
use crate::expressions::Expression;
|
|
162
161
|
#[cfg(feature = "transpile")]
|
|
163
162
|
use crate::expressions::{ColumnConstraint, Function, Identifier, Literal};
|
|
163
|
+
use crate::expressions::{DataType, Expression};
|
|
164
164
|
#[cfg(any(
|
|
165
165
|
feature = "transpile",
|
|
166
166
|
feature = "ast-tools",
|
|
@@ -168,12 +168,16 @@ use crate::expressions::{ColumnConstraint, Function, Identifier, Literal};
|
|
|
168
168
|
feature = "semantic"
|
|
169
169
|
))]
|
|
170
170
|
use crate::expressions::{From, FunctionBody, Join, Null, OrderBy, OutputClause, TableRef, With};
|
|
171
|
+
#[cfg(feature = "transpile")]
|
|
172
|
+
use crate::generator::UnsupportedLevel;
|
|
171
173
|
#[cfg(feature = "generate")]
|
|
172
174
|
use crate::generator::{Generator, GeneratorConfig};
|
|
173
175
|
use crate::parser::Parser;
|
|
174
176
|
#[cfg(feature = "transpile")]
|
|
175
177
|
use crate::tokens::TokenType;
|
|
176
178
|
use crate::tokens::{Token, Tokenizer, TokenizerConfig};
|
|
179
|
+
#[cfg(feature = "transpile")]
|
|
180
|
+
use crate::traversal::ExpressionWalk;
|
|
177
181
|
use serde::{Deserialize, Serialize};
|
|
178
182
|
use std::collections::HashMap;
|
|
179
183
|
use std::sync::{Arc, LazyLock, RwLock};
|
|
@@ -3730,19 +3734,60 @@ pub struct Dialect {
|
|
|
3730
3734
|
/// The struct derives `Serialize`/`Deserialize` using camelCase field names so
|
|
3731
3735
|
/// it can be round-tripped over JSON bridges (C FFI, WASM) without mapping.
|
|
3732
3736
|
#[cfg(feature = "transpile")]
|
|
3733
|
-
#[derive(Debug, Clone,
|
|
3737
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
3734
3738
|
#[serde(rename_all = "camelCase", default)]
|
|
3735
3739
|
#[non_exhaustive]
|
|
3736
3740
|
pub struct TranspileOptions {
|
|
3737
3741
|
/// Whether to pretty-print the output SQL.
|
|
3738
3742
|
pub pretty: bool,
|
|
3743
|
+
/// How unsupported target-dialect constructs should be handled.
|
|
3744
|
+
///
|
|
3745
|
+
/// The default is [`UnsupportedLevel::Warn`], which preserves the current
|
|
3746
|
+
/// compatibility behavior and continues transpilation.
|
|
3747
|
+
pub unsupported_level: UnsupportedLevel,
|
|
3748
|
+
/// Maximum number of unsupported diagnostics to include in raised errors.
|
|
3749
|
+
pub max_unsupported: usize,
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
#[cfg(feature = "transpile")]
|
|
3753
|
+
impl Default for TranspileOptions {
|
|
3754
|
+
fn default() -> Self {
|
|
3755
|
+
Self {
|
|
3756
|
+
pretty: false,
|
|
3757
|
+
unsupported_level: UnsupportedLevel::Warn,
|
|
3758
|
+
max_unsupported: 3,
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3739
3761
|
}
|
|
3740
3762
|
|
|
3741
3763
|
#[cfg(feature = "transpile")]
|
|
3742
3764
|
impl TranspileOptions {
|
|
3743
3765
|
/// Construct options with pretty-printing enabled.
|
|
3744
3766
|
pub fn pretty() -> Self {
|
|
3745
|
-
Self {
|
|
3767
|
+
Self {
|
|
3768
|
+
pretty: true,
|
|
3769
|
+
..Default::default()
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3773
|
+
/// Construct options that raise when known unsupported constructs remain.
|
|
3774
|
+
pub fn strict() -> Self {
|
|
3775
|
+
Self {
|
|
3776
|
+
unsupported_level: UnsupportedLevel::Raise,
|
|
3777
|
+
..Default::default()
|
|
3778
|
+
}
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3781
|
+
/// Set how unsupported target-dialect constructs should be handled.
|
|
3782
|
+
pub fn with_unsupported_level(mut self, level: UnsupportedLevel) -> Self {
|
|
3783
|
+
self.unsupported_level = level;
|
|
3784
|
+
self
|
|
3785
|
+
}
|
|
3786
|
+
|
|
3787
|
+
/// Set the maximum number of unsupported diagnostics to include in raised errors.
|
|
3788
|
+
pub fn with_max_unsupported(mut self, max: usize) -> Self {
|
|
3789
|
+
self.max_unsupported = max;
|
|
3790
|
+
self
|
|
3746
3791
|
}
|
|
3747
3792
|
}
|
|
3748
3793
|
|
|
@@ -3891,6 +3936,20 @@ impl Dialect {
|
|
|
3891
3936
|
parser.parse()
|
|
3892
3937
|
}
|
|
3893
3938
|
|
|
3939
|
+
/// Parse a standalone SQL data type using this dialect's tokenizer and parser.
|
|
3940
|
+
///
|
|
3941
|
+
/// This accepts type strings such as `DECIMAL(10, 2)`, `INT[]`, or
|
|
3942
|
+
/// `STRUCT(a INT, b VARCHAR)` without requiring a surrounding statement.
|
|
3943
|
+
pub fn parse_data_type(&self, sql: &str) -> Result<DataType> {
|
|
3944
|
+
let tokens = self.tokenizer.tokenize(sql)?;
|
|
3945
|
+
let config = crate::parser::ParserConfig {
|
|
3946
|
+
dialect: Some(self.dialect_type),
|
|
3947
|
+
..Default::default()
|
|
3948
|
+
};
|
|
3949
|
+
let mut parser = Parser::with_source(tokens, config, sql.to_string());
|
|
3950
|
+
parser.parse_standalone_data_type()
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3894
3953
|
/// Tokenize SQL using this dialect's tokenizer configuration.
|
|
3895
3954
|
pub fn tokenize(&self, sql: &str) -> Result<Vec<Token>> {
|
|
3896
3955
|
self.tokenizer.tokenize(sql)
|
|
@@ -3956,6 +4015,23 @@ impl Dialect {
|
|
|
3956
4015
|
generator.generate(expr)
|
|
3957
4016
|
}
|
|
3958
4017
|
|
|
4018
|
+
/// Generate SQL from an expression with source dialect and transpile options.
|
|
4019
|
+
#[cfg(all(feature = "generate", feature = "transpile"))]
|
|
4020
|
+
fn generate_with_transpile_options(
|
|
4021
|
+
&self,
|
|
4022
|
+
expr: &Expression,
|
|
4023
|
+
source: DialectType,
|
|
4024
|
+
opts: &TranspileOptions,
|
|
4025
|
+
) -> Result<String> {
|
|
4026
|
+
let mut config = self.get_config_for_expr(expr);
|
|
4027
|
+
config.source_dialect = Some(source);
|
|
4028
|
+
config.pretty = opts.pretty;
|
|
4029
|
+
config.unsupported_level = opts.unsupported_level;
|
|
4030
|
+
config.max_unsupported = opts.max_unsupported.max(1);
|
|
4031
|
+
let mut generator = Generator::with_config(config);
|
|
4032
|
+
generator.generate(expr)
|
|
4033
|
+
}
|
|
4034
|
+
|
|
3959
4035
|
/// Generate SQL from an expression with forced identifier quoting (identify=True)
|
|
3960
4036
|
#[cfg(feature = "generate")]
|
|
3961
4037
|
pub fn generate_with_identify(&self, expr: &Expression) -> Result<String> {
|
|
@@ -4232,7 +4308,7 @@ impl Dialect {
|
|
|
4232
4308
|
target: T,
|
|
4233
4309
|
opts: TranspileOptions,
|
|
4234
4310
|
) -> Result<Vec<String>> {
|
|
4235
|
-
target.with_dialect(|td| self.transpile_inner(sql, td, opts
|
|
4311
|
+
target.with_dialect(|td| self.transpile_inner(sql, td, &opts))
|
|
4236
4312
|
}
|
|
4237
4313
|
|
|
4238
4314
|
#[cfg(feature = "transpile")]
|
|
@@ -4240,7 +4316,7 @@ impl Dialect {
|
|
|
4240
4316
|
&self,
|
|
4241
4317
|
sql: &str,
|
|
4242
4318
|
target_dialect: &Dialect,
|
|
4243
|
-
|
|
4319
|
+
opts: &TranspileOptions,
|
|
4244
4320
|
) -> Result<Vec<String>> {
|
|
4245
4321
|
let target = target_dialect.dialect_type;
|
|
4246
4322
|
if matches!(self.dialect_type, DialectType::PostgreSQL)
|
|
@@ -4256,11 +4332,8 @@ impl Dialect {
|
|
|
4256
4332
|
return expressions
|
|
4257
4333
|
.into_iter()
|
|
4258
4334
|
.map(|expr| {
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
} else {
|
|
4262
|
-
target_dialect.generate_with_source(&expr, self.dialect_type)
|
|
4263
|
-
}
|
|
4335
|
+
Self::reject_strict_unsupported(&expr, self.dialect_type, target, opts)?;
|
|
4336
|
+
target_dialect.generate_with_transpile_options(&expr, self.dialect_type, opts)
|
|
4264
4337
|
})
|
|
4265
4338
|
.collect();
|
|
4266
4339
|
}
|
|
@@ -4744,14 +4817,16 @@ impl Dialect {
|
|
|
4744
4817
|
transformed
|
|
4745
4818
|
};
|
|
4746
4819
|
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4820
|
+
Self::reject_strict_unsupported(&transformed, self.dialect_type, target, opts)?;
|
|
4821
|
+
|
|
4822
|
+
let mut sql = target_dialect.generate_with_transpile_options(
|
|
4823
|
+
&transformed,
|
|
4824
|
+
self.dialect_type,
|
|
4825
|
+
opts,
|
|
4826
|
+
)?;
|
|
4752
4827
|
|
|
4753
4828
|
// Align a known Snowflake pretty-print edge case with Python sqlglot output.
|
|
4754
|
-
if pretty && target == DialectType::Snowflake {
|
|
4829
|
+
if opts.pretty && target == DialectType::Snowflake {
|
|
4755
4830
|
sql = Self::normalize_snowflake_pretty(sql);
|
|
4756
4831
|
}
|
|
4757
4832
|
|
|
@@ -4764,6 +4839,193 @@ impl Dialect {
|
|
|
4764
4839
|
// Transpile-only methods: cross-dialect normalization and helpers
|
|
4765
4840
|
#[cfg(feature = "transpile")]
|
|
4766
4841
|
impl Dialect {
|
|
4842
|
+
fn reject_strict_unsupported(
|
|
4843
|
+
expr: &Expression,
|
|
4844
|
+
source: DialectType,
|
|
4845
|
+
target: DialectType,
|
|
4846
|
+
opts: &TranspileOptions,
|
|
4847
|
+
) -> Result<()> {
|
|
4848
|
+
if !matches!(
|
|
4849
|
+
opts.unsupported_level,
|
|
4850
|
+
UnsupportedLevel::Raise | UnsupportedLevel::Immediate
|
|
4851
|
+
) {
|
|
4852
|
+
return Ok(());
|
|
4853
|
+
}
|
|
4854
|
+
|
|
4855
|
+
let mut diagnostics = Vec::new();
|
|
4856
|
+
|
|
4857
|
+
for node in expr.dfs() {
|
|
4858
|
+
if matches!(target, DialectType::Fabric | DialectType::Hive)
|
|
4859
|
+
&& Self::node_has_recursive_with(node)
|
|
4860
|
+
{
|
|
4861
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "recursive CTEs");
|
|
4862
|
+
}
|
|
4863
|
+
|
|
4864
|
+
if matches!(target, DialectType::TSQL | DialectType::Fabric)
|
|
4865
|
+
&& Self::node_has_lateral(node)
|
|
4866
|
+
{
|
|
4867
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "LATERAL joins and subqueries");
|
|
4868
|
+
}
|
|
4869
|
+
|
|
4870
|
+
if !Self::target_supports_remaining_unnest(target) && Self::node_is_unnest(node) {
|
|
4871
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "UNNEST");
|
|
4872
|
+
}
|
|
4873
|
+
|
|
4874
|
+
if !Self::target_supports_remaining_explode(target) && Self::node_is_explode(node) {
|
|
4875
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "EXPLODE");
|
|
4876
|
+
}
|
|
4877
|
+
|
|
4878
|
+
if Self::target_lacks_array_agg(target) && Self::node_is_array_agg(node) {
|
|
4879
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "ARRAY_AGG");
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
if matches!(source, DialectType::PostgreSQL | DialectType::CockroachDB)
|
|
4883
|
+
&& !matches!(target, DialectType::PostgreSQL | DialectType::CockroachDB)
|
|
4884
|
+
{
|
|
4885
|
+
if Self::node_is_function_named(node, "JSONB_BUILD_OBJECT") {
|
|
4886
|
+
Self::push_unsupported_diagnostic(
|
|
4887
|
+
&mut diagnostics,
|
|
4888
|
+
"PostgreSQL JSONB_BUILD_OBJECT",
|
|
4889
|
+
);
|
|
4890
|
+
}
|
|
4891
|
+
if Self::node_is_function_named(node, "TO_TSVECTOR") {
|
|
4892
|
+
Self::push_unsupported_diagnostic(&mut diagnostics, "PostgreSQL TO_TSVECTOR");
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
|
|
4896
|
+
if opts.unsupported_level == UnsupportedLevel::Immediate && !diagnostics.is_empty() {
|
|
4897
|
+
break;
|
|
4898
|
+
}
|
|
4899
|
+
}
|
|
4900
|
+
|
|
4901
|
+
if diagnostics.is_empty() {
|
|
4902
|
+
return Ok(());
|
|
4903
|
+
}
|
|
4904
|
+
|
|
4905
|
+
let limit = if opts.unsupported_level == UnsupportedLevel::Immediate {
|
|
4906
|
+
1
|
|
4907
|
+
} else {
|
|
4908
|
+
opts.max_unsupported.max(1)
|
|
4909
|
+
};
|
|
4910
|
+
let mut messages = diagnostics.iter().take(limit).cloned().collect::<Vec<_>>();
|
|
4911
|
+
if diagnostics.len() > limit {
|
|
4912
|
+
messages.push(format!("... and {} more", diagnostics.len() - limit));
|
|
4913
|
+
}
|
|
4914
|
+
|
|
4915
|
+
Err(crate::error::Error::unsupported(
|
|
4916
|
+
messages.join("; "),
|
|
4917
|
+
target.to_string(),
|
|
4918
|
+
))
|
|
4919
|
+
}
|
|
4920
|
+
|
|
4921
|
+
fn push_unsupported_diagnostic(diagnostics: &mut Vec<String>, message: &str) {
|
|
4922
|
+
if !diagnostics.iter().any(|existing| existing == message) {
|
|
4923
|
+
diagnostics.push(message.to_string());
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4926
|
+
|
|
4927
|
+
fn node_has_recursive_with(expr: &Expression) -> bool {
|
|
4928
|
+
fn recursive(with: &Option<With>) -> bool {
|
|
4929
|
+
with.as_ref().is_some_and(|with| with.recursive)
|
|
4930
|
+
}
|
|
4931
|
+
|
|
4932
|
+
match expr {
|
|
4933
|
+
Expression::With(with) => with.recursive,
|
|
4934
|
+
Expression::Select(select) => recursive(&select.with),
|
|
4935
|
+
Expression::Union(union) => recursive(&union.with),
|
|
4936
|
+
Expression::Intersect(intersect) => recursive(&intersect.with),
|
|
4937
|
+
Expression::Except(except) => recursive(&except.with),
|
|
4938
|
+
Expression::Pivot(pivot) => recursive(&pivot.with),
|
|
4939
|
+
Expression::Insert(insert) => recursive(&insert.with),
|
|
4940
|
+
Expression::Update(update) => recursive(&update.with),
|
|
4941
|
+
Expression::Delete(delete) => recursive(&delete.with),
|
|
4942
|
+
_ => false,
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
|
|
4946
|
+
fn node_has_lateral(expr: &Expression) -> bool {
|
|
4947
|
+
fn joins_have_lateral(joins: &[Join]) -> bool {
|
|
4948
|
+
joins.iter().any(|join| {
|
|
4949
|
+
matches!(
|
|
4950
|
+
join.kind,
|
|
4951
|
+
crate::expressions::JoinKind::Lateral
|
|
4952
|
+
| crate::expressions::JoinKind::LeftLateral
|
|
4953
|
+
)
|
|
4954
|
+
})
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4957
|
+
match expr {
|
|
4958
|
+
Expression::Subquery(subquery) => subquery.lateral,
|
|
4959
|
+
Expression::Lateral(_) | Expression::LateralView(_) => true,
|
|
4960
|
+
Expression::Join(join) => matches!(
|
|
4961
|
+
join.kind,
|
|
4962
|
+
crate::expressions::JoinKind::Lateral | crate::expressions::JoinKind::LeftLateral
|
|
4963
|
+
),
|
|
4964
|
+
Expression::Select(select) => {
|
|
4965
|
+
!select.lateral_views.is_empty() || joins_have_lateral(&select.joins)
|
|
4966
|
+
}
|
|
4967
|
+
Expression::JoinedTable(joined) => {
|
|
4968
|
+
!joined.lateral_views.is_empty() || joins_have_lateral(&joined.joins)
|
|
4969
|
+
}
|
|
4970
|
+
Expression::Update(update) => {
|
|
4971
|
+
joins_have_lateral(&update.table_joins) || joins_have_lateral(&update.from_joins)
|
|
4972
|
+
}
|
|
4973
|
+
_ => false,
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
|
|
4977
|
+
fn target_supports_remaining_unnest(target: DialectType) -> bool {
|
|
4978
|
+
matches!(
|
|
4979
|
+
target,
|
|
4980
|
+
DialectType::PostgreSQL
|
|
4981
|
+
| DialectType::BigQuery
|
|
4982
|
+
| DialectType::DuckDB
|
|
4983
|
+
| DialectType::Presto
|
|
4984
|
+
| DialectType::Trino
|
|
4985
|
+
| DialectType::Athena
|
|
4986
|
+
)
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
fn target_supports_remaining_explode(target: DialectType) -> bool {
|
|
4990
|
+
matches!(
|
|
4991
|
+
target,
|
|
4992
|
+
DialectType::Spark | DialectType::Databricks | DialectType::Hive
|
|
4993
|
+
)
|
|
4994
|
+
}
|
|
4995
|
+
|
|
4996
|
+
fn target_lacks_array_agg(target: DialectType) -> bool {
|
|
4997
|
+
matches!(
|
|
4998
|
+
target,
|
|
4999
|
+
DialectType::Fabric
|
|
5000
|
+
| DialectType::TSQL
|
|
5001
|
+
| DialectType::MySQL
|
|
5002
|
+
| DialectType::SQLite
|
|
5003
|
+
| DialectType::Oracle
|
|
5004
|
+
)
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
fn node_is_unnest(expr: &Expression) -> bool {
|
|
5008
|
+
matches!(expr, Expression::Unnest(_)) || Self::node_is_function_named(expr, "UNNEST")
|
|
5009
|
+
}
|
|
5010
|
+
|
|
5011
|
+
fn node_is_explode(expr: &Expression) -> bool {
|
|
5012
|
+
matches!(expr, Expression::Explode(_) | Expression::ExplodeOuter(_))
|
|
5013
|
+
|| Self::node_is_function_named(expr, "EXPLODE")
|
|
5014
|
+
|| Self::node_is_function_named(expr, "EXPLODE_OUTER")
|
|
5015
|
+
}
|
|
5016
|
+
|
|
5017
|
+
fn node_is_array_agg(expr: &Expression) -> bool {
|
|
5018
|
+
matches!(expr, Expression::ArrayAgg(_)) || Self::node_is_function_named(expr, "ARRAY_AGG")
|
|
5019
|
+
}
|
|
5020
|
+
|
|
5021
|
+
fn node_is_function_named(expr: &Expression, name: &str) -> bool {
|
|
5022
|
+
match expr {
|
|
5023
|
+
Expression::Function(function) => function.name.eq_ignore_ascii_case(name),
|
|
5024
|
+
Expression::AggregateFunction(function) => function.name.eq_ignore_ascii_case(name),
|
|
5025
|
+
_ => false,
|
|
5026
|
+
}
|
|
5027
|
+
}
|
|
5028
|
+
|
|
4767
5029
|
fn rewrite_boolean_values_for_tsql(expr: Expression) -> Result<Expression> {
|
|
4768
5030
|
match expr {
|
|
4769
5031
|
Expression::Select(select) => Self::rewrite_boolean_values_in_tsql_select(select),
|
|
@@ -65,6 +65,19 @@ impl DialectImpl for PostgresDialect {
|
|
|
65
65
|
config
|
|
66
66
|
.keywords
|
|
67
67
|
.insert("EXEC".to_string(), TokenType::Command);
|
|
68
|
+
for command in [
|
|
69
|
+
"BASE_BACKUP",
|
|
70
|
+
"CREATE_REPLICATION_SLOT",
|
|
71
|
+
"DROP_REPLICATION_SLOT",
|
|
72
|
+
"IDENTIFY_SYSTEM",
|
|
73
|
+
"READ_REPLICATION_SLOT",
|
|
74
|
+
"START_REPLICATION",
|
|
75
|
+
"TIMELINE_HISTORY",
|
|
76
|
+
] {
|
|
77
|
+
config
|
|
78
|
+
.keywords
|
|
79
|
+
.insert(command.to_string(), TokenType::Command);
|
|
80
|
+
}
|
|
68
81
|
config
|
|
69
82
|
}
|
|
70
83
|
|