polyglot-sql 0.3.3__tar.gz → 0.3.4__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.
Files changed (167) hide show
  1. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/Cargo.lock +5 -5
  2. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/Cargo.toml +1 -1
  3. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/PKG-INFO +1 -1
  4. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/Cargo.toml +1 -1
  5. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/builder.rs +1 -0
  6. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/databricks.rs +106 -0
  7. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/fabric.rs +11 -22
  8. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/hive.rs +6 -0
  9. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/mod.rs +97 -3
  10. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/mysql.rs +23 -0
  11. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/snowflake.rs +31 -0
  12. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/spark.rs +6 -0
  13. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/tsql.rs +86 -4
  14. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/expressions.rs +4 -0
  15. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/generator.rs +69 -54
  16. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/parser.rs +196 -16
  17. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/dialect_matrix.rs +84 -0
  18. polyglot_sql-0.3.4/crates/polyglot-sql/tests/fabric_regression.rs +85 -0
  19. polyglot_sql-0.3.4/crates/polyglot-sql/tests/tsql_regression.rs +85 -0
  20. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/README.md +0 -0
  21. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/README.md +0 -0
  22. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/benches/in_list.rs +0 -0
  23. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/benches/parsing.rs +0 -0
  24. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  25. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/benches/transpile.rs +0 -0
  26. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  27. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  28. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  29. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  30. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  31. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  32. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  33. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  34. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  35. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  36. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  37. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  38. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
  39. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  40. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  41. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  42. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  43. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  44. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
  45. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  46. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  47. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  48. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  49. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  50. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  51. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  52. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  53. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  54. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  55. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  56. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/diff.rs +0 -0
  57. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/error.rs +0 -0
  58. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  59. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/function_registry.rs +0 -0
  60. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/helper.rs +0 -0
  61. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/lib.rs +0 -0
  62. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/lineage.rs +0 -0
  63. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  64. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  65. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  66. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  67. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  68. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  69. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  70. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  71. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  72. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  73. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  74. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  75. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
  76. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  77. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  78. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  79. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/planner.rs +0 -0
  80. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/resolver.rs +0 -0
  81. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/schema.rs +0 -0
  82. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/scope.rs +0 -0
  83. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/time.rs +0 -0
  84. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/tokens.rs +0 -0
  85. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/transforms.rs +0 -0
  86. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/traversal.rs +0 -0
  87. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/trie.rs +0 -0
  88. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  89. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/src/validation.rs +0 -0
  90. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  91. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  92. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  93. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  94. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  95. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  96. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  97. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  98. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  99. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  100. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  101. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  102. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  103. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  104. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  105. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  106. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  107. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  108. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  109. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  110. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  111. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  112. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  113. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  114. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  115. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  116. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  117. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  118. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  119. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  120. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  121. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  122. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  123. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  124. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  125. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  126. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  127. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  128. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  129. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/Cargo.toml +0 -0
  130. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/README.md +0 -0
  131. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/docs/api.md +0 -0
  132. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/docs/index.md +0 -0
  133. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  134. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  135. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  136. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/diff.rs +0 -0
  137. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/errors.rs +0 -0
  138. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/expr.rs +0 -0
  139. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  140. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/format.rs +0 -0
  141. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/generate.rs +0 -0
  142. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  143. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/lib.rs +0 -0
  144. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  145. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  146. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/parse.rs +0 -0
  147. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  148. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  149. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/types.rs +0 -0
  150. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/src/validate.rs +0 -0
  151. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  152. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  153. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  154. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  155. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  156. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  157. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  158. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  159. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  160. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
  161. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  162. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  163. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/crates/polyglot-sql-python/uv.lock +0 -0
  164. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/pyproject.toml +0 -0
  165. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/python/polyglot_sql/__init__.py +0 -0
  166. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/python/polyglot_sql/__init__.pyi +0 -0
  167. {polyglot_sql-0.3.3 → polyglot_sql-0.3.4}/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.3.3"
