polyglot-sql 0.4.4__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/Cargo.lock +5 -5
  2. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/Cargo.toml +1 -1
  3. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/PKG-INFO +31 -1
  4. {polyglot_sql-0.4.4/crates/polyglot-sql-python → polyglot_sql-0.5.1}/README.md +30 -0
  5. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/Cargo.toml +1 -1
  6. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/README.md +39 -4
  7. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/mod.rs +278 -16
  8. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/postgres.rs +13 -0
  9. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/generator.rs +12 -4
  10. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/lib.rs +35 -2
  11. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/lineage.rs +330 -0
  12. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/parser.rs +35 -0
  13. polyglot_sql-0.5.1/crates/polyglot-sql/src/query_analysis.rs +769 -0
  14. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/scope.rs +28 -0
  15. polyglot_sql-0.5.1/crates/polyglot-sql/tests/data_type_api.rs +86 -0
  16. polyglot_sql-0.5.1/crates/polyglot-sql/tests/issue226_regression_test.rs +48 -0
  17. polyglot_sql-0.5.1/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +181 -0
  18. polyglot_sql-0.5.1/crates/polyglot-sql/tests/query_analysis.rs +143 -0
  19. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/snowflake_regression_test.rs +66 -1
  20. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/tsql_regression.rs +53 -0
  21. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1/crates/polyglot-sql-python}/README.md +30 -0
  22. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/docs/api.md +31 -2
  23. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/docs/index.md +25 -0
  24. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/helpers.rs +31 -8
  25. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/lib.rs +3 -0
  26. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/parse.rs +32 -2
  27. polyglot_sql-0.5.1/crates/polyglot-sql-python/src/query_analysis.rs +33 -0
  28. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/transpile.rs +14 -3
  29. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_parse.py +26 -0
  30. polyglot_sql-0.5.1/crates/polyglot-sql-python/tests/test_query_analysis.py +45 -0
  31. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_transpile.py +33 -0
  32. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/python/polyglot_sql/__init__.py +4 -0
  33. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/python/polyglot_sql/__init__.pyi +62 -4
  34. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/in_list.rs +0 -0
  35. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/parsing.rs +0 -0
  36. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  37. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/benches/transpile.rs +0 -0
  38. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  39. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  40. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  41. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/builder.rs +0 -0
  42. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  43. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  44. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  45. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  46. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  47. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  48. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  49. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  50. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  51. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  52. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
  53. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  54. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  55. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  56. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  57. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  58. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  59. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
  60. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  61. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  62. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  63. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  64. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  65. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
  66. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  67. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  68. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  69. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  70. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  71. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  72. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  73. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  74. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
  75. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/diff.rs +0 -0
  76. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/error.rs +0 -0
  77. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/expressions.rs +0 -0
  78. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  79. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/function_registry.rs +0 -0
  80. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/helper.rs +0 -0
  81. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/openlineage.rs +0 -0
  82. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  83. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  84. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  85. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  86. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  87. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  88. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  89. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  90. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  91. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  92. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  93. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  94. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +0 -0
  95. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  96. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  97. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  98. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/planner.rs +0 -0
  99. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/resolver.rs +0 -0
  100. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/schema.rs +0 -0
  101. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/time.rs +0 -0
  102. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/tokens.rs +0 -0
  103. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/transforms.rs +0 -0
  104. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/traversal.rs +0 -0
  105. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/trie.rs +0 -0
  106. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  107. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/src/validation.rs +0 -0
  108. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  109. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  110. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  111. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  112. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  113. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  114. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  115. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  116. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  117. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  118. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  119. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  120. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  121. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  122. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  123. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  124. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  125. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  126. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  127. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
  128. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  129. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
  130. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
  131. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  132. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
  133. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
  134. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  135. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  136. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  137. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  138. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  139. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  140. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  141. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  142. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  143. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  144. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  145. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  146. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  147. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  148. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  149. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  150. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  151. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  152. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/Cargo.toml +0 -0
  153. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  154. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  155. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  156. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/diff.rs +0 -0
  157. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/errors.rs +0 -0
  158. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/expr.rs +0 -0
  159. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  160. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/format.rs +0 -0
  161. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/generate.rs +0 -0
  162. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  163. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
  164. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  165. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  166. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/transforms.rs +0 -0
  167. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/types.rs +0 -0
  168. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/src/validate.rs +0 -0
  169. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  170. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  171. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  172. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  173. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  174. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  175. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  176. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  177. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  178. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
  179. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  180. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/crates/polyglot-sql-python/uv.lock +0 -0
  181. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/pyproject.toml +0 -0
  182. {polyglot_sql-0.4.4 → polyglot_sql-0.5.1}/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.4.4"
