polyglot-sql 0.5.0__tar.gz → 0.5.2__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.5.0 → polyglot_sql-0.5.2}/Cargo.lock +5 -5
  2. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/Cargo.toml +1 -1
  3. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/PKG-INFO +39 -1
  4. {polyglot_sql-0.5.0/crates/polyglot-sql-python → polyglot_sql-0.5.2}/README.md +38 -0
  5. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/Cargo.toml +1 -1
  6. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/README.md +53 -4
  7. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mod.rs +15 -1
  8. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/postgres.rs +13 -0
  9. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/generator.rs +9 -3
  10. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lib.rs +34 -1
  11. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lineage.rs +41 -2
  12. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +43 -7
  13. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/parser.rs +35 -0
  14. polyglot_sql-0.5.2/crates/polyglot-sql/src/query_analysis.rs +917 -0
  15. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/scope.rs +5 -1
  16. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/traversal.rs +15 -2
  17. polyglot_sql-0.5.2/crates/polyglot-sql/tests/data_type_api.rs +86 -0
  18. polyglot_sql-0.5.2/crates/polyglot-sql/tests/issue226_regression_test.rs +48 -0
  19. polyglot_sql-0.5.2/crates/polyglot-sql/tests/query_analysis.rs +340 -0
  20. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/snowflake_regression_test.rs +66 -1
  21. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tsql_regression.rs +53 -0
  22. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2/crates/polyglot-sql-python}/README.md +38 -0
  23. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/api.md +31 -2
  24. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/index.md +40 -0
  25. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/helpers.rs +17 -11
  26. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lib.rs +3 -0
  27. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/parse.rs +32 -2
  28. polyglot_sql-0.5.2/crates/polyglot-sql-python/src/query_analysis.rs +33 -0
  29. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_parse.py +26 -0
  30. polyglot_sql-0.5.2/crates/polyglot-sql-python/tests/test_query_analysis.py +71 -0
  31. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.py +4 -0
  32. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.pyi +62 -4
  33. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/in_list.rs +0 -0
  34. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/parsing.rs +0 -0
  35. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  36. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/transpile.rs +0 -0
  37. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  38. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  39. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  40. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/builder.rs +0 -0
  41. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  42. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  43. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  44. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  45. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  46. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  47. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  48. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  49. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  50. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  51. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
  52. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  53. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  54. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  55. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  56. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  57. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  58. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
  59. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  60. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  61. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  62. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  63. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  64. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
  65. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  66. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  67. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  68. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  69. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  70. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  71. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  72. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  73. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
  74. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/diff.rs +0 -0
  75. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/error.rs +0 -0
  76. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/expressions.rs +0 -0
  77. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  78. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_registry.rs +0 -0
  79. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/helper.rs +0 -0
  80. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/openlineage.rs +0 -0
  81. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  82. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  83. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  84. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  85. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  86. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  87. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  88. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  89. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  90. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  91. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  92. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  93. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  94. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  95. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  96. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/planner.rs +0 -0
  97. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/resolver.rs +0 -0
  98. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/schema.rs +0 -0
  99. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/time.rs +0 -0
  100. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/tokens.rs +0 -0
  101. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/transforms.rs +0 -0
  102. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/trie.rs +0 -0
  103. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  104. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation.rs +0 -0
  105. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  106. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  107. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  108. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  109. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  110. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  111. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  112. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  113. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  114. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  115. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  116. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  117. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  118. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  119. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  120. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  121. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  122. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  123. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  124. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
  125. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  126. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
  127. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
  128. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  129. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
  130. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
  131. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
  132. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  133. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  134. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  135. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  136. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  137. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  138. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  139. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  140. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  141. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  142. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  143. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  144. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  145. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  146. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  147. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  148. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  149. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  150. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/Cargo.toml +0 -0
  151. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  152. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  153. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  154. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/diff.rs +0 -0
  155. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/errors.rs +0 -0
  156. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr.rs +0 -0
  157. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  158. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/format.rs +0 -0
  159. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/generate.rs +0 -0
  160. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  161. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
  162. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  163. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  164. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transforms.rs +0 -0
  165. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  166. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/types.rs +0 -0
  167. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/validate.rs +0 -0
  168. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  169. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  170. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  171. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  172. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  173. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  174. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  175. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  176. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  177. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
  178. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  179. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  180. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/uv.lock +0 -0
  181. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/pyproject.toml +0 -0
  182. {polyglot_sql-0.5.0 → polyglot_sql-0.5.2}/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.5.0"
