polyglot-sql 0.5.9__tar.gz → 0.5.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/Cargo.lock +5 -5
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/Cargo.toml +1 -1
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/PKG-INFO +1 -1
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/duckdb.rs +40 -1
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/generator.rs +27 -11
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/lineage.rs +86 -2
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/query_analysis.rs +3 -1
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/validation/tests.rs +23 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/query_analysis.rs +112 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_lineage.py +17 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_query_analysis.py +30 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/README.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/README.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/ast_json.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/mod.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/lib.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/parser.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/scope.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/traversal.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue226_regression_test.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/pyproject.toml +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/python/polyglot_sql/py.typed +0 -0
|
@@ -605,7 +605,7 @@ dependencies = [
|
|
|
605
605
|
|
|
606
606
|
[[package]]
|
|
607
607
|
name = "polyglot-sql"
|
|
608
|
-
version = "0.5.
|
|
608
|
+
version = "0.5.10"
|
|
609
609
|
dependencies = [
|
|
610
610
|
"criterion",
|
|
611
611
|
"once_cell",
|
|
@@ -621,7 +621,7 @@ dependencies = [
|
|
|
621
621
|
|
|
622
622
|
[[package]]
|
|
623
623
|
name = "polyglot-sql-ffi"
|
|
624
|
-
version = "0.5.
|
|
624
|
+
version = "0.5.10"
|
|
625
625
|
dependencies = [
|
|
626
626
|
"cbindgen",
|
|
627
627
|
"polyglot-sql",
|
|
@@ -631,11 +631,11 @@ dependencies = [
|
|
|
631
631
|
|
|
632
632
|
[[package]]
|
|
633
633
|
name = "polyglot-sql-function-catalogs"
|
|
634
|
-
version = "0.5.
|
|
634
|
+
version = "0.5.10"
|
|
635
635
|
|
|
636
636
|
[[package]]
|
|
637
637
|
name = "polyglot-sql-python"
|
|
638
|
-
version = "0.5.
|
|
638
|
+
version = "0.5.10"
|
|
639
639
|
dependencies = [
|
|
640
640
|
"polyglot-sql",
|
|
641
641
|
"pyo3",
|
|
@@ -646,7 +646,7 @@ dependencies = [
|
|
|
646
646
|
|
|
647
647
|
[[package]]
|
|
648
648
|
name = "polyglot-sql-wasm"
|
|
649
|
-
version = "0.5.
|
|
649
|
+
version = "0.5.10"
|
|
650
650
|
dependencies = [
|
|
651
651
|
"console_error_panic_hook",
|
|
652
652
|
"js-sys",
|
|
@@ -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.10", optional = true, default-features = false }
|
|
110
110
|
|
|
111
111
|
[dev-dependencies]
|
|
112
112
|
pretty_assertions = "1.4"
|
|
@@ -1068,6 +1068,11 @@ impl DialectImpl for DuckDBDialect {
|
|
|
1068
1068
|
// WithinGroup: PERCENTILE_CONT/DISC WITHIN GROUP (ORDER BY ...) -> QUANTILE_CONT/DISC(col, quantile ORDER BY ...)
|
|
1069
1069
|
Expression::WithinGroup(wg) => {
|
|
1070
1070
|
match &wg.this {
|
|
1071
|
+
Expression::ListAgg(listagg) => {
|
|
1072
|
+
let mut listagg = listagg.clone();
|
|
1073
|
+
listagg.order_by = Some(wg.order_by.clone());
|
|
1074
|
+
Ok(Expression::ListAgg(listagg))
|
|
1075
|
+
}
|
|
1071
1076
|
Expression::PercentileCont(p) => {
|
|
1072
1077
|
let column = wg
|
|
1073
1078
|
.order_by
|
|
@@ -7496,7 +7501,11 @@ mod tests {
|
|
|
7496
7501
|
use crate::dialects::Dialect;
|
|
7497
7502
|
|
|
7498
7503
|
fn transpile_to_duckdb(sql: &str) -> String {
|
|
7499
|
-
|
|
7504
|
+
transpile_to_duckdb_from(sql, DialectType::Generic)
|
|
7505
|
+
}
|
|
7506
|
+
|
|
7507
|
+
fn transpile_to_duckdb_from(sql: &str, read: DialectType) -> String {
|
|
7508
|
+
let dialect = Dialect::get(read);
|
|
7500
7509
|
let result = dialect
|
|
7501
7510
|
.transpile(sql, DialectType::DuckDB)
|
|
7502
7511
|
.expect("Transpile failed");
|
|
@@ -7550,6 +7559,36 @@ mod tests {
|
|
|
7550
7559
|
);
|
|
7551
7560
|
}
|
|
7552
7561
|
|
|
7562
|
+
#[test]
|
|
7563
|
+
fn test_ordered_string_agg_uses_duckdb_listagg_order_syntax() {
|
|
7564
|
+
let result = transpile_to_duckdb_from(
|
|
7565
|
+
"SELECT string_agg(nm, ',' ORDER BY id) AS v FROM t",
|
|
7566
|
+
DialectType::PostgreSQL,
|
|
7567
|
+
);
|
|
7568
|
+
assert_eq!(result, "SELECT LISTAGG(nm, ',' ORDER BY id) AS v FROM t");
|
|
7569
|
+
}
|
|
7570
|
+
|
|
7571
|
+
#[test]
|
|
7572
|
+
fn test_ordered_listagg_uses_duckdb_order_syntax() {
|
|
7573
|
+
let result = transpile_to_duckdb_from(
|
|
7574
|
+
"SELECT LISTAGG(col, '|SEPARATOR|') WITHIN GROUP (ORDER BY col2) FROM t",
|
|
7575
|
+
DialectType::Snowflake,
|
|
7576
|
+
);
|
|
7577
|
+
assert_eq!(
|
|
7578
|
+
result,
|
|
7579
|
+
"SELECT LISTAGG(col, '|SEPARATOR|' ORDER BY col2) FROM t"
|
|
7580
|
+
);
|
|
7581
|
+
}
|
|
7582
|
+
|
|
7583
|
+
#[test]
|
|
7584
|
+
fn test_ordered_group_concat_uses_duckdb_listagg_order_syntax() {
|
|
7585
|
+
let result = transpile_to_duckdb_from(
|
|
7586
|
+
"SELECT GROUP_CONCAT(nm ORDER BY id SEPARATOR ',') AS v FROM t",
|
|
7587
|
+
DialectType::MySQL,
|
|
7588
|
+
);
|
|
7589
|
+
assert_eq!(result, "SELECT LISTAGG(nm, ',' ORDER BY id) AS v FROM t");
|
|
7590
|
+
}
|
|
7591
|
+
|
|
7553
7592
|
#[test]
|
|
7554
7593
|
fn test_date_format_to_strftime() {
|
|
7555
7594
|
let result = transpile_to_duckdb("SELECT DATE_FORMAT(d, '%Y-%m-%d')");
|
|
@@ -20369,6 +20369,7 @@ impl Generator {
|
|
|
20369
20369
|
|
|
20370
20370
|
fn generate_listagg(&mut self, f: &ListAggFunc) -> Result<()> {
|
|
20371
20371
|
use crate::dialects::DialectType;
|
|
20372
|
+
let order_inside_args = matches!(self.config.dialect, Some(DialectType::DuckDB));
|
|
20372
20373
|
self.write_keyword("LISTAGG");
|
|
20373
20374
|
self.write("(");
|
|
20374
20375
|
if f.distinct {
|
|
@@ -20408,20 +20409,35 @@ impl Generator {
|
|
|
20408
20409
|
}
|
|
20409
20410
|
}
|
|
20410
20411
|
}
|
|
20412
|
+
if order_inside_args {
|
|
20413
|
+
if let Some(ref order_by) = f.order_by {
|
|
20414
|
+
self.write_space();
|
|
20415
|
+
self.write_keyword("ORDER BY");
|
|
20416
|
+
self.write_space();
|
|
20417
|
+
for (i, ord) in order_by.iter().enumerate() {
|
|
20418
|
+
if i > 0 {
|
|
20419
|
+
self.write(", ");
|
|
20420
|
+
}
|
|
20421
|
+
self.generate_ordered(ord)?;
|
|
20422
|
+
}
|
|
20423
|
+
}
|
|
20424
|
+
}
|
|
20411
20425
|
self.write(")");
|
|
20412
|
-
if
|
|
20413
|
-
|
|
20414
|
-
|
|
20415
|
-
|
|
20416
|
-
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
|
|
20420
|
-
|
|
20426
|
+
if !order_inside_args {
|
|
20427
|
+
if let Some(ref order_by) = f.order_by {
|
|
20428
|
+
self.write_space();
|
|
20429
|
+
self.write_keyword("WITHIN GROUP");
|
|
20430
|
+
self.write(" (");
|
|
20431
|
+
self.write_keyword("ORDER BY");
|
|
20432
|
+
self.write_space();
|
|
20433
|
+
for (i, ord) in order_by.iter().enumerate() {
|
|
20434
|
+
if i > 0 {
|
|
20435
|
+
self.write(", ");
|
|
20436
|
+
}
|
|
20437
|
+
self.generate_ordered(ord)?;
|
|
20421
20438
|
}
|
|
20422
|
-
self.
|
|
20439
|
+
self.write(")");
|
|
20423
20440
|
}
|
|
20424
|
-
self.write(")");
|
|
20425
20441
|
}
|
|
20426
20442
|
if let Some(ref filter) = f.filter {
|
|
20427
20443
|
self.write_space();
|
|
@@ -194,9 +194,11 @@ pub fn lineage_with_schema(
|
|
|
194
194
|
let normalized_expression = lineage_normalized_expression(sql);
|
|
195
195
|
let mut qualified_expression = if let Some(schema) = schema {
|
|
196
196
|
let options = if let Some(dialect_type) = dialect.or_else(|| schema.dialect()) {
|
|
197
|
-
QualifyColumnsOptions::new().with_dialect(dialect_type)
|
|
198
|
-
} else {
|
|
199
197
|
QualifyColumnsOptions::new()
|
|
198
|
+
.with_dialect(dialect_type)
|
|
199
|
+
.with_allow_partial(true)
|
|
200
|
+
} else {
|
|
201
|
+
QualifyColumnsOptions::new().with_allow_partial(true)
|
|
200
202
|
};
|
|
201
203
|
|
|
202
204
|
qualify_columns(normalized_expression.clone(), schema, &options).map_err(|e| {
|
|
@@ -3705,6 +3707,88 @@ mod tests {
|
|
|
3705
3707
|
assert_eq!(expr_with.inferred_type(), Some(&DataType::Text));
|
|
3706
3708
|
}
|
|
3707
3709
|
|
|
3710
|
+
#[test]
|
|
3711
|
+
fn test_lineage_with_schema_tolerates_partial_schema_for_known_column() {
|
|
3712
|
+
let expr = parse_dialect("SELECT order_id, amount FROM t", DialectType::DuckDB);
|
|
3713
|
+
let mut schema = MappingSchema::with_dialect(DialectType::DuckDB);
|
|
3714
|
+
schema
|
|
3715
|
+
.add_table(
|
|
3716
|
+
"t",
|
|
3717
|
+
&[("amount".into(), DataType::BigInt { length: None })],
|
|
3718
|
+
None,
|
|
3719
|
+
)
|
|
3720
|
+
.expect("schema setup");
|
|
3721
|
+
|
|
3722
|
+
let node = lineage_with_schema(
|
|
3723
|
+
"amount",
|
|
3724
|
+
&expr,
|
|
3725
|
+
Some(&schema),
|
|
3726
|
+
Some(DialectType::DuckDB),
|
|
3727
|
+
false,
|
|
3728
|
+
)
|
|
3729
|
+
.expect("lineage_with_schema should tolerate unrelated unknown columns");
|
|
3730
|
+
|
|
3731
|
+
assert_lineage_contains(&node, "t.amount");
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
#[test]
|
|
3735
|
+
fn test_lineage_with_schema_tolerates_partial_schema_for_unknown_column() {
|
|
3736
|
+
let expr = parse_dialect("SELECT order_id, amount FROM t", DialectType::DuckDB);
|
|
3737
|
+
let mut schema = MappingSchema::with_dialect(DialectType::DuckDB);
|
|
3738
|
+
schema
|
|
3739
|
+
.add_table(
|
|
3740
|
+
"t",
|
|
3741
|
+
&[("amount".into(), DataType::BigInt { length: None })],
|
|
3742
|
+
None,
|
|
3743
|
+
)
|
|
3744
|
+
.expect("schema setup");
|
|
3745
|
+
|
|
3746
|
+
let node = lineage_with_schema(
|
|
3747
|
+
"order_id",
|
|
3748
|
+
&expr,
|
|
3749
|
+
Some(&schema),
|
|
3750
|
+
Some(DialectType::DuckDB),
|
|
3751
|
+
false,
|
|
3752
|
+
)
|
|
3753
|
+
.expect("lineage_with_schema should keep unknown selected columns");
|
|
3754
|
+
|
|
3755
|
+
assert_lineage_contains(&node, "t.order_id");
|
|
3756
|
+
}
|
|
3757
|
+
|
|
3758
|
+
#[test]
|
|
3759
|
+
fn test_lineage_with_schema_tolerates_partial_schema_for_join_conditions() {
|
|
3760
|
+
let expr = parse_dialect(
|
|
3761
|
+
"SELECT a.order_id, b.amount FROM t a JOIN u b ON a.id = b.id",
|
|
3762
|
+
DialectType::DuckDB,
|
|
3763
|
+
);
|
|
3764
|
+
let mut schema = MappingSchema::with_dialect(DialectType::DuckDB);
|
|
3765
|
+
schema
|
|
3766
|
+
.add_table(
|
|
3767
|
+
"t",
|
|
3768
|
+
&[("order_id".into(), DataType::BigInt { length: None })],
|
|
3769
|
+
None,
|
|
3770
|
+
)
|
|
3771
|
+
.expect("schema setup");
|
|
3772
|
+
schema
|
|
3773
|
+
.add_table(
|
|
3774
|
+
"u",
|
|
3775
|
+
&[("amount".into(), DataType::BigInt { length: None })],
|
|
3776
|
+
None,
|
|
3777
|
+
)
|
|
3778
|
+
.expect("schema setup");
|
|
3779
|
+
|
|
3780
|
+
let node = lineage_with_schema(
|
|
3781
|
+
"amount",
|
|
3782
|
+
&expr,
|
|
3783
|
+
Some(&schema),
|
|
3784
|
+
Some(DialectType::DuckDB),
|
|
3785
|
+
false,
|
|
3786
|
+
)
|
|
3787
|
+
.expect("lineage_with_schema should tolerate unknown join keys");
|
|
3788
|
+
|
|
3789
|
+
assert_lineage_contains(&node, "b.amount");
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3708
3792
|
#[test]
|
|
3709
3793
|
fn test_lineage_with_schema_correlated_scalar_subquery() {
|
|
3710
3794
|
let query = "SELECT id, (SELECT AVG(val) FROM t2 WHERE t2.id = t1.id) AS avg_val FROM t1";
|
|
@@ -187,7 +187,9 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
|
|
|
187
187
|
let star_projections = star_projection_facts(&original_expression, mapping_schema.as_ref());
|
|
188
188
|
|
|
189
189
|
if let Some(schema) = mapping_schema.as_ref() {
|
|
190
|
-
let qualify_options = QualifyColumnsOptions::new()
|
|
190
|
+
let qualify_options = QualifyColumnsOptions::new()
|
|
191
|
+
.with_dialect(options.dialect)
|
|
192
|
+
.with_allow_partial(true);
|
|
191
193
|
expression = qualify_columns(expression, schema, &qualify_options)
|
|
192
194
|
.map_err(|e| Error::internal(format!("query analysis qualification failed: {e}")))?;
|
|
193
195
|
}
|
|
@@ -217,6 +217,29 @@ fn test_validate_with_schema_unknown_column() {
|
|
|
217
217
|
);
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
#[test]
|
|
221
|
+
fn test_validate_with_schema_partial_schema_stays_strict() {
|
|
222
|
+
let mut schema = base_schema();
|
|
223
|
+
let users = schema
|
|
224
|
+
.tables
|
|
225
|
+
.iter_mut()
|
|
226
|
+
.find(|table| table.name == "users")
|
|
227
|
+
.expect("users table");
|
|
228
|
+
users.columns.retain(|column| column.name == "id");
|
|
229
|
+
|
|
230
|
+
let opts = SchemaValidationOptions::default();
|
|
231
|
+
let result = validate_with_schema(
|
|
232
|
+
"SELECT id, name FROM users",
|
|
233
|
+
DialectType::Generic,
|
|
234
|
+
&schema,
|
|
235
|
+
&opts,
|
|
236
|
+
);
|
|
237
|
+
assert!(!result.valid);
|
|
238
|
+
assert!(result.errors.iter().any(|error| {
|
|
239
|
+
error.code == validation_codes::E_UNKNOWN_COLUMN && error.message.contains("name")
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
|
|
220
243
|
#[test]
|
|
221
244
|
fn test_validate_with_schema_function_catalog_unknown_function() {
|
|
222
245
|
let schema = base_schema();
|
|
@@ -736,6 +736,118 @@ fn analyze_query_resolves_unnest_virtual_output_aliases_with_schema() {
|
|
|
736
736
|
}
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
+
#[test]
|
|
740
|
+
fn analyze_query_tolerates_partial_schema_for_unknown_columns() {
|
|
741
|
+
let analysis = analyze_query(
|
|
742
|
+
"SELECT order_id, amount FROM t",
|
|
743
|
+
AnalyzeQueryOptions {
|
|
744
|
+
dialect: DialectType::DuckDB,
|
|
745
|
+
schema: Some(single_column_schema(&["t"], "amount")),
|
|
746
|
+
},
|
|
747
|
+
)
|
|
748
|
+
.unwrap();
|
|
749
|
+
|
|
750
|
+
assert_eq!(analysis.projections.len(), 2);
|
|
751
|
+
assert_eq!(analysis.projections[0].name.as_deref(), Some("order_id"));
|
|
752
|
+
assert_eq!(analysis.projections[1].name.as_deref(), Some("amount"));
|
|
753
|
+
|
|
754
|
+
let order_id = &analysis.projections[0].upstream;
|
|
755
|
+
assert!(
|
|
756
|
+
order_id.iter().any(|reference| {
|
|
757
|
+
reference.column == "order_id"
|
|
758
|
+
&& reference.confidence == ReferenceConfidence::Resolved
|
|
759
|
+
&& reference.source_name.as_deref() == Some("t")
|
|
760
|
+
&& reference.table.as_deref() == Some("t")
|
|
761
|
+
}),
|
|
762
|
+
"expected best-effort order_id reference, got {order_id:?}"
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
let amount = &analysis.projections[1].upstream;
|
|
766
|
+
assert!(
|
|
767
|
+
amount.iter().any(|reference| {
|
|
768
|
+
reference.column == "amount"
|
|
769
|
+
&& reference.confidence == ReferenceConfidence::Resolved
|
|
770
|
+
&& reference.table.as_deref() == Some("t")
|
|
771
|
+
}),
|
|
772
|
+
"expected schema-backed amount reference, got {amount:?}"
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
#[test]
|
|
777
|
+
fn analyze_query_tolerates_partial_schema_for_qualified_unknown_columns() {
|
|
778
|
+
let analysis = analyze_query(
|
|
779
|
+
"SELECT t.order_id, t.amount FROM t",
|
|
780
|
+
AnalyzeQueryOptions {
|
|
781
|
+
dialect: DialectType::DuckDB,
|
|
782
|
+
schema: Some(single_column_schema(&["t"], "amount")),
|
|
783
|
+
},
|
|
784
|
+
)
|
|
785
|
+
.unwrap();
|
|
786
|
+
|
|
787
|
+
assert!(
|
|
788
|
+
analysis.projections[0].upstream.iter().any(|reference| {
|
|
789
|
+
reference.column == "order_id"
|
|
790
|
+
&& reference.confidence == ReferenceConfidence::Resolved
|
|
791
|
+
&& reference.table.as_deref() == Some("t")
|
|
792
|
+
}),
|
|
793
|
+
"expected qualified unknown column to stay as best-effort t.order_id, got {:?}",
|
|
794
|
+
analysis.projections[0].upstream
|
|
795
|
+
);
|
|
796
|
+
assert!(
|
|
797
|
+
analysis.projections[1].upstream.iter().any(|reference| {
|
|
798
|
+
reference.column == "amount" && reference.table.as_deref() == Some("t")
|
|
799
|
+
}),
|
|
800
|
+
"expected known t.amount to resolve, got {:?}",
|
|
801
|
+
analysis.projections[1].upstream
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
#[test]
|
|
806
|
+
fn analyze_query_tolerates_partial_schema_for_join_conditions() {
|
|
807
|
+
let schema: ValidationSchema = serde_json::from_value(json!({
|
|
808
|
+
"tables": [
|
|
809
|
+
{
|
|
810
|
+
"name": "t",
|
|
811
|
+
"columns": [{"name": "order_id", "type": "INT"}]
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
"name": "u",
|
|
815
|
+
"columns": [{"name": "amount", "type": "INT"}]
|
|
816
|
+
}
|
|
817
|
+
]
|
|
818
|
+
}))
|
|
819
|
+
.unwrap();
|
|
820
|
+
|
|
821
|
+
let analysis = analyze_query(
|
|
822
|
+
"SELECT a.order_id, b.amount FROM t a JOIN u b ON a.id = b.id",
|
|
823
|
+
AnalyzeQueryOptions {
|
|
824
|
+
dialect: DialectType::DuckDB,
|
|
825
|
+
schema: Some(schema),
|
|
826
|
+
},
|
|
827
|
+
)
|
|
828
|
+
.unwrap();
|
|
829
|
+
|
|
830
|
+
assert_eq!(analysis.projections.len(), 2);
|
|
831
|
+
assert!(
|
|
832
|
+
analysis.projections[0].upstream.iter().any(|reference| {
|
|
833
|
+
reference.column == "order_id"
|
|
834
|
+
&& reference.source_alias.as_deref() == Some("a")
|
|
835
|
+
&& reference.table.as_deref() == Some("t")
|
|
836
|
+
}),
|
|
837
|
+
"expected a.order_id to resolve, got {:?}",
|
|
838
|
+
analysis.projections[0].upstream
|
|
839
|
+
);
|
|
840
|
+
assert!(
|
|
841
|
+
analysis.projections[1].upstream.iter().any(|reference| {
|
|
842
|
+
reference.column == "amount"
|
|
843
|
+
&& reference.source_alias.as_deref() == Some("b")
|
|
844
|
+
&& reference.table.as_deref() == Some("u")
|
|
845
|
+
}),
|
|
846
|
+
"expected b.amount to resolve, got {:?}",
|
|
847
|
+
analysis.projections[1].upstream
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
|
|
739
851
|
#[test]
|
|
740
852
|
fn analyze_query_resolves_same_select_alias_reference() {
|
|
741
853
|
let analysis = analyze_query(
|
|
@@ -113,6 +113,23 @@ def test_lineage_with_schema_resolves_ambiguous_column():
|
|
|
113
113
|
assert any(name == "u.id" for name in names), f"expected u.id in lineage tree, got: {names}"
|
|
114
114
|
|
|
115
115
|
|
|
116
|
+
def test_lineage_with_schema_tolerates_partial_schema():
|
|
117
|
+
schema = {
|
|
118
|
+
"tables": [
|
|
119
|
+
{
|
|
120
|
+
"name": "t",
|
|
121
|
+
"columns": [{"name": "amount", "type": "INT"}],
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
result = polyglot_sql.lineage_with_schema(
|
|
126
|
+
"amount", "SELECT order_id, amount FROM t", schema, dialect="duckdb"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
names = collect_names(result)
|
|
130
|
+
assert "t.amount" in names
|
|
131
|
+
|
|
132
|
+
|
|
116
133
|
def test_bigquery_unnest_lineage_marks_virtual_source():
|
|
117
134
|
sql = """
|
|
118
135
|
SELECT date_val AS week_start
|
{polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_query_analysis.py
RENAMED
|
@@ -35,6 +35,36 @@ def test_analyze_query_accepts_schema_options():
|
|
|
35
35
|
assert result["projections"][0]["castType"] == "TEXT"
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def test_analyze_query_tolerates_partial_schema():
|
|
39
|
+
schema = {
|
|
40
|
+
"tables": [
|
|
41
|
+
{
|
|
42
|
+
"name": "t",
|
|
43
|
+
"columns": [{"name": "amount", "type": "INT"}],
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
result = polyglot_sql.analyze_query(
|
|
48
|
+
"SELECT order_id, amount FROM t",
|
|
49
|
+
{"schema": schema, "dialect": "duckdb"},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
assert [projection["name"] for projection in result["projections"]] == [
|
|
53
|
+
"order_id",
|
|
54
|
+
"amount",
|
|
55
|
+
]
|
|
56
|
+
assert any(
|
|
57
|
+
reference["column"] == "order_id"
|
|
58
|
+
and reference["table"] == "t"
|
|
59
|
+
and reference["confidence"] == "resolved"
|
|
60
|
+
for reference in result["projections"][0]["upstream"]
|
|
61
|
+
)
|
|
62
|
+
assert any(
|
|
63
|
+
reference["column"] == "amount" and reference["table"] == "t"
|
|
64
|
+
for reference in result["projections"][1]["upstream"]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
38
68
|
def test_analyze_query_reports_transform_function_arguments():
|
|
39
69
|
schema = {
|
|
40
70
|
"tables": [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyglot_sql-0.5.9 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/annotate_types.rs
RENAMED
|
File without changes
|