polyglot-sql 0.3.5__tar.gz → 0.3.6__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 (168) hide show
  1. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/Cargo.lock +5 -5
  2. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/Cargo.toml +1 -1
  3. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/PKG-INFO +1 -1
  4. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/Cargo.toml +1 -1
  5. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/databricks.rs +31 -0
  6. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/duckdb.rs +21 -4
  7. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/mod.rs +222 -100
  8. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/mysql.rs +1 -0
  9. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/redshift.rs +1 -0
  10. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/snowflake.rs +9 -0
  11. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/spark.rs +45 -5
  12. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/expressions.rs +2 -0
  13. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/generator.rs +156 -6
  14. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/parser.rs +255 -34
  15. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/fabric_regression.rs +43 -0
  16. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/README.md +0 -0
  17. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/README.md +0 -0
  18. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/benches/in_list.rs +0 -0
  19. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/benches/parsing.rs +0 -0
  20. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  21. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/benches/transpile.rs +0 -0
  22. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  23. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  24. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  25. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/builder.rs +0 -0
  26. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  27. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  28. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  29. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  30. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  31. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  32. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  33. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  34. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  35. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  36. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  37. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  38. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  39. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  40. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  41. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  42. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
  43. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  44. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  45. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  46. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  47. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  48. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  49. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  50. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  51. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  52. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  53. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
  54. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/diff.rs +0 -0
  55. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/error.rs +0 -0
  56. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  57. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/function_registry.rs +0 -0
  58. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/helper.rs +0 -0
  59. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/lib.rs +0 -0
  60. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/lineage.rs +0 -0
  61. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  62. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  63. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  64. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  65. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  66. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  67. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  68. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  69. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  70. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  71. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  72. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  73. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
  74. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  75. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  76. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  77. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/planner.rs +0 -0
  78. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/resolver.rs +0 -0
  79. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/schema.rs +0 -0
  80. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/scope.rs +0 -0
  81. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/time.rs +0 -0
  82. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/tokens.rs +0 -0
  83. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/transforms.rs +0 -0
  84. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/traversal.rs +0 -0
  85. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/trie.rs +0 -0
  86. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  87. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/src/validation.rs +0 -0
  88. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  89. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  90. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  91. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  92. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  93. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  94. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  95. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  96. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  97. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  98. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  99. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  100. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  101. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  102. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  103. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  104. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  105. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  106. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  107. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
  108. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  109. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  110. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  111. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  112. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  113. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  114. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  115. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  116. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  117. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  118. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  119. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  120. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  121. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  122. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
  123. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  124. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  125. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  126. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  127. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  128. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  129. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  130. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/Cargo.toml +0 -0
  131. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/README.md +0 -0
  132. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/docs/api.md +0 -0
  133. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/docs/index.md +0 -0
  134. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  135. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  136. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  137. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/diff.rs +0 -0
  138. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/errors.rs +0 -0
  139. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/expr.rs +0 -0
  140. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  141. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/format.rs +0 -0
  142. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/generate.rs +0 -0
  143. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  144. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/lib.rs +0 -0
  145. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  146. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  147. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/parse.rs +0 -0
  148. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  149. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  150. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/types.rs +0 -0
  151. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/src/validate.rs +0 -0
  152. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  153. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  154. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  155. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  156. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  157. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  158. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  159. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  160. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  161. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
  162. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  163. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  164. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/crates/polyglot-sql-python/uv.lock +0 -0
  165. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/pyproject.toml +0 -0
  166. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/python/polyglot_sql/__init__.py +0 -0
  167. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/python/polyglot_sql/__init__.pyi +0 -0
  168. {polyglot_sql-0.3.5 → polyglot_sql-0.3.6}/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.5"
608
+ version = "0.3.6"
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.5"
624
+ version = "0.3.6"
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.5"
634
+ version = "0.3.6"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.3.5"
638
+ version = "0.3.6"
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.5"
649
+ version = "0.3.6"
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.5"
9
+ version = "0.3.6"
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.5
3
+ Version: 0.3.6
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.5", optional = true, default-features = false }
86
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.6", optional = true, default-features = false }
87
87
 
88
88
  [dev-dependencies]