608
+ version = "0.5.2"
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.5.0"
624
+ version = "0.5.2"
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.5.0"
634
+ version = "0.5.2"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.5.0"
638
+ version = "0.5.2"
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.5.0"
649
+ version = "0.5.2"
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.5.0"
9
+ version = "0.5.2"
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.5.0
3
+ Version: 0.5.2
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,32 @@ 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 SUM(o.amount) AS total FROM orders AS o",
129
+ {
130
+ "dialect": "generic",
131
+ "schema": {
132
+ "tables": [
133
+ {
134
+ "name": "orders",
135
+ "columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
136
+ }
137
+ ]
138
+ },
139
+ },
140
+ )
141
+ print(analysis["projections"][0]["transformKind"]) # "aggregation"
142
+ print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
143
+ print(analysis["baseTables"][0]["name"]) # "orders"
144
+ ```
145
+
146
+ `analysis["relations"]` reports sources visible in the analyzed scope.
147
+ `analysis["baseTables"]` reports deduplicated physical table dependencies across
148
+ nested CTEs, derived tables, subqueries, and set-operation branches. Validation
149
+ uses broad type families, while query analysis preserves parseable detailed
150
+ schema type strings for projection `typeHint` values.
151
+
117
152
  ## API Reference
118
153
 
119
154
  All functions are exported from `polyglot_sql`.
@@ -121,6 +156,8 @@ All functions are exported from `polyglot_sql`.
121
156
  - `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
122
157
  - `parse(sql: str, dialect: str = "generic") -> list[dict]`
123
158
  - `parse_one(sql: str, dialect: str = "generic") -> dict`
159
+ - `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
160
+ - `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
124
161
  - `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
125
162
  - `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
163
  - `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 +165,7 @@ All functions are exported from `polyglot_sql`.
128
165
  - `optimize(sql: str, dialect: str = "generic") -> str`
129
166
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
130
167
  - `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
168
+ - `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
131
169
  - `openlineage_column_lineage(sql: str, options: dict) -> dict`
132
170
  - `openlineage_job_event(sql: str, options: dict) -> dict`
133
171
  - `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,32 @@ 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 SUM(o.amount) AS total FROM orders AS o",
102
+ {
103
+ "dialect": "generic",
104
+ "schema": {
105
+ "tables": [
106
+ {
107
+ "name": "orders",
108
+ "columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
109
+ }
110
+ ]
111
+ },
112
+ },
113
+ )
114
+ print(analysis["projections"][0]["transformKind"]) # "aggregation"
115
+ print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
116
+ print(analysis["baseTables"][0]["name"]) # "orders"
117
+ ```
118
+
119
+ `analysis["relations"]` reports sources visible in the analyzed scope.
120
+ `analysis["baseTables"]` reports deduplicated physical table dependencies across
121
+ nested CTEs, derived tables, subqueries, and set-operation branches. Validation
122
+ uses broad type families, while query analysis preserves parseable detailed
123
+ schema type strings for projection `typeHint` values.
124
+
90
125
  ## API Reference
91
126
 
92
127
  All functions are exported from `polyglot_sql`.
@@ -94,6 +129,8 @@ All functions are exported from `polyglot_sql`.
94
129
  - `transpile(sql: str, read: str = "generic", write: str = "generic", *, pretty: bool = False) -> list[str]`
95
130
  - `parse(sql: str, dialect: str = "generic") -> list[dict]`
96
131
  - `parse_one(sql: str, dialect: str = "generic") -> dict`
132
+ - `parse_one(sql: str, dialect: str = "generic", *, into=polyglot_sql.DataType) -> DataType` (only `DataType` is supported for `into`)
133
+ - `parse_data_type(sql: str, dialect: str = "generic") -> DataType`
97
134
  - `generate(ast: dict | list[dict], dialect: str = "generic", *, pretty: bool = False) -> list[str]`
98
135
  - `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
136
  - `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 +138,7 @@ All functions are exported from `polyglot_sql`.
101
138
  - `optimize(sql: str, dialect: str = "generic") -> str`
102
139
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
103
140
  - `source_tables(column: str, sql: str, dialect: str = "generic") -> list[str]`
141
+ - `analyze_query(sql: str, options: dict | None = None, dialect: str = "generic") -> dict`
104
142
  - `openlineage_column_lineage(sql: str, options: dict) -> dict`
105
143
  - `openlineage_job_event(sql: str, options: dict) -> dict`
106
144
  - `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.5.0", optional = true, default-features = false }
