polyglot-sql 0.5.1__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.1 → polyglot_sql-0.5.2}/Cargo.lock +5 -5
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/Cargo.toml +1 -1
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/PKG-INFO +12 -4
- {polyglot_sql-0.5.1/crates/polyglot-sql-python → polyglot_sql-0.5.2}/README.md +11 -3
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/README.md +17 -3
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lineage.rs +22 -2
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +43 -7
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/query_analysis.rs +153 -5
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/scope.rs +5 -1
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/traversal.rs +15 -2
- polyglot_sql-0.5.2/crates/polyglot-sql/tests/query_analysis.rs +340 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2/crates/polyglot-sql-python}/README.md +11 -3
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/index.md +18 -3
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_query_analysis.py +26 -0
- polyglot_sql-0.5.1/crates/polyglot-sql/tests/query_analysis.rs +0 -143
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/builder.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mod.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/diff.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/expressions.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_registry.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/generator.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lib.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/parser.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/resolver.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/schema.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/tokens.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/transforms.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue226_regression_test.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transforms.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/pyproject.toml +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.5.1 → 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
|
|
@@ -125,22 +125,30 @@ emission are intentionally out of scope.
|
|
|
125
125
|
|
|
126
126
|
```python
|
|
127
127
|
analysis = polyglot_sql.analyze_query(
|
|
128
|
-
"SELECT
|
|
128
|
+
"SELECT SUM(o.amount) AS total FROM orders AS o",
|
|
129
129
|
{
|
|
130
130
|
"dialect": "generic",
|
|
131
131
|
"schema": {
|
|
132
132
|
"tables": [
|
|
133
133
|
{
|
|
134
134
|
"name": "orders",
|
|
135
|
-
"columns": [{"name": "
|
|
135
|
+
"columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
|
|
136
136
|
}
|
|
137
137
|
]
|
|
138
138
|
},
|
|
139
139
|
},
|
|
140
140
|
)
|
|
141
|
-
print(analysis["projections"][0]["transformKind"]) # "
|
|
141
|
+
print(analysis["projections"][0]["transformKind"]) # "aggregation"
|
|
142
|
+
print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
|
|
143
|
+
print(analysis["baseTables"][0]["name"]) # "orders"
|
|
142
144
|
```
|
|
143
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
|
+
|
|
144
152
|
## API Reference
|
|
145
153
|
|
|
146
154
|
All functions are exported from `polyglot_sql`.
|
|
@@ -98,22 +98,30 @@ emission are intentionally out of scope.
|
|
|
98
98
|
|
|
99
99
|
```python
|
|
100
100
|
analysis = polyglot_sql.analyze_query(
|
|
101
|
-
"SELECT
|
|
101
|
+
"SELECT SUM(o.amount) AS total FROM orders AS o",
|
|
102
102
|
{
|
|
103
103
|
"dialect": "generic",
|
|
104
104
|
"schema": {
|
|
105
105
|
"tables": [
|
|
106
106
|
{
|
|
107
107
|
"name": "orders",
|
|
108
|
-
"columns": [{"name": "
|
|
108
|
+
"columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
|
|
109
109
|
}
|
|
110
110
|
]
|
|
111
111
|
},
|
|
112
112
|
},
|
|
113
113
|
)
|
|
114
|
-
print(analysis["projections"][0]["transformKind"]) # "
|
|
114
|
+
print(analysis["projections"][0]["transformKind"]) # "aggregation"
|
|
115
|
+
print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
|
|
116
|
+
print(analysis["baseTables"][0]["name"]) # "orders"
|
|
115
117
|
```
|
|
116
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
|
+
|
|
117
125
|
## API Reference
|
|
118
126
|
|
|
119
127
|
All functions are exported from `polyglot_sql`.
|
|
@@ -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"
|
|
@@ -313,21 +313,35 @@ Schema-aware validation emits stable codes such as:
|
|
|
313
313
|
### Compact Query Analysis
|
|
314
314
|
|
|
315
315
|
Use `analyze_query` when you need high-level facts without consuming the full AST
|
|
316
|
-
or full lineage graph
|
|
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.
|
|
317
321
|
|
|
318
322
|
```rust
|
|
319
323
|
use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
|
|
320
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
|
+
|
|
321
332
|
let analysis = analyze_query(
|
|
322
|
-
"SELECT o.
|
|
333
|
+
"SELECT SUM(o.amount) AS total FROM orders o",
|
|
323
334
|
AnalyzeQueryOptions {
|
|
324
335
|
dialect: DialectType::Generic,
|
|
325
|
-
schema:
|
|
336
|
+
schema: Some(schema),
|
|
326
337
|
},
|
|
327
338
|
).unwrap();
|
|
328
339
|
|
|
329
340
|
assert_eq!(analysis.shape, QueryShape::Select);
|
|
330
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"));
|
|
331
345
|
```
|
|
332
346
|
|
|
333
347
|
### Tokenize
|
|
@@ -772,12 +772,32 @@ fn to_node_inner(
|
|
|
772
772
|
apply_scope_context(&mut node, scope, source_name, reference_node_name);
|
|
773
773
|
|
|
774
774
|
// 5. Star handling — add downstream for each source
|
|
775
|
-
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());
|
|
776
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
|
+
|
|
777
797
|
let mut child = LineageNode::new(
|
|
778
798
|
format!("{}.*", name),
|
|
779
799
|
Expression::Star(crate::expressions::Star {
|
|
780
|
-
table:
|
|
800
|
+
table: star.table.clone(),
|
|
781
801
|
except: None,
|
|
782
802
|
replace: None,
|
|
783
803
|
rename: None,
|
{polyglot_sql-0.5.1 → 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
|
}
|
|
@@ -11,11 +11,11 @@ use crate::expressions::{DataType, Expression, TableRef, With};
|
|
|
11
11
|
use crate::lineage::{lineage_by_index_from_expression, LineageNode};
|
|
12
12
|
use crate::optimizer::annotate_types::annotate_types;
|
|
13
13
|
use crate::optimizer::qualify_columns::{qualify_columns, QualifyColumnsOptions};
|
|
14
|
-
use crate::schema::Schema;
|
|
14
|
+
use crate::schema::{MappingSchema, Schema};
|
|
15
15
|
use crate::scope::{build_scope, Scope, SourceInfo, SourceKind};
|
|
16
16
|
use crate::traversal::{contains_aggregate, ExpressionWalk};
|
|
17
17
|
use crate::validation::{mapping_schema_from_validation_schema, ValidationSchema};
|
|
18
|
-
use crate::{parse_one, Error, Result};
|
|
18
|
+
use crate::{parse_data_type, parse_one, Error, Result};
|
|
19
19
|
use serde::{Deserialize, Serialize};
|
|
20
20
|
use std::collections::HashSet;
|
|
21
21
|
|
|
@@ -37,6 +37,7 @@ pub struct QueryAnalysis {
|
|
|
37
37
|
pub ctes: Vec<String>,
|
|
38
38
|
pub projections: Vec<ProjectionFact>,
|
|
39
39
|
pub relations: Vec<RelationFact>,
|
|
40
|
+
pub base_tables: Vec<RelationFact>,
|
|
40
41
|
pub set_operations: Vec<SetOperationFact>,
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -134,7 +135,7 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
|
|
|
134
135
|
let mapping_schema = options
|
|
135
136
|
.schema
|
|
136
137
|
.as_ref()
|
|
137
|
-
.map(
|
|
138
|
+
.map(|schema| analysis_mapping_schema(schema, options.dialect));
|
|
138
139
|
|
|
139
140
|
if let Some(schema) = mapping_schema.as_ref() {
|
|
140
141
|
let qualify_options = QualifyColumnsOptions::new().with_dialect(options.dialect);
|
|
@@ -142,12 +143,31 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
|
|
|
142
143
|
.map_err(|e| Error::internal(format!("query analysis qualification failed: {e}")))?;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
let annotation_schema = mapping_schema.as_ref().map(|schema| {
|
|
147
|
+
let mut alias_schema = schema.clone();
|
|
148
|
+
add_scope_aliases_to_schema(
|
|
149
|
+
&build_scope(&expression),
|
|
150
|
+
schema,
|
|
151
|
+
&mut alias_schema,
|
|
152
|
+
options.dialect,
|
|
153
|
+
);
|
|
154
|
+
alias_schema
|
|
155
|
+
});
|
|
156
|
+
|
|
145
157
|
annotate_types(
|
|
146
158
|
&mut expression,
|
|
147
|
-
|
|
159
|
+
annotation_schema
|
|
160
|
+
.as_ref()
|
|
161
|
+
.map(|schema| schema as &dyn Schema),
|
|
148
162
|
Some(options.dialect),
|
|
149
163
|
);
|
|
150
|
-
crate::lineage::expand_cte_stars(
|
|
164
|
+
crate::lineage::expand_cte_stars(
|
|
165
|
+
&mut expression,
|
|
166
|
+
annotation_schema
|
|
167
|
+
.as_ref()
|
|
168
|
+
.or(mapping_schema.as_ref())
|
|
169
|
+
.map(|schema| schema as &dyn Schema),
|
|
170
|
+
);
|
|
151
171
|
|
|
152
172
|
let scope = build_scope(&expression);
|
|
153
173
|
let shape = if is_set_operation(&expression) {
|
|
@@ -161,10 +181,106 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
|
|
|
161
181
|
ctes: collect_cte_names(&expression),
|
|
162
182
|
projections: projection_facts_for_query(&expression, &scope, options.dialect),
|
|
163
183
|
relations: relation_facts(&scope, mapping_schema.as_ref()),
|
|
184
|
+
base_tables: base_table_facts(&scope, mapping_schema.as_ref()),
|
|
164
185
|
set_operations: set_operation_facts(&expression, &scope, options.dialect),
|
|
165
186
|
})
|
|
166
187
|
}
|
|
167
188
|
|
|
189
|
+
fn analysis_mapping_schema(schema: &ValidationSchema, dialect: DialectType) -> MappingSchema {
|
|
190
|
+
let broad_schema = mapping_schema_from_validation_schema(schema);
|
|
191
|
+
let mut mapping_schema = MappingSchema::with_dialect(dialect);
|
|
192
|
+
|
|
193
|
+
for table in &schema.tables {
|
|
194
|
+
let table_names = validation_table_names(table);
|
|
195
|
+
if table_names.is_empty() {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
let fallback_table = table_names[0].as_str();
|
|
200
|
+
let columns: Vec<(String, DataType)> = table
|
|
201
|
+
.columns
|
|
202
|
+
.iter()
|
|
203
|
+
.map(|column| {
|
|
204
|
+
let data_type = parse_analysis_data_type(&column.data_type, dialect)
|
|
205
|
+
.unwrap_or_else(|| {
|
|
206
|
+
broad_schema
|
|
207
|
+
.get_column_type(fallback_table, &column.name)
|
|
208
|
+
.unwrap_or(DataType::Unknown)
|
|
209
|
+
});
|
|
210
|
+
(column.name.to_ascii_lowercase(), data_type)
|
|
211
|
+
})
|
|
212
|
+
.collect();
|
|
213
|
+
|
|
214
|
+
for table_name in table_names {
|
|
215
|
+
let _ = mapping_schema.add_table(&table_name, &columns, Some(dialect));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
mapping_schema
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
fn validation_table_names(table: &crate::validation::SchemaTable) -> Vec<String> {
|
|
223
|
+
let mut names = Vec::new();
|
|
224
|
+
|
|
225
|
+
names.push(table.name.to_ascii_lowercase());
|
|
226
|
+
if let Some(schema_name) = &table.schema {
|
|
227
|
+
names.push(format!(
|
|
228
|
+
"{}.{}",
|
|
229
|
+
schema_name.to_ascii_lowercase(),
|
|
230
|
+
table.name.to_ascii_lowercase()
|
|
231
|
+
));
|
|
232
|
+
}
|
|
233
|
+
for alias in &table.aliases {
|
|
234
|
+
names.push(alias.to_ascii_lowercase());
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
names.sort();
|
|
238
|
+
names.dedup();
|
|
239
|
+
names
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
fn parse_analysis_data_type(data_type: &str, dialect: DialectType) -> Option<DataType> {
|
|
243
|
+
let trimmed = data_type.trim();
|
|
244
|
+
if trimmed.is_empty() {
|
|
245
|
+
return None;
|
|
246
|
+
}
|
|
247
|
+
parse_data_type(trimmed, dialect).ok()
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
fn add_scope_aliases_to_schema(
|
|
251
|
+
scope: &Scope,
|
|
252
|
+
source_schema: &MappingSchema,
|
|
253
|
+
target_schema: &mut MappingSchema,
|
|
254
|
+
dialect: DialectType,
|
|
255
|
+
) {
|
|
256
|
+
for child_scope in scope.traverse() {
|
|
257
|
+
for (source_name, source) in &child_scope.sources {
|
|
258
|
+
if source.kind != SourceKind::Table {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if let Some(table_name) = source_table_name(source) {
|
|
262
|
+
if source_name == &table_name {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
if let Ok(column_names) = source_schema.column_names(&table_name) {
|
|
266
|
+
let columns: Vec<(String, DataType)> = column_names
|
|
267
|
+
.iter()
|
|
268
|
+
.map(|column| {
|
|
269
|
+
(
|
|
270
|
+
column.clone(),
|
|
271
|
+
source_schema
|
|
272
|
+
.get_column_type(&table_name, column)
|
|
273
|
+
.unwrap_or(DataType::Unknown),
|
|
274
|
+
)
|
|
275
|
+
})
|
|
276
|
+
.collect();
|
|
277
|
+
let _ = target_schema.add_table(source_name, &columns, Some(dialect));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
168
284
|
fn effective_query(expression: Expression) -> Expression {
|
|
169
285
|
match expression {
|
|
170
286
|
Expression::Prepare(prepare) => prepare.statement,
|
|
@@ -621,6 +737,38 @@ fn collect_relation_facts(
|
|
|
621
737
|
}
|
|
622
738
|
}
|
|
623
739
|
|
|
740
|
+
fn base_table_facts(
|
|
741
|
+
scope: &Scope,
|
|
742
|
+
mapping_schema: Option<&crate::schema::MappingSchema>,
|
|
743
|
+
) -> Vec<RelationFact> {
|
|
744
|
+
let mut relations = Vec::new();
|
|
745
|
+
let mut seen = HashSet::new();
|
|
746
|
+
|
|
747
|
+
for child_scope in scope.traverse() {
|
|
748
|
+
for source in child_scope.sources.values() {
|
|
749
|
+
if source.kind != SourceKind::Table {
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
let Some(table_name) = source_table_name(source) else {
|
|
754
|
+
continue;
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
if seen.insert(table_name.clone()) {
|
|
758
|
+
relations.push(RelationFact {
|
|
759
|
+
name: table_name,
|
|
760
|
+
alias: source.alias.clone().or_else(|| source_alias(source)),
|
|
761
|
+
kind: SourceKind::Table,
|
|
762
|
+
columns: source_columns(source, mapping_schema),
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
relations.sort_by(|left, right| left.name.cmp(&right.name));
|
|
769
|
+
relations
|
|
770
|
+
}
|
|
771
|
+
|
|
624
772
|
fn source_columns(
|
|
625
773
|
source: &SourceInfo,
|
|
626
774
|
mapping_schema: Option<&crate::schema::MappingSchema>,
|
|
@@ -726,7 +726,11 @@ fn add_table_to_scope(expr: &Expression, scope: &mut Scope) {
|
|
|
726
726
|
if let Some(source) = cte_source {
|
|
727
727
|
scope.add_source_info(name, source.clone());
|
|
728
728
|
} else {
|
|
729
|
-
|
|
729
|
+
let mut source = SourceInfo::new(expr.clone(), false, SourceKind::Table);
|
|
730
|
+
if let Some(alias) = &table.alias {
|
|
731
|
+
source = source.with_alias(alias.name.clone());
|
|
732
|
+
}
|
|
733
|
+
scope.add_source_info(name, source);
|
|
730
734
|
}
|
|
731
735
|
}
|
|
732
736
|
Expression::Subquery(subquery) => {
|
|
@@ -1098,9 +1098,22 @@ pub fn is_select(expr: &Expression) -> bool {
|
|
|
1098
1098
|
matches!(expr, Expression::Select(_))
|
|
1099
1099
|
}
|
|
1100
1100
|
|
|
1101
|
-
/// Returns `true` if `expr` is an aggregate function
|
|
1101
|
+
/// Returns `true` if `expr` is an aggregate function.
|
|
1102
1102
|
pub fn is_aggregate(expr: &Expression) -> bool {
|
|
1103
|
-
matches!(
|
|
1103
|
+
matches!(
|
|
1104
|
+
expr,
|
|
1105
|
+
Expression::AggregateFunction(_)
|
|
1106
|
+
| Expression::Count(_)
|
|
1107
|
+
| Expression::Sum(_)
|
|
1108
|
+
| Expression::Avg(_)
|
|
1109
|
+
| Expression::Min(_)
|
|
1110
|
+
| Expression::Max(_)
|
|
1111
|
+
| Expression::GroupConcat(_)
|
|
1112
|
+
| Expression::StringAgg(_)
|
|
1113
|
+
| Expression::ListAgg(_)
|
|
1114
|
+
| Expression::CountIf(_)
|
|
1115
|
+
| Expression::SumIf(_)
|
|
1116
|
+
)
|
|
1104
1117
|
}
|
|
1105
1118
|
|
|
1106
1119
|
/// Returns `true` if `expr` is a window function ([`Expression::WindowFunction`]).
|