608
+ version = "0.5.1"
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.4.4"
624
+ version = "0.5.1"
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.4.4"
634
+ version = "0.5.1"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.4.4"
638
+ version = "0.5.1"
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.4.4"
649
+ version = "0.5.1"
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.4.4"
9
+ version = "0.5.1"
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.4.4
3
+ Version: 0.5.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -55,6 +55,15 @@ ast = polyglot_sql.parse_one("SELECT 1 + 2", dialect="postgres")
55
55
  polyglot_sql.generate(ast, dialect="mysql")
56
56
  ```
57
57
 
58
+ ```python
59
+ data_type = polyglot_sql.parse_data_type("DECIMAL(10, 2)", dialect="duckdb")
60
+ data_type.sql("postgres")
61
+ # "DECIMAL(10, 2)"
62
+
63
+ # SQLGlot-compatible narrow form for data types only:
64
+ polyglot_sql.parse_one("VARCHAR(255)", dialect="duckdb", into=polyglot_sql.DataType)
65
+ ```
66
+
58
67
  ```python
59
68
  polyglot_sql.format_sql("SELECT a,b FROM t WHERE x=1", dialect="postgres")
60
69
  ```
@@ -114,6 +123,24 @@ print(payload["facet"]["fields"])
114
123
  OpenLineage helpers only produce compatible payloads. Transport and client
115
124
  emission are intentionally out of scope.
116
125
 
126
+ ```python
127
+ analysis = polyglot_sql.analyze_query(
128
+ "SELECT CAST(total AS TEXT) AS total_text FROM orders",
129
+ {
130
+ "dialect": "generic",
131
+ "schema": {
132
+ "tables": [
133
+ {
134
+ "name": "orders",
135
+ "columns": [{"name": "total", "type": "INT"}],
136
+ }
137
+ ]
138
+ },
139
+ },
140
+ )
141
+ print(analysis["projections"][0]["transformKind"]) # "cast"
142
+ ```
143
+
117
144
  ## API Reference
118
145
 
119
146
  All functions are exported from `polyglot_sql`.
@@ -121,6 +148,8 @@ All functions are exported from `polyglot_sql`.
121
148
  - `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
122
149
  - `parse(sql: str, dialect: str = "generic") -> list[dict]`
123
150
  - `parse_one(sql: str, dialect: str = "generic") -> dict`