89
89
  pretty_assertions = "1.4"
@@ -213,6 +213,37 @@ impl DatabricksDialect {
213
213
  f.args,
214
214
  )))),
215
215
 
216
+ // NAMED_STRUCT('a', 1) -> STRUCT(1 AS a) for SQLGlot Databricks outputs
217
+ "NAMED_STRUCT" if f.args.len() % 2 == 0 => {
218
+ let original_args = f.args.clone();
219
+ let mut struct_args = Vec::new();
220
+ for pair in f.args.chunks(2) {
221
+ if let Expression::Literal(lit) = &pair[0] {
222
+ if let Literal::String(field_name) = lit.as_ref() {
223
+ struct_args.push(Expression::Alias(Box::new(
224
+ crate::expressions::Alias {
225
+ this: pair[1].clone(),
226
+ alias: crate::expressions::Identifier::new(field_name),
227
+ column_aliases: Vec::new(),
228
+ pre_alias_comments: Vec::new(),
229
+ trailing_comments: Vec::new(),
230
+ inferred_type: None,
231
+ },
232
+ )));
233
+ continue;
234
+ }
235
+ }
236
+ return Ok(Expression::Function(Box::new(Function::new(
237
+ "NAMED_STRUCT".to_string(),
238
+ original_args,
239
+ ))));
240
+ }
241
+ Ok(Expression::Function(Box::new(Function::new(
242
+ "STRUCT".to_string(),
243
+ struct_args,
244
+ ))))
245
+ }
246
+
216
247
  // GETDATE -> CURRENT_TIMESTAMP
217
248
  "GETDATE" => Ok(Expression::CurrentTimestamp(
218
249
  crate::expressions::CurrentTimestamp {
@@ -3466,10 +3466,27 @@ impl DuckDBDialect {
3466
3466
  vec![arg, Expression::number(2)],
3467
3467
  ))))
3468
3468
  }
