polyglot-sql 0.5.8__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.8 → polyglot_sql-0.5.10}/Cargo.lock +5 -5
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/Cargo.toml +1 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/PKG-INFO +1 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/duckdb.rs +40 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/generator.rs +27 -11
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/lineage.rs +86 -2
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/query_analysis.rs +3 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/resolver.rs +92 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/validation/tests.rs +23 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/query_analysis.rs +211 -1
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_lineage.py +17 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_query_analysis.py +70 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/README.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/README.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/ast_json.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/mod.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/lib.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/parser.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/scope.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/traversal.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue226_regression_test.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/pyproject.toml +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.5.8 → polyglot_sql-0.5.10}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.5.8 → 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
|
}
|
|
@@ -173,7 +173,14 @@ impl<'a> Resolver<'a> {
|
|
|
173
173
|
|
|
174
174
|
/// Extract column names from a source expression
|
|
175
175
|
fn extract_columns_from_source(&self, source_info: &SourceInfo) -> ResolverResult<Vec<String>> {
|
|
176
|
-
|
|
176
|
+
self.get_source_columns_for_expression(&source_info.expression)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fn get_source_columns_for_expression(
|
|
180
|
+
&self,
|
|
181
|
+
expression: &Expression,
|
|
182
|
+
) -> ResolverResult<Vec<String>> {
|
|
183
|
+
let columns = match expression {
|
|
177
184
|
Expression::Table(table) => {
|
|
178
185
|
// For tables, try to get columns from schema.
|
|
179
186
|
// Build the fully qualified name (catalog.schema.table) to
|
|
@@ -211,6 +218,17 @@ impl<'a> Resolver<'a> {
|
|
|
211
218
|
}
|
|
212
219
|
Expression::Pivot(pivot) => self.get_pivot_output_columns(pivot),
|
|
213
220
|
Expression::Unpivot(unpivot) => self.get_unpivot_output_columns(unpivot),
|
|
221
|
+
Expression::Alias(alias) if matches!(&alias.this, Expression::Unnest(_)) => {
|
|
222
|
+
alias_output_columns(alias)
|
|
223
|
+
}
|
|
224
|
+
Expression::Alias(alias) => {
|
|
225
|
+
let columns = self.get_source_columns_for_expression(&alias.this)?;
|
|
226
|
+
apply_alias_columns(columns, &alias.column_aliases)
|
|
227
|
+
}
|
|
228
|
+
Expression::Unnest(unnest) => unnest_output_columns(unnest),
|
|
229
|
+
Expression::Lateral(lateral) => lateral_output_columns(lateral),
|
|
230
|
+
Expression::LateralView(lateral_view) => lateral_view_output_columns(lateral_view),
|
|
231
|
+
Expression::Paren(paren) => self.get_source_columns_for_expression(&paren.this)?,
|
|
214
232
|
_ => Vec::new(),
|
|
215
233
|
};
|
|
216
234
|
|
|
@@ -228,6 +246,11 @@ impl<'a> Resolver<'a> {
|
|
|
228
246
|
Expression::Intersect(intersect) => self.get_named_selects(&intersect.left),
|
|
229
247
|
Expression::Except(except) => self.get_named_selects(&except.left),
|
|
230
248
|
Expression::Subquery(subquery) => self.get_named_selects(&subquery.this),
|
|
249
|
+
Expression::Alias(alias) => {
|
|
250
|
+
let columns = self.get_named_selects(&alias.this);
|
|
251
|
+
apply_alias_columns(columns, &alias.column_aliases)
|
|
252
|
+
}
|
|
253
|
+
Expression::Paren(paren) => self.get_named_selects(&paren.this),
|
|
231
254
|
_ => Vec::new(),
|
|
232
255
|
}
|
|
233
256
|
}
|
|
@@ -351,6 +374,16 @@ impl<'a> Resolver<'a> {
|
|
|
351
374
|
Expression::Union(_) | Expression::Intersect(_) | Expression::Except(_) => self
|
|
352
375
|
.get_source_columns_from_set_op(source)
|
|
353
376
|
.unwrap_or_default(),
|
|
377
|
+
Expression::Alias(alias) if matches!(&alias.this, Expression::Unnest(_)) => {
|
|
378
|
+
alias_output_columns(alias)
|
|
379
|
+
}
|
|
380
|
+
Expression::Alias(alias) => {
|
|
381
|
+
let columns = self.get_source_output_columns(&alias.this);
|
|
382
|
+
apply_alias_columns(columns, &alias.column_aliases)
|
|
383
|
+
}
|
|
384
|
+
Expression::Unnest(unnest) => unnest_output_columns(unnest),
|
|
385
|
+
Expression::Lateral(lateral) => lateral_output_columns(lateral),
|
|
386
|
+
Expression::LateralView(lateral_view) => lateral_view_output_columns(lateral_view),
|
|
354
387
|
Expression::Cte(cte) => {
|
|
355
388
|
if cte.columns.is_empty() {
|
|
356
389
|
self.get_named_selects(&cte.this)
|
|
@@ -383,6 +416,11 @@ impl<'a> Resolver<'a> {
|
|
|
383
416
|
Ok(self.get_named_selects(&subquery.this))
|
|
384
417
|
}
|
|
385
418
|
}
|
|
419
|
+
Expression::Alias(alias) => {
|
|
420
|
+
let columns = self.get_source_columns_from_set_op(&alias.this)?;
|
|
421
|
+
Ok(apply_alias_columns(columns, &alias.column_aliases))
|
|
422
|
+
}
|
|
423
|
+
Expression::Paren(paren) => self.get_source_columns_from_set_op(&paren.this),
|
|
386
424
|
Expression::Union(union) => {
|
|
387
425
|
// Standard UNION: columns come from the left side
|
|
388
426
|
self.get_source_columns_from_set_op(&union.left)
|
|
@@ -540,6 +578,59 @@ fn apply_alias_columns(mut columns: Vec<String>, alias_columns: &[Identifier]) -
|
|
|
540
578
|
columns
|
|
541
579
|
}
|
|
542
580
|
|
|
581
|
+
fn unnest_output_columns(unnest: &crate::expressions::UnnestFunc) -> Vec<String> {
|
|
582
|
+
unnest
|
|
583
|
+
.alias
|
|
584
|
+
.iter()
|
|
585
|
+
.map(|alias| alias.name.clone())
|
|
586
|
+
.chain(unnest.offset_alias.iter().map(|alias| alias.name.clone()))
|
|
587
|
+
.collect()
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
fn alias_output_columns(alias: &crate::expressions::Alias) -> Vec<String> {
|
|
591
|
+
if alias.column_aliases.is_empty() {
|
|
592
|
+
vec![alias.alias.name.clone()]
|
|
593
|
+
} else {
|
|
594
|
+
alias
|
|
595
|
+
.column_aliases
|
|
596
|
+
.iter()
|
|
597
|
+
.map(|column| column.name.clone())
|
|
598
|
+
.collect()
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
fn lateral_output_columns(lateral: &crate::expressions::Lateral) -> Vec<String> {
|
|
603
|
+
if lateral.column_aliases.is_empty() {
|
|
604
|
+
default_virtual_output_columns(&lateral.this)
|
|
605
|
+
} else {
|
|
606
|
+
lateral.column_aliases.clone()
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
fn lateral_view_output_columns(lateral_view: &crate::expressions::LateralView) -> Vec<String> {
|
|
611
|
+
lateral_view
|
|
612
|
+
.column_aliases
|
|
613
|
+
.iter()
|
|
614
|
+
.map(|column| column.name.clone())
|
|
615
|
+
.collect()
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
fn default_virtual_output_columns(expression: &Expression) -> Vec<String> {
|
|
619
|
+
match expression {
|
|
620
|
+
Expression::Unnest(unnest) => unnest_output_columns(unnest),
|
|
621
|
+
Expression::Alias(alias) if matches!(&alias.this, Expression::Unnest(_)) => {
|
|
622
|
+
alias_output_columns(alias)
|
|
623
|
+
}
|
|
624
|
+
Expression::Function(function) if function.name.eq_ignore_ascii_case("FLATTEN") => {
|
|
625
|
+
["seq", "key", "path", "index", "value", "this"]
|
|
626
|
+
.into_iter()
|
|
627
|
+
.map(String::from)
|
|
628
|
+
.collect()
|
|
629
|
+
}
|
|
630
|
+
_ => Vec::new(),
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
543
634
|
fn pivot_excluded_source_columns(
|
|
544
635
|
pivot: &crate::expressions::Pivot,
|
|
545
636
|
dialect: Option<DialectType>,
|
|
@@ -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();
|