polyglot-sql 0.5.0__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/Cargo.lock +5 -5
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/Cargo.toml +1 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/PKG-INFO +39 -1
- {polyglot_sql-0.5.0/crates/polyglot-sql-python → polyglot_sql-0.5.2}/README.md +38 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/README.md +53 -4
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mod.rs +15 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/postgres.rs +13 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/generator.rs +9 -3
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lib.rs +34 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lineage.rs +41 -2
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +43 -7
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/parser.rs +35 -0
- polyglot_sql-0.5.2/crates/polyglot-sql/src/query_analysis.rs +917 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/scope.rs +5 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/traversal.rs +15 -2
- polyglot_sql-0.5.2/crates/polyglot-sql/tests/data_type_api.rs +86 -0
- polyglot_sql-0.5.2/crates/polyglot-sql/tests/issue226_regression_test.rs +48 -0
- polyglot_sql-0.5.2/crates/polyglot-sql/tests/query_analysis.rs +340 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/snowflake_regression_test.rs +66 -1
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tsql_regression.rs +53 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2/crates/polyglot-sql-python}/README.md +38 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/api.md +31 -2
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/index.md +40 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/helpers.rs +17 -11
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lib.rs +3 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/parse.rs +32 -2
- polyglot_sql-0.5.2/crates/polyglot-sql-python/src/query_analysis.rs +33 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_parse.py +26 -0
- polyglot_sql-0.5.2/crates/polyglot-sql-python/tests/test_query_analysis.py +71 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.py +4 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.pyi +62 -4
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/pyproject.toml +0 -0
- {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/python/polyglot_sql/py.typed +0 -0
|
@@ -605,7 +605,7 @@ dependencies = [
|
|
|
605
605
|
|
|
606
606
|
[[package]]
|
|
607
607
|
name = "polyglot-sql"
|
|
608
|
-
version = "0.5.
|
|
608
|
+
version = "0.5.2"
|
|
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.5.
|
|
624
|
+
version = "0.5.2"
|
|
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.5.
|
|
634
|
+
version = "0.5.2"
|
|
635
635
|
|
|
636
636
|
[[package]]
|
|
637
637
|
name = "polyglot-sql-python"
|
|
638
|
-
version = "0.5.
|
|
638
|
+
version = "0.5.2"
|
|
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.5.
|
|
649
|
+
version = "0.5.2"
|
|
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.5.
|
|
3
|
+
Version: 0.5.2
|
|
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,32 @@ 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 SUM(o.amount) AS total FROM orders AS o",
|
|
129
|
+
{
|
|
130
|
+
"dialect": "generic",
|
|
131
|
+
"schema": {
|
|
132
|
+
"tables": [
|
|
133
|
+
{
|
|
134
|
+
"name": "orders",
|
|
135
|
+
"columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
)
|
|
141
|
+
print(analysis["projections"][0]["transformKind"]) # "aggregation"
|
|
142
|
+
print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
|
|
143
|
+
print(analysis["baseTables"][0]["name"]) # "orders"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`analysis["relations"]` reports sources visible in the analyzed scope.
|
|
147
|
+
`analysis["baseTables"]` reports deduplicated physical table dependencies across
|
|
148
|
+
nested CTEs, derived tables, subqueries, and set-operation branches. Validation
|
|
149
|
+
uses broad type families, while query analysis preserves parseable detailed
|
|
150
|
+
schema type strings for projection `typeHint` values.
|
|
151
|
+
|
|
117
152
|
## API Reference
|
|
118
153
|
|
|
119
154
|
All functions are exported from `polyglot_sql`.
|
|
@@ -121,6 +156,8 @@ All functions are exported from `polyglot_sql`.
|
|
|
121
156
|
- `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
122
157
|
- `parse(sql: str, dialect: str = "generic") -> list[dict]`
|
|
123
158
|
- `parse_one(sql: str, dialect: str = "generic") -> dict`
|
|
159
|
+
- `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
|
|
160
|
+
- `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
|
|
124
161
|
- `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
125
162
|
- `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
163
|
- `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 +165,7 @@ All functions are exported from `polyglot_sql`.
|
|
|
128
165
|
- `optimize(sql: str, dialect: str = "generic") -> str`
|
|
129
166
|
- `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
|
|
130
167
|
- `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
|
|
168
|
+
- `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
|
|
131
169
|
- `openlineage_column_lineage(sql: str, options: dict) -> dict`
|
|
132
170
|
- `openlineage_job_event(sql: str, options: dict) -> dict`
|
|
133
171
|
- `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,32 @@ 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 SUM(o.amount) AS total FROM orders AS o",
|
|
102
|
+
{
|
|
103
|
+
"dialect": "generic",
|
|
104
|
+
"schema": {
|
|
105
|
+
"tables": [
|
|
106
|
+
{
|
|
107
|
+
"name": "orders",
|
|
108
|
+
"columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
)
|
|
114
|
+
print(analysis["projections"][0]["transformKind"]) # "aggregation"
|
|
115
|
+
print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
|
|
116
|
+
print(analysis["baseTables"][0]["name"]) # "orders"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`analysis["relations"]` reports sources visible in the analyzed scope.
|
|
120
|
+
`analysis["baseTables"]` reports deduplicated physical table dependencies across
|
|
121
|
+
nested CTEs, derived tables, subqueries, and set-operation branches. Validation
|
|
122
|
+
uses broad type families, while query analysis preserves parseable detailed
|
|
123
|
+
schema type strings for projection `typeHint` values.
|
|
124
|
+
|
|
90
125
|
## API Reference
|
|
91
126
|
|
|
92
127
|
All functions are exported from `polyglot_sql`.
|
|
@@ -94,6 +129,8 @@ All functions are exported from `polyglot_sql`.
|
|
|
94
129
|
- `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
95
130
|
- `parse(sql: str, dialect: str = "generic") -> list[dict]`
|
|
96
131
|
- `parse_one(sql: str, dialect: str = "generic") -> dict`
|
|
132
|
+
- `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
|
|
133
|
+
- `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
|
|
97
134
|
- `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
|
|
98
135
|
- `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
136
|
- `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 +138,7 @@ All functions are exported from `polyglot_sql`.
|
|
|
101
138
|
- `optimize(sql: str, dialect: str = "generic") -> str`
|
|
102
139
|
- `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
|
|
103
140
|
- `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
|
|
141
|
+
- `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
|
|
104
142
|
- `openlineage_column_lineage(sql: str, options: dict) -> dict`
|
|
105
143
|
- `openlineage_job_event(sql: str, options: dict) -> dict`
|
|
106
144
|
- `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.5.
|
|
109
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.5.2", 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,40 @@ 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. `relations` reports sources visible in the analyzed
|
|
317
|
+
scope, while `base_tables` reports deduplicated physical table dependencies
|
|
318
|
+
across CTEs, derived tables, subqueries, and set-operation branches. When a
|
|
319
|
+
`ValidationSchema` is supplied, detailed type strings such as `DECIMAL(10,2)`
|
|
320
|
+
are preserved in projection `type_hint` values when parseable.
|
|
321
|
+
|
|
322
|
+
```rust
|
|
323
|
+
use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
|
|
324
|
+
|
|
325
|
+
let schema: polyglot_sql::ValidationSchema = serde_json::from_value(serde_json::json!({
|
|
326
|
+
"tables": [{
|
|
327
|
+
"name": "orders",
|
|
328
|
+
"columns": [{"name": "amount", "type": "DECIMAL(10,2)"}]
|
|
329
|
+
}]
|
|
330
|
+
})).unwrap();
|
|
331
|
+
|
|
332
|
+
let analysis = analyze_query(
|
|
333
|
+
"SELECT SUM(o.amount) AS total FROM orders o",
|
|
334
|
+
AnalyzeQueryOptions {
|
|
335
|
+
dialect: DialectType::Generic,
|
|
336
|
+
schema: Some(schema),
|
|
337
|
+
},
|
|
338
|
+
).unwrap();
|
|
339
|
+
|
|
340
|
+
assert_eq!(analysis.shape, QueryShape::Select);
|
|
341
|
+
assert_eq!(analysis.projections[0].name.as_deref(), Some("total"));
|
|
342
|
+
assert_eq!(analysis.projections[0].transform_kind, polyglot_sql::TransformKind::Aggregation);
|
|
343
|
+
assert_eq!(analysis.base_tables[0].name, "orders");
|
|
344
|
+
assert_eq!(analysis.base_tables[0].alias.as_deref(), Some("o"));
|
|
345
|
+
```
|
|
346
|
+
|
|
298
347
|
### Tokenize
|
|
299
348
|
|
|
300
349
|
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",
|
|
@@ -3936,6 +3936,20 @@ impl Dialect {
|
|
|
3936
3936
|
parser.parse()
|
|
3937
3937
|
}
|
|
3938
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
|
+
|
|
3939
3953
|
/// Tokenize SQL using this dialect's tokenizer configuration.
|
|
3940
3954
|
pub fn tokenize(&self, sql: &str) -> Result<Vec<Token>> {
|
|
3941
3955
|
self.tokenizer.tokenize(sql)
|
|
@@ -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
|
|
|
@@ -19705,9 +19705,15 @@ impl Generator {
|
|
|
19705
19705
|
self.write_simple_interval_unit(unit, false); // Use singular form for DATEDIFF
|
|
19706
19706
|
self.write(", ");
|
|
19707
19707
|
}
|
|
19708
|
-
self.
|
|
19709
|
-
|
|
19710
|
-
|
|
19708
|
+
if self.config.dialect == Some(DialectType::Snowflake) {
|
|
19709
|
+
self.generate_expression(&f.expression)?;
|
|
19710
|
+
self.write(", ");
|
|
19711
|
+
self.generate_expression(&f.this)?;
|
|
19712
|
+
} else {
|
|
19713
|
+
self.generate_expression(&f.this)?;
|
|
19714
|
+
self.write(", ");
|
|
19715
|
+
self.generate_expression(&f.expression)?;
|
|
19716
|
+
}
|
|
19711
19717
|
self.write(")");
|
|
19712
19718
|
Ok(())
|
|
19713
19719
|
}
|
|
@@ -37,6 +37,8 @@ pub mod optimizer;
|
|
|
37
37
|
pub mod parser;
|
|
38
38
|
#[cfg(feature = "planner")]
|
|
39
39
|
pub mod planner;
|
|
40
|
+
#[cfg(all(feature = "semantic", feature = "generate"))]
|
|
41
|
+
pub mod query_analysis;
|
|
40
42
|
#[cfg(feature = "semantic")]
|
|
41
43
|
pub mod resolver;
|
|
42
44
|
#[cfg(feature = "semantic")]
|
|
@@ -72,7 +74,7 @@ pub use dialects::{TranspileOptions, TranspileTarget};
|
|
|
72
74
|
pub use error::{Error, Result};
|
|
73
75
|
#[cfg(feature = "semantic")]
|
|
74
76
|
pub use error::{ValidationError, ValidationResult, ValidationSeverity};
|
|
75
|
-
pub use expressions::Expression;
|
|
77
|
+
pub use expressions::{DataType, Expression};
|
|
76
78
|
#[cfg(feature = "semantic")]
|
|
77
79
|
pub use function_catalog::{
|
|
78
80
|
FunctionCatalog, FunctionNameCase, FunctionSignature, HashMapFunctionCatalog,
|
|
@@ -89,6 +91,12 @@ pub use optimizer::{
|
|
|
89
91
|
annotate_types, qualify_tables, QualifyTablesOptions, TypeAnnotator, TypeCoercionClass,
|
|
90
92
|
};
|
|
91
93
|
pub use parser::Parser;
|
|
94
|
+
#[cfg(all(feature = "semantic", feature = "generate"))]
|
|
95
|
+
pub use query_analysis::{
|
|
96
|
+
analyze_query, AnalyzeQueryOptions, ColumnReferenceFact, ProjectionFact, QueryAnalysis,
|
|
97
|
+
QueryShape, ReferenceConfidence, RelationFact, SetOperationBranchFact, SetOperationFact,
|
|
98
|
+
TransformKind,
|
|
99
|
+
};
|
|
92
100
|
#[cfg(feature = "semantic")]
|
|
93
101
|
pub use resolver::{is_column_ambiguous, resolve_column, Resolver, ResolverError, ResolverResult};
|
|
94
102
|
#[cfg(feature = "semantic")]
|
|
@@ -495,6 +503,31 @@ pub fn parse_one(sql: &str, dialect: DialectType) -> Result<Expression> {
|
|
|
495
503
|
Ok(expressions.remove(0))
|
|
496
504
|
}
|
|
497
505
|
|
|
506
|
+
/// Parse a standalone SQL data type.
|
|
507
|
+
///
|
|
508
|
+
/// # Arguments
|
|
509
|
+
/// * `sql` - The data type string to parse, e.g. `DECIMAL(10, 2)`
|
|
510
|
+
/// * `dialect` - The dialect to use for parsing
|
|
511
|
+
///
|
|
512
|
+
/// # Returns
|
|
513
|
+
/// The parsed data type
|
|
514
|
+
pub fn parse_data_type(sql: &str, dialect: DialectType) -> Result<DataType> {
|
|
515
|
+
Dialect::get(dialect).parse_data_type(sql)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/// Generate SQL from a standalone data type.
|
|
519
|
+
///
|
|
520
|
+
/// # Arguments
|
|
521
|
+
/// * `data_type` - The data type to render
|
|
522
|
+
/// * `dialect` - The target dialect
|
|
523
|
+
///
|
|
524
|
+
/// # Returns
|
|
525
|
+
/// The generated type SQL string
|
|
526
|
+
#[cfg(feature = "generate")]
|
|
527
|
+
pub fn generate_data_type(data_type: &DataType, dialect: DialectType) -> Result<String> {
|
|
528
|
+
Dialect::get(dialect).generate(&Expression::DataType(data_type.clone()))
|
|
529
|
+
}
|
|
530
|
+
|
|
498
531
|
/// Generate SQL from an AST.
|
|
499
532
|
///
|
|
500
533
|
/// # Arguments
|
|
@@ -235,6 +235,25 @@ fn lineage_from_expression(
|
|
|
235
235
|
)
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
pub(crate) fn lineage_by_index_from_expression(
|
|
239
|
+
column_index: usize,
|
|
240
|
+
sql: &Expression,
|
|
241
|
+
dialect: Option<DialectType>,
|
|
242
|
+
trim_selects: bool,
|
|
243
|
+
) -> Result<LineageNode> {
|
|
244
|
+
let sql = lineage_effective_expression(sql);
|
|
245
|
+
let scope = build_scope(sql);
|
|
246
|
+
to_node(
|
|
247
|
+
ColumnRef::Index(column_index),
|
|
248
|
+
&scope,
|
|
249
|
+
dialect,
|
|
250
|
+
"",
|
|
251
|
+
"",
|
|
252
|
+
"",
|
|
253
|
+
trim_selects,
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
|
|
238
257
|
fn lineage_effective_expression(sql: &Expression) -> &Expression {
|
|
239
258
|
match sql {
|
|
240
259
|
Expression::Prepare(prepare) => &prepare.statement,
|
|
@@ -753,12 +772,32 @@ fn to_node_inner(
|
|
|
753
772
|
apply_scope_context(&mut node, scope, source_name, reference_node_name);
|
|
754
773
|
|
|
755
774
|
// 5. Star handling — add downstream for each source
|
|
756
|
-
if
|
|
775
|
+
if let Expression::Star(star) = &select_expr {
|
|
776
|
+
let star_table = star
|
|
777
|
+
.table
|
|
778
|
+
.as_ref()
|
|
779
|
+
.map(|identifier| identifier.name.as_str());
|
|
757
780
|
for (name, source_info) in &scope.sources {
|
|
781
|
+
if let Some(star_table) = star_table {
|
|
782
|
+
let table_matches = name.eq_ignore_ascii_case(star_table)
|
|
783
|
+
|| source_info
|
|
784
|
+
.alias
|
|
785
|
+
.as_deref()
|
|
786
|
+
.is_some_and(|alias| alias.eq_ignore_ascii_case(star_table))
|
|
787
|
+
|| matches!(
|
|
788
|
+
&source_info.expression,
|
|
789
|
+
Expression::Table(table_ref)
|
|
790
|
+
if table_name_from_table_ref(table_ref).eq_ignore_ascii_case(star_table)
|
|
791
|
+
);
|
|
792
|
+
if !table_matches {
|
|
793
|
+
continue;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
758
797
|
let mut child = LineageNode::new(
|
|
759
798
|
format!("{}.*", name),
|
|
760
799
|
Expression::Star(crate::expressions::Star {
|
|
761
|
-
table:
|
|
800
|
+
table: star.table.clone(),
|
|
762
801
|
except: None,
|
|
763
802
|
replace: None,
|
|
764
803
|
rename: None,
|
{polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs
RENAMED
|
@@ -653,21 +653,23 @@ fn expand_stars(
|
|
|
653
653
|
|
|
654
654
|
for expr in &select.expressions {
|
|
655
655
|
match expr {
|
|
656
|
-
Expression::Star(
|
|
656
|
+
Expression::Star(star) => {
|
|
657
657
|
has_star = true;
|
|
658
|
-
|
|
659
|
-
|
|
658
|
+
if let Some(table) = &star.table {
|
|
659
|
+
let table_name = &table.name;
|
|
660
|
+
if !ordered_sources.contains(table_name) {
|
|
661
|
+
return Err(QualifyColumnsError::UnknownTable(table_name.clone()));
|
|
662
|
+
}
|
|
663
|
+
if let Ok(columns) = resolver.get_source_columns(table_name) {
|
|
660
664
|
if columns.contains(&"*".to_string()) || columns.is_empty() {
|
|
661
665
|
return Ok(());
|
|
662
666
|
}
|
|
663
667
|
for col_name in &columns {
|
|
664
668
|
if coalesced_columns.contains(col_name) {
|
|
665
|
-
// Already emitted as COALESCE, skip
|
|
666
669
|
continue;
|
|
667
670
|
}
|
|
668
671
|
if let Some(tables) = column_tables.get(col_name) {
|
|
669
|
-
if tables.contains(
|
|
670
|
-
// Emit COALESCE and mark as coalesced
|
|
672
|
+
if tables.contains(table_name) {
|
|
671
673
|
coalesced_columns.insert(col_name.clone());
|
|
672
674
|
let coalesce = make_coalesce(col_name, tables);
|
|
673
675
|
new_selections.push(Expression::Alias(Box::new(Alias {
|
|
@@ -684,7 +686,41 @@ fn expand_stars(
|
|
|
684
686
|
}
|
|
685
687
|
}
|
|
686
688
|
new_selections
|
|
687
|
-
.push(create_qualified_column(col_name, Some(
|
|
689
|
+
.push(create_qualified_column(col_name, Some(table_name)));
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
} else {
|
|
693
|
+
for source_name in &ordered_sources {
|
|
694
|
+
if let Ok(columns) = resolver.get_source_columns(source_name) {
|
|
695
|
+
if columns.contains(&"*".to_string()) || columns.is_empty() {
|
|
696
|
+
return Ok(());
|
|
697
|
+
}
|
|
698
|
+
for col_name in &columns {
|
|
699
|
+
if coalesced_columns.contains(col_name) {
|
|
700
|
+
// Already emitted as COALESCE, skip
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if let Some(tables) = column_tables.get(col_name) {
|
|
704
|
+
if tables.contains(source_name) {
|
|
705
|
+
// Emit COALESCE and mark as coalesced
|
|
706
|
+
coalesced_columns.insert(col_name.clone());
|
|
707
|
+
let coalesce = make_coalesce(col_name, tables);
|
|
708
|
+
new_selections.push(Expression::Alias(Box::new(Alias {
|
|
709
|
+
this: coalesce,
|
|
710
|
+
alias: Identifier::new(col_name),
|
|
711
|
+
column_aliases: vec![],
|
|
712
|
+
alias_explicit_as: false,
|
|
713
|
+
alias_keyword: None,
|
|
714
|
+
pre_alias_comments: vec![],
|
|
715
|
+
trailing_comments: vec![],
|
|
716
|
+
inferred_type: None,
|
|
717
|
+
})));
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
new_selections
|
|
722
|
+
.push(create_qualified_column(col_name, Some(source_name)));
|
|
723
|
+
}
|
|
688
724
|
}
|
|
689
725
|
}
|
|
690
726
|
}
|
|
@@ -740,6 +740,28 @@ impl Parser {
|
|
|
740
740
|
Ok(statements)
|
|
741
741
|
}
|
|
742
742
|
|
|
743
|
+
/// Parse exactly one standalone data type from the token stream.
|
|
744
|
+
///
|
|
745
|
+
/// This entry point is intended for callers that need to parse native type
|
|
746
|
+
/// strings such as `DECIMAL(10, 2)` without wrapping them in a SQL statement
|
|
747
|
+
/// or `CAST(...)` expression.
|
|
748
|
+
pub fn parse_standalone_data_type(&mut self) -> Result<DataType> {
|
|
749
|
+
let data_type = self.parse_data_type()?;
|
|
750
|
+
|
|
751
|
+
if self.check(TokenType::Semicolon) {
|
|
752
|
+
self.skip();
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
if !self.is_at_end() {
|
|
756
|
+
return Err(self.parse_error(format!(
|
|
757
|
+
"Unexpected token after data type: {}",
|
|
758
|
+
self.peek().text
|
|
759
|
+
)));
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
Ok(data_type)
|
|
763
|
+
}
|
|
764
|
+
|
|
743
765
|
/// Parse a single SQL statement from the current position in the token stream.
|
|
744
766
|
///
|
|
745
767
|
/// Dispatches to the appropriate sub-parser based on the leading keyword
|
|
@@ -24338,10 +24360,23 @@ impl Parser {
|
|
|
24338
24360
|
|
|
24339
24361
|
/// Parse SET statement
|
|
24340
24362
|
fn parse_set(&mut self) -> Result<Expression> {
|
|
24363
|
+
let statement_start = self.current;
|
|
24341
24364
|
self.expect(TokenType::Set)?;
|
|
24342
24365
|
|
|
24343
24366
|
let mut items = Vec::new();
|
|
24344
24367
|
|
|
24368
|
+
// T-SQL: SET STATISTICS TIME|IO|XML|PROFILE ON|OFF. The existing SET
|
|
24369
|
+
// parser handles simple options like SET NOCOUNT ON, but these
|
|
24370
|
+
// multi-token STATISTICS options are better preserved as commands.
|
|
24371
|
+
if matches!(
|
|
24372
|
+
self.config.dialect,
|
|
24373
|
+
Some(crate::dialects::DialectType::TSQL)
|
|
24374
|
+
) && self.check_identifier("STATISTICS")
|
|
24375
|
+
{
|
|
24376
|
+
self.current = statement_start;
|
|
24377
|
+
return self.fallback_to_command(statement_start);
|
|
24378
|
+
}
|
|
24379
|
+
|
|
24345
24380
|
// ClickHouse: SET DEFAULT ROLE ... TO user - parse as command
|
|
24346
24381
|
if matches!(
|
|
24347
24382
|
self.config.dialect,
|