3469
- "UUID_STRING" => Ok(Expression::Function(Box::new(Function::new(
3470
- "UUID".to_string(),
3471
- vec![],
3472
- )))),
3469
+ "LIST"
3470
+ if f.args.len() == 1 && !matches!(f.args.first(), Some(Expression::Select(_))) =>
3471
+ {
3472
+ Ok(Expression::Function(Box::new(Function::new(
3473
+ "ARRAY_AGG".to_string(),
3474
+ f.args,
3475
+ ))))
3476
+ }
3477
+ "UUID_STRING" => {
3478
+ if f.args.is_empty() {
3479
+ Ok(Expression::Function(Box::new(Function::new(
3480
+ "UUID".to_string(),
3481
+ vec![],
3482
+ ))))
3483
+ } else {
3484
+ Ok(Expression::Function(Box::new(Function::new(
3485
+ "UUID_STRING".to_string(),
3486
+ f.args,
3487
+ ))))
3488
+ }
3489
+ }
3473
3490
  "ENDSWITH" => Ok(Expression::Function(Box::new(Function::new(
3474
3491
  "ENDS_WITH".to_string(),
3475
3492
  f.args,
@@ -17530,7 +17530,13 @@ impl Dialect {
17530
17530
  let mut args = f.args;
17531
17531
  let date = args.remove(0);
17532
17532
  let interval_expr = args.remove(0);
17533
- let (val, unit) = Self::extract_interval_parts(&interval_expr);
17533
+ let (val, unit) = Self::extract_interval_parts(&interval_expr)
17534
+ .unwrap_or_else(|| {
17535
+ (
17536
+ interval_expr.clone(),
17537
+ crate::expressions::IntervalUnit::Day,
17538
+ )
17539
+ });
17534
17540
  let unit_str = Self::interval_unit_to_string(&unit);
17535
17541
  let is_literal = matches!(&val,
17536
17542
  Expression::Literal(lit) if matches!(lit.as_ref(), Literal::Number(_) | Literal::String(_))
@@ -20841,37 +20847,13 @@ impl Dialect {
20841
20847
  _ => Ok(Expression::Function(f)),
20842
20848
  }
20843
20849
  }
20844
- // CONCAT_WS('-', args...) -> CONCAT_WS('-', CAST(arg AS VARCHAR), ...) for Presto/Trino
20845
- "CONCAT_WS" if f.args.len() >= 2 => match target {
20846
- DialectType::Presto | DialectType::Trino | DialectType::Athena => {
20847
- let mut args = f.args;
20848
- let sep = args.remove(0);
20849
- let cast_args: Vec<Expression> = args
20850
- .into_iter()
20851
- .map(|a| {
20852
- Expression::Cast(Box::new(Cast {
20853
- this: a,
20854
- to: DataType::VarChar {
20855
- length: None,
20856
- parenthesized_length: false,
20857
- },
20858
- double_colon_syntax: false,
20859
- trailing_comments: Vec::new(),
20860
- format: None,
20861
- default: None,
20862
- inferred_type: None,
20863
- }))
20864
- })
20865
- .collect();
20866
- let mut new_args = vec![sep];
20867
- new_args.extend(cast_args);
20868
- Ok(Expression::Function(Box::new(Function::new(
20869
- "CONCAT_WS".to_string(),
20870
- new_args,
20871
- ))))
20872
- }
20873
- DialectType::DuckDB => {
20874
- let args = f.args;
20850
+ // CONCAT_WS from Generic is null-propagating in SQLGlot fixtures.
20851
+ // Trino also requires non-separator arguments cast to VARCHAR.
20852
+ "CONCAT_WS" if f.args.len() >= 2 => {
20853
+ fn concat_ws_null_case(
20854
+ args: Vec<Expression>,
20855
+ else_expr: Expression,
20856
+ ) -> Expression {
20875
20857
  let mut null_checks = args.iter().cloned().map(|arg| {
20876
20858
  Expression::IsNull(Box::new(crate::expressions::IsNull {
20877
20859
  this: arg,
@@ -20893,19 +20875,89 @@ impl Dialect {
20893
20875
  inferred_type: None,
20894
20876
  }))
20895
20877
  });
20896
- Ok(Expression::Case(Box::new(Case {
20878
+ Expression::Case(Box::new(Case {
20897
20879
  operand: None,
20898
20880
  whens: vec![(null_check, Expression::Null(Null))],
20899
- else_: Some(Expression::Function(Box::new(Function::new(
20900
- "CONCAT_WS".to_string(),
20901
- args,
20902
- )))),
20881
+ else_: Some(else_expr),
20903
20882
  comments: vec![],
20904
20883
  inferred_type: None,
20905
- })))
20884
+ }))
20906
20885
  }
20907
- _ => Ok(Expression::Function(f)),
20908
- },
20886
+
20887
+ match target {
20888
+ DialectType::Trino
20889
+ if matches!(source, DialectType::Generic) =>
20890
+ {
20891
+ let original_args = f.args.clone();
20892
+ let mut args = f.args;
20893
+ let sep = args.remove(0);
20894
+ let cast_args: Vec<Expression> = args
20895
+ .into_iter()
20896
+ .map(|a| {
20897
+ Expression::Cast(Box::new(Cast {
20898
+ this: a,
20899
+ to: DataType::VarChar {
20900
+ length: None,
20901
+ parenthesized_length: false,
20902
+ },
20903
+ double_colon_syntax: false,
20904
+ trailing_comments: Vec::new(),
20905
+ format: None,
20906
+ default: None,
20907
+ inferred_type: None,
20908
+ }))
20909
+ })
20910
+ .collect();
20911
+ let mut new_args = vec![sep];
20912
+ new_args.extend(cast_args);
20913
+ let else_expr = Expression::Function(Box::new(
20914
+ Function::new("CONCAT_WS".to_string(), new_args),
20915
+ ));
20916
+ Ok(concat_ws_null_case(original_args, else_expr))
20917
+ }
20918
+ DialectType::Presto
20919
+ | DialectType::Trino
20920
+ | DialectType::Athena => {
20921
+ let mut args = f.args;
20922
+ let sep = args.remove(0);
20923
+ let cast_args: Vec<Expression> = args
20924
+ .into_iter()
20925
+ .map(|a| {
20926
+ Expression::Cast(Box::new(Cast {
20927
+ this: a,
20928
+ to: DataType::VarChar {
20929
+ length: None,
20930
+ parenthesized_length: false,
20931
+ },
20932
+ double_colon_syntax: false,
20933
+ trailing_comments: Vec::new(),
20934
+ format: None,
20935
+ default: None,
20936
+ inferred_type: None,
20937
+ }))
20938
+ })
20939
+ .collect();
20940
+ let mut new_args = vec![sep];
20941
+ new_args.extend(cast_args);
20942
+ Ok(Expression::Function(Box::new(Function::new(
20943
+ "CONCAT_WS".to_string(),
20944
+ new_args,
20945
+ ))))
20946
+ }
20947
+ DialectType::Spark
20948
+ | DialectType::Hive
20949
+ | DialectType::DuckDB
20950
+ if matches!(source, DialectType::Generic) =>
20951
+ {
20952
+ let args = f.args;
20953
+ let else_expr = Expression::Function(Box::new(
20954
+ Function::new("CONCAT_WS".to_string(), args.clone()),
20955
+ ));
20956
+ Ok(concat_ws_null_case(args, else_expr))
20957
+ }
20958
+ _ => Ok(Expression::Function(f)),
20959
+ }
20960
+ }
20909
20961
  // ARRAY_SLICE(x, start, end) -> SLICE(x, start, end) for Presto/Trino/Databricks, arraySlice for ClickHouse
20910
20962
  "ARRAY_SLICE" if f.args.len() >= 2 => match target {
20911
20963
  DialectType::DuckDB
@@ -31957,66 +32009,93 @@ impl Dialect {
31957
32009
  /// Returns (value_expression, IntervalUnit)
31958
32010
  fn extract_interval_parts(
31959
32011
  interval_expr: &Expression,
31960
- ) -> (Expression, crate::expressions::IntervalUnit) {
31961
- use crate::expressions::{IntervalUnit, IntervalUnitSpec};
31962
-
31963
- if let Expression::Interval(iv) = interval_expr {
31964
- let val = iv.this.clone().unwrap_or(Expression::number(0));
31965
- let unit = match &iv.unit {
31966
- Some(IntervalUnitSpec::Simple { unit, .. }) => *unit,
31967
- None => {
31968
- // Unit might be embedded in the string value (Snowflake format: '5 DAY')
31969
- if let Expression::Literal(lit) = &val {
31970
- if let crate::expressions::Literal::String(s) = lit.as_ref() {
31971
- let parts: Vec<&str> = s.trim().splitn(2, ' ').collect();
31972
- if parts.len() == 2 {
31973
- let unit_str = parts[1].trim().to_ascii_uppercase();
31974
- let parsed_unit = match unit_str.as_str() {
31975
- "YEAR" | "YEARS" => IntervalUnit::Year,
31976
- "QUARTER" | "QUARTERS" => IntervalUnit::Quarter,
31977
- "MONTH" | "MONTHS" => IntervalUnit::Month,
31978
- "WEEK" | "WEEKS" | "ISOWEEK" => IntervalUnit::Week,
31979
- "DAY" | "DAYS" => IntervalUnit::Day,
31980
- "HOUR" | "HOURS" => IntervalUnit::Hour,
31981
- "MINUTE" | "MINUTES" => IntervalUnit::Minute,
31982
- "SECOND" | "SECONDS" => IntervalUnit::Second,
31983
- "MILLISECOND" | "MILLISECONDS" => IntervalUnit::Millisecond,
31984
- "MICROSECOND" | "MICROSECONDS" => IntervalUnit::Microsecond,
31985
- _ => IntervalUnit::Day,
31986
- };
31987
- // Return just the numeric part as value and parsed unit
31988
- return (
31989
- Expression::Literal(Box::new(
31990
- crate::expressions::Literal::String(
31991
- parts[0].trim().to_string(),
31992
- ),
31993
- )),
31994
- parsed_unit,
31995
- );
31996
- }
31997
- IntervalUnit::Day
31998
- } else {
31999
- IntervalUnit::Day
32012
+ ) -> Option<(Expression, crate::expressions::IntervalUnit)> {
32013
+ use crate::expressions::{DataType, IntervalUnit, IntervalUnitSpec, Literal};
32014
+
32015
+ fn unit_from_str(unit: &str) -> Option<IntervalUnit> {
32016
+ match unit.trim().to_ascii_uppercase().as_str() {
32017
+ "YEAR" | "YEARS" => Some(IntervalUnit::Year),
32018
+ "QUARTER" | "QUARTERS" => Some(IntervalUnit::Quarter),
32019
+ "MONTH" | "MONTHS" => Some(IntervalUnit::Month),
32020
+ "WEEK" | "WEEKS" | "ISOWEEK" => Some(IntervalUnit::Week),
32021
+ "DAY" | "DAYS" => Some(IntervalUnit::Day),
32022
+ "HOUR" | "HOURS" => Some(IntervalUnit::Hour),
32023
+ "MINUTE" | "MINUTES" => Some(IntervalUnit::Minute),
32024
+ "SECOND" | "SECONDS" => Some(IntervalUnit::Second),
32025
+ "MILLISECOND" | "MILLISECONDS" => Some(IntervalUnit::Millisecond),
32026
+ "MICROSECOND" | "MICROSECONDS" => Some(IntervalUnit::Microsecond),
32027
+ "NANOSECOND" | "NANOSECONDS" => Some(IntervalUnit::Nanosecond),
32028
+ _ => None,
32029
+ }
32030
+ }
32031
+
32032
+ fn parts_from_literal_string(s: &str) -> Option<(Expression, IntervalUnit)> {
32033
+ let mut parts = s.split_whitespace();
32034
+ let value = parts.next()?;
32035
+ let unit = unit_from_str(parts.next()?)?;
32036
+ Some((
32037
+ Expression::Literal(Box::new(Literal::String(value.to_string()))),
32038
+ unit,
32039
+ ))
32040
+ }
32041
+
32042
+ fn unit_from_spec(unit: &IntervalUnitSpec) -> Option<IntervalUnit> {
32043
+ match unit {
32044
+ IntervalUnitSpec::Simple { unit, .. } => Some(*unit),
32045
+ IntervalUnitSpec::Expr(expr) => match expr.as_ref() {
32046
+ Expression::Day(_) => Some(IntervalUnit::Day),
32047
+ Expression::Month(_) => Some(IntervalUnit::Month),
32048
+ Expression::Year(_) => Some(IntervalUnit::Year),
32049
+ Expression::Identifier(id) => unit_from_str(&id.name),
32050
+ Expression::Var(v) => unit_from_str(&v.this),
32051
+ Expression::Column(col) => unit_from_str(&col.name.name),
32052
+ _ => None,
32053
+ },
32054
+ _ => None,
32055
+ }
32056
+ }
32057
+
32058
+ match interval_expr {
32059
+ Expression::Interval(iv) => {
32060
+ let val = iv.this.clone().unwrap_or(Expression::number(0));
32061
+ if let Expression::Literal(lit) = &val {
32062
+ if let Literal::String(s) = lit.as_ref() {
32063
+ if let Some(parts) = parts_from_literal_string(s) {
32064
+ return Some(parts);
32000
32065
  }
32001
- } else {
32002
- IntervalUnit::Day
32003
32066
  }
32004
32067
  }
32005
- _ => IntervalUnit::Day,
32006
- };
32007
- (val, unit)
32008
- } else {
32009
- // Not an interval - pass through
32010
- (interval_expr.clone(), crate::expressions::IntervalUnit::Day)
32068
+ let unit = iv
32069
+ .unit
32070
+ .as_ref()
32071
+ .and_then(unit_from_spec)
32072
+ .unwrap_or(IntervalUnit::Day);
32073
+ Some((val, unit))
32074
+ }
32075
+ Expression::Cast(cast) if matches!(cast.to, DataType::Interval { .. }) => {
32076
+ if let Expression::Literal(lit) = &cast.this {
32077
+ if let Literal::String(s) = lit.as_ref() {
32078
+ if let Some(parts) = parts_from_literal_string(s) {
32079
+ return Some(parts);
32080
+ }
32081
+ }
32082
+ }
32083
+ let unit = match &cast.to {
32084
+ DataType::Interval {
32085
+ unit: Some(unit), ..
32086
+ } => unit_from_str(unit).unwrap_or(IntervalUnit::Day),
32087
+ _ => IntervalUnit::Day,
32088
+ };
32089
+ Some((cast.this.clone(), unit))
32090
+ }
32091
+ _ => None,
32011
32092
  }
32012
32093
  }
32013
32094
 
32014
32095
  fn rewrite_tsql_interval_arithmetic(expr: &Expression) -> Option<Expression> {
32015
32096
  match expr {
32016
32097
  Expression::Add(op) => {
32017
- let Expression::Interval(_) = &op.right else {
32018
- return None;
32019
- };
32098
+ Self::extract_interval_parts(&op.right)?;
32020
32099
  Some(Self::build_tsql_dateadd_from_interval(
32021
32100
  op.left.clone(),
32022
32101
  &op.right,
@@ -32024,9 +32103,7 @@ impl Dialect {
32024
32103
  ))
32025
32104
  }
32026
32105
  Expression::Sub(op) => {
32027
- let Expression::Interval(_) = &op.right else {
32028
- return None;
32029
- };
32106
+ Self::extract_interval_parts(&op.right)?;
32030
32107
  Some(Self::build_tsql_dateadd_from_interval(
32031
32108
  op.left.clone(),
32032
32109
  &op.right,
@@ -32042,7 +32119,8 @@ impl Dialect {
32042
32119
  interval: &Expression,
32043
32120
  subtract: bool,
32044
32121
  ) -> Expression {
32045
- let (value, unit) = Self::extract_interval_parts(interval);
32122
+ let (value, unit) = Self::extract_interval_parts(interval)
32123
+ .unwrap_or_else(|| (interval.clone(), crate::expressions::IntervalUnit::Day));
32046
32124
  let unit = Self::interval_unit_to_string(&unit);
32047
32125
  let amount = Self::tsql_dateadd_amount(value, subtract);
32048
32126
 
@@ -32053,7 +32131,7 @@ impl Dialect {
32053
32131
  }
32054
32132
 
32055
32133
  fn tsql_dateadd_amount(value: Expression, negate: bool) -> Expression {
32056
- use crate::expressions::UnaryOp;
32134
+ use crate::expressions::{Parameter, ParameterStyle, UnaryOp};
32057
32135
 
32058
32136
  fn numeric_literal_value(value: &Expression) -> Option<&str> {
32059
32137
  match value {
@@ -32066,6 +32144,38 @@ impl Dialect {
32066
32144
  }
32067
32145
  }
32068
32146
 
32147
+ fn colon_parameter(value: &Expression) -> Option<Expression> {
32148
+ let Expression::Literal(lit) = value else {
32149
+ return None;
32150
+ };
32151
+ let crate::expressions::Literal::String(s) = lit.as_ref() else {
32152
+ return None;
32153
+ };
32154
+ let name = s.strip_prefix(':')?;
32155
+ if name.is_empty()
32156
+ || !name
32157
+ .chars()
32158
+ .all(|ch| ch.is_ascii_alphanumeric() || ch == '_')
32159
+ {
32160
+ return None;
32161
+ }
32162
+
32163
+ Some(Expression::Parameter(Box::new(Parameter {
32164
+ name: if name.chars().all(|ch| ch.is_ascii_digit()) {
32165
+ None
32166
+ } else {
32167
+ Some(name.to_string())
32168
+ },
32169
+ index: name.parse::<u32>().ok(),
32170
+ style: ParameterStyle::Colon,
32171
+ quoted: false,
32172
+ string_quoted: false,
32173
+ expression: None,
32174
+ })))
32175
+ }
32176
+
32177
+ let value = colon_parameter(&value).unwrap_or(value);
32178
+
32069
32179
  if let Some(n) = numeric_literal_value(&value) {
32070
32180
  if let Ok(parsed) = n.parse::<f64>() {
32071
32181
  let normalized = if negate { -parsed } else { parsed };
@@ -32527,7 +32637,10 @@ impl Dialect {
32527
32637
  "TIMESTAMP_ADD" | "DATETIME_ADD" | "TIME_ADD" if args.len() == 2 => {
32528
32638
  let ts = args.remove(0);
32529
32639
  let interval_expr = args.remove(0);
32530
- let (val, unit) = Self::extract_interval_parts(&interval_expr);
32640
+ let (val, unit) =
32641
+ Self::extract_interval_parts(&interval_expr).unwrap_or_else(|| {
32642
+ (interval_expr.clone(), crate::expressions::IntervalUnit::Day)
32643
+ });
32531
32644
 
32532
32645
  match target {
32533
32646
  DialectType::Snowflake => {
@@ -32657,7 +32770,10 @@ impl Dialect {
32657
32770
  "TIMESTAMP_SUB" | "DATETIME_SUB" | "TIME_SUB" if args.len() == 2 => {
32658
32771
  let ts = args.remove(0);
32659
32772
  let interval_expr = args.remove(0);
32660
- let (val, unit) = Self::extract_interval_parts(&interval_expr);
32773
+ let (val, unit) =
32774
+ Self::extract_interval_parts(&interval_expr).unwrap_or_else(|| {
32775
+ (interval_expr.clone(), crate::expressions::IntervalUnit::Day)
32776
+ });
32661
32777
 
32662
32778
  match target {
32663
32779
  DialectType::Snowflake => {
@@ -32789,7 +32905,10 @@ impl Dialect {
32789
32905
  "DATE_SUB" if args.len() == 2 => {
32790
32906
  let date = args.remove(0);
32791
32907
  let interval_expr = args.remove(0);
32792
- let (val, unit) = Self::extract_interval_parts(&interval_expr);
32908
+ let (val, unit) =
32909
+ Self::extract_interval_parts(&interval_expr).unwrap_or_else(|| {
32910
+ (interval_expr.clone(), crate::expressions::IntervalUnit::Day)
32911
+ });
32793
32912
 
32794
32913
  match target {
32795
32914
  DialectType::Databricks | DialectType::Spark => {
@@ -33144,7 +33263,10 @@ impl Dialect {
33144
33263
  "DATE_ADD" if args.len() == 2 => {
33145
33264
  let date = args.remove(0);
33146
33265
  let interval_expr = args.remove(0);
33147
- let (val, unit) = Self::extract_interval_parts(&interval_expr);
33266
+ let (val, unit) =
33267
+ Self::extract_interval_parts(&interval_expr).unwrap_or_else(|| {
33268
+ (interval_expr.clone(), crate::expressions::IntervalUnit::Day)
33269
+ });
33148
33270
  let unit_str = Self::interval_unit_to_string(&unit);
33149
33271
 
33150
33272
  match target {
@@ -83,6 +83,7 @@ impl DialectImpl for MySQLDialect {
83
83
  config.escape_follow_chars = vec!['0', 'b', 'n', 'r', 't', 'Z', '%', '_'];
84
84
  // MySQL allows identifiers to start with digits (e.g., 1a, 1_a)
85
85
  config.identifiers_can_start_with_digit = true;
86
+ config.hex_number_strings = true;
86
87
  config
87
88
  }
88
89
 
@@ -42,6 +42,7 @@ impl DialectImpl for RedshiftDialect {
42
42
  supports_column_join_marks: true,
43
43
  locking_reads_supported: false,
44
44
  tz_to_with_time_zone: true,
45
+ single_string_interval: true,
45
46
  ..Default::default()
46
47
  }
47
48
  }
@@ -2392,6 +2392,15 @@ impl SnowflakeDialect {
2392
2392
  ))))
2393
2393
  }
2394
2394
 
2395
+ "STRTOK_TO_ARRAY" if f.args.len() == 1 => {
2396
+ let mut args = f.args;
2397
+ args.push(Expression::string(" ".to_string()));
2398
+ Ok(Expression::Function(Box::new(Function::new(
2399
+ "STRTOK_TO_ARRAY".to_string(),
2400
+ args,
2401
+ ))))
2402
+ }
2403
+
2395
2404
  // WEEKOFYEAR -> WEEK
2396
2405
  "WEEKOFYEAR" => Ok(Expression::Function(Box::new(Function::new(
2397
2406
  "WEEK".to_string(),