polyglot-sql 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/Cargo.lock +5 -5
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/Cargo.toml +1 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/PKG-INFO +1 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/Cargo.toml +1 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/builder.rs +16 -5
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/bigquery.rs +90 -9
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/clickhouse.rs +1 -2
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/databricks.rs +22 -9
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/datafusion.rs +3 -3
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/duckdb.rs +630 -136
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/exasol.rs +38 -33
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/hive.rs +6 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/mod.rs +3197 -2173
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/mysql.rs +22 -18
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/oracle.rs +12 -11
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/postgres.rs +84 -30
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/presto.rs +12 -6
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/snowflake.rs +252 -206
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/spark.rs +31 -19
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/sqlite.rs +8 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/teradata.rs +8 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/trino.rs +8 -5
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/tsql.rs +27 -20
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/diff.rs +6 -2
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/expressions.rs +385 -124
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/function_registry.rs +1 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/generator.rs +483 -204
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/lib.rs +2 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/lineage.rs +87 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/annotate_types.rs +3 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/canonicalize.rs +20 -20
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +3 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +100 -1
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/simplify.rs +29 -11
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/parser.rs +1324 -409
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/resolver.rs +19 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/schema.rs +15 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/tokens.rs +13 -6
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/transforms.rs +239 -88
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/traversal.rs +93 -4
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/validation.rs +14 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/expr.rs +15 -12
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/expr_types.rs +2 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/README.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/README.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/benches/in_list.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/benches/parsing.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/benches/transpile.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/examples/bench_json.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/error.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/function_catalog.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/helper.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/planner.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/scope.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/time.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/trie.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/src/validation/tests.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/common/mod.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/error_handling.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/README.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/Cargo.toml +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/README.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/docs/api.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/docs/index.md +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/mkdocs.yml +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/dialects.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/diff.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/errors.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/format.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/generate.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/helpers.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/lib.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/lineage.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/optimize.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/parse.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/transpile.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/types.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/src/validate.rs +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/conftest.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_format.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/crates/polyglot-sql-python/uv.lock +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/pyproject.toml +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/python/polyglot_sql/__init__.py +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/python/polyglot_sql/__init__.pyi +0 -0
- {polyglot_sql-0.2.0 → polyglot_sql-0.2.1}/python/polyglot_sql/py.typed +0 -0
|
@@ -587,7 +587,7 @@ dependencies = [
|
|
|
587
587
|
|
|
588
588
|
[[package]]
|
|
589
589
|
name = "polyglot-sql"
|
|
590
|
-
version = "0.2.
|
|
590
|
+
version = "0.2.1"
|
|
591
591
|
dependencies = [
|
|
592
592
|
"criterion",
|
|
593
593
|
"once_cell",
|
|
@@ -602,7 +602,7 @@ dependencies = [
|
|
|
602
602
|
|
|
603
603
|
[[package]]
|
|
604
604
|
name = "polyglot-sql-ffi"
|
|
605
|
-
version = "0.2.
|
|
605
|
+
version = "0.2.1"
|
|
606
606
|
dependencies = [
|
|
607
607
|
"cbindgen",
|
|
608
608
|
"polyglot-sql",
|
|
@@ -612,11 +612,11 @@ dependencies = [
|
|
|
612
612
|
|
|
613
613
|
[[package]]
|
|
614
614
|
name = "polyglot-sql-function-catalogs"
|
|
615
|
-
version = "0.2.
|
|
615
|
+
version = "0.2.1"
|
|
616
616
|
|
|
617
617
|
[[package]]
|
|
618
618
|
name = "polyglot-sql-python"
|
|
619
|
-
version = "0.2.
|
|
619
|
+
version = "0.2.1"
|
|
620
620
|
dependencies = [
|
|
621
621
|
"polyglot-sql",
|
|
622
622
|
"pyo3",
|
|
@@ -627,7 +627,7 @@ dependencies = [
|
|
|
627
627
|
|
|
628
628
|
[[package]]
|
|
629
629
|
name = "polyglot-sql-wasm"
|
|
630
|
-
version = "0.2.
|
|
630
|
+
version = "0.2.1"
|
|
631
631
|
dependencies = [
|
|
632
632
|
"console_error_panic_hook",
|
|
633
633
|
"js-sys",
|
|
@@ -78,7 +78,7 @@ serde_json = { workspace = true }
|
|
|
78
78
|
thiserror = { workspace = true }
|
|
79
79
|
unicode-segmentation = { workspace = true }
|
|
80
80
|
ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
|
|
81
|
-
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.2.
|
|
81
|
+
polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.2.1", optional = true, default-features = false }
|
|
82
82
|
|
|
83
83
|
[dev-dependencies]
|
|
84
84
|
pretty_assertions = "1.4"
|
|
@@ -1617,6 +1617,7 @@ impl SelectBuilder {
|
|
|
1617
1617
|
copy_grants: false,
|
|
1618
1618
|
using_template: None,
|
|
1619
1619
|
rollup: None,
|
|
1620
|
+
uuid: None,
|
|
1620
1621
|
}))
|
|
1621
1622
|
}
|
|
1622
1623
|
|
|
@@ -2328,7 +2329,9 @@ pub trait IntoLiteral {
|
|
|
2328
2329
|
impl IntoLiteral for &str {
|
|
2329
2330
|
/// Produce a SQL string literal (e.g. `'hello'`).
|
|
2330
2331
|
fn into_literal(self) -> Expr {
|
|
2331
|
-
Expr(Expression::Literal(Box::new(Literal::String(
|
|
2332
|
+
Expr(Expression::Literal(Box::new(Literal::String(
|
|
2333
|
+
self.to_string(),
|
|
2334
|
+
))))
|
|
2332
2335
|
}
|
|
2333
2336
|
}
|
|
2334
2337
|
|
|
@@ -2342,28 +2345,36 @@ impl IntoLiteral for String {
|
|
|
2342
2345
|
impl IntoLiteral for i64 {
|
|
2343
2346
|
/// Produce a SQL numeric literal from a 64-bit integer.
|
|
2344
2347
|
fn into_literal(self) -> Expr {
|
|
2345
|
-
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2348
|
+
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2349
|
+
self.to_string(),
|
|
2350
|
+
))))
|
|
2346
2351
|
}
|
|
2347
2352
|
}
|
|
2348
2353
|
|
|
2349
2354
|
impl IntoLiteral for i32 {
|
|
2350
2355
|
/// Produce a SQL numeric literal from a 32-bit integer.
|
|
2351
2356
|
fn into_literal(self) -> Expr {
|
|
2352
|
-
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2357
|
+
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2358
|
+
self.to_string(),
|
|
2359
|
+
))))
|
|
2353
2360
|
}
|
|
2354
2361
|
}
|
|
2355
2362
|
|
|
2356
2363
|
impl IntoLiteral for usize {
|
|
2357
2364
|
/// Produce a SQL numeric literal from a `usize`.
|
|
2358
2365
|
fn into_literal(self) -> Expr {
|
|
2359
|
-
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2366
|
+
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2367
|
+
self.to_string(),
|
|
2368
|
+
))))
|
|
2360
2369
|
}
|
|
2361
2370
|
}
|
|
2362
2371
|
|
|
2363
2372
|
impl IntoLiteral for f64 {
|
|
2364
2373
|
/// Produce a SQL numeric literal from a 64-bit float.
|
|
2365
2374
|
fn into_literal(self) -> Expr {
|
|
2366
|
-
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2375
|
+
Expr(Expression::Literal(Box::new(Literal::Number(
|
|
2376
|
+
self.to_string(),
|
|
2377
|
+
))))
|
|
2367
2378
|
}
|
|
2368
2379
|
}
|
|
2369
2380
|
|
|
@@ -523,8 +523,11 @@ impl DialectImpl for BigQueryDialect {
|
|
|
523
523
|
Expression::Split(f) => {
|
|
524
524
|
// Check if delimiter is empty or a placeholder - add default comma
|
|
525
525
|
let delimiter = match &f.delimiter {
|
|
526
|
-
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(s) if s.is_empty()) =>
|
|
527
|
-
|
|
526
|
+
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(s) if s.is_empty()) =>
|
|
527
|
+
{
|
|
528
|
+
let Literal::String(_) = lit.as_ref() else {
|
|
529
|
+
unreachable!()
|
|
530
|
+
};
|
|
528
531
|
Expression::Literal(Box::new(Literal::String(",".to_string())))
|
|
529
532
|
}
|
|
530
533
|
_ => f.delimiter,
|
|
@@ -537,16 +540,56 @@ impl DialectImpl for BigQueryDialect {
|
|
|
537
540
|
|
|
538
541
|
// Cast: Transform the target type according to BigQuery TYPE_MAPPING
|
|
539
542
|
// Special case: CAST to JSON -> PARSE_JSON in BigQuery
|
|
543
|
+
// Special case: CAST(x AS temporal FORMAT 'fmt') -> PARSE_DATE/PARSE_TIMESTAMP
|
|
540
544
|
Expression::Cast(c) => {
|
|
541
545
|
use crate::expressions::DataType;
|
|
542
546
|
// Check if casting to JSON - use PARSE_JSON instead
|
|
543
|
-
// Handle both DataType::Json/JsonB and DataType::Custom { name: "JSON" }
|
|
544
|
-
// (parser creates Custom for type literals like JSON 'string')
|
|
545
547
|
let is_json = matches!(c.to, DataType::Json | DataType::JsonB)
|
|
546
548
|
|| matches!(&c.to, DataType::Custom { name } if name.eq_ignore_ascii_case("JSON") || name.eq_ignore_ascii_case("JSONB"));
|
|
547
549
|
if is_json {
|
|
548
550
|
return Ok(Expression::ParseJson(Box::new(UnaryFunc::new(c.this))));
|
|
549
551
|
}
|
|
552
|
+
// CAST(x AS temporal_type FORMAT 'fmt') -> PARSE_DATE/PARSE_TIMESTAMP(strftime_fmt, x)
|
|
553
|
+
if c.format.is_some() {
|
|
554
|
+
let is_temporal = matches!(
|
|
555
|
+
c.to,
|
|
556
|
+
DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. }
|
|
557
|
+
) || matches!(&c.to, DataType::Custom { name } if
|
|
558
|
+
name.eq_ignore_ascii_case("TIMESTAMP") ||
|
|
559
|
+
name.eq_ignore_ascii_case("DATE") ||
|
|
560
|
+
name.eq_ignore_ascii_case("DATETIME") ||
|
|
561
|
+
name.eq_ignore_ascii_case("TIME")
|
|
562
|
+
);
|
|
563
|
+
if is_temporal {
|
|
564
|
+
let format_expr = c.format.as_ref().unwrap().as_ref();
|
|
565
|
+
// Extract the actual format expr and timezone (if AT TIME ZONE is present)
|
|
566
|
+
let (actual_format, timezone) = match format_expr {
|
|
567
|
+
Expression::AtTimeZone(ref atz) => {
|
|
568
|
+
(atz.this.clone(), Some(atz.zone.clone()))
|
|
569
|
+
}
|
|
570
|
+
_ => (format_expr.clone(), None),
|
|
571
|
+
};
|
|
572
|
+
let strftime_fmt = Self::bq_cast_format_to_strftime(&actual_format);
|
|
573
|
+
let func_name = match &c.to {
|
|
574
|
+
DataType::Date => "PARSE_DATE",
|
|
575
|
+
DataType::Custom { name } if name.eq_ignore_ascii_case("DATE") => {
|
|
576
|
+
"PARSE_DATE"
|
|
577
|
+
}
|
|
578
|
+
DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => {
|
|
579
|
+
"PARSE_DATETIME"
|
|
580
|
+
}
|
|
581
|
+
_ => "PARSE_TIMESTAMP",
|
|
582
|
+
};
|
|
583
|
+
let mut func_args = vec![strftime_fmt, c.this];
|
|
584
|
+
if let Some(tz) = timezone {
|
|
585
|
+
func_args.push(tz);
|
|
586
|
+
}
|
|
587
|
+
return Ok(Expression::Function(Box::new(Function::new(
|
|
588
|
+
func_name.to_string(),
|
|
589
|
+
func_args,
|
|
590
|
+
))));
|
|
591
|
+
}
|
|
592
|
+
}
|
|
550
593
|
let transformed_type = match self.transform_data_type(c.to)? {
|
|
551
594
|
Expression::DataType(dt) => dt,
|
|
552
595
|
_ => return Err(crate::error::Error::parse("Expected DataType", 0, 0, 0, 0)),
|
|
@@ -599,7 +642,8 @@ impl DialectImpl for BigQueryDialect {
|
|
|
599
642
|
if let Some(ref mut group_by) = select.group_by {
|
|
600
643
|
for grouped in group_by.expressions.iter_mut() {
|
|
601
644
|
// Skip numeric indices (already aliased)
|
|
602
|
-
if matches!(grouped, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
|
|
645
|
+
if matches!(grouped, Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_)))
|
|
646
|
+
{
|
|
603
647
|
continue;
|
|
604
648
|
}
|
|
605
649
|
// Check if this GROUP BY expression matches a SELECT alias
|
|
@@ -662,7 +706,9 @@ impl DialectImpl for BigQueryDialect {
|
|
|
662
706
|
})),
|
|
663
707
|
};
|
|
664
708
|
let inner_select = Expression::Select(Box::new(Select {
|
|
665
|
-
expressions: vec![Expression::Literal(Box::new(Literal::Number(
|
|
709
|
+
expressions: vec![Expression::Literal(Box::new(Literal::Number(
|
|
710
|
+
"1".to_string(),
|
|
711
|
+
)))],
|
|
666
712
|
from: Some(From {
|
|
667
713
|
expressions: vec![aliased_unnest],
|
|
668
714
|
}),
|
|
@@ -718,7 +764,9 @@ impl DialectImpl for BigQueryDialect {
|
|
|
718
764
|
Expression::JSONExtract(e) if e.variant_extract.is_some() => {
|
|
719
765
|
let path = match *e.expression {
|
|
720
766
|
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
|
|
721
|
-
let Literal::String(s) = lit.as_ref() else {
|
|
767
|
+
let Literal::String(s) = lit.as_ref() else {
|
|
768
|
+
unreachable!()
|
|
769
|
+
};
|
|
722
770
|
let normalized = if s.starts_with('$') {
|
|
723
771
|
s.clone()
|
|
724
772
|
} else if s.starts_with('[') {
|
|
@@ -1193,7 +1241,9 @@ impl BigQueryDialect {
|
|
|
1193
1241
|
// SPLIT(foo) -> SPLIT(foo, ',')
|
|
1194
1242
|
"SPLIT" if f.args.len() == 1 => {
|
|
1195
1243
|
let mut args = f.args;
|
|
1196
|
-
args.push(Expression::Literal(Box::new(Literal::String(
|
|
1244
|
+
args.push(Expression::Literal(Box::new(Literal::String(
|
|
1245
|
+
",".to_string(),
|
|
1246
|
+
))));
|
|
1197
1247
|
Ok(Expression::Split(Box::new(SplitFunc {
|
|
1198
1248
|
this: args.remove(0),
|
|
1199
1249
|
delimiter: args.remove(0),
|
|
@@ -1299,7 +1349,9 @@ impl BigQueryDialect {
|
|
|
1299
1349
|
let path = args.remove(0);
|
|
1300
1350
|
let json_path = match &path {
|
|
1301
1351
|
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::String(_)) => {
|
|
1302
|
-
let Literal::String(s) = lit.as_ref() else {
|
|
1352
|
+
let Literal::String(s) = lit.as_ref() else {
|
|
1353
|
+
unreachable!()
|
|
1354
|
+
};
|
|
1303
1355
|
let normalized = if s.starts_with('$') {
|
|
1304
1356
|
s.clone()
|
|
1305
1357
|
} else if s.starts_with('[') {
|
|
@@ -1399,6 +1451,35 @@ impl BigQueryDialect {
|
|
|
1399
1451
|
fn normalize_time_format(&self, format: &str) -> String {
|
|
1400
1452
|
format.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T")
|
|
1401
1453
|
}
|
|
1454
|
+
|
|
1455
|
+
/// Convert BigQuery CAST FORMAT elements to strftime equivalents,
|
|
1456
|
+
/// then normalize BigQuery shorthand forms (%Y-%m-%d -> %F, %H:%M:%S -> %T)
|
|
1457
|
+
fn bq_cast_format_to_strftime(format_expr: &Expression) -> Expression {
|
|
1458
|
+
use crate::expressions::Literal;
|
|
1459
|
+
if let Expression::Literal(lit) = format_expr {
|
|
1460
|
+
if let Literal::String(s) = lit.as_ref() {
|
|
1461
|
+
let result = s
|
|
1462
|
+
.replace("YYYYMMDD", "%Y%m%d")
|
|
1463
|
+
.replace("YYYY", "%Y")
|
|
1464
|
+
.replace("YY", "%y")
|
|
1465
|
+
.replace("MONTH", "%B")
|
|
1466
|
+
.replace("MON", "%b")
|
|
1467
|
+
.replace("MM", "%m")
|
|
1468
|
+
.replace("DD", "%d")
|
|
1469
|
+
.replace("HH24", "%H")
|
|
1470
|
+
.replace("HH12", "%I")
|
|
1471
|
+
.replace("HH", "%I")
|
|
1472
|
+
.replace("MI", "%M")
|
|
1473
|
+
.replace("SSTZH", "%S%z")
|
|
1474
|
+
.replace("SS", "%S")
|
|
1475
|
+
.replace("TZH", "%z");
|
|
1476
|
+
// Normalize: %Y-%m-%d -> %F, %H:%M:%S -> %T
|
|
1477
|
+
let normalized = result.replace("%Y-%m-%d", "%F").replace("%H:%M:%S", "%T");
|
|
1478
|
+
return Expression::Literal(Box::new(Literal::String(normalized)));
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
format_expr.clone()
|
|
1482
|
+
}
|
|
1402
1483
|
}
|
|
1403
1484
|
|
|
1404
1485
|
#[cfg(test)]
|
|
@@ -149,11 +149,14 @@ impl DialectImpl for DatabricksDialect {
|
|
|
149
149
|
Expression::DateSub(f) => {
|
|
150
150
|
// Convert string literals to numbers (interval values are often stored as strings)
|
|
151
151
|
let val = match f.interval {
|
|
152
|
-
Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::String(s) if s.parse::<i64>().is_ok())
|
|
153
|
-
=>
|
|
152
|
+
Expression::Literal(lit) if matches!(lit.as_ref(), crate::expressions::Literal::String(s) if s.parse::<i64>().is_ok()) =>
|
|
154
153
|
{
|
|
155
|
-
let crate::expressions::Literal::String(s) = lit.as_ref() else {
|
|
156
|
-
|
|
154
|
+
let crate::expressions::Literal::String(s) = lit.as_ref() else {
|
|
155
|
+
unreachable!()
|
|
156
|
+
};
|
|
157
|
+
Expression::Literal(Box::new(crate::expressions::Literal::Number(
|
|
158
|
+
s.clone(),
|
|
159
|
+
)))
|
|
157
160
|
}
|
|
158
161
|
other => other,
|
|
159
162
|
};
|
|
@@ -515,8 +518,12 @@ impl DatabricksDialect {
|
|
|
515
518
|
|
|
516
519
|
// Extract and strip the $. prefix from the path
|
|
517
520
|
let path_expr = match &path_arg {
|
|
518
|
-
Expression::Literal(lit)
|
|
519
|
-
|
|
521
|
+
Expression::Literal(lit)
|
|
522
|
+
if matches!(lit.as_ref(), crate::expressions::Literal::String(_)) =>
|
|
523
|
+
{
|
|
524
|
+
let crate::expressions::Literal::String(s) = lit.as_ref() else {
|
|
525
|
+
unreachable!()
|
|
526
|
+
};
|
|
520
527
|
// Strip leading '$.' if present
|
|
521
528
|
let stripped = if s.starts_with("$.") {
|
|
522
529
|
&s[2..]
|
|
@@ -819,7 +826,9 @@ impl DatabricksDialect {
|
|
|
819
826
|
match &c.this {
|
|
820
827
|
// TIMESTAMP 'value'::TYPE -> CAST(CAST('value' AS TYPE) AS TIMESTAMP)
|
|
821
828
|
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Timestamp(_)) => {
|
|
822
|
-
let Literal::Timestamp(value) = lit.as_ref() else {
|
|
829
|
+
let Literal::Timestamp(value) = lit.as_ref() else {
|
|
830
|
+
unreachable!()
|
|
831
|
+
};
|
|
823
832
|
// Create inner cast: CAST('value' AS target_type)
|
|
824
833
|
let inner_cast = Expression::Cast(Box::new(Cast {
|
|
825
834
|
this: Expression::Literal(Box::new(Literal::String(value.clone()))),
|
|
@@ -846,7 +855,9 @@ impl DatabricksDialect {
|
|
|
846
855
|
}
|
|
847
856
|
// DATE 'value'::TYPE -> CAST(CAST('value' AS TYPE) AS DATE)
|
|
848
857
|
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Date(_)) => {
|
|
849
|
-
let Literal::Date(value) = lit.as_ref() else {
|
|
858
|
+
let Literal::Date(value) = lit.as_ref() else {
|
|
859
|
+
unreachable!()
|
|
860
|
+
};
|
|
850
861
|
let inner_cast = Expression::Cast(Box::new(Cast {
|
|
851
862
|
this: Expression::Literal(Box::new(Literal::String(value.clone()))),
|
|
852
863
|
to: c.to,
|
|
@@ -868,7 +879,9 @@ impl DatabricksDialect {
|
|
|
868
879
|
}
|
|
869
880
|
// TIME 'value'::TYPE -> CAST(CAST('value' AS TYPE) AS TIME)
|
|
870
881
|
Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Time(_)) => {
|
|
871
|
-
let Literal::Time(value) = lit.as_ref() else {
|
|
882
|
+
let Literal::Time(value) = lit.as_ref() else {
|
|
883
|
+
unreachable!()
|
|
884
|
+
};
|
|
872
885
|
let inner_cast = Expression::Cast(Box::new(Cast {
|
|
873
886
|
this: Expression::Literal(Box::new(Literal::String(value.clone()))),
|
|
874
887
|
to: c.to,
|
|
@@ -113,9 +113,9 @@ impl DataFusionDialect {
|
|
|
113
113
|
// SQUARE(x) → POWER(x, 2)
|
|
114
114
|
"SQUARE" => {
|
|
115
115
|
let mut args = f.args;
|
|
116
|
-
args.push(Expression::Literal(Box::new(
|
|
117
|
-
"2".to_string(),
|
|
118
|
-
)))
|
|
116
|
+
args.push(Expression::Literal(Box::new(
|
|
117
|
+
crate::expressions::Literal::Number("2".to_string()),
|
|
118
|
+
)));
|
|
119
119
|
Ok(Expression::Function(Box::new(Function::new(
|
|
120
120
|
"power".to_string(),
|
|
121
121
|
args,
|