polyglot-sql 0.6.2__tar.gz → 0.6.3__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 (203) hide show
  1. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/Cargo.lock +6 -6
  2. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/Cargo.toml +1 -1
  3. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/PKG-INFO +1 -1
  4. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/Cargo.toml +2 -2
  5. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/README.md +1 -1
  6. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/athena.rs +2 -0
  7. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/bigquery.rs +3 -0
  8. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/duckdb.rs +1 -0
  9. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/mod.rs +382 -2
  10. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/mysql.rs +50 -0
  11. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/collections.rs +7 -0
  12. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/mod.rs +5 -3
  13. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/scalar.rs +1 -0
  14. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/temporal.rs +37 -27
  15. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/postgres.rs +2 -0
  16. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/presto.rs +2 -0
  17. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/trino.rs +2 -0
  18. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/tsql.rs +97 -23
  19. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/expressions.rs +119 -0
  20. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/generator.rs +642 -31
  21. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/lib.rs +4 -4
  22. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/lineage.rs +421 -57
  23. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/openlineage.rs +2 -2
  24. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/annotate_types.rs +445 -4
  25. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/parser.rs +802 -108
  26. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/query_analysis.rs +5 -92
  27. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/tokens.rs +0 -2
  28. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/transforms.rs +10 -0
  29. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/validation.rs +64 -1
  30. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/dialect_matrix.rs +41 -3
  31. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/fabric_regression.rs +261 -26
  32. polyglot_sql-0.6.3/crates/polyglot-sql/tests/oracle_data_types_regression.rs +285 -0
  33. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/query_analysis.rs +77 -0
  34. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_compat.rs +63 -0
  35. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/tsql_regression.rs +308 -25
  36. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/annotate_types.rs +9 -3
  37. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/lineage.rs +7 -1
  38. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/README.md +0 -0
  39. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/allocation_hotspots.rs +0 -0
  40. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/ast_traversal.rs +0 -0
  41. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/in_list.rs +0 -0
  42. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/lineage.rs +0 -0
  43. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/parsing.rs +0 -0
  44. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/performance_hotspots.rs +0 -0
  45. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  46. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/benches/transpile.rs +0 -0
  47. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  48. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  49. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/ast_children.rs +0 -0
  50. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/ast_json.rs +0 -0
  51. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  52. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/builder.rs +0 -0
  53. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  54. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  55. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  56. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  57. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  58. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  59. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  60. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  61. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  62. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  63. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  64. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  65. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  66. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  67. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +0 -0
  68. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/json.rs +0 -0
  69. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/operators.rs +0 -0
  70. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/postgres_interval.rs +0 -0
  71. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/statements.rs +0 -0
  72. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/normalization/types.rs +0 -0
  73. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  74. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  75. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  76. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  77. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
  78. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  79. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  80. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  81. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  82. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  83. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  84. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  85. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/diff.rs +0 -0
  86. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/error.rs +0 -0
  87. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/format_tokens.rs +0 -0
  88. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  89. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/function_registry.rs +0 -0
  90. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/guard.rs +0 -0
  91. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/helper.rs +0 -0
  92. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  93. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  94. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  95. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  96. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  97. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  98. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  99. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  100. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  101. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  102. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  103. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
  104. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  105. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  106. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  107. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/planner.rs +0 -0
  108. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/resolver.rs +0 -0
  109. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/schema.rs +0 -0
  110. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/scope.rs +0 -0
  111. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/time.rs +0 -0
  112. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/traversal.rs +0 -0
  113. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/trie.rs +0 -0
  114. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  115. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  116. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  117. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  118. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  119. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  120. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  121. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/create_view_security_comment_regression.rs +0 -0
  122. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  123. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  124. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  125. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  126. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  127. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  128. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  129. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  130. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  131. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  132. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  133. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  134. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
  135. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  136. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  137. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
  138. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  139. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/postgres_explain_options.rs +0 -0
  140. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/postgres_regexp_clickhouse.rs +0 -0
  141. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  142. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
  143. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  144. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  145. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  146. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  147. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  148. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  149. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  150. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  151. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  152. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  153. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-ast-derive/Cargo.toml +0 -0
  154. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-ast-derive/src/lib.rs +0 -0
  155. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  156. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  157. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  158. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  159. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  160. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  161. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  162. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/Cargo.toml +0 -0
  163. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/README.md +0 -0
  164. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/docs/api.md +0 -0
  165. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/docs/index.md +0 -0
  166. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  167. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  168. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/diff.rs +0 -0
  169. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/errors.rs +0 -0
  170. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/expr.rs +0 -0
  171. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  172. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/format.rs +0 -0
  173. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/generate.rs +0 -0
  174. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  175. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/lib.rs +0 -0
  176. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
  177. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  178. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/parse.rs +0 -0
  179. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
  180. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  181. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/transforms.rs +0 -0
  182. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  183. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/types.rs +0 -0
  184. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/src/validate.rs +0 -0
  185. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  186. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  187. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  188. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  189. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  190. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  191. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  192. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  193. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  194. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
  195. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_query_analysis.py +0 -0
  196. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
  197. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  198. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  199. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/crates/polyglot-sql-python/uv.lock +0 -0
  200. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/pyproject.toml +0 -0
  201. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/python/polyglot_sql/__init__.py +0 -0
  202. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/python/polyglot_sql/__init__.pyi +0 -0
  203. {polyglot_sql-0.6.2 → polyglot_sql-0.6.3}/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.6.2"