608
+ version = "0.3.4"
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.3.3"
624
+ version = "0.3.4"
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.3.3"
634
+ version = "0.3.4"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.3.3"
638
+ version = "0.3.4"
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.3.3"
649
+ version = "0.3.4"
650
650
  dependencies = [
651
651
  "console_error_panic_hook",
652
652
  "js-sys",
@@ -6,7 +6,7 @@ exclude = [
6
6
  ]
7
7
 
8
8
  [workspace.package]
9
- version = "0.3.3"
9
+ version = "0.3.4"
10
10
  edition = "2021"
11
11
  license = "MIT"
12
12
  authors = ["polyglot contributors"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyglot-sql
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -83,7 +83,7 @@ thiserror = { workspace = true }
83
83
  unicode-segmentation = { workspace = true }
84
84
  stacker = { version = "0.1", optional = true }
85
85
  ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
86
- polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.3", optional = true, default-features = false }
86
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.4", optional = true, default-features = false }
87
87
 
88
88
  [dev-dependencies]
89
89
  pretty_assertions = "1.4"
@@ -1603,6 +1603,7 @@ impl SelectBuilder {
1603
1603
  clone_at_clause: None,
1604
1604
  is_copy: false,
1605
1605
  shallow_clone: false,
1606
+ deep_clone: false,
1606
1607
  leading_comments: vec![],
1607
1608
  with_properties: vec![],
1608
1609
  teradata_post_name_options: vec![],
@@ -37,6 +37,12 @@ impl DialectImpl for DatabricksDialect {
37
37
  config
38
38
  .keywords
39
39
  .insert("DIV".to_string(), crate::tokens::TokenType::Div);
40
+ config
41
+ .keywords
42
+ .insert("REPAIR".to_string(), crate::tokens::TokenType::Command);
43
+ config
44
+ .keywords
45
+ .insert("MSCK".to_string(), crate::tokens::TokenType::Command);
40
46
  // Databricks numeric literal suffixes (same as Hive/Spark)
41
47
  config
42
48
  .numeric_literals
@@ -1009,4 +1015,104 @@ mod tests {
1009
1015
  "FROM_UTC_TIMESTAMP with existing CAST failed"
1010
1016
  );
1011
1017
  }
1018
+
1019
+ #[test]
1020
+ fn test_deep_clone_version_as_of() {
1021
+ let sql = "CREATE TABLE events_clone DEEP CLONE events VERSION AS OF 5";
1022
+ let d = Dialect::get(DialectType::Databricks);
1023
+ let ast = d.parse(sql).expect("Parse failed");
1024
+ let output = d.generate(&ast[0]).expect("Generate failed");
1025
+
1026
+ assert_eq!(output, sql);
1027
+ }
1028
+
1029
+ #[test]
1030
+ fn test_deep_clone_timestamp_as_of() {
1031
+ let sql = "CREATE TABLE events_clone DEEP CLONE events TIMESTAMP AS OF '2024-01-01'";
1032
+ let d = Dialect::get(DialectType::Databricks);
1033
+ let ast = d.parse(sql).expect("Parse failed");
1034
+ let output = d.generate(&ast[0]).expect("Generate failed");
1035
+
1036
+ assert_eq!(output, sql);
1037
+ }
1038
+
1039
+ #[test]
1040
+ fn test_shallow_clone_still_roundtrips() {
1041
+ let sql = "CREATE TABLE events_clone SHALLOW CLONE events";
1042
+ let d = Dialect::get(DialectType::Databricks);
1043
+ let ast = d.parse(sql).expect("Parse failed");
1044
+ let output = d.generate(&ast[0]).expect("Generate failed");
1045
+
1046
+ assert_eq!(output, sql);
1047
+ }
1048
+
1049
+ #[test]
1050
+ fn test_repair_table_commands_roundtrip() {
1051
+ let d = Dialect::get(DialectType::Databricks);
1052
+ let cases = [
1053
+ "REPAIR TABLE events",
1054
+ "MSCK REPAIR TABLE events",
1055
+ "REPAIR TABLE events ADD PARTITIONS",
1056
+ "REPAIR TABLE events DROP PARTITIONS",
1057
+ "REPAIR TABLE events SYNC PARTITIONS",
1058
+ "REPAIR TABLE events SYNC METADATA",
1059
+ ];
1060
+
1061
+ for sql in cases {
1062
+ let ast = d.parse(sql).expect("Parse failed");
1063
+ let output = d.generate(&ast[0]).expect("Generate failed");
1064
+ assert_eq!(output, sql);
1065
+ }
1066
+ }
1067
+
1068
+ #[test]
1069
+ fn test_apply_changes_commands_roundtrip() {
1070
+ let d = Dialect::get(DialectType::Databricks);
1071
+ let cases = [
1072
+ "APPLY CHANGES INTO silver.orders FROM STREAM(bronze.orders) KEYS (id) SEQUENCE BY ts",
1073
+ "APPLY CHANGES INTO LIVE.silver_orders FROM STREAM(LIVE.bronze_orders) KEYS (id) IGNORE NULL UPDATES SEQUENCE BY ts",
1074
+ "APPLY CHANGES INTO LIVE.silver_orders FROM STREAM(LIVE.bronze_orders) KEYS (id) APPLY AS DELETE WHEN operation = 'DELETE' SEQUENCE BY ts COLUMNS * EXCEPT (operation) STORED AS SCD TYPE 1",
1075
+ "APPLY CHANGES INTO LIVE.silver_orders FROM STREAM(LIVE.bronze_orders) KEYS (id) SEQUENCE BY ts STORED AS SCD TYPE 2 TRACK HISTORY ON * EXCEPT (updated_at)",
1076
+ "AUTO CDC INTO silver.orders FROM STREAM(bronze.orders) KEYS (id) SEQUENCE BY ts",
1077
+ "CREATE FLOW apply_cdc AS AUTO CDC INTO silver.orders FROM STREAM(bronze.orders) KEYS (id) SEQUENCE BY ts",
1078
+ ];
1079
+
1080
+ for sql in cases {
1081
+ let ast = d.parse(sql).expect("Parse failed");
1082
+ let output = d.generate(&ast[0]).expect("Generate failed");
1083
+ assert_eq!(output, sql);
1084
+ }
1085
+ }
1086
+
1087
+ #[test]
1088
+ fn test_generate_symlink_format_manifest_roundtrip() {
1089
+ let d = Dialect::get(DialectType::Databricks);
1090
+ let cases = [
1091
+ "GENERATE symlink_format_manifest FOR TABLE events",
1092
+ "GENERATE symlink_format_manifest FOR TABLE catalog.schema.events",
1093
+ ];
1094
+
1095
+ for sql in cases {
1096
+ let ast = d.parse(sql).expect("Parse failed");
1097
+ let output = d.generate(&ast[0]).expect("Generate failed");
1098
+ assert_eq!(output, sql);
1099
+ }
1100
+ }
1101
+
1102
+ #[test]
1103
+ fn test_convert_to_delta_roundtrip() {
1104
+ let d = Dialect::get(DialectType::Databricks);
1105
+ let cases = [
1106
+ "CONVERT TO DELTA parquet.`/mnt/data/events`",
1107
+ "CONVERT TO DELTA database_name.table_name",
1108
+ "CONVERT TO DELTA parquet.`s3://my-bucket/path/to/table` PARTITIONED BY (date DATE)",
1109
+ "CONVERT TO DELTA database_name.table_name NO STATISTICS",
1110
+ ];
1111
+
1112
+ for sql in cases {
1113
+ let ast = d.parse(sql).expect("Parse failed");
1114
+ let output = d.generate(&ast[0]).expect("Generate failed");
1115
+ assert_eq!(output, sql);
1116
+ }
1117
+ }
1012
1118
  }
@@ -42,6 +42,7 @@ impl DialectImpl for FabricDialect {
42
42
  identifier_quote: '[',
43
43
  identifier_quote_style: IdentifierQuoteStyle::BRACKET,
44
44
  dialect: Some(DialectType::Fabric),
45
+ null_ordering_supported: false,
45
46
  ..Default::default()
46
47
  }
47
48
  }
@@ -63,7 +64,14 @@ impl DialectImpl for FabricDialect {
63
64
  }
64
65
  _ => {}
65
66
  }