151
+ - `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
152
+ - `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
124
153
  - `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
125
154
  - `format_sql(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str`
126
155
  - `format(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str` (alias of `format_sql`)
@@ -128,6 +157,7 @@ All functions are exported from `polyglot_sql`.
128
157
  - `optimize(sql: str, dialect: str = "generic") -> str`
129
158
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
130
159
  - `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
160
+ - `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
131
161
  - `openlineage_column_lineage(sql: str, options: dict) -> dict`
132
162
  - `openlineage_job_event(sql: str, options: dict) -> dict`
133
163
  - `openlineage_run_event(sql: str, options: dict) -> dict`
@@ -28,6 +28,15 @@ ast = polyglot_sql.parse_one("SELECT 1 + 2", dialect="postgres")
28
28
  polyglot_sql.generate(ast, dialect="mysql")
29
29
  ```
30
30
 
31
+ ```python
32
+ data_type = polyglot_sql.parse_data_type("DECIMAL(10, 2)", dialect="duckdb")
33
+ data_type.sql("postgres")
34
+ # "DECIMAL(10, 2)"
35
+
36
+ # SQLGlot-compatible narrow form for data types only:
37
+ polyglot_sql.parse_one("VARCHAR(255)", dialect="duckdb", into=polyglot_sql.DataType)
38
+ ```
39
+
31
40
  ```python
32
41
  polyglot_sql.format_sql("SELECT a,b FROM t WHERE x=1", dialect="postgres")
33
42
  ```
@@ -87,6 +96,24 @@ print(payload["facet"]["fields"])
87
96
  OpenLineage helpers only produce compatible payloads. Transport and client
88
97
  emission are intentionally out of scope.
89
98
 
99
+ ```python
100
+ analysis = polyglot_sql.analyze_query(
101
+ "SELECT CAST(total AS TEXT) AS total_text FROM orders",
102
+ {
103
+ "dialect": "generic",
104
+ "schema": {
105
+ "tables": [
106
+ {
107
+ "name": "orders",
108
+ "columns": [{"name": "total", "type": "INT"}],
109
+ }
110
+ ]
111
+ },
112
+ },
113
+ )
114
+ print(analysis["projections"][0]["transformKind"]) # "cast"
115
+ ```
116
+
90
117
  ## API Reference
91
118
 
92
119
  All functions are exported from `polyglot_sql`.
@@ -94,6 +121,8 @@ All functions are exported from `polyglot_sql`.
94
121
  - `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
95
122
  - `parse(sql: str, dialect: str = "generic") -> list[dict]`
96
123
  - `parse_one(sql: str, dialect: str = "generic") -> dict`
124
+ - `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
125
+ - `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
97
126
  - `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
98
127
  - `format_sql(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str`
99
128
  - `format(sql: str, dialect: str = "generic", *, max_input_bytes: int | None = None, max_tokens: int | None = None, max_ast_nodes: int | None = None, max_set_op_chain: int | None = None) -> str` (alias of `format_sql`)
@@ -101,6 +130,7 @@ All functions are exported from `polyglot_sql`.
101
130
  - `optimize(sql: str, dialect: str = "generic") -> str`
102
131
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
103
132
  - `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
133
+ - `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
104
134
  - `openlineage_column_lineage(sql: str, options: dict) -> dict`
105
135
  - `openlineage_job_event(sql: str, options: dict) -> dict`
106
136
  - `openlineage_run_event(sql: str, options: dict) -> dict`
@@ -106,7 +106,7 @@ thiserror = { workspace = true }
106
106
  unicode-segmentation = { workspace = true }
107
107
  stacker = { version = "0.1", optional = true }
108
108
  ts-rs = { version = "12.0", features = ["serde-compat"], optional = true }
109
- polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.4.4", optional = true, default-features = false }
109
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.5.1", optional = true, default-features = false }
110
110
 
111
111
  [dev-dependencies]
112
112
  pretty_assertions = "1.4"
@@ -7,6 +7,7 @@ Part of the [Polyglot](https://github.com/tobilg/polyglot) project.
7
7
  ## Features
8
8
 
9
9
  - **Parse** SQL into a fully-typed AST with 200+ expression types
10
+ - **Parse standalone data types** such as `DECIMAL(10, 2)` without a statement wrapper
10
11
  - **Generate** SQL from AST nodes for any target dialect
11
12
  - **Transpile** between any pair of 32 dialects in one call
12
13
  - **Format** / pretty-print SQL
@@ -14,6 +15,7 @@ Part of the [Polyglot](https://github.com/tobilg/polyglot) project.
14
15
  - **AST traversal** utilities (DFS/BFS iterators, transform, walk)
15
16
  - **Validation** with syntax checking and error location reporting
16
17
  - **Schema** module for column resolution and type annotation
18
+ - **Compact query analysis** for projection, relation, CTE, set-operation, and upstream-reference facts
17
19
 
18
20
  ## Usage
19
21
 
@@ -23,12 +25,12 @@ By default, `polyglot-sql` enables the full public API. Parser-only consumers ca
23
25
  disable default features and opt into only the dialect parsers they need:
24
26
 
25
27
  ```toml
26
- polyglot-sql = { version = "0.4", default-features = false }
28
+ polyglot-sql = { version = "0.5", default-features = false }
27
29
  ```
28
30
 
29
31
  ```toml
30
32
  polyglot-sql = {
31
- version = "0.4",
33
+ version = "0.5",
32
34
  default-features = false,
33
35
  features = ["dialect-clickhouse"],
34
36
  }
@@ -42,14 +44,14 @@ Examples:
42
44
  ```toml
43
45
  # Parse and generate SQL for one dialect.
44
46
  polyglot-sql = {
45
- version = "0.4",
47
+ version = "0.5",
46
48
  default-features = false,
47
49
  features = ["generate", "dialect-clickhouse"],
48
50
  }
49
51
 
50
52
  # Cross-dialect transpilation.
51
53
  polyglot-sql = {
52
- version = "0.4",
54
+ version = "0.5",
53
55
  default-features = false,
54
56
  features = ["transpile", "dialect-clickhouse", "dialect-postgresql"],
55
57
  }
@@ -103,6 +105,19 @@ let sql = generate(&ast[0], DialectType::Postgres).unwrap();
103
105
  assert_eq!(sql, "SELECT 1 + 2");
104
106
  ```
105
107
 
108
+ ### Standalone Data Types
109
+
110
+ ```rust
111
+ use polyglot_sql::{generate_data_type, parse_data_type, DialectType};
112
+
113
+ let data_type = parse_data_type("DECIMAL(10, 2)", DialectType::DuckDB).unwrap();
114
+ let sql = generate_data_type(&data_type, DialectType::Postgres).unwrap();
115
+ assert_eq!(sql, "DECIMAL(10, 2)");
116
+ ```
117
+
118
+ `parse_data_type` parses exactly one type string and rejects trailing SQL. Type
119
+ rendering requires the `generate` feature, which is enabled by default.
120
+
106
121
  ### Format With Guard Options
107
122
 
108
123
  Formatting is protected by guard limits by default:
@@ -295,6 +310,26 @@ Schema-aware validation emits stable codes such as:
295
310
  - `E210-E217` and `W210-W216` for type checks
296
311
  - `E220`, `E221`, `W220`, `W221`, `W222` for reference/FK checks
297
312
 
313
+ ### Compact Query Analysis
314
+
315
+ Use `analyze_query` when you need high-level facts without consuming the full AST
316
+ or full lineage graph:
317
+
318
+ ```rust
319
+ use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
320
+
321
+ let analysis = analyze_query(
322
+ "SELECT o.total AS total FROM orders o",
323
+ AnalyzeQueryOptions {
324
+ dialect: DialectType::Generic,
325
+ schema: None,
326
+ },
327
+ ).unwrap();
328
+
329
+ assert_eq!(analysis.shape, QueryShape::Select);
330
+ assert_eq!(analysis.projections[0].name.as_deref(), Some("total"));
331
+ ```
332
+
298
333
  ### Tokenize
299
334
 
300
335
  Access the raw token stream with full source position spans. Each token carries a `Span` with byte offsets and line/column numbers.
@@ -158,9 +158,9 @@ pub use trino::TrinoDialect;
158
158
  pub use tsql::TSQLDialect;
159
159
 
160
160
  use crate::error::Result;
161
- use crate::expressions::Expression;
162
161
  #[cfg(feature = "transpile")]
163
162
  use crate::expressions::{ColumnConstraint, Function, Identifier, Literal};
163
+ use crate::expressions::{DataType, Expression};
164
164
  #[cfg(any(
165
165
  feature = "transpile",
166
166
  feature = "ast-tools",
@@ -168,12 +168,16 @@ use crate::expressions::{ColumnConstraint, Function, Identifier, Literal};
168
168
  feature = "semantic"
169
169
  ))]
170
170
  use crate::expressions::{From, FunctionBody, Join, Null, OrderBy, OutputClause, TableRef, With};
171
+ #[cfg(feature = "transpile")]
172
+ use crate::generator::UnsupportedLevel;
171
173
  #[cfg(feature = "generate")]
172
174
  use crate::generator::{Generator, GeneratorConfig};
173
175
  use crate::parser::Parser;
174
176
  #[cfg(feature = "transpile")]
175
177
  use crate::tokens::TokenType;
176
178
  use crate::tokens::{Token, Tokenizer, TokenizerConfig};
179
+ #[cfg(feature = "transpile")]
180
+ use crate::traversal::ExpressionWalk;
177
181
  use serde::{Deserialize, Serialize};
178
182
  use std::collections::HashMap;
179
183
  use std::sync::{Arc, LazyLock, RwLock};
@@ -3730,19 +3734,60 @@ pub struct Dialect {
3730
3734
  /// The struct derives `Serialize`/`Deserialize` using camelCase field names so
3731
3735
  /// it can be round-tripped over JSON bridges (C FFI, WASM) without mapping.
3732
3736
  #[cfg(feature = "transpile")]
3733
- #[derive(Debug, Clone, Default, Serialize, Deserialize)]
3737
+ #[derive(Debug, Clone, Serialize, Deserialize)]
3734
3738
  #[serde(rename_all = "camelCase", default)]
3735
3739
  #[non_exhaustive]
3736
3740
  pub struct TranspileOptions {
3737
3741
  /// Whether to pretty-print the output SQL.
3738
3742
  pub pretty: bool,
3743
+ /// How unsupported target-dialect constructs should be handled.
3744
+ ///
3745
+ /// The default is [`UnsupportedLevel::Warn`], which preserves the current
3746
+ /// compatibility behavior and continues transpilation.
3747
+ pub unsupported_level: UnsupportedLevel,
3748
+ /// Maximum number of unsupported diagnostics to include in raised errors.
3749
+ pub max_unsupported: usize,
3750
+ }
3751
+
3752
+ #[cfg(feature = "transpile")]
3753
+ impl Default for TranspileOptions {
3754
+ fn default() -> Self {
3755
+ Self {
3756
+ pretty: false,
3757
+ unsupported_level: UnsupportedLevel::Warn,
3758
+ max_unsupported: 3,
3759
+ }
3760
+ }
3739
3761
  }
3740
3762
 
3741
3763
  #[cfg(feature = "transpile")]
3742
3764
  impl TranspileOptions {
3743
3765
  /// Construct options with pretty-printing enabled.
3744
3766
  pub fn pretty() -> Self {
3745
- Self { pretty: true }
3767
+ Self {
3768
+ pretty: true,
3769
+ ..Default::default()
3770
+ }
3771
+ }
3772
+
3773
+ /// Construct options that raise when known unsupported constructs remain.
3774
+ pub fn strict() -> Self {
3775
+ Self {
3776
+ unsupported_level: UnsupportedLevel::Raise,
3777
+ ..Default::default()
3778
+ }
3779
+ }
3780
+
3781
+ /// Set how unsupported target-dialect constructs should be handled.
3782
+ pub fn with_unsupported_level(mut self, level: UnsupportedLevel) -> Self {
3783
+ self.unsupported_level = level;
3784
+ self
3785
+ }
3786
+
3787
+ /// Set the maximum number of unsupported diagnostics to include in raised errors.
3788
+ pub fn with_max_unsupported(mut self, max: usize) -> Self {
3789
+ self.max_unsupported = max;
3790
+ self
3746
3791
  }
3747
3792
  }
3748
3793
 
@@ -3891,6 +3936,20 @@ impl Dialect {
3891
3936
  parser.parse()
3892
3937
  }
3893
3938
 
3939
+ /// Parse a standalone SQL data type using this dialect's tokenizer and parser.
3940
+ ///
3941
+ /// This accepts type strings such as `DECIMAL(10, 2)`, `INT[]`, or
3942
+ /// `STRUCT(a INT, b VARCHAR)` without requiring a surrounding statement.
3943
+ pub fn parse_data_type(&self, sql: &str) -> Result<DataType> {
3944
+ let tokens = self.tokenizer.tokenize(sql)?;
3945
+ let config = crate::parser::ParserConfig {
3946
+ dialect: Some(self.dialect_type),
3947
+ ..Default::default()
3948
+ };
3949
+ let mut parser = Parser::with_source(tokens, config, sql.to_string());
3950
+ parser.parse_standalone_data_type()
3951
+ }
3952
+
3894
3953
  /// Tokenize SQL using this dialect's tokenizer configuration.
3895
3954
  pub fn tokenize(&self, sql: &str) -> Result<Vec<Token>> {
3896
3955
  self.tokenizer.tokenize(sql)
@@ -3956,6 +4015,23 @@ impl Dialect {
3956
4015
  generator.generate(expr)
3957
4016
  }
3958
4017
 
4018
+ /// Generate SQL from an expression with source dialect and transpile options.
4019
+ #[cfg(all(feature = "generate", feature = "transpile"))]
4020
+ fn generate_with_transpile_options(
4021
+ &self,
4022
+ expr: &Expression,
4023
+ source: DialectType,
4024
+ opts: &TranspileOptions,
4025
+ ) -> Result<String> {
4026
+ let mut config = self.get_config_for_expr(expr);
4027
+ config.source_dialect = Some(source);
4028
+ config.pretty = opts.pretty;
4029
+ config.unsupported_level = opts.unsupported_level;
4030
+ config.max_unsupported = opts.max_unsupported.max(1);
4031
+ let mut generator = Generator::with_config(config);
4032
+ generator.generate(expr)
4033
+ }
4034
+
3959
4035
  /// Generate SQL from an expression with forced identifier quoting (identify=True)
3960
4036
  #[cfg(feature = "generate")]
3961
4037
  pub fn generate_with_identify(&self, expr: &Expression) -> Result<String> {
@@ -4232,7 +4308,7 @@ impl Dialect {
4232
4308
  target: T,
4233
4309
  opts: TranspileOptions,
4234
4310
  ) -> Result<Vec<String>> {
4235
- target.with_dialect(|td| self.transpile_inner(sql, td, opts.pretty))
4311
+ target.with_dialect(|td| self.transpile_inner(sql, td, &opts))
4236
4312
  }
4237
4313
 
4238
4314
  #[cfg(feature = "transpile")]
@@ -4240,7 +4316,7 @@ impl Dialect {
4240
4316
  &self,
4241
4317
  sql: &str,
4242
4318
  target_dialect: &Dialect,
4243
- pretty: bool,
4319
+ opts: &TranspileOptions,
4244
4320
  ) -> Result<Vec<String>> {
4245
4321
  let target = target_dialect.dialect_type;
4246
4322
  if matches!(self.dialect_type, DialectType::PostgreSQL)
@@ -4256,11 +4332,8 @@ impl Dialect {
4256
4332
  return expressions
4257
4333
  .into_iter()
4258
4334
  .map(|expr| {
4259
- if pretty {
4260
- target_dialect.generate_pretty_with_source(&expr, self.dialect_type)
4261
- } else {
4262
- target_dialect.generate_with_source(&expr, self.dialect_type)
4263
- }
4335
+ Self::reject_strict_unsupported(&expr, self.dialect_type, target, opts)?;
4336
+ target_dialect.generate_with_transpile_options(&expr, self.dialect_type, opts)
4264
4337
  })
4265
4338
  .collect();
4266
4339
  }
@@ -4744,14 +4817,16 @@ impl Dialect {
4744
4817
  transformed
4745
4818
  };
4746
4819
 
4747
- let mut sql = if pretty {
4748
- target_dialect.generate_pretty_with_source(&transformed, self.dialect_type)?
4749
- } else {
4750
- target_dialect.generate_with_source(&transformed, self.dialect_type)?
4751
- };
4820
+ Self::reject_strict_unsupported(&transformed, self.dialect_type, target, opts)?;
4821
+
4822
+ let mut sql = target_dialect.generate_with_transpile_options(
4823
+ &transformed,
4824
+ self.dialect_type,
4825
+ opts,
4826
+ )?;
4752
4827
 
4753
4828
  // Align a known Snowflake pretty-print edge case with Python sqlglot output.
4754
- if pretty && target == DialectType::Snowflake {
4829
+ if opts.pretty && target == DialectType::Snowflake {
4755
4830
  sql = Self::normalize_snowflake_pretty(sql);
4756
4831
  }
4757
4832
 
@@ -4764,6 +4839,193 @@ impl Dialect {
4764
4839
  // Transpile-only methods: cross-dialect normalization and helpers
4765
4840
  #[cfg(feature = "transpile")]
4766
4841
  impl Dialect {
4842
+ fn reject_strict_unsupported(
4843
+ expr: &Expression,
4844
+ source: DialectType,
4845
+ target: DialectType,
4846
+ opts: &TranspileOptions,
4847
+ ) -> Result<()> {
4848
+ if !matches!(
4849
+ opts.unsupported_level,
4850
+ UnsupportedLevel::Raise | UnsupportedLevel::Immediate
4851
+ ) {
4852
+ return Ok(());
4853
+ }
4854
+
4855
+ let mut diagnostics = Vec::new();
4856
+
4857
+ for node in expr.dfs() {
4858
+ if matches!(target, DialectType::Fabric | DialectType::Hive)
4859
+ && Self::node_has_recursive_with(node)
4860
+ {
4861
+ Self::push_unsupported_diagnostic(&mut diagnostics, "recursive CTEs");
4862
+ }
4863
+
4864
+ if matches!(target, DialectType::TSQL | DialectType::Fabric)
4865
+ && Self::node_has_lateral(node)
4866
+ {
4867
+ Self::push_unsupported_diagnostic(&mut diagnostics, "LATERAL joins and subqueries");
4868
+ }
4869
+
4870
+ if !Self::target_supports_remaining_unnest(target) && Self::node_is_unnest(node) {
4871
+ Self::push_unsupported_diagnostic(&mut diagnostics, "UNNEST");
4872
+ }
4873
+
4874
+ if !Self::target_supports_remaining_explode(target) && Self::node_is_explode(node) {
4875
+ Self::push_unsupported_diagnostic(&mut diagnostics, "EXPLODE");
4876
+ }
4877
+
4878
+ if Self::target_lacks_array_agg(target) && Self::node_is_array_agg(node) {
4879
+ Self::push_unsupported_diagnostic(&mut diagnostics, "ARRAY_AGG");
4880
+ }
4881
+
4882
+ if matches!(source, DialectType::PostgreSQL | DialectType::CockroachDB)
4883
+ && !matches!(target, DialectType::PostgreSQL | DialectType::CockroachDB)
4884
+ {
4885
+ if Self::node_is_function_named(node, "JSONB_BUILD_OBJECT") {
4886
+ Self::push_unsupported_diagnostic(
4887
+ &mut diagnostics,
4888
+ "PostgreSQL JSONB_BUILD_OBJECT",
4889
+ );
4890
+ }
4891
+ if Self::node_is_function_named(node, "TO_TSVECTOR") {
4892
+ Self::push_unsupported_diagnostic(&mut diagnostics, "PostgreSQL TO_TSVECTOR");
4893
+ }
4894
+ }
4895
+
4896
+ if opts.unsupported_level == UnsupportedLevel::Immediate && !diagnostics.is_empty() {
4897
+ break;
4898
+ }
4899
+ }
4900
+
4901
+ if diagnostics.is_empty() {
4902
+ return Ok(());
4903
+ }
4904
+
4905
+ let limit = if opts.unsupported_level == UnsupportedLevel::Immediate {
4906
+ 1
4907
+ } else {
4908
+ opts.max_unsupported.max(1)
4909
+ };
4910
+ let mut messages = diagnostics.iter().take(limit).cloned().collect::<Vec<_>>();
4911
+ if diagnostics.len() > limit {
4912
+ messages.push(format!("... and {} more", diagnostics.len() - limit));
4913
+ }
4914
+
4915
+ Err(crate::error::Error::unsupported(
4916
+ messages.join("; "),
4917
+ target.to_string(),
4918
+ ))
4919
+ }
4920
+
4921
+ fn push_unsupported_diagnostic(diagnostics: &mut Vec<String>, message: &str) {
4922
+ if !diagnostics.iter().any(|existing| existing == message) {
4923
+ diagnostics.push(message.to_string());
4924
+ }
4925
+ }
4926
+
4927
+ fn node_has_recursive_with(expr: &Expression) -> bool {
4928
+ fn recursive(with: &Option<With>) -> bool {
4929
+ with.as_ref().is_some_and(|with| with.recursive)
4930
+ }
4931
+
4932
+ match expr {
4933
+ Expression::With(with) => with.recursive,
4934
+ Expression::Select(select) => recursive(&select.with),
4935
+ Expression::Union(union) => recursive(&union.with),
4936
+ Expression::Intersect(intersect) => recursive(&intersect.with),
4937
+ Expression::Except(except) => recursive(&except.with),
4938
+ Expression::Pivot(pivot) => recursive(&pivot.with),
4939
+ Expression::Insert(insert) => recursive(&insert.with),
4940
+ Expression::Update(update) => recursive(&update.with),
4941
+ Expression::Delete(delete) => recursive(&delete.with),
4942
+ _ => false,
4943
+ }
4944
+ }
4945
+
4946
+ fn node_has_lateral(expr: &Expression) -> bool {
4947
+ fn joins_have_lateral(joins: &[Join]) -> bool {
4948
+ joins.iter().any(|join| {
4949
+ matches!(
4950
+ join.kind,
4951
+ crate::expressions::JoinKind::Lateral
4952
+ | crate::expressions::JoinKind::LeftLateral
4953
+ )
4954
+ })
4955
+ }
4956
+
4957
+ match expr {
4958
+ Expression::Subquery(subquery) => subquery.lateral,
4959
+ Expression::Lateral(_) | Expression::LateralView(_) => true,
4960
+ Expression::Join(join) => matches!(
4961
+ join.kind,
4962
+ crate::expressions::JoinKind::Lateral | crate::expressions::JoinKind::LeftLateral
4963
+ ),
4964
+ Expression::Select(select) => {
4965
+ !select.lateral_views.is_empty() || joins_have_lateral(&select.joins)
4966
+ }
4967
+ Expression::JoinedTable(joined) => {
4968
+ !joined.lateral_views.is_empty() || joins_have_lateral(&joined.joins)
4969
+ }
4970
+ Expression::Update(update) => {
4971
+ joins_have_lateral(&update.table_joins) || joins_have_lateral(&update.from_joins)
4972
+ }
4973
+ _ => false,
4974
+ }
4975
+ }
4976
+
4977
+ fn target_supports_remaining_unnest(target: DialectType) -> bool {
4978
+ matches!(
4979
+ target,
4980
+ DialectType::PostgreSQL
4981
+ | DialectType::BigQuery
4982
+ | DialectType::DuckDB
4983
+ | DialectType::Presto
4984
+ | DialectType::Trino
4985
+ | DialectType::Athena
4986
+ )
4987
+ }
4988
+
4989
+ fn target_supports_remaining_explode(target: DialectType) -> bool {
4990
+ matches!(
4991
+ target,
4992
+ DialectType::Spark | DialectType::Databricks | DialectType::Hive
4993
+ )
4994
+ }
4995
+
4996
+ fn target_lacks_array_agg(target: DialectType) -> bool {
4997
+ matches!(
4998
+ target,
4999
+ DialectType::Fabric
5000
+ | DialectType::TSQL
5001
+ | DialectType::MySQL
5002
+ | DialectType::SQLite
5003
+ | DialectType::Oracle
5004
+ )
5005
+ }
5006
+
5007
+ fn node_is_unnest(expr: &Expression) -> bool {
5008
+ matches!(expr, Expression::Unnest(_)) || Self::node_is_function_named(expr, "UNNEST")
5009
+ }
5010
+
5011
+ fn node_is_explode(expr: &Expression) -> bool {
5012
+ matches!(expr, Expression::Explode(_) | Expression::ExplodeOuter(_))
5013
+ || Self::node_is_function_named(expr, "EXPLODE")
5014
+ || Self::node_is_function_named(expr, "EXPLODE_OUTER")
5015
+ }
5016
+
5017
+ fn node_is_array_agg(expr: &Expression) -> bool {
5018
+ matches!(expr, Expression::ArrayAgg(_)) || Self::node_is_function_named(expr, "ARRAY_AGG")
5019
+ }
5020
+
5021
+ fn node_is_function_named(expr: &Expression, name: &str) -> bool {
5022
+ match expr {
5023
+ Expression::Function(function) => function.name.eq_ignore_ascii_case(name),
5024
+ Expression::AggregateFunction(function) => function.name.eq_ignore_ascii_case(name),
5025
+ _ => false,
5026
+ }
5027
+ }
5028
+
4767
5029
  fn rewrite_boolean_values_for_tsql(expr: Expression) -> Result<Expression> {
4768
5030
  match expr {
4769
5031
  Expression::Select(select) => Self::rewrite_boolean_values_in_tsql_select(select),
@@ -65,6 +65,19 @@ impl DialectImpl for PostgresDialect {
65
65
  config
66
66
  .keywords
67
67
  .insert("EXEC".to_string(), TokenType::Command);
68
+ for command in [
69
+ "BASE_BACKUP",
70
+ "CREATE_REPLICATION_SLOT",
71
+ "DROP_REPLICATION_SLOT",
72
+ "IDENTIFY_SYSTEM",
73
+ "READ_REPLICATION_SLOT",
74
+ "START_REPLICATION",
75
+ "TIMELINE_HISTORY",
76
+ ] {
77
+ config
78
+ .keywords
79
+ .insert(command.to_string(), TokenType::Command);
80
+ }
68
81
  config
69
82
  }
70
83