608
+ version = "0.6.3"
609
609
  dependencies = [
610
610
  "criterion",
611
611
  "once_cell",
@@ -623,7 +623,7 @@ dependencies = [
623
623
 
624
624
  [[package]]
625
625
  name = "polyglot-sql-ast-derive"
626
- version = "0.6.2"
626
+ version = "0.6.3"
627
627
  dependencies = [
628
628
  "proc-macro2",
629
629
  "quote",
@@ -632,7 +632,7 @@ dependencies = [
632
632
 
633
633
  [[package]]
634
634
  name = "polyglot-sql-ffi"
635
- version = "0.6.2"
635
+ version = "0.6.3"
636
636
  dependencies = [
637
637
  "cbindgen",
638
638
  "polyglot-sql",
@@ -642,11 +642,11 @@ dependencies = [
642
642
 
643
643
  [[package]]
644
644
  name = "polyglot-sql-function-catalogs"
645
- version = "0.6.2"
645
+ version = "0.6.3"
646
646
 
647
647
  [[package]]
648
648
  name = "polyglot-sql-python"
649
- version = "0.6.2"
649
+ version = "0.6.3"
650
650
  dependencies = [
651
651
  "polyglot-sql",
652
652
  "pyo3",
@@ -657,7 +657,7 @@ dependencies = [
657
657
 
658
658
  [[package]]
659
659
  name = "polyglot-sql-wasm"
660
- version = "0.6.2"
660
+ version = "0.6.3"
661
661
  dependencies = [
662
662
  "console_error_panic_hook",
663
663
  "js-sys",
@@ -6,7 +6,7 @@ exclude = [
6
6
  ]
7
7
 
8
8
  [workspace.package]
9
- version = "0.6.2"
9
+ version = "0.6.3"
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.6.2
3
+ Version: 0.6.3
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -100,14 +100,14 @@ function-catalog-all-dialects = [
100
100
  ]
101
101
 
102
102
  [dependencies]
103
- polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.6.2" }
103
+ polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.6.3" }
104
104
  serde = { workspace = true }
105
105
  serde_json = { workspace = true }
106
106
  thiserror = { workspace = true }
107
107
  unicode-segmentation = { workspace = true }
108
108
  stacker = { version = "0.1", optional = true }
109
109
  ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
110
- polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.6.2", optional = true, default-features = false }
110
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.6.3", optional = true, default-features = false }
111
111
 
112
112
  [dev-dependencies]
113
113
  pretty_assertions = "1.4"
@@ -25,7 +25,7 @@ By default, `polyglot-sql` enables the full public API. Parser-only consumers ca
25
25
  disable default features and opt into only the dialect parsers they need:
26
26
 
27
27
  ```toml
28
- polyglot-sql = { version = "0.6.2", default-features = false }
28
+ polyglot-sql = { version = "0.6.3", default-features = false }
29
29
  ```
30
30
 
31
31
  ```toml
@@ -147,6 +147,7 @@ impl DialectImpl for AthenaDialect {
147
147
  with_ordinality: false,
148
148
  alias: None,
149
149
  offset_alias: None,
150
+ inferred_type: None,
150
151
  },
151
152
  ))),
152
153
 
@@ -158,6 +159,7 @@ impl DialectImpl for AthenaDialect {
158
159
  with_ordinality: false,
159
160
  alias: None,
160
161
  offset_alias: None,
162
+ inferred_type: None,
161
163
  },
162
164
  ))),
163
165
 
@@ -196,6 +196,7 @@ impl DialectImpl for BigQueryDialect {
196
196
  with_ordinality: false,
197
197
  alias: None,
198
198
  offset_alias: None,
199
+ inferred_type: None,
199
200
  },
200
201
  ))),
201
202
 
@@ -207,6 +208,7 @@ impl DialectImpl for BigQueryDialect {
207
208
  with_ordinality: false,
208
209
  alias: None,
209
210
  offset_alias: None,
211
+ inferred_type: None,
210
212
  },
211
213
  ))),
212
214
 
@@ -703,6 +705,7 @@ impl DialectImpl for BigQueryDialect {
703
705
  with_ordinality: false,
704
706
  alias: None,
705
707
  offset_alias: None,
708
+ inferred_type: None,
706
709
  }));
707
710
  let aliased_unnest = Expression::Alias(Box::new(Alias {
708
711
  this: unnest,
@@ -238,6 +238,7 @@ impl DialectImpl for DuckDBDialect {
238
238
  with_ordinality: false,
239
239
  alias: None,
240
240
  offset_alias: None,
241
+ inferred_type: None,
241
242
  },
242
243
  ))),
243
244
 
@@ -163,8 +163,8 @@ use crate::error::Result;
163
163
  #[cfg(feature = "transpile")]
164
164
  use crate::expressions::{
165
165
  BinaryOp, Case, Cast, ColumnConstraint, DateBin, Fetch, Function, Identifier, Interval,
166
- IntervalUnit, IntervalUnitSpec, Literal, Offset, Over, Top, Var, WindowFrame, WindowFrameBound,
167
- WindowFrameKind,
166
+ IntervalUnit, IntervalUnitSpec, Literal, Offset, Over, Select, Subquery, Top, Var, WindowFrame,
167
+ WindowFrameBound, WindowFrameKind,
168
168
  };
169
169
  use crate::expressions::{DataType, Expression};
170
170
  #[cfg(any(
@@ -181,6 +181,8 @@ use crate::generator::{Generator, GeneratorConfig};
181
181
  #[cfg(feature = "transpile")]
182
182
  use crate::guard::enforce_generate_ast;
183
183
  use crate::guard::{enforce_input, ComplexityGuardOptions};
184
+ #[cfg(feature = "transpile")]
185
+ use crate::helper::find_new_name;
184
186
  use crate::parser::Parser;
185
187
  #[cfg(feature = "transpile")]
186
188
  use crate::tokens::TokenType;
@@ -274,6 +276,16 @@ pub enum DialectType {
274
276
  DataFusion,
275
277
  }
276
278
 
279
+ impl DialectType {
280
+ /// Whether SELECT projections may use string literals as column aliases.
281
+ pub(crate) const fn supports_string_aliases(self) -> bool {
282
+ matches!(
283
+ self,
284
+ DialectType::TSQL | DialectType::Fabric | DialectType::MySQL | DialectType::SQLite
285
+ )
286
+ }
287
+ }
288
+
277
289
  impl Default for DialectType {
278
290
  fn default() -> Self {
279
291
  DialectType::Generic
@@ -3858,6 +3870,14 @@ impl Dialect {
3858
3870
  normalized
3859
3871
  };
3860
3872
 
3873
+ let normalized = if self.dialect_type == DialectType::PostgreSQL
3874
+ && matches!(target, DialectType::TSQL | DialectType::Fabric)
3875
+ {
3876
+ Self::normalize_postgres_bytea_literals_for_tsql(normalized)?
3877
+ } else {
3878
+ normalized
3879
+ };
3880
+
3861
3881
  let normalized = if matches!(
3862
3882
  self.dialect_type,
3863
3883
  DialectType::PostgreSQL | DialectType::CockroachDB
@@ -3917,6 +3937,11 @@ impl Dialect {
3917
3937
  let normalized = if matches!(target, DialectType::TSQL | DialectType::Fabric)
3918
3938
  && !matches!(self.dialect_type, DialectType::TSQL | DialectType::Fabric)
3919
3939
  {
3940
+ let normalized = if self.dialect_type == DialectType::PostgreSQL {
3941
+ Self::rewrite_postgres_row_value_equality_for_tsql(normalized)?
3942
+ } else {
3943
+ normalized
3944
+ };
3920
3945
  Self::rewrite_boolean_values_for_tsql(normalized)?
3921
3946
  } else {
3922
3947
  normalized
@@ -4422,6 +4447,16 @@ impl Dialect {
4422
4447
  &format!("PostgreSQL {string_semantics}"),
4423
4448
  );
4424
4449
  }
4450
+ if source == DialectType::PostgreSQL {
4451
+ if let Some(binary_semantics) =
4452
+ Self::postgres_tsql_unsupported_binary_semantics(node)
4453
+ {
4454
+ Self::push_unsupported_diagnostic(
4455
+ &mut diagnostics,
4456
+ &format!("PostgreSQL {binary_semantics}"),
4457
+ );
4458
+ }
4459
+ }
4425
4460
  if let Some(function_name) =
4426
4461
  Self::postgres_tsql_unsupported_function_name(node, target)
4427
4462
  {
@@ -6093,6 +6128,110 @@ impl Dialect {
6093
6128
  })
6094
6129
  }
6095
6130
 
6131
+ fn normalize_postgres_bytea_literals_for_tsql(expr: Expression) -> Result<Expression> {
6132
+ transform_recursive(expr, &|e| match e {
6133
+ Expression::Cast(cast) if Self::is_postgres_bytea_data_type(&cast.to) => {
6134
+ let Some(value) = Self::postgres_plain_string_literal_value(&cast.this) else {
6135
+ return Ok(Expression::Cast(cast));
6136
+ };
6137
+ let Some(hex) = Self::postgres_bytea_hex_payload(value) else {
6138
+ return Ok(Expression::Cast(cast));
6139
+ };
6140
+
6141
+ // Replace the complete BYTEA cast. Keeping a bare T-SQL
6142
+ // CAST(... AS VARBINARY) would apply SQL Server's default length
6143
+ // and could truncate payloads longer than 30 bytes.
6144
+ Ok(Expression::Literal(Box::new(Literal::HexString(hex))))
6145
+ }
6146
+ other => Ok(other),
6147
+ })
6148
+ }
6149
+
6150
+ fn postgres_plain_string_literal_value(expr: &Expression) -> Option<&str> {
6151
+ match expr {
6152
+ Expression::Literal(literal) => match literal.as_ref() {
6153
+ Literal::String(value) => Some(value),
6154
+ _ => None,
6155
+ },
6156
+ Expression::Paren(paren) => Self::postgres_plain_string_literal_value(&paren.this),
6157
+ _ => None,
6158
+ }
6159
+ }
6160
+
6161
+ fn postgres_bytea_hex_payload(value: &str) -> Option<String> {
6162
+ let payload = value.strip_prefix("\\x")?;
6163
+ if payload.is_empty() {
6164
+ return Some(String::new());
6165
+ }
6166
+
6167
+ let mut chars = payload.chars().peekable();
6168
+ let mut hex = String::with_capacity(payload.len());
6169
+ loop {
6170
+ let high = chars.next()?;
6171
+ let low = chars.next()?;
6172
+ if !high.is_ascii_hexdigit() || !low.is_ascii_hexdigit() {
6173
+ return None;
6174
+ }
6175
+ hex.push(high);
6176
+ hex.push(low);
6177
+
6178
+ let Some(next) = chars.peek().copied() else {
6179
+ return Some(hex);
6180
+ };
6181
+ if next.is_ascii_whitespace() {
6182
+ while chars
6183
+ .peek()
6184
+ .is_some_and(|character| character.is_ascii_whitespace())
6185
+ {
6186
+ chars.next();
6187
+ }
6188
+ // PostgreSQL permits whitespace between byte pairs, not after
6189
+ // the prefix or after the final pair.
6190
+ chars.peek()?;
6191
+ }
6192
+ }
6193
+ }
6194
+
6195
+ fn is_postgres_bytea_data_type(data_type: &DataType) -> bool {
6196
+ match data_type {
6197
+ DataType::VarBinary { length: None } => true,
6198
+ DataType::Custom { name } => name.trim().eq_ignore_ascii_case("BYTEA"),
6199
+ _ => false,
6200
+ }
6201
+ }
6202
+
6203
+ fn postgres_tsql_unsupported_binary_semantics(expr: &Expression) -> Option<&'static str> {
6204
+ let cast = match expr {
6205
+ Expression::Cast(cast) | Expression::TryCast(cast) | Expression::SafeCast(cast)
6206
+ if Self::is_postgres_bytea_data_type(&cast.to) =>
6207
+ {
6208
+ cast
6209
+ }
6210
+ _ => return None,
6211
+ };
6212
+
6213
+ let literal = match &cast.this {
6214
+ Expression::Literal(literal) => literal.as_ref(),
6215
+ Expression::Paren(paren) => match &paren.this {
6216
+ Expression::Literal(literal) => literal.as_ref(),
6217
+ _ => return None,
6218
+ },
6219
+ _ => return None,
6220
+ };
6221
+ let value = match literal {
6222
+ Literal::String(value) | Literal::EscapeString(value) => value,
6223
+ _ => return None,
6224
+ };
6225
+
6226
+ if value.starts_with("\\x") {
6227
+ Some("bytea hex literals with invalid or unsupported formatting")
6228
+ } else if value.contains('\\') {
6229
+ Some("bytea escape-format literals")
6230
+ } else {
6231
+ None
6232
+ }
6233
+ }
6234
+
6096
6235
  fn recover_postgres_like_escape(op: &mut crate::expressions::LikeOp) {
6097
6236
  if op.escape.is_some() {
6098
6237
  return;
@@ -6616,6 +6755,247 @@ impl Dialect {
6616
6755
  }
6617
6756
  }
6618
6757
 
6758
+ fn rewrite_postgres_row_value_equality_for_tsql(expr: Expression) -> Result<Expression> {
6759
+ transform_recursive(expr, &|e| match e {
6760
+ Expression::Eq(op) => {
6761
+ let op = *op;
6762
+ Ok(Self::postgres_row_value_equality_to_tsql_scalar(&op)
6763
+ .unwrap_or_else(|| Expression::Eq(Box::new(op))))
6764
+ }
6765
+ other => Ok(other),
6766
+ })
6767
+ }
6768
+
6769
+ fn postgres_row_value_equality_to_tsql_scalar(op: &BinaryOp) -> Option<Expression> {
6770
+ let (row, query) =
6771
+ if Self::expr_is_row_value(&op.left) && Self::expr_is_subquery_like(&op.right) {
6772
+ (&op.left, &op.right)
6773
+ } else if Self::expr_is_row_value(&op.right) && Self::expr_is_subquery_like(&op.left) {
6774
+ (&op.right, &op.left)
6775
+ } else {
6776
+ return None;
6777
+ };
6778
+
6779
+ let row_values = Self::row_value_expressions(row)?;
6780
+ let projection_count = Self::subquery_projection_count(query)?;
6781
+ if row_values.is_empty() || row_values.len() != projection_count {
6782
+ return None;
6783
+ }
6784
+
6785
+ // Keep the complete original query behind a derived table. The outer scalar
6786
+ // SELECT therefore returns the same number of rows as the PostgreSQL
6787
+ // single-row subquery: zero rows stay NULL and multiple rows still raise a
6788
+ // scalar-subquery cardinality error in T-SQL/Fabric.
6789
+ let mut taken_names = HashSet::new();
6790
+ Self::collect_generated_alias_conflicts(row, &mut taken_names);
6791
+ Self::collect_generated_alias_conflicts(query, &mut taken_names);
6792
+
6793
+ let source_alias = find_new_name(&taken_names, "_polyglot_row");
6794
+ taken_names.insert(source_alias.to_ascii_lowercase());
6795
+ let column_aliases = (1..=row_values.len())
6796
+ .map(|index| {
6797
+ let name = find_new_name(&taken_names, &format!("_polyglot_row_value_{index}"));
6798
+ taken_names.insert(name.to_ascii_lowercase());
6799
+ Identifier::new(name)
6800
+ })
6801
+ .collect::<Vec<_>>();
6802
+ let source = Self::subquery_as_derived_table(
6803
+ query,
6804
+ Identifier::new(&source_alias),
6805
+ column_aliases.clone(),
6806
+ )?;
6807
+
6808
+ let mut equal_components = Vec::with_capacity(row_values.len());
6809
+ let mut unequal_components = Vec::with_capacity(row_values.len());
6810
+ for (column, row_value) in column_aliases.into_iter().zip(row_values) {
6811
+ let projected = Expression::qualified_column(source_alias.clone(), column.name);
6812
+ equal_components.push(Expression::Eq(Box::new(BinaryOp::new(
6813
+ projected.clone(),
6814
+ row_value.clone(),
6815
+ ))));
6816
+ unequal_components.push(Expression::Neq(Box::new(BinaryOp::new(
6817
+ projected, row_value,
6818
+ ))));
6819
+ }
6820
+
6821
+ let all_equal = equal_components
6822
+ .into_iter()
6823
+ .reduce(|left, right| Expression::And(Box::new(BinaryOp::new(left, right))))?;
6824
+ let any_unequal = unequal_components
6825
+ .into_iter()
6826
+ .reduce(|left, right| Expression::Or(Box::new(BinaryOp::new(left, right))))?;
6827
+ let comparison = Expression::Case(Box::new(Case {
6828
+ operand: None,
6829
+ whens: vec![
6830
+ (all_equal, Expression::number(1)),
6831
+ (any_unequal, Expression::number(0)),
6832
+ ],
6833
+ else_: Some(Expression::null()),
6834
+ comments: Vec::new(),
6835
+ inferred_type: None,
6836
+ }));
6837
+
6838
+ let scalar_select = Select::new().column(comparison).from(source);
6839
+ let scalar_subquery = Expression::Subquery(Box::new(Subquery {
6840
+ this: Expression::Select(Box::new(scalar_select)),
6841
+ alias: None,
6842
+ column_aliases: Vec::new(),
6843
+ alias_explicit_as: false,
6844
+ alias_keyword: None,
6845
+ order_by: None,
6846
+ limit: None,
6847
+ offset: None,
6848
+ distribute_by: None,
6849
+ sort_by: None,
6850
+ cluster_by: None,
6851
+ lateral: false,
6852
+ modifiers_inside: false,
6853
+ trailing_comments: Vec::new(),
6854
+ inferred_type: Some(DataType::Boolean),
6855
+ }));
6856
+
6857
+ Some(Expression::Cast(Box::new(Cast {
6858
+ this: scalar_subquery,
6859
+ to: DataType::Boolean,
6860
+ trailing_comments: Vec::new(),
6861
+ double_colon_syntax: false,
6862
+ format: None,
6863
+ default: None,
6864
+ inferred_type: Some(DataType::Boolean),
6865
+ })))
6866
+ }
6867
+
6868
+ fn row_value_expressions(expr: &Expression) -> Option<Vec<Expression>> {
6869
+ match expr {
6870
+ Expression::Tuple(tuple) => Some(tuple.expressions.clone()),
6871
+ Expression::Function(function) if function.name.eq_ignore_ascii_case("ROW") => {
6872
+ Some(function.args.clone())
6873
+ }
6874
+ Expression::Paren(paren) => Self::row_value_expressions(&paren.this),
6875
+ _ => None,
6876
+ }
6877
+ }
6878
+
6879
+ fn subquery_projection_count(expr: &Expression) -> Option<usize> {
6880
+ match expr {
6881
+ Expression::Select(select) => Some(select.expressions.len()),
6882
+ Expression::Subquery(subquery) => Self::subquery_projection_count(&subquery.this),
6883
+ Expression::Paren(paren) => Self::subquery_projection_count(&paren.this),
6884
+ _ => None,
6885
+ }
6886
+ }
6887
+
6888
+ fn subquery_as_derived_table(
6889
+ expr: &Expression,
6890
+ alias: Identifier,
6891
+ column_aliases: Vec<Identifier>,
6892
+ ) -> Option<Expression> {
6893
+ match expr.clone() {
6894
+ Expression::Subquery(mut subquery) => {
6895
+ subquery.alias = Some(alias);
6896
+ subquery.column_aliases = column_aliases;
6897
+ subquery.alias_explicit_as = true;
6898
+ subquery.alias_keyword = None;
6899
+ Some(Expression::Subquery(subquery))
6900
+ }
6901
+ Expression::Select(_) | Expression::Paren(_) => {
6902
+ Some(Expression::Subquery(Box::new(Subquery {
6903
+ this: expr.clone(),
6904
+ alias: Some(alias),
6905
+ column_aliases,
6906
+ alias_explicit_as: true,
6907
+ alias_keyword: None,
6908
+ order_by: None,
6909
+ limit: None,
6910
+ offset: None,
6911
+ distribute_by: None,
6912
+ sort_by: None,
6913
+ cluster_by: None,
6914
+ lateral: false,
6915
+ modifiers_inside: false,
6916
+ trailing_comments: Vec::new(),
6917
+ inferred_type: None,
6918
+ })))
6919
+ }
6920
+ _ => None,
6921
+ }
6922
+ }
6923
+
6924
+ fn collect_generated_alias_conflicts(expr: &Expression, names: &mut HashSet<String>) {
6925
+ fn insert(names: &mut HashSet<String>, identifier: &Identifier) {
6926
+ if !identifier.name.is_empty() {
6927
+ names.insert(identifier.name.to_ascii_lowercase());
6928
+ }
6929
+ }
6930
+
6931
+ for node in expr.dfs() {
6932
+ match node {
6933
+ Expression::Identifier(identifier) => insert(names, identifier),
6934
+ Expression::Column(column) => {
6935
+ insert(names, &column.name);
6936
+ if let Some(table) = &column.table {
6937
+ insert(names, table);
6938
+ }
6939
+ }
6940
+ Expression::Table(table) => {
6941
+ insert(names, &table.name);
6942
+ if let Some(schema) = &table.schema {
6943
+ insert(names, schema);
6944
+ }
6945
+ if let Some(catalog) = &table.catalog {
6946
+ insert(names, catalog);
6947
+ }
6948
+ if let Some(alias) = &table.alias {
6949
+ insert(names, alias);
6950
+ }
6951
+ for alias in &table.column_aliases {
6952
+ insert(names, alias);
6953
+ }
6954
+ }
6955
+ Expression::Alias(alias) => {
6956
+ insert(names, &alias.alias);
6957
+ for column_alias in &alias.column_aliases {
6958
+ insert(names, column_alias);
6959
+ }
6960
+ }
6961
+ Expression::Subquery(subquery) => {
6962
+ if let Some(alias) = &subquery.alias {
6963
+ insert(names, alias);
6964
+ }
6965
+ for column_alias in &subquery.column_aliases {
6966
+ insert(names, column_alias);
6967
+ }
6968
+ }
6969
+ Expression::Cte(cte) => {
6970
+ insert(names, &cte.alias);
6971
+ for column in &cte.columns {
6972
+ insert(names, column);
6973
+ }
6974
+ for key in &cte.key_expressions {
6975
+ insert(names, key);
6976
+ }
6977
+ }
6978
+ Expression::Values(values) => {
6979
+ if let Some(alias) = &values.alias {
6980
+ insert(names, alias);
6981
+ }
6982
+ for column_alias in &values.column_aliases {
6983
+ insert(names, column_alias);
6984
+ }
6985
+ }
6986
+ Expression::Unnest(unnest) => {
6987
+ if let Some(alias) = &unnest.alias {
6988
+ insert(names, alias);
6989
+ }
6990
+ if let Some(offset_alias) = &unnest.offset_alias {
6991
+ insert(names, offset_alias);
6992
+ }
6993
+ }
6994
+ _ => {}
6995
+ }
6996
+ }
6997
+ }
6998
+
6619
6999
  fn rewrite_postgres_format_for_tsql(
6620
7000
  expr: Expression,
6621
7001
  target: DialectType,
@@ -1404,6 +1404,56 @@ END;";
1404
1404
  assert!(output.contains("INSERT INTO employees (salary) VALUES (p_salary)"));
1405
1405
  }
1406
1406
 
1407
+ #[test]
1408
+ fn test_mysql_functional_index_key_parts() {
1409
+ let dialect = Dialect::get(DialectType::MySQL);
1410
+ let issue_sql = "CREATE TABLE `test_report` (
1411
+ `id` bigint NOT NULL AUTO_INCREMENT,
1412
+ `batch_no` varchar(64) NOT NULL,
1413
+ PRIMARY KEY (`id`),
1414
+ KEY `idx_clean_batch` ((trim(leading _utf8mb4'0' from `batch_no`)))
1415
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
1416
+ let ast = dialect.parse(issue_sql).expect("Issue #371 should parse");
1417
+ let output = dialect.generate(&ast[0]).expect("Generate failed");
1418
+ assert!(
1419
+ output.contains("INDEX idx_clean_batch ((TRIM(LEADING _utf8mb4 '0' FROM `batch_no`)))"),
1420
+ "Unexpected output: {output}"
1421
+ );
1422
+
1423
+ for (sql, expected) in [
1424
+ (
1425
+ "CREATE TABLE t (c VARCHAR(20), d INT, KEY idx (d, (LOWER(c)) DESC))",
1426
+ "INDEX idx (d, (LOWER(c)) DESC)",
1427
+ ),
1428
+ (
1429
+ "CREATE TABLE t (c VARCHAR(20), UNIQUE INDEX idx ((LOWER(c))))",
1430
+ "UNIQUE idx ((LOWER(c)))",
1431
+ ),
1432
+ (
1433
+ "ALTER TABLE t ADD INDEX idx ((LOWER(c)))",
1434
+ "ADD INDEX idx ((LOWER(c)))",
1435
+ ),
1436
+ (
1437
+ "CREATE INDEX idx ON t ((LOWER(c)))",
1438
+ "CREATE INDEX idx ON t((LOWER(c)))",
1439
+ ),
1440
+ (
1441
+ "CREATE INDEX idx ON t (c(10), d DESC)",
1442
+ "CREATE INDEX idx ON t(c(10), d DESC)",
1443
+ ),
1444
+ ] {
1445
+ let ast = dialect
1446
+ .parse(sql)
1447
+ .unwrap_or_else(|error| panic!("{sql}: {error}"));
1448
+ let output = dialect.generate(&ast[0]).expect("Generate failed");
1449
+ assert!(
1450
+ output.contains(expected),
1451
+ "SQL: {sql}\nExpected: {expected}\nActual: {output}"
1452
+ );
1453
+ assert!(!output.contains('?'), "Expression was lost: {output}");
1454
+ }
1455
+ }
1456
+
1407
1457
  fn mysql_identity(sql: &str, expected: &str) {
1408
1458
  let dialect = Dialect::get(DialectType::MySQL);
1409
1459
  let ast = dialect.parse(sql).expect("Parse failed");