109
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.5.2", 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,40 @@ 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. `relations` reports sources visible in the analyzed
317
+ scope, while `base_tables` reports deduplicated physical table dependencies
318
+ across CTEs, derived tables, subqueries, and set-operation branches. When a
319
+ `ValidationSchema` is supplied, detailed type strings such as `DECIMAL(10,2)`
320
+ are preserved in projection `type_hint` values when parseable.
321
+
322
+ ```rust
323
+ use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
324
+
325
+ let schema: polyglot_sql::ValidationSchema = serde_json::from_value(serde_json::json!({
326
+ "tables": [{
327
+ "name": "orders",
328
+ "columns": [{"name": "amount", "type": "DECIMAL(10,2)"}]
329
+ }]
330
+ })).unwrap();
331
+
332
+ let analysis = analyze_query(
333
+ "SELECT SUM(o.amount) AS total FROM orders o",
334
+ AnalyzeQueryOptions {
335
+ dialect: DialectType::Generic,
336
+ schema: Some(schema),
337
+ },
338
+ ).unwrap();
339
+
340
+ assert_eq!(analysis.shape, QueryShape::Select);
341
+ assert_eq!(analysis.projections[0].name.as_deref(), Some("total"));
342
+ assert_eq!(analysis.projections[0].transform_kind, polyglot_sql::TransformKind::Aggregation);
343
+ assert_eq!(analysis.base_tables[0].name, "orders");
344
+ assert_eq!(analysis.base_tables[0].alias.as_deref(), Some("o"));
345
+ ```
346
+
298
347
  ### Tokenize
299
348
 
300
349
  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",
@@ -3936,6 +3936,20 @@ impl Dialect {
3936
3936
  parser.parse()
3937
3937
  }
3938
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
+
3939
3953
  /// Tokenize SQL using this dialect's tokenizer configuration.
3940
3954
  pub fn tokenize(&self, sql: &str) -> Result<Vec<Token>> {
3941
3955
  self.tokenizer.tokenize(sql)
@@ -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
 
@@ -19705,9 +19705,15 @@ impl Generator {
19705
19705
  self.write_simple_interval_unit(unit, false); // Use singular form for DATEDIFF
19706
19706
  self.write(", ");
19707
19707
  }
19708
- self.generate_expression(&f.this)?;
19709
- self.write(", ");
19710
- self.generate_expression(&f.expression)?;
19708
+ if self.config.dialect == Some(DialectType::Snowflake) {
19709
+ self.generate_expression(&f.expression)?;
19710
+ self.write(", ");
19711
+ self.generate_expression(&f.this)?;
19712
+ } else {
19713
+ self.generate_expression(&f.this)?;
19714
+ self.write(", ");
19715
+ self.generate_expression(&f.expression)?;
19716
+ }
19711
19717
  self.write(")");
19712
19718
  Ok(())
19713
19719
  }
@@ -37,6 +37,8 @@ pub mod optimizer;
37
37
  pub mod parser;
38
38
  #[cfg(feature = "planner")]
39
39
  pub mod planner;
40
+ #[cfg(all(feature = "semantic", feature = "generate"))]
41
+ pub mod query_analysis;
40
42
  #[cfg(feature = "semantic")]
41
43
  pub mod resolver;
42
44
  #[cfg(feature = "semantic")]
@@ -72,7 +74,7 @@ pub use dialects::{TranspileOptions, TranspileTarget};
72
74
  pub use error::{Error, Result};
73
75
  #[cfg(feature = "semantic")]
74
76
  pub use error::{ValidationError, ValidationResult, ValidationSeverity};
75
- pub use expressions::Expression;
77
+ pub use expressions::{DataType, Expression};
76
78
  #[cfg(feature = "semantic")]