66
- // Also transform column data types through Fabric's type mappings
67
+ // Also transform column data types through Fabric's type mappings.
68
+ // Apply TSQL normalisation first (e.g. BPCHAR → Char), then Fabric-specific.
69
+ let tsql = TSQLDialect;
70
+ if let Ok(Expression::DataType(tsql_dt)) =
71
+ tsql.transform_data_type(col.data_type.clone())
72
+ {
73
+ col.data_type = tsql_dt;
74
+ }
67
75
  if let Expression::DataType(new_dt) =
68
76
  self.transform_fabric_data_type(col.data_type.clone())?
69
77
  {
@@ -361,7 +369,8 @@ impl FabricDialect {
361
369
  let upper = name.to_uppercase();
362
370
 
363
371
  // Parse out precision and scale if present: "TYPENAME(n)" or "TYPENAME(n, m)"
364
- let (base_name, precision, scale) = Self::parse_type_precision_and_scale(&upper);
372
+ let (base_name, precision, scale) =
373
+ TSQLDialect::parse_type_precision_and_scale(&upper);
365
374
 
366
375
  match base_name.as_str() {
367
376
  // DATETIME -> DATETIME2(6)
@@ -518,24 +527,4 @@ impl FabricDialect {
518
527
  None => max, // Default to max if not specified
519
528
  }
520
529
  }
521
-
522
- /// Parse type name and optional precision/scale from strings like "DATETIME2(7)" or "NUMERIC(10, 2)"
523
- fn parse_type_precision_and_scale(name: &str) -> (String, Option<u32>, Option<u32>) {
524
- if let Some(paren_pos) = name.find('(') {
525
- let base = name[..paren_pos].to_string();
526
- let rest = &name[paren_pos + 1..];
527
- if let Some(close_pos) = rest.find(')') {
528
- let args = &rest[..close_pos];
529
- let parts: Vec<&str> = args.split(',').map(|s| s.trim()).collect();
530
-
531
- let precision = parts.first().and_then(|s| s.parse::<u32>().ok());
532
- let scale = parts.get(1).and_then(|s| s.parse::<u32>().ok());
533
-
534
- return (base, precision, scale);
535
- }
536
- (base, None, None)
537
- } else {
538
- (name.to_string(), None, None)
539
- }
540
- }
541
530
  }
@@ -42,6 +42,12 @@ impl DialectImpl for HiveDialect {
42
42
  config
43
43
  .keywords
44
44
  .insert("DIV".to_string(), crate::tokens::TokenType::Div);
45
+ config
46
+ .keywords
47
+ .insert("REPAIR".to_string(), crate::tokens::TokenType::Command);
48
+ config
49
+ .keywords
50
+ .insert("MSCK".to_string(), crate::tokens::TokenType::Command);
45
51
  // Hive numeric literal suffixes: 1L -> BIGINT, 1S -> SMALLINT, etc.
46
52
  config
47
53
  .numeric_literals
@@ -158,7 +158,7 @@ pub use trino::TrinoDialect;
158
158
  pub use tsql::TSQLDialect;
159
159
 
160
160
  use crate::error::Result;
161
- use crate::expressions::{Expression, FunctionBody, Null};
161
+ use crate::expressions::{Expression, Function, FunctionBody, Identifier, Null};
162
162
  use crate::generator::{Generator, GeneratorConfig};
163
163
  use crate::parser::Parser;
164
164
  use crate::tokens::{Token, Tokenizer, TokenizerConfig};
@@ -9067,6 +9067,11 @@ impl Dialect {
9067
9067
  match action {
9068
9068
  Action::None => {
9069
9069
  // Handle inline transforms that don't need a dedicated action
9070
+ if matches!(target, DialectType::TSQL | DialectType::Fabric) {
9071
+ if let Some(rewritten) = Self::rewrite_tsql_interval_arithmetic(&e) {
9072
+ return Ok(rewritten);
9073
+ }
9074
+ }
9070
9075
 
9071
9076
  // BETWEEN SYMMETRIC/ASYMMETRIC expansion for non-PostgreSQL/Dremio targets
9072
9077
  if let Expression::Between(ref b) = e {
@@ -31321,6 +31326,7 @@ impl Dialect {
31321
31326
  clone_source: None,
31322
31327
  clone_at_clause: None,
31323
31328
  shallow_clone: false,
31329
+ deep_clone: false,
31324
31330
  is_copy: false,
31325
31331
  leading_comments: Vec::new(),
31326
31332
  with_properties: Vec::new(),
@@ -31897,7 +31903,9 @@ impl Dialect {
31897
31903
  // Return just the numeric part as value and parsed unit
31898
31904
  return (
31899
31905
  Expression::Literal(Box::new(
31900
- crate::expressions::Literal::String(parts[0].to_string()),
31906
+ crate::expressions::Literal::String(
31907
+ parts[0].trim().to_string(),
31908
+ ),
31901
31909
  )),
31902
31910
  parsed_unit,
31903
31911
  );
@@ -31919,6 +31927,88 @@ impl Dialect {
31919
31927
  }
31920
31928
  }
31921
31929
 
31930
+ fn rewrite_tsql_interval_arithmetic(expr: &Expression) -> Option<Expression> {
31931
+ match expr {
31932
+ Expression::Add(op) => {
31933
+ let Expression::Interval(_) = &op.right else {
31934
+ return None;
31935
+ };
31936
+ Some(Self::build_tsql_dateadd_from_interval(
31937
+ op.left.clone(),
31938
+ &op.right,
31939
+ false,
31940
+ ))
31941
+ }
31942
+ Expression::Sub(op) => {
31943
+ let Expression::Interval(_) = &op.right else {
31944
+ return None;
31945
+ };
31946
+ Some(Self::build_tsql_dateadd_from_interval(
31947
+ op.left.clone(),
31948
+ &op.right,
31949
+ true,
31950
+ ))
31951
+ }
31952
+ _ => None,
31953
+ }
31954
+ }
31955
+
31956
+ fn build_tsql_dateadd_from_interval(
31957
+ date: Expression,
31958
+ interval: &Expression,
31959
+ subtract: bool,
31960
+ ) -> Expression {
31961
+ let (value, unit) = Self::extract_interval_parts(interval);
31962
+ let unit = Self::interval_unit_to_string(&unit);
31963
+ let amount = Self::tsql_dateadd_amount(value, subtract);
31964
+
31965
+ Expression::Function(Box::new(Function::new(
31966
+ "DATEADD".to_string(),
31967
+ vec![Expression::Identifier(Identifier::new(unit)), amount, date],
31968
+ )))
31969
+ }
31970
+
31971
+ fn tsql_dateadd_amount(value: Expression, negate: bool) -> Expression {
31972
+ use crate::expressions::UnaryOp;
31973
+
31974
+ fn numeric_literal_value(value: &Expression) -> Option<&str> {
31975
+ match value {
31976
+ Expression::Literal(lit) => match lit.as_ref() {
31977
+ crate::expressions::Literal::Number(n)
31978
+ | crate::expressions::Literal::String(n) => Some(n.as_str()),
31979
+ _ => None,
31980
+ },
31981
+ _ => None,
31982
+ }
31983
+ }
31984
+
31985
+ if let Some(n) = numeric_literal_value(&value) {
31986
+ if let Ok(parsed) = n.parse::<f64>() {
31987
+ let normalized = if negate { -parsed } else { parsed };
31988
+ let rendered = if normalized.fract() == 0.0 {
31989
+ format!("{}", normalized as i64)
31990
+ } else {
31991
+ normalized.to_string()
31992
+ };
31993
+ return Expression::Literal(Box::new(crate::expressions::Literal::Number(
31994
+ rendered,
31995
+ )));
31996
+ }
31997
+ }
31998
+
31999
+ if !negate {
32000
+ return value;
32001
+ }
32002
+
32003
+ match value {
32004
+ Expression::Neg(op) => op.this,
32005
+ other => Expression::Neg(Box::new(UnaryOp {
32006
+ this: other,
32007
+ inferred_type: None,
32008
+ })),
32009
+ }
32010
+ }
32011
+
31922
32012
  /// Normalize BigQuery-specific functions to standard forms that target dialects can handle
31923
32013
  fn normalize_bigquery_function(
31924
32014
  e: Expression,
@@ -37962,7 +38052,11 @@ mod tests {
37962
38052
  "Expected IS NOT DISTINCT FROM: {}",
37963
38053
  result[0]
37964
38054
  );
37965
- assert!(result[0].contains("= 0"), "Expected = 0 filter: {}", result[0]);
38055
+ assert!(
38056
+ result[0].contains("= 0"),
38057
+ "Expected = 0 filter: {}",
38058
+ result[0]
38059
+ );
37966
38060
  }
37967
38061
 
37968
38062
  #[test]
@@ -1217,6 +1217,29 @@ mod tests {
1217
1217
  assert_eq!(config.identifier_quote, '`');
1218
1218
  }
1219
1219
 
1220
+ #[test]
1221
+ fn test_create_procedure_signal_sqlstate_regression() {
1222
+ let sql = "CREATE PROCEDURE CheckSalary(IN p_salary DECIMAL(10,2))
1223
+ BEGIN
1224
+ IF p_salary <= 0 THEN
1225
+ SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary must be positive';
1226
+ END IF;
1227
+ INSERT INTO employees (salary) VALUES (p_salary);
1228
+ END;";
1229
+
1230
+ let dialect = Dialect::get(DialectType::MySQL);
1231
+ let ast = dialect.parse(sql).expect("Parse failed");
1232
+ let output = dialect.generate(&ast[0]).expect("Generate failed");
1233
+
1234
+ assert!(output.contains("CREATE PROCEDURE CheckSalary"));
1235
+ assert!(output.contains("IF p_salary <= 0 THEN"));
1236
+ assert!(
1237
+ output.contains("SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary must be positive'")
1238
+ );
1239
+ assert!(output.contains("END IF"));
1240
+ assert!(output.contains("INSERT INTO employees (salary) VALUES (p_salary)"));
1241
+ }
1242
+
1220
1243
  fn mysql_identity(sql: &str, expected: &str) {
1221
1244
  let dialect = Dialect::get(DialectType::MySQL);
1222
1245
  let ast = dialect.parse(sql).expect("Parse failed");
@@ -3921,6 +3921,37 @@ mod tests {
3921
3921
  assert!(result.contains("FROM users"));
3922
3922
  }
3923
3923
 
3924
+ #[test]
3925
+ fn test_snowflake_scripting_cursor_declare_block_roundtrip() {
3926
+ let sql = "DECLARE
3927
+ emp CURSOR FOR SELECT salary FROM employees;
3928
+ BEGIN
3929
+ RETURN 1;
3930
+ END";
3931
+
3932
+ let dialect = Dialect::get(DialectType::Snowflake);
3933
+ let ast = dialect.parse(sql).expect("Parse failed");
3934
+ let output = dialect.generate(&ast[0]).expect("Generate failed");
3935
+
3936
+ assert_eq!(output, sql);
3937
+ }
3938
+
3939
+ #[test]
3940
+ fn test_snowflake_scripting_cursor_return_table_roundtrip() {
3941
+ let sql = "DECLARE
3942
+ c1 CURSOR FOR SELECT * FROM invoices;
3943
+ BEGIN
3944
+ OPEN c1;
3945
+ RETURN TABLE(RESULTSET_FROM_CURSOR(c1));
3946
+ END";
3947
+
3948
+ let dialect = Dialect::get(DialectType::Snowflake);
3949
+ let ast = dialect.parse(sql).expect("Parse failed");
3950
+ let output = dialect.generate(&ast[0]).expect("Generate failed");
3951
+
3952
+ assert_eq!(output, sql);
3953
+ }
3954
+
3924
3955
  #[test]
3925
3956
  fn test_group_concat_to_listagg() {
3926
3957
  let result = transpile_to_snowflake("SELECT GROUP_CONCAT(name)");
@@ -41,6 +41,12 @@ impl DialectImpl for SparkDialect {
41
41
  config
42
42
  .keywords
43
43
  .insert("DIV".to_string(), crate::tokens::TokenType::Div);
44
+ config
45
+ .keywords
46
+ .insert("REPAIR".to_string(), crate::tokens::TokenType::Command);
47
+ config
48
+ .keywords
49
+ .insert("MSCK".to_string(), crate::tokens::TokenType::Command);
44
50
  // Spark numeric literal suffixes (same as Hive): 1L -> BIGINT, 1S -> SMALLINT, etc.
45
51
  config
46
52
  .numeric_literals
@@ -13,8 +13,8 @@
13
13
  use super::{DialectImpl, DialectType};
14
14
  use crate::error::Result;
15
15
  use crate::expressions::{
16
- Alias, Cast, Cte, DataType, Expression, Function, Identifier, Join, JoinKind, LikeOp, Literal,
17
- Null, StringAggFunc, Subquery, UnaryFunc,
16
+ Alias, Cast, Cte, DataType, Expression, Function, Identifier, In, Join, JoinKind, LikeOp,
17
+ Literal, Null, QuantifiedOp, StringAggFunc, Subquery, UnaryFunc,
18
18
  };
19
19
  use crate::generator::GeneratorConfig;
20
20
  use crate::tokens::TokenizerConfig;
@@ -91,6 +91,18 @@ impl DialectImpl for TSQLDialect {
91
91
  }
92
92
 
93
93
  fn transform_expr(&self, expr: Expression) -> Result<Expression> {
94
+ // Transform column data types in DDL (transform_recursive skips them by design).
95
+ if let Expression::CreateTable(mut ct) = expr {
96
+ for col in &mut ct.columns {
97
+ if let Ok(Expression::DataType(new_dt)) =
98
+ self.transform_data_type(col.data_type.clone())
99
+ {
100
+ col.data_type = new_dt;
101
+ }
102
+ }
103
+ return Ok(Expression::CreateTable(ct));
104
+ }
105
+
94
106
  match expr {
95
107
  // ===== SELECT a = 1 → SELECT 1 AS a =====
96
108
  // In T-SQL, `SELECT a = expr` is equivalent to `SELECT expr AS a`
@@ -629,6 +641,36 @@ impl DialectImpl for TSQLDialect {
629
641
  vec![f.this, f.path],
630
642
  )))),
631
643
 
644
+ // PostgreSQL pg_get_querydef can emit scalar array comparisons for
645
+ // literal arrays/tuples. T-SQL/Fabric require IN for this shape.
646
+ Expression::Any(ref q) if matches!(&q.op, Some(QuantifiedOp::Eq)) => {
647
+ let values: Option<Vec<Expression>> = match &q.subquery {
648
+ Expression::ArrayFunc(a) => Some(a.expressions.clone()),
649
+ Expression::Array(a) => Some(a.expressions.clone()),
650
+ Expression::Tuple(t) => Some(t.expressions.clone()),
651
+ _ => None,
652
+ };
653
+
654
+ match values {
655
+ Some(expressions) if expressions.is_empty() => {
656
+ Ok(Expression::Eq(Box::new(crate::expressions::BinaryOp::new(
657
+ Expression::Literal(Box::new(Literal::Number("1".to_string()))),
658
+ Expression::Literal(Box::new(Literal::Number("0".to_string()))),
659
+ ))))
660
+ }
661
+ Some(expressions) => Ok(Expression::In(Box::new(In {
662
+ this: q.this.clone(),
663
+ expressions,
664
+ query: None,
665
+ not: false,
666
+ global: false,
667
+ unnest: None,
668
+ is_field: false,
669
+ }))),
670
+ None => Ok(expr.clone()),
671
+ }
672
+ }
673
+
632
674
  // Pass through everything else
633
675
  _ => Ok(expr),
634
676
  }
@@ -637,7 +679,10 @@ impl DialectImpl for TSQLDialect {
637
679
 
638
680
  impl TSQLDialect {
639
681
  /// Transform data types according to T-SQL TYPE_MAPPING
640
- fn transform_data_type(&self, dt: crate::expressions::DataType) -> Result<Expression> {
682
+ pub(super) fn transform_data_type(
683
+ &self,
684
+ dt: crate::expressions::DataType,
685
+ ) -> Result<Expression> {
641
686
  use crate::expressions::DataType;
642
687
  let transformed = match dt {
643
688
  // BOOLEAN -> BIT
@@ -669,12 +714,46 @@ impl TSQLDialect {
669
714
  DataType::Uuid => DataType::Custom {
670
715
  name: "UNIQUEIDENTIFIER".to_string(),
671
716
  },
717
+ // Normalise custom type names that have PostgreSQL aliases
718
+ DataType::Custom { ref name } => {
719
+ let upper = name.trim().to_uppercase();
720
+ let (base_name, precision, _scale) = Self::parse_type_precision_and_scale(&upper);
721
+ match base_name.as_str() {
722
+ // BPCHAR is PostgreSQL's blank-padded CHAR alias — map to CHAR
723
+ "BPCHAR" => {
724
+ if let Some(len) = precision {
725
+ DataType::Char { length: Some(len) }
726
+ } else {
727
+ DataType::Char { length: None }
728
+ }
729
+ }
730
+ _ => dt,
731
+ }
732
+ }
672
733
  // Keep all other types as-is
673
734
  other => other,
674
735
  };
675
736
  Ok(Expression::DataType(transformed))
676
737
  }
677
738
 
739
+ /// Parse a type name that may embed precision/scale: `"TYPENAME(n, m)"` → `("TYPENAME", Some(n), Some(m))`.
740
+ pub(super) fn parse_type_precision_and_scale(name: &str) -> (String, Option<u32>, Option<u32>) {
741
+ if let Some(paren_pos) = name.find('(') {
742
+ let base = name[..paren_pos].to_string();
743
+ let rest = &name[paren_pos + 1..];
744
+ if let Some(close_pos) = rest.find(')') {
745
+ let args = &rest[..close_pos];
746
+ let parts: Vec<&str> = args.split(',').map(|s| s.trim()).collect();
747
+ let precision = parts.first().and_then(|s| s.parse::<u32>().ok());
748
+ let scale = parts.get(1).and_then(|s| s.parse::<u32>().ok());
749
+ return (base, precision, scale);
750
+ }
751
+ (base, None, None)
752
+ } else {
753
+ (name.to_string(), None, None)
754
+ }
755
+ }
756
+
678
757
  fn transform_function(&self, f: Function) -> Result<Expression> {
679
758
  let name_upper = f.name.to_uppercase();
680
759
  match name_upper.as_str() {
@@ -1346,6 +1425,9 @@ mod tests {
1346
1425
  )
1347
1426
  .expect("transpile failed");
1348
1427
  let expected = r#"ISNULL(JSON_QUERY(REPLACE(REPLACE(x, '''', '"'), '""', '"'), '$'), JSON_VALUE(REPLACE(REPLACE(x, '''', '"'), '""', '"'), '$'))"#;
1349
- assert_eq!(result[0], expected, "JSON_QUERY should be wrapped with ISNULL");
1428
+ assert_eq!(
1429
+ result[0], expected,
1430
+ "JSON_QUERY should be wrapped with ISNULL"
1431
+ );
1350
1432
  }
1351
1433
  }
@@ -7297,6 +7297,9 @@ pub struct CreateTable {
7297
7297
  /// Whether this is a SHALLOW CLONE (Databricks/Delta Lake)
7298
7298
  #[serde(default)]
7299
7299
  pub shallow_clone: bool,
7300
+ /// Whether this is an explicit DEEP CLONE (Databricks/Delta Lake)
7301
+ #[serde(default)]
7302
+ pub deep_clone: bool,
7300
7303
  /// Leading comments before the statement
7301
7304
  #[serde(default)]
7302
7305
  pub leading_comments: Vec<String>,
@@ -7406,6 +7409,7 @@ impl CreateTable {
7406
7409
  clone_source: None,
7407
7410
  clone_at_clause: None,
7408
7411
  shallow_clone: false,
7412
+ deep_clone: false,
7409
7413
  is_copy: false,
7410
7414
  leading_comments: Vec::new(),
7411
7415
  with_properties: Vec::new(),