polyglot-sql 0.3.7__tar.gz → 0.3.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/Cargo.lock +5 -5
  2. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/Cargo.toml +1 -1
  3. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/PKG-INFO +1 -1
  4. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/Cargo.toml +1 -1
  5. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/ast_transforms.rs +73 -0
  6. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/mod.rs +201 -5
  7. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/expressions.rs +15 -0
  8. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/generator.rs +91 -4
  9. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/lib.rs +5 -3
  10. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/lineage.rs +10 -0
  11. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +315 -30
  12. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/parser.rs +88 -66
  13. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/scope.rs +10 -0
  14. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/traversal.rs +6 -0
  15. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +9 -9
  16. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/fabric_regression.rs +111 -0
  17. polyglot_sql-0.3.10/crates/polyglot-sql/tests/fabric_tpch_regression.rs +580 -0
  18. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/transform_regression.rs +130 -2
  19. polyglot_sql-0.3.10/crates/polyglot-sql/tests/tsql_regression.rs +243 -0
  20. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/expr_types.rs +1 -0
  21. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/lib.rs +3 -0
  22. polyglot_sql-0.3.10/crates/polyglot-sql-python/src/transforms.rs +121 -0
  23. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_parse.py +19 -0
  24. polyglot_sql-0.3.10/crates/polyglot-sql-python/tests/test_transforms.py +44 -0
  25. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/python/polyglot_sql/__init__.py +6 -0
  26. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/python/polyglot_sql/__init__.pyi +46 -10
  27. polyglot_sql-0.3.7/crates/polyglot-sql/tests/tsql_regression.rs +0 -85
  28. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/README.md +0 -0
  29. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/README.md +0 -0
  30. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/in_list.rs +0 -0
  31. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/parsing.rs +0 -0
  32. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  33. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/benches/transpile.rs +0 -0
  34. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  35. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  36. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/builder.rs +0 -0
  37. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  38. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  39. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  40. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  41. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  42. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  43. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  44. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  45. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  46. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  47. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
  48. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  49. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  50. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  51. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  52. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  53. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  54. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
  55. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  56. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
  57. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  58. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  59. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  60. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  61. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
  62. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  63. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  64. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  65. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  66. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  67. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  68. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  69. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  70. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
  71. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/diff.rs +0 -0
  72. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/error.rs +0 -0
  73. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  74. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/function_registry.rs +0 -0
  75. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/helper.rs +0 -0
  76. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  77. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  78. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  79. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  80. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  81. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  82. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  83. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  84. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  85. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  86. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  87. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  88. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
  89. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  90. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  91. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/planner.rs +0 -0
  92. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/resolver.rs +0 -0
  93. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/schema.rs +0 -0
  94. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/time.rs +0 -0
  95. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/tokens.rs +0 -0
  96. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/transforms.rs +0 -0
  97. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/trie.rs +0 -0
  98. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  99. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/src/validation.rs +0 -0
  100. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  101. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  102. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  103. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  104. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  105. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  106. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  107. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  108. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  109. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  110. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  111. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  112. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  113. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  114. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  115. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  116. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  117. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  118. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
  119. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  120. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  121. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  122. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  123. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  124. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  125. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  126. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  127. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  128. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  129. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  130. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  131. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  132. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  133. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  134. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  135. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  136. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  137. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  138. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  139. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/Cargo.toml +0 -0
  140. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/README.md +0 -0
  141. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/docs/api.md +0 -0
  142. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/docs/index.md +0 -0
  143. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  144. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  145. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  146. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/diff.rs +0 -0
  147. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/errors.rs +0 -0
  148. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/expr.rs +0 -0
  149. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/format.rs +0 -0
  150. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/generate.rs +0 -0
  151. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  152. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  153. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  154. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/parse.rs +0 -0
  155. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  156. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  157. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/types.rs +0 -0
  158. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/src/validate.rs +0 -0
  159. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  160. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  161. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  162. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  163. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  164. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  165. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  166. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  167. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  168. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  169. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  170. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/crates/polyglot-sql-python/uv.lock +0 -0
  171. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/pyproject.toml +0 -0
  172. {polyglot_sql-0.3.7 → polyglot_sql-0.3.10}/python/polyglot_sql/py.typed +0 -0