77
79
  pub use function_catalog::{
78
80
  FunctionCatalog, FunctionNameCase, FunctionSignature, HashMapFunctionCatalog,
@@ -89,6 +91,12 @@ pub use optimizer::{
89
91
  annotate_types, qualify_tables, QualifyTablesOptions, TypeAnnotator, TypeCoercionClass,
90
92
  };
91
93
  pub use parser::Parser;
94
+ #[cfg(all(feature = "semantic", feature = "generate"))]
95
+ pub use query_analysis::{
96
+ analyze_query, AnalyzeQueryOptions, ColumnReferenceFact, ProjectionFact, QueryAnalysis,
97
+ QueryShape, ReferenceConfidence, RelationFact, SetOperationBranchFact, SetOperationFact,
98
+ TransformKind,
99
+ };
92
100
  #[cfg(feature = "semantic")]
93
101
  pub use resolver::{is_column_ambiguous, resolve_column, Resolver, ResolverError, ResolverResult};
94
102
  #[cfg(feature = "semantic")]
@@ -495,6 +503,31 @@ pub fn parse_one(sql: &str, dialect: DialectType) -> Result<Expression> {
495
503
  Ok(expressions.remove(0))
496
504
  }
497
505
 
506
+ /// Parse a standalone SQL data type.
507
+ ///
508
+ /// # Arguments
509
+ /// * `sql` - The data type string to parse, e.g. `DECIMAL(10, 2)`
510
+ /// * `dialect` - The dialect to use for parsing
511
+ ///
512
+ /// # Returns
513
+ /// The parsed data type
514
+ pub fn parse_data_type(sql: &str, dialect: DialectType) -> Result<DataType> {
515
+ Dialect::get(dialect).parse_data_type(sql)
516
+ }
517
+
518
+ /// Generate SQL from a standalone data type.
519
+ ///
520
+ /// # Arguments
521
+ /// * `data_type` - The data type to render
522
+ /// * `dialect` - The target dialect
523
+ ///
524
+ /// # Returns
525
+ /// The generated type SQL string
526
+ #[cfg(feature = "generate")]
527
+ pub fn generate_data_type(data_type: &DataType, dialect: DialectType) -> Result<String> {
528
+ Dialect::get(dialect).generate(&Expression::DataType(data_type.clone()))
529
+ }
530
+
498
531
  /// Generate SQL from an AST.
499
532
  ///
500
533
  /// # Arguments
@@ -235,6 +235,25 @@ fn lineage_from_expression(
235
235
  )
236
236
  }
237
237
 
238
+ pub(crate) fn lineage_by_index_from_expression(
239
+ column_index: usize,
240
+ sql: &Expression,
241
+ dialect: Option<DialectType>,
242
+ trim_selects: bool,
243
+ ) -> Result<LineageNode> {
244
+ let sql = lineage_effective_expression(sql);
245
+ let scope = build_scope(sql);
246
+ to_node(
247
+ ColumnRef::Index(column_index),
248
+ &scope,
249
+ dialect,
250
+ "",
251
+ "",
252
+ "",
253
+ trim_selects,
254
+ )
255
+ }
256
+
238
257
  fn lineage_effective_expression(sql: &Expression) -> &Expression {
239
258
  match sql {
240
259
  Expression::Prepare(prepare) => &prepare.statement,
@@ -753,12 +772,32 @@ fn to_node_inner(
753
772
  apply_scope_context(&mut node, scope, source_name, reference_node_name);
754
773
 
755
774
  // 5. Star handling — add downstream for each source
756
- if matches!(&select_expr, Expression::Star(_)) {
775
+ if let Expression::Star(star) = &select_expr {
776
+ let star_table = star
777
+ .table
778
+ .as_ref()
779
+ .map(|identifier| identifier.name.as_str());
757
780
  for (name, source_info) in &scope.sources {
781
+ if let Some(star_table) = star_table {
782
+ let table_matches = name.eq_ignore_ascii_case(star_table)
783
+ || source_info
784
+ .alias
785
+ .as_deref()
786
+ .is_some_and(|alias| alias.eq_ignore_ascii_case(star_table))
787
+ || matches!(
788
+ &source_info.expression,
789
+ Expression::Table(table_ref)
790
+ if table_name_from_table_ref(table_ref).eq_ignore_ascii_case(star_table)
791
+ );
792
+ if !table_matches {
793
+ continue;
794
+ }
795
+ }
796
+
758
797
  let mut child = LineageNode::new(
759
798
  format!("{}.*", name),
760
799
  Expression::Star(crate::expressions::Star {
761
- table: None,
800
+ table: star.table.clone(),
762
801
  except: None,
763
802
  replace: None,
764
803
  rename: None,
@@ -653,21 +653,23 @@ fn expand_stars(
653
653
 
654
654
  for expr in &select.expressions {
655
655
  match expr {
656
- Expression::Star(_) => {
656
+ Expression::Star(star) => {
657
657
  has_star = true;
658
- for source_name in &ordered_sources {
659
- if let Ok(columns) = resolver.get_source_columns(source_name) {
658
+ if let Some(table) = &star.table {
659
+ let table_name = &table.name;
660
+ if !ordered_sources.contains(table_name) {
661
+ return Err(QualifyColumnsError::UnknownTable(table_name.clone()));
662
+ }
663
+ if let Ok(columns) = resolver.get_source_columns(table_name) {
660
664
  if columns.contains(&"*".to_string()) || columns.is_empty() {
661
665
  return Ok(());
662
666
  }
663
667
  for col_name in &columns {
664
668
  if coalesced_columns.contains(col_name) {
665
- // Already emitted as COALESCE, skip
666
669
  continue;
667
670
  }
668
671
  if let Some(tables) = column_tables.get(col_name) {
669
- if tables.contains(source_name) {
670
- // Emit COALESCE and mark as coalesced
672
+ if tables.contains(table_name) {
671
673
  coalesced_columns.insert(col_name.clone());
672
674
  let coalesce = make_coalesce(col_name, tables);
673
675
  new_selections.push(Expression::Alias(Box::new(Alias {
@@ -684,7 +686,41 @@ fn expand_stars(
684
686
  }
685
687
  }
686
688
  new_selections
687
- .push(create_qualified_column(col_name, Some(source_name)));
689
+ .push(create_qualified_column(col_name, Some(table_name)));
690
+ }
691
+ }
692
+ } else {
693
+ for source_name in &ordered_sources {
694
+ if let Ok(columns) = resolver.get_source_columns(source_name) {
695
+ if columns.contains(&"*".to_string()) || columns.is_empty() {
696
+ return Ok(());
697
+ }
698
+ for col_name in &columns {
699
+ if coalesced_columns.contains(col_name) {
700
+ // Already emitted as COALESCE, skip
701
+ continue;
702
+ }
703
+ if let Some(tables) = column_tables.get(col_name) {
704
+ if tables.contains(source_name) {
705
+ // Emit COALESCE and mark as coalesced
706
+ coalesced_columns.insert(col_name.clone());
707
+ let coalesce = make_coalesce(col_name, tables);
708
+ new_selections.push(Expression::Alias(Box::new(Alias {
709
+ this: coalesce,
710
+ alias: Identifier::new(col_name),
711
+ column_aliases: vec![],
712
+ alias_explicit_as: false,
713
+ alias_keyword: None,
714
+ pre_alias_comments: vec![],
715
+ trailing_comments: vec![],
716
+ inferred_type: None,
717
+ })));
718
+ continue;
719
+ }
720
+ }
721
+ new_selections
722
+ .push(create_qualified_column(col_name, Some(source_name)));
723
+ }
688
724
  }
689
725
  }
690
726
  }
@@ -740,6 +740,28 @@ impl Parser {
740
740
  Ok(statements)
741
741
  }
742
742
 
743
+ /// Parse exactly one standalone data type from the token stream.
744
+ ///
745
+ /// This entry point is intended for callers that need to parse native type
746
+ /// strings such as `DECIMAL(10, 2)` without wrapping them in a SQL statement
747
+ /// or `CAST(...)` expression.
748
+ pub fn parse_standalone_data_type(&mut self) -> Result<DataType> {
749
+ let data_type = self.parse_data_type()?;
750
+
751
+ if self.check(TokenType::Semicolon) {
752
+ self.skip();
753
+ }
754
+
755
+ if !self.is_at_end() {
756
+ return Err(self.parse_error(format!(
757
+ "Unexpected token after data type: {}",
758
+ self.peek().text
759
+ )));
760
+ }
761
+
762
+ Ok(data_type)
763
+ }
764
+
743
765
  /// Parse a single SQL statement from the current position in the token stream.
744
766
  ///
745
767
  /// Dispatches to the appropriate sub-parser based on the leading keyword
@@ -24338,10 +24360,23 @@ impl Parser {
24338
24360
 
24339
24361
  /// Parse SET statement
24340
24362
  fn parse_set(&mut self) -> Result<Expression> {
24363
+ let statement_start = self.current;
24341
24364
  self.expect(TokenType::Set)?;
24342
24365
 
24343
24366
  let mut items = Vec::new();
24344
24367
 
24368
+ // T-SQL: SET STATISTICS TIME|IO|XML|PROFILE ON|OFF. The existing SET
24369
+ // parser handles simple options like SET NOCOUNT ON, but these
24370
+ // multi-token STATISTICS options are better preserved as commands.
24371
+ if matches!(
24372
+ self.config.dialect,
24373
+ Some(crate::dialects::DialectType::TSQL)
24374
+ ) && self.check_identifier("STATISTICS")
24375
+ {
24376
+ self.current = statement_start;
24377
+ return self.fallback_to_command(statement_start);
24378
+ }
24379
+
24345
24380
  // ClickHouse: SET DEFAULT ROLE ... TO user - parse as command
24346
24381
  if matches!(
24347
24382
  self.config.dialect,