@@ -605,7 +605,7 @@ dependencies = [
605
605
 
606
606
  [[package]]
607
607
  name = "polyglot-sql"
608
- version = "0.3.7"
608
+ version = "0.3.10"
609
609
  dependencies = [
610
610
  "criterion",
611
611
  "once_cell",
@@ -621,7 +621,7 @@ dependencies = [
621
621
 
622
622
  [[package]]
623
623
  name = "polyglot-sql-ffi"
624
- version = "0.3.7"
624
+ version = "0.3.10"
625
625
  dependencies = [
626
626
  "cbindgen",
627
627
  "polyglot-sql",
@@ -631,11 +631,11 @@ dependencies = [
631
631
 
632
632
  [[package]]
633
633
  name = "polyglot-sql-function-catalogs"
634
- version = "0.3.7"
634
+ version = "0.3.10"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.3.7"
638
+ version = "0.3.10"
639
639
  dependencies = [
640
640
  "polyglot-sql",
641
641
  "pyo3",
@@ -646,7 +646,7 @@ dependencies = [
646
646
 
647
647
  [[package]]
648
648
  name = "polyglot-sql-wasm"
649
- version = "0.3.7"
649
+ version = "0.3.10"
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.7"
9
+ version = "0.3.10"
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.7
3
+ Version: 0.3.10
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.7", optional = true, default-features = false }
86
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.3.10", optional = true, default-features = false }
87
87
 
88
88
  [dev-dependencies]
89
89
  pretty_assertions = "1.4"
@@ -159,12 +159,61 @@ pub fn rename_columns(expr: Expression, mapping: &HashMap<String, String>) -> Ex
159
159
  })
160
160
  }
161
161
 
162
+ /// Options for table renaming.
163
+ #[derive(Debug, Clone)]
164
+ pub struct RenameTablesOptions {
165
+ /// Whether renamed table references should receive aliases.
166
+ pub alias_renamed_tables: bool,
167
+ /// Whether existing aliases should be preserved when aliasing renamed tables.
168
+ pub preserve_existing_aliases: bool,
169
+ }
170
+
171
+ impl Default for RenameTablesOptions {
172
+ fn default() -> Self {
173
+ Self {
174
+ alias_renamed_tables: false,
175
+ preserve_existing_aliases: true,
176
+ }
177
+ }
178
+ }
179
+
180
+ impl RenameTablesOptions {
181
+ pub fn new() -> Self {
182
+ Self::default()
183
+ }
184
+
185
+ pub fn with_alias_renamed_tables(mut self, alias: bool) -> Self {
186
+ self.alias_renamed_tables = alias;
187
+ self
188
+ }
189
+
190
+ pub fn with_preserve_existing_aliases(mut self, preserve: bool) -> Self {
191
+ self.preserve_existing_aliases = preserve;
192
+ self
193
+ }
194
+ }
195
+
162
196
  /// Rename tables throughout the expression tree using the provided mapping.
163
197
  pub fn rename_tables(expr: Expression, mapping: &HashMap<String, String>) -> Expression {
198
+ rename_tables_with_options(expr, mapping, &RenameTablesOptions::default())
199
+ }
200
+
201
+ /// Rename tables throughout the expression tree using the provided mapping and options.
202
+ pub fn rename_tables_with_options(
203
+ expr: Expression,
204
+ mapping: &HashMap<String, String>,
205
+ options: &RenameTablesOptions,
206
+ ) -> Expression {
164
207
  xform(expr, |node| match node {
165
208
  Expression::Table(mut tbl) => {
166
209
  if let Some(new_name) = mapping.get(&tbl.name.name) {
167
210
  tbl.name.name = new_name.clone();
211
+ if options.alias_renamed_tables
212
+ && (!options.preserve_existing_aliases || tbl.alias.is_none())
213
+ {
214
+ tbl.alias = Some(Identifier::new(new_name));
215
+ tbl.alias_explicit_as = true;
216
+ }
168
217
  }
169
218
  Expression::Table(tbl)
170
219
  }
@@ -701,6 +750,30 @@ mod tests {
701
750
  assert!(sql.contains("new_table"), "Expected new_table in: {}", sql);
702
751
  }
703
752
 
753
+ #[test]
754
+ fn test_rename_tables_with_alias_renamed_tables() {
755
+ let expr = parse_one("SELECT a FROM old_table");
756
+ let mut mapping = HashMap::new();
757
+ mapping.insert("old_table".to_string(), "new_table".to_string());
758
+ let options = RenameTablesOptions::new().with_alias_renamed_tables(true);
759
+ let result = rename_tables_with_options(expr, &mapping, &options);
760
+ let sql = result.sql();
761
+
762
+ assert_eq!(sql, "SELECT a FROM new_table AS new_table");
763
+ }
764
+
765
+ #[test]
766
+ fn test_rename_tables_with_alias_preserves_existing_alias() {
767
+ let expr = parse_one("SELECT a FROM old_table AS t");
768
+ let mut mapping = HashMap::new();
769
+ mapping.insert("old_table".to_string(), "new_table".to_string());
770
+ let options = RenameTablesOptions::new().with_alias_renamed_tables(true);
771
+ let result = rename_tables_with_options(expr, &mapping, &options);
772
+ let sql = result.sql();
773
+
774
+ assert_eq!(sql, "SELECT a FROM new_table AS t");
775
+ }
776
+
704
777
  #[test]
705
778
  fn test_set_distinct() {
706
779
  let expr = parse_one("SELECT a FROM t");
@@ -158,7 +158,10 @@ pub use trino::TrinoDialect;
158
158
  pub use tsql::TSQLDialect;
159
159
 
160
160
  use crate::error::Result;
161
- use crate::expressions::{Expression, Function, FunctionBody, Identifier, Null};
161
+ use crate::expressions::{
162
+ Expression, From, Function, FunctionBody, Identifier, Join, Null, OrderBy, OutputClause,
163
+ TableRef, With,
164
+ };
162
165
  use crate::generator::{Generator, GeneratorConfig};
163
166
  use crate::parser::Parser;
164
167
  use crate::tokens::{Token, TokenType, Tokenizer, TokenizerConfig};
@@ -1661,6 +1664,122 @@ where
1661
1664
  }
1662
1665
  }
1663
1666
 
1667
+ fn transform_table_ref_recursive<F>(table: TableRef, transform_fn: &F) -> Result<TableRef>
1668
+ where
1669
+ F: Fn(Expression) -> Result<Expression>,
1670
+ {
1671
+ match transform_recursive(Expression::Table(Box::new(table)), transform_fn)? {
1672
+ Expression::Table(table) => Ok(*table),
1673
+ _ => Err(crate::error::Error::parse(
1674
+ "TableRef transformation returned non-table expression",
1675
+ 0,
1676
+ 0,
1677
+ 0,
1678
+ 0,
1679
+ )),
1680
+ }
1681
+ }
1682
+
1683
+ fn transform_from_recursive<F>(from: From, transform_fn: &F) -> Result<From>
1684
+ where
1685
+ F: Fn(Expression) -> Result<Expression>,
1686
+ {
1687
+ match transform_recursive(Expression::From(Box::new(from)), transform_fn)? {
1688
+ Expression::From(from) => Ok(*from),
1689
+ _ => Err(crate::error::Error::parse(
1690
+ "FROM transformation returned non-FROM expression",
1691
+ 0,
1692
+ 0,
1693
+ 0,
1694
+ 0,
1695
+ )),
1696
+ }
1697
+ }
1698
+
1699
+ fn transform_join_recursive<F>(mut join: Join, transform_fn: &F) -> Result<Join>
1700
+ where
1701
+ F: Fn(Expression) -> Result<Expression>,
1702
+ {
1703
+ join.this = transform_recursive(join.this, transform_fn)?;
1704
+ if let Some(on) = join.on.take() {
1705
+ join.on = Some(transform_recursive(on, transform_fn)?);
1706
+ }
1707
+ if let Some(match_condition) = join.match_condition.take() {
1708
+ join.match_condition = Some(transform_recursive(match_condition, transform_fn)?);
1709
+ }
1710
+ join.pivots = join
1711
+ .pivots
1712
+ .into_iter()
1713
+ .map(|pivot| transform_recursive(pivot, transform_fn))
1714
+ .collect::<Result<Vec<_>>>()?;
1715
+
1716
+ match transform_fn(Expression::Join(Box::new(join)))? {
1717
+ Expression::Join(join) => Ok(*join),
1718
+ _ => Err(crate::error::Error::parse(
1719
+ "Join transformation returned non-join expression",
1720
+ 0,
1721
+ 0,
1722
+ 0,
1723
+ 0,
1724
+ )),
1725
+ }
1726
+ }
1727
+
1728
+ fn transform_output_clause_recursive<F>(
1729
+ mut output: OutputClause,
1730
+ transform_fn: &F,
1731
+ ) -> Result<OutputClause>
1732
+ where
1733
+ F: Fn(Expression) -> Result<Expression>,
1734
+ {
1735
+ output.columns = output
1736
+ .columns
1737
+ .into_iter()
1738
+ .map(|column| transform_recursive(column, transform_fn))
1739
+ .collect::<Result<Vec<_>>>()?;
1740
+ if let Some(into_table) = output.into_table.take() {
1741
+ output.into_table = Some(transform_recursive(into_table, transform_fn)?);
1742
+ }
1743
+ Ok(output)
1744
+ }
1745
+
1746
+ fn transform_with_recursive<F>(mut with: With, transform_fn: &F) -> Result<With>
1747
+ where
1748
+ F: Fn(Expression) -> Result<Expression>,
1749
+ {
1750
+ with.ctes = with
1751
+ .ctes
1752
+ .into_iter()
1753
+ .map(|mut cte| {
1754
+ cte.this = transform_recursive(cte.this, transform_fn)?;
1755
+ Ok(cte)
1756
+ })
1757
+ .collect::<Result<Vec<_>>>()?;
1758
+ if let Some(search) = with.search.take() {
1759
+ with.search = Some(Box::new(transform_recursive(*search, transform_fn)?));
1760
+ }
1761
+ Ok(with)
1762
+ }
1763
+
1764
+ fn transform_order_by_recursive<F>(mut order: OrderBy, transform_fn: &F) -> Result<OrderBy>
1765
+ where
1766
+ F: Fn(Expression) -> Result<Expression>,
1767
+ {
1768
+ order.expressions = order
1769
+ .expressions
1770
+ .into_iter()
1771
+ .map(|mut ordered| {
1772
+ let original = ordered.this.clone();
1773
+ ordered.this = transform_recursive(ordered.this, transform_fn).unwrap_or(original);
1774
+ match transform_fn(Expression::Ordered(Box::new(ordered.clone()))) {
1775
+ Ok(Expression::Ordered(transformed)) => Ok(*transformed),
1776
+ Ok(_) | Err(_) => Ok(ordered),
1777
+ }
1778
+ })
1779
+ .collect::<Result<Vec<_>>>()?;
1780
+ Ok(order)
1781
+ }
1782
+
1664
1783
  fn transform_recursive_reference<F>(expr: Expression, transform_fn: &F) -> Result<Expression>
1665
1784
  where
1666
1785
  F: Fn(Expression) -> Result<Expression>,
@@ -2377,6 +2496,17 @@ where
2377
2496
  Expression::Insert(ins)
2378
2497
  }
2379
2498
  Expression::Update(mut upd) => {
2499
+ upd.table = transform_table_ref_recursive(upd.table, transform_fn)?;
2500
+ upd.extra_tables = upd
2501
+ .extra_tables
2502
+ .into_iter()
2503
+ .map(|table| transform_table_ref_recursive(table, transform_fn))
2504
+ .collect::<Result<Vec<_>>>()?;
2505
+ upd.table_joins = upd
2506
+ .table_joins
2507
+ .into_iter()
2508
+ .map(|join| transform_join_recursive(join, transform_fn))
2509
+ .collect::<Result<Vec<_>>>()?;
2380
2510
  upd.set = upd
2381
2511
  .set
2382
2512
  .into_iter()
@@ -2385,17 +2515,75 @@ where
2385
2515
  (id, new_val)
2386
2516
  })
2387
2517
  .collect();
2518
+ if let Some(from_clause) = upd.from_clause.take() {
2519
+ upd.from_clause = Some(transform_from_recursive(from_clause, transform_fn)?);
2520
+ }
2521
+ upd.from_joins = upd
2522
+ .from_joins
2523
+ .into_iter()
2524
+ .map(|join| transform_join_recursive(join, transform_fn))
2525
+ .collect::<Result<Vec<_>>>()?;
2388
2526
  if let Some(mut where_clause) = upd.where_clause.take() {
2389
2527
  where_clause.this = transform_recursive(where_clause.this, transform_fn)?;
2390
2528
  upd.where_clause = Some(where_clause);
2391
2529
  }
2530
+ upd.returning = upd
2531
+ .returning
2532
+ .into_iter()
2533
+ .map(|expr| transform_recursive(expr, transform_fn))
2534
+ .collect::<Result<Vec<_>>>()?;
2535
+ if let Some(output) = upd.output.take() {
2536
+ upd.output = Some(transform_output_clause_recursive(output, transform_fn)?);
2537
+ }
2538
+ if let Some(with) = upd.with.take() {
2539
+ upd.with = Some(transform_with_recursive(with, transform_fn)?);
2540
+ }
2541
+ if let Some(limit) = upd.limit.take() {
2542
+ upd.limit = Some(transform_recursive(limit, transform_fn)?);
2543
+ }
2544
+ if let Some(order_by) = upd.order_by.take() {
2545
+ upd.order_by = Some(transform_order_by_recursive(order_by, transform_fn)?);
2546
+ }
2392
2547
  Expression::Update(upd)
2393
2548
  }
2394
2549
  Expression::Delete(mut del) => {
2550
+ del.table = transform_table_ref_recursive(del.table, transform_fn)?;
2551
+ del.using = del
2552
+ .using
2553
+ .into_iter()
2554
+ .map(|table| transform_table_ref_recursive(table, transform_fn))
2555
+ .collect::<Result<Vec<_>>>()?;
2395
2556
  if let Some(mut where_clause) = del.where_clause.take() {
2396
2557
  where_clause.this = transform_recursive(where_clause.this, transform_fn)?;
2397
2558
  del.where_clause = Some(where_clause);
2398
2559
  }
2560
+ if let Some(output) = del.output.take() {
2561
+ del.output = Some(transform_output_clause_recursive(output, transform_fn)?);
2562
+ }
2563
+ if let Some(with) = del.with.take() {
2564
+ del.with = Some(transform_with_recursive(with, transform_fn)?);
2565
+ }
2566
+ if let Some(limit) = del.limit.take() {
2567
+ del.limit = Some(transform_recursive(limit, transform_fn)?);
2568
+ }
2569
+ if let Some(order_by) = del.order_by.take() {
2570
+ del.order_by = Some(transform_order_by_recursive(order_by, transform_fn)?);
2571
+ }
2572
+ del.returning = del
2573
+ .returning
2574
+ .into_iter()
2575
+ .map(|expr| transform_recursive(expr, transform_fn))
2576
+ .collect::<Result<Vec<_>>>()?;
2577
+ del.tables = del
2578
+ .tables
2579
+ .into_iter()
2580
+ .map(|table| transform_table_ref_recursive(table, transform_fn))
2581
+ .collect::<Result<Vec<_>>>()?;
2582
+ del.joins = del
2583
+ .joins
2584
+ .into_iter()
2585
+ .map(|join| transform_join_recursive(join, transform_fn))
2586
+ .collect::<Result<Vec<_>>>()?;
2399
2587
  Expression::Delete(del)
2400
2588
  }
2401
2589
 
@@ -8097,15 +8285,21 @@ impl Dialect {
8097
8285
  if matches!(target, DialectType::MySQL) && o.nulls_first.is_some() {
8098
8286
  Action::MysqlNullsOrdering
8099
8287
  } else {
8100
- // Skip targets that don't support NULLS FIRST/LAST syntax
8288
+ // Skip targets that don't support NULLS FIRST/LAST syntax unless
8289
+ // the generator can preserve semantics with a CASE sort key.
8290
+ let target_rewrites_nulls =
8291
+ matches!(target, DialectType::TSQL | DialectType::Fabric);
8101
8292
  let target_supports_nulls = !matches!(
8102
8293
  target,
8103
8294
  DialectType::MySQL
8104
8295
  | DialectType::TSQL
8296
+ | DialectType::Fabric
8105
8297
  | DialectType::StarRocks
8106
8298
  | DialectType::Doris
8107
8299
  );
8108
- if o.nulls_first.is_none() && source != target && target_supports_nulls
8300
+ if o.nulls_first.is_none()
8301
+ && source != target
8302
+ && (target_supports_nulls || target_rewrites_nulls)
8109
8303
  {
8110
8304
  Action::NullsOrdering
8111
8305
  } else {
@@ -32060,7 +32254,7 @@ impl Dialect {
32060
32254
  match unit.trim().to_ascii_uppercase().as_str() {
32061
32255
  "YEAR" | "YEARS" => Some(IntervalUnit::Year),
32062
32256
  "QUARTER" | "QUARTERS" => Some(IntervalUnit::Quarter),
32063
- "MONTH" | "MONTHS" => Some(IntervalUnit::Month),
32257
+ "MONTH" | "MONTHS" | "MON" | "MONS" | "MM" => Some(IntervalUnit::Month),
32064
32258
  "WEEK" | "WEEKS" | "ISOWEEK" => Some(IntervalUnit::Week),
32065
32259
  "DAY" | "DAYS" => Some(IntervalUnit::Day),
32066
32260
  "HOUR" | "HOURS" => Some(IntervalUnit::Hour),
@@ -36732,7 +36926,9 @@ impl Dialect {
36732
36926
  match s {
36733
36927
  "YEAR" | "YY" | "YYYY" => crate::expressions::IntervalUnit::Year,
36734
36928
  "QUARTER" | "QQ" | "Q" => crate::expressions::IntervalUnit::Quarter,
36735
- "MONTH" | "MM" | "M" => crate::expressions::IntervalUnit::Month,
36929
+ "MONTH" | "MONTHS" | "MON" | "MONS" | "MM" | "M" => {
36930
+ crate::expressions::IntervalUnit::Month
36931
+ }
36736
36932
  "WEEK" | "WK" | "WW" | "ISOWEEK" => crate::expressions::IntervalUnit::Week,
36737
36933
  "DAY" | "DD" | "D" | "DY" => crate::expressions::IntervalUnit::Day,
36738
36934
  "HOUR" | "HH" => crate::expressions::IntervalUnit::Hour,
@@ -114,6 +114,7 @@ pub enum Expression {
114
114
  Copy(Box<CopyStmt>),
115
115
  Put(Box<PutStmt>),
116
116
  StageReference(Box<StageReference>),
117
+ TryCatch(Box<TryCatch>),
117
118
 
118
119
  // Expressions
119
120
  Alias(Box<Alias>),
@@ -1146,6 +1147,7 @@ impl Expression {
1146
1147
  | Expression::Copy(_)
1147
1148
  | Expression::Put(_)
1148
1149
  | Expression::Merge(_)
1150
+ | Expression::TryCatch(_)
1149
1151
 
1150
1152
  // DDL
1151
1153
  | Expression::CreateTable(_)
@@ -2229,6 +2231,7 @@ impl Expression {
2229
2231
  Expression::Describe(_) => "describe",
2230
2232
  Expression::Show(_) => "show",
2231
2233
  Expression::Command(_) => "command",
2234
+ Expression::TryCatch(_) => "try_catch",
2232
2235
  Expression::Kill(_) => "kill",
2233
2236
  Expression::Execute(_) => "execute",
2234
2237
  Expression::Raw(_) => "raw",
@@ -6003,6 +6006,18 @@ pub struct Command {
6003
6006
  pub this: String,
6004
6007
  }
6005
6008
 
6009
+ /// T-SQL TRY/CATCH block.
6010
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6011
+ #[cfg_attr(feature = "bindings", derive(TS))]
6012
+ pub struct TryCatch {
6013
+ /// Statements inside BEGIN TRY ... END TRY.
6014
+ #[serde(default)]
6015
+ pub try_body: Vec<Expression>,
6016
+ /// Statements inside BEGIN CATCH ... END CATCH, when present.
6017
+ #[serde(default, skip_serializing_if = "Option::is_none")]
6018
+ pub catch_body: Option<Vec<Expression>>,
6019
+ }
6020
+
6006
6021
  /// EXEC/EXECUTE statement (TSQL stored procedure call)
6007
6022
  /// Syntax: EXEC [schema.]procedure_name [@param=value, ...]
6008
6023
  #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -3342,6 +3342,7 @@ impl Generator {
3342
3342
  Ok(())
3343
3343
  }
3344
3344
  Expression::CreateTask(task) => self.generate_create_task(task),
3345
+ Expression::TryCatch(try_catch) => self.generate_try_catch(try_catch),
3345
3346
  Expression::Command(cmd) => {
3346
3347
  self.write(&cmd.this);
3347
3348
  Ok(())
@@ -4802,7 +4803,10 @@ impl Generator {
4802
4803
  } else {
4803
4804
  self.write_space();
4804
4805
  }
4805
- if matches!(self.config.dialect, Some(DialectType::TSQL)) {
4806
+ if matches!(
4807
+ self.config.dialect,
4808
+ Some(DialectType::TSQL) | Some(DialectType::Fabric)
4809
+ ) {
4806
4810
  // SQL Server 2012+ OFFSET ... FETCH syntax
4807
4811
  self.write_keyword("OFFSET");
4808
4812
  self.write_space();
@@ -14109,6 +14113,58 @@ impl Generator {
14109
14113
  Ok(())
14110
14114
  }
14111
14115
 
14116
+ fn generate_try_catch(&mut self, try_catch: &TryCatch) -> Result<()> {
14117
+ self.write_keyword("BEGIN TRY");
14118
+ self.generate_tsql_block_statements(&try_catch.try_body)?;
14119
+ self.write_keyword("END TRY");
14120
+
14121
+ if let Some(catch_body) = &try_catch.catch_body {
14122
+ if self.config.pretty {
14123
+ self.write_newline();
14124
+ self.write_indent();
14125
+ } else {
14126
+ self.write_space();
14127
+ }
14128
+ self.write_keyword("BEGIN CATCH");
14129
+ self.generate_tsql_block_statements(catch_body)?;
14130
+ self.write_keyword("END CATCH");
14131
+ }
14132
+
14133
+ Ok(())
14134
+ }
14135
+
14136
+ fn generate_tsql_block_statements(&mut self, statements: &[Expression]) -> Result<()> {
14137
+ if statements.is_empty() {
14138
+ self.write_space();
14139
+ return Ok(());
14140
+ }
14141
+
14142
+ if self.config.pretty {
14143
+ self.indent_level += 1;
14144
+ for stmt in statements {
14145
+ self.write_newline();
14146
+ self.write_indent();
14147
+ self.generate_expression(stmt)?;
14148
+ self.write(";");
14149
+ }
14150
+ self.indent_level -= 1;
14151
+ self.write_newline();
14152
+ self.write_indent();
14153
+ } else {
14154
+ self.write_space();
14155
+ for (i, stmt) in statements.iter().enumerate() {
14156
+ if i > 0 {
14157
+ self.write_space();
14158
+ }
14159
+ self.generate_expression(stmt)?;
14160
+ self.write(";");
14161
+ }
14162
+ self.write_space();
14163
+ }
14164
+
14165
+ Ok(())
14166
+ }
14167
+
14112
14168
  fn generate_drop_type(&mut self, dt: &DropType) -> Result<()> {
14113
14169
  self.write_keyword("DROP TYPE");
14114
14170
 
@@ -18528,7 +18584,7 @@ impl Generator {
18528
18584
  };
18529
18585
  match lower {
18530
18586
  "day" | "days" | "d" => "DAY".to_string(),
18531
- "month" | "months" | "mon" | "mm" => "MONTH".to_string(),
18587
+ "month" | "months" | "mon" | "mons" | "mm" => "MONTH".to_string(),
18532
18588
  "year" | "years" | "y" | "yy" | "yyyy" => "YEAR".to_string(),
18533
18589
  "week" | "weeks" | "w" | "wk" => "WEEK".to_string(),
18534
18590
  "hour" | "hours" | "h" | "hh" => "HOUR".to_string(),
@@ -23159,6 +23215,36 @@ impl Generator {
23159
23215
  }
23160
23216
 
23161
23217
  fn generate_ordered(&mut self, ordered: &Ordered) -> Result<()> {
23218
+ let unsupported_tsql_null_ordering = ordered.nulls_first.is_some()
23219
+ && !self.config.null_ordering_supported
23220
+ && matches!(
23221
+ self.config.dialect,
23222
+ Some(DialectType::TSQL) | Some(DialectType::Fabric)
23223
+ );
23224
+ let random_ordering = matches!(ordered.this, Expression::Rand(_) | Expression::Random(_));
23225
+ let emulate_tsql_null_ordering = if let Some(nulls_first) = ordered.nulls_first {
23226
+ let target_default_nulls_first = !ordered.desc;
23227
+
23228
+ unsupported_tsql_null_ordering
23229
+ && nulls_first != target_default_nulls_first
23230
+ && !random_ordering
23231
+ } else {
23232
+ false
23233
+ };
23234
+
23235
+ if emulate_tsql_null_ordering {
23236
+ self.write_keyword("CASE WHEN");
23237
+ self.write_space();
23238
+ self.generate_expression(&ordered.this)?;
23239
+ self.write_space();
23240
+ self.write_keyword("IS NULL THEN 1 ELSE 0 END");
23241
+ if ordered.nulls_first == Some(true) {
23242
+ self.write_space();
23243
+ self.write_keyword("DESC");
23244
+ }
23245
+ self.write(", ");
23246
+ }
23247
+
23162
23248
  self.generate_expression(&ordered.this)?;
23163
23249
  if ordered.desc {
23164
23250
  self.write_space();
@@ -23168,8 +23254,9 @@ impl Generator {
23168
23254
  self.write_keyword("ASC");
23169
23255
  }
23170
23256
  if let Some(nulls_first) = ordered.nulls_first {
23171
- if self.config.null_ordering_supported
23172
- || !matches!(self.config.dialect, Some(DialectType::Fabric))
23257
+ if !unsupported_tsql_null_ordering
23258
+ && (self.config.null_ordering_supported
23259
+ || !matches!(self.config.dialect, Some(DialectType::Fabric)))
23173
23260
  {
23174
23261
  // Determine if we should skip outputting NULLS FIRST/LAST when it's the default
23175
23262
  // for the dialect. Different dialects have different NULL ordering defaults:
@@ -42,8 +42,8 @@ pub use ast_transforms::{
42
42
  add_select_columns, add_where, get_aggregate_functions, get_column_names, get_functions,
43
43
  get_identifiers, get_literals, get_output_column_names, get_subqueries, get_table_names,
44
44
  get_window_functions, node_count, qualify_columns, remove_limit_offset, remove_nodes,
45
- remove_select_columns, remove_where, rename_columns, rename_tables, replace_by_type,
46
- replace_nodes, set_distinct, set_limit, set_offset,
45
+ remove_select_columns, remove_where, rename_columns, rename_tables, rename_tables_with_options,
46
+ replace_by_type, replace_nodes, set_distinct, set_limit, set_offset, RenameTablesOptions,
47
47
  };
48
48
  pub use dialects::{
49
49
  unregister_custom_dialect, CustomDialectBuilder, Dialect, DialectType, TranspileOptions,
@@ -59,7 +59,9 @@ pub use helper::{
59
59
  csv, find_new_name, is_date_unit, is_float, is_int, is_iso_date, is_iso_datetime, merge_ranges,
60
60
  name_sequence, seq_get, split_num_words, tsort, while_changing, DATE_UNITS,
61
61
  };
62
- pub use optimizer::{annotate_types, TypeAnnotator, TypeCoercionClass};
62
+ pub use optimizer::{
63
+ annotate_types, qualify_tables, QualifyTablesOptions, TypeAnnotator, TypeCoercionClass,
64
+ };
63
65
  pub use parser::Parser;
64
66
  pub use resolver::{is_column_ambiguous, resolve_column, Resolver, ResolverError, ResolverResult};
65
67
  pub use schema::{
@@ -1658,6 +1658,16 @@ fn collect_column_refs(expr: &Expression, refs: &mut Vec<SimpleColumnRef>) {
1658
1658
  Expression::NamedArgument(n) => {
1659
1659
  stack.push(&n.value);
1660
1660
  }
1661
+ Expression::TryCatch(t) => {
1662
+ for stmt in &t.try_body {
1663
+ stack.push(stmt);
1664
+ }
1665
+ if let Some(catch_body) = &t.catch_body {
1666
+ for stmt in catch_body {
1667
+ stack.push(stmt);
1668
+ }
1669
+ }
1670
+ }
1661
1671
  Expression::BracedWildcard(e) | Expression::ReturnStmt(e) => {
1662
1672
  stack.push(e);
1663
1673
  }