polyglot-sql 0.9.1__tar.gz → 0.10.0__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 (211) hide show
  1. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/Cargo.lock +6 -6
  2. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/Cargo.toml +1 -1
  3. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/PKG-INFO +55 -2
  4. {polyglot_sql-0.9.1/crates/polyglot-sql-python → polyglot_sql-0.10.0}/README.md +54 -1
  5. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/Cargo.toml +2 -2
  6. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/README.md +6 -1
  7. polyglot_sql-0.9.1/crates/polyglot-sql/src/builder/engine.rs → polyglot_sql-0.10.0/crates/polyglot-sql/src/ast_mutation.rs +8 -4
  8. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/ast_transforms.rs +22 -1
  9. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/builder/mod.rs +55 -1
  10. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/builder/plan.rs +2 -1
  11. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/duckdb.rs +173 -21
  12. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/fabric.rs +2 -2
  13. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/mod.rs +3 -2
  14. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/mysql.rs +7 -0
  15. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +90 -9
  16. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/collections.rs +5 -0
  17. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/mod.rs +5 -0
  18. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/operators.rs +13 -16
  19. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/scalar.rs +18 -0
  20. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/types.rs +1 -3
  21. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/postgres.rs +2 -0
  22. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/snowflake.rs +9 -0
  23. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/tsql.rs +1 -0
  24. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/error.rs +2 -2
  25. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/expressions.rs +123 -4
  26. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/function_registry.rs +187 -5
  27. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/generator.rs +357 -46
  28. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/lib.rs +7 -4
  29. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/lineage.rs +187 -3
  30. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/annotate_types.rs +1375 -54
  31. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/mod.rs +24 -0
  32. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +177 -6
  33. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/simplify.rs +24 -6
  34. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/subquery.rs +26 -1
  35. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/parser.rs +1208 -508
  36. polyglot_sql-0.10.0/crates/polyglot-sql/src/query_analysis/column_uses.rs +735 -0
  37. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/query_analysis.rs +83 -2
  38. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/scope.rs +87 -17
  39. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/tokens.rs +12 -4
  40. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/transforms.rs +2 -0
  41. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/validation/tests.rs +367 -0
  42. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/validation.rs +268 -215
  43. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/deep_nesting_regression.rs +1 -0
  44. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/dialect_matrix.rs +30 -0
  45. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/query_analysis.rs +899 -2
  46. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_compat.rs +118 -0
  47. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/tsql_regression.rs +20 -0
  48. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-ast-derive/src/lib.rs +51 -0
  49. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0/crates/polyglot-sql-python}/README.md +54 -1
  50. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/lib.rs +1 -0
  51. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/types.rs +14 -0
  52. polyglot_sql-0.10.0/crates/polyglot-sql-python/src/validate.rs +55 -0
  53. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_parse.py +70 -0
  54. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_query_analysis.py +39 -0
  55. polyglot_sql-0.10.0/crates/polyglot-sql-python/tests/test_validate.py +173 -0
  56. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/python/polyglot_sql/__init__.py +2 -0
  57. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/python/polyglot_sql/__init__.pyi +42 -2
  58. polyglot_sql-0.9.1/crates/polyglot-sql-python/src/validate.rs +0 -23
  59. polyglot_sql-0.9.1/crates/polyglot-sql-python/tests/test_validate.py +0 -53
  60. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/allocation_hotspots.rs +0 -0
  61. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/ast_traversal.rs +0 -0
  62. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/in_list.rs +0 -0
  63. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/lineage.rs +0 -0
  64. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/parsing.rs +0 -0
  65. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/performance_hotspots.rs +0 -0
  66. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  67. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/benches/transpile.rs +0 -0
  68. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  69. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  70. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/ast_children.rs +0 -0
  71. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/ast_json.rs +0 -0
  72. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  73. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  74. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  75. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  76. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  77. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  78. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  79. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  80. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  81. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  82. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  83. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  84. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  85. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  86. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  87. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/json.rs +0 -0
  88. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/postgres_interval.rs +0 -0
  89. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/statements.rs +0 -0
  90. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/normalization/temporal.rs +0 -0
  91. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  92. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  93. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  94. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  95. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  96. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  97. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  98. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  99. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  100. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  101. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  102. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  103. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  104. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/diff.rs +0 -0
  105. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/format_tokens.rs +0 -0
  106. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  107. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/guard.rs +0 -0
  108. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/helper.rs +0 -0
  109. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/openlineage.rs +0 -0
  110. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  111. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  112. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  113. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  114. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  115. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  116. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  117. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  118. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  119. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  120. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  121. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/planner.rs +0 -0
  122. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/resolver.rs +0 -0
  123. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/schema.rs +0 -0
  124. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/set_operation.rs +0 -0
  125. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/time.rs +0 -0
  126. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/traversal.rs +0 -0
  127. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/src/trie.rs +0 -0
  128. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  129. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  130. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  131. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  132. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  133. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  134. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/create_view_security_comment_regression.rs +0 -0
  135. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  136. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  137. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  138. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  139. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  140. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  141. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  142. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  143. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  144. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  145. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  146. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  147. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
  148. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  149. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
  150. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
  151. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  152. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/oracle_data_types_regression.rs +0 -0
  153. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/postgres_explain_options.rs +0 -0
  154. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/postgres_regexp_clickhouse.rs +0 -0
  155. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  156. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/query_analysis_regression.rs +0 -0
  157. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  158. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  159. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  160. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  161. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  162. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  163. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  164. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  165. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  166. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  167. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-ast-derive/Cargo.toml +0 -0
  168. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  169. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  170. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  171. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  172. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  173. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  174. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  175. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/Cargo.toml +0 -0
  176. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/docs/api.md +0 -0
  177. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/docs/index.md +0 -0
  178. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  179. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  180. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/builders.rs +0 -0
  181. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  182. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/diff.rs +0 -0
  183. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/errors.rs +0 -0
  184. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/expr.rs +0 -0
  185. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  186. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/format.rs +0 -0
  187. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/generate.rs +0 -0
  188. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  189. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  190. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
  191. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  192. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/parse.rs +0 -0
  193. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
  194. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  195. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/transforms.rs +0 -0
  196. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  197. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  198. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_builders.py +0 -0
  199. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  200. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  201. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  202. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  203. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  204. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  205. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  206. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  207. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
  208. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  209. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/crates/polyglot-sql-python/uv.lock +0 -0
  210. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/pyproject.toml +0 -0
  211. {polyglot_sql-0.9.1 → polyglot_sql-0.10.0}/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.9.1"
608
+ version = "0.10.0"
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.9.1"
626
+ version = "0.10.0"
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.9.1"
635
+ version = "0.10.0"
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.9.1"
645
+ version = "0.10.0"
646
646
 
647
647
  [[package]]
648
648
  name = "polyglot-sql-python"
649
- version = "0.9.1"
649
+ version = "0.10.0"
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.9.1"
660
+ version = "0.10.0"
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.9.1"
9
+ version = "0.10.0"
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.9.1
3
+ Version: 0.10.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -150,6 +150,29 @@ if result:
150
150
  print("valid")
151
151
  ```
152
152
 
153
+ Schema-aware validation uses the same Rust validator as the TypeScript SDK:
154
+
155
+ ```python
156
+ sql = "SELECT o.order_id FROM orders o WHERE o.missing_column = TRUE"
157
+ schema = {"tables": [{"name": "orders", "columns": [{"name": "order_id", "type": "INT"}]}]}
158
+ result = polyglot_sql.validate_with_schema(
159
+ sql, schema, dialect="snowflake", check_types=True, check_references=True,
160
+ )
161
+ for error in result.errors:
162
+ print(error.code, error.message)
163
+ if error.start is not None and error.end is not None:
164
+ print(sql[error.start:error.end])
165
+ ```
166
+
167
+ Unknown tables, columns and aliases are checked by default. `check_references`
168
+ also checks ambiguous columns and foreign-key metadata; `check_types` enables
169
+ type checks. `strict` overrides the schema's `strict` value, which defaults to
170
+ `True`; `strict=False` reports reference/type findings as warnings. An empty
171
+ column list or a `*` column denotes an open schema, so unknown columns are not
172
+ rejected solely because their names are absent. Nonempty lists without `*`
173
+ are treated as complete. Options use snake_case keyword arguments, not an
174
+ `options` dictionary. Invalid schemas and unknown dialects raise `ValueError`.
175
+
153
176
  ```python
154
177
  options = {
155
178
  "producer": "https://github.com/tobilg/polyglot",
@@ -195,6 +218,26 @@ print(analysis["baseTables"][0]["name"]) # "orders"
195
218
  print(analysis["baseTables"][0]["table"]) # "orders"
196
219
  ```
197
220
 
221
+ Non-projection uses are available through the same shared Rust analysis:
222
+
223
+ ```python
224
+ analysis = polyglot_sql.analyze_query(
225
+ "SELECT o.id FROM orders o WHERE o.amount > 0", dialect="duckdb"
226
+ )
227
+ use = analysis["columnUses"][0]
228
+ print(use["context"]) # "filter"
229
+ print(use["references"][0]["column"]) # "amount"
230
+ print(use["scopePath"]) # "root"
231
+ ```
232
+
233
+ `columnUses` groups references by clause expression without changing projection
234
+ lineage. It covers joins, filters, grouping, HAVING/QUALIFY, window keys/frames,
235
+ ordering and set-operation filter inputs. `scopePath`/`expressionPath` identify
236
+ the scope and expression; `expressionSql` is dialect-rendered SQL. Optional
237
+ `span` objects use half-open Unicode-character offsets in the original input.
238
+ Reference spans locate uses, not upstream definitions. Unknown or ambiguous
239
+ sources remain conservative; whole-expression spans are omitted when unavailable.
240
+
198
241
  `analysis["relations"]` reports sources visible in the analyzed scope.
199
242
  `analysis["baseTables"]` reports deduplicated physical table dependencies across
200
243
  nested CTEs, derived tables, subqueries, and set-operation branches. For
@@ -259,6 +302,7 @@ All functions are exported from `polyglot_sql`.
259
302
  - `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`
260
303
  - `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`)
261
304
  - `validate(sql: str, dialect: str = "generic", *, strict_syntax: bool = False, semantic: bool = False) -> ValidationResult`
305
+ - `validate_with_schema(sql: str, schema: dict, dialect: str = "generic", *, check_types: bool = False, check_references: bool = False, strict: bool | None = None, semantic: bool = False, strict_syntax: bool = False) -> ValidationResult`
262
306
  - `optimize(sql: str, dialect: str = "generic") -> str`
263
307
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
264
308
  - `lineage_at(ordinal: int, sql: str, dialect: str = "generic") -> dict`
@@ -294,7 +338,8 @@ Exception hierarchy:
294
338
 
295
339
  Unknown dialect names raise built-in `ValueError`.
296
340
 
297
- `validate(...)` returns `ValidationResult`:
341
+ `validate(...)` and `validate_with_schema(...)` return `ValidationResult`:
342
+
298
343
  - `result.valid: bool`
299
344
  - `result.errors: list[ValidationErrorInfo]`
300
345
  - `bool(result)` works (`True` when valid)
@@ -305,11 +350,19 @@ clause boundaries. `semantic=True` adds warning diagnostics W001-W004 for
305
350
  `LIMIT` without `ORDER BY`; warnings do not make the result invalid.
306
351
 
307
352
  Each `ValidationErrorInfo` has:
353
+
308
354
  - `message: str`
309
355
  - `line: int`
310
356
  - `col: int`
311
357
  - `code: str`
312
358
  - `severity: str`
359
+ - `start: int | None` (zero-based Unicode character offset)
360
+ - `end: int | None` (exclusive Unicode character offset)
361
+
362
+ Source ranges refer to the original SQL and support Python string slicing.
363
+ Reference diagnostics point to the offending identifier when available;
364
+ synthetic or schema-only findings have no source range. Existing `line` and
365
+ `col` fields remain integers and use `0` when unavailable.
313
366
 
314
367
  ## Performance Note
315
368
 
@@ -123,6 +123,29 @@ if result:
123
123
  print("valid")
124
124
  ```
125
125
 
126
+ Schema-aware validation uses the same Rust validator as the TypeScript SDK:
127
+
128
+ ```python
129
+ sql = "SELECT o.order_id FROM orders o WHERE o.missing_column = TRUE"
130
+ schema = {"tables": [{"name": "orders", "columns": [{"name": "order_id", "type": "INT"}]}]}
131
+ result = polyglot_sql.validate_with_schema(
132
+ sql, schema, dialect="snowflake", check_types=True, check_references=True,
133
+ )
134
+ for error in result.errors:
135
+ print(error.code, error.message)
136
+ if error.start is not None and error.end is not None:
137
+ print(sql[error.start:error.end])
138
+ ```
139
+
140
+ Unknown tables, columns and aliases are checked by default. `check_references`
141
+ also checks ambiguous columns and foreign-key metadata; `check_types` enables
142
+ type checks. `strict` overrides the schema's `strict` value, which defaults to
143
+ `True`; `strict=False` reports reference/type findings as warnings. An empty
144
+ column list or a `*` column denotes an open schema, so unknown columns are not
145
+ rejected solely because their names are absent. Nonempty lists without `*`
146
+ are treated as complete. Options use snake_case keyword arguments, not an
147
+ `options` dictionary. Invalid schemas and unknown dialects raise `ValueError`.
148
+
126
149
  ```python
127
150
  options = {
128
151
  "producer": "https://github.com/tobilg/polyglot",
@@ -168,6 +191,26 @@ print(analysis["baseTables"][0]["name"]) # "orders"
168
191
  print(analysis["baseTables"][0]["table"]) # "orders"
169
192
  ```
170
193
 
194
+ Non-projection uses are available through the same shared Rust analysis:
195
+
196
+ ```python
197
+ analysis = polyglot_sql.analyze_query(
198
+ "SELECT o.id FROM orders o WHERE o.amount > 0", dialect="duckdb"
199
+ )
200
+ use = analysis["columnUses"][0]
201
+ print(use["context"]) # "filter"
202
+ print(use["references"][0]["column"]) # "amount"
203
+ print(use["scopePath"]) # "root"
204
+ ```
205
+
206
+ `columnUses` groups references by clause expression without changing projection
207
+ lineage. It covers joins, filters, grouping, HAVING/QUALIFY, window keys/frames,
208
+ ordering and set-operation filter inputs. `scopePath`/`expressionPath` identify
209
+ the scope and expression; `expressionSql` is dialect-rendered SQL. Optional
210
+ `span` objects use half-open Unicode-character offsets in the original input.
211
+ Reference spans locate uses, not upstream definitions. Unknown or ambiguous
212
+ sources remain conservative; whole-expression spans are omitted when unavailable.
213
+
171
214
  `analysis["relations"]` reports sources visible in the analyzed scope.
172
215
  `analysis["baseTables"]` reports deduplicated physical table dependencies across
173
216
  nested CTEs, derived tables, subqueries, and set-operation branches. For
@@ -232,6 +275,7 @@ All functions are exported from `polyglot_sql`.
232
275
  - `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`
233
276
  - `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`)
234
277
  - `validate(sql: str, dialect: str = "generic", *, strict_syntax: bool = False, semantic: bool = False) -> ValidationResult`
278
+ - `validate_with_schema(sql: str, schema: dict, dialect: str = "generic", *, check_types: bool = False, check_references: bool = False, strict: bool | None = None, semantic: bool = False, strict_syntax: bool = False) -> ValidationResult`
235
279
  - `optimize(sql: str, dialect: str = "generic") -> str`
236
280
  - `lineage(column: str, sql: str, dialect: str = "generic") -> dict`
237
281
  - `lineage_at(ordinal: int, sql: str, dialect: str = "generic") -> dict`
@@ -267,7 +311,8 @@ Exception hierarchy:
267
311
 
268
312
  Unknown dialect names raise built-in `ValueError`.
269
313
 
270
- `validate(...)` returns `ValidationResult`:
314
+ `validate(...)` and `validate_with_schema(...)` return `ValidationResult`:
315
+
271
316
  - `result.valid: bool`
272
317
  - `result.errors: list[ValidationErrorInfo]`
273
318
  - `bool(result)` works (`True` when valid)
@@ -278,11 +323,19 @@ clause boundaries. `semantic=True` adds warning diagnostics W001-W004 for
278
323
  `LIMIT` without `ORDER BY`; warnings do not make the result invalid.
279
324
 
280
325
  Each `ValidationErrorInfo` has:
326
+
281
327
  - `message: str`
282
328
  - `line: int`
283
329
  - `col: int`
284
330
  - `code: str`
285
331
  - `severity: str`
332
+ - `start: int | None` (zero-based Unicode character offset)
333
+ - `end: int | None` (exclusive Unicode character offset)
334
+
335
+ Source ranges refer to the original SQL and support Python string slicing.
336
+ Reference diagnostics point to the offending identifier when available;
337
+ synthetic or schema-only findings have no source range. Existing `line` and
338
+ `col` fields remain integers and use `0` when unavailable.
286
339
 
287
340
  ## Performance Note
288
341
 
@@ -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.9.1" }
103
+ polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.10.0" }
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.9.1", optional = true, default-features = false }
110
+ polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.10.0", 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.9.1", default-features = false }
28
+ polyglot-sql = { version = "0.10.0", default-features = false }
29
29
  ```
30
30
 
31
31
  ```toml
@@ -479,6 +479,11 @@ Athena, BigQuery, ClickHouse, CockroachDB, DataFusion, Databricks, Doris, Dremio
479
479
  | `time` | Enable time-format conversion helpers |
480
480
  | `bindings` | Enable `ts-rs` TypeScript type generation |
481
481
 
482
+ With `default-features = false`, `ast-tools` and `semantic` can be used without
483
+ enabling `builder` or `generate`. AST transforms reuse the same internal mutation
484
+ primitives as the native and serializable builders, while the public builder APIs
485
+ remain gated by `builder`.
486
+
482
487
  ## License
483
488
 
484
489
  [MIT](../../LICENSE)
@@ -1,8 +1,12 @@
1
- //! Canonical AST construction and mutation primitives shared by builder façades.
1
+ //! Canonical AST construction and mutation primitives shared by AST consumers.
2
2
  //!
3
- //! This module deliberately knows nothing about serde or a language binding. The
4
- //! native fluent API and [`super::plan`] both delegate their AST edits here so a
5
- //! clause has exactly one implementation.
3
+ //! AST transform helpers, the native fluent builder, and serializable builder
4
+ //! plans delegate their AST edits here so a clause has exactly one implementation.
5
+ //! This module depends only on AST and error types, not the optional public builder
6
+ //! API, SQL generation, serde, or a language binding.
7
+
8
+ // AST-only consumers use a subset of the primitives; builders use the full set.
9
+ #![cfg_attr(not(feature = "builder"), allow(dead_code))]
6
10
 
7
11
  use crate::error::{Error, Result};
8
12
  use crate::expressions::*;
@@ -9,7 +9,7 @@
9
9
 
10
10
  use std::collections::{HashMap, HashSet};
11
11
 
12
- use crate::builder::engine;
12
+ use crate::ast_mutation as engine;
13
13
  use crate::expressions::*;
14
14
  use crate::traversal::{is_aggregate, ExpressionWalk};
15
15
 
@@ -897,4 +897,25 @@ mod tests {
897
897
 
898
898
  assert_eq!(aggregate_types, vec!["count_if", "median", "first"]);
899
899
  }
900
+
901
+ #[test]
902
+ fn test_get_duckdb_null_preserving_arg_extrema() {
903
+ let expr = crate::parse_one(
904
+ "SELECT ARG_MAX_NULL(label, score), ARG_MIN_NULL(label, score) FROM source_table",
905
+ crate::dialects::DialectType::DuckDB,
906
+ )
907
+ .unwrap();
908
+ let aggregates = get_aggregate_functions(&expr);
909
+
910
+ assert_eq!(aggregates.len(), 2);
911
+ for (aggregate, expected_name) in
912
+ aggregates.into_iter().zip(["ARG_MAX_NULL", "ARG_MIN_NULL"])
913
+ {
914
+ let Expression::AggregateFunction(function) = aggregate else {
915
+ panic!("expected a generic aggregate node, got {aggregate:?}");
916
+ };
917
+ assert_eq!(function.name, expected_name);
918
+ assert_eq!(function.args.len(), 2);
919
+ }
920
+ }
900
921
  }
@@ -55,9 +55,9 @@
55
55
  //! .build();
56
56
  //! ```
57
57
 
58
- pub(crate) mod engine;
59
58
  pub mod plan;
60
59
 
60
+ use crate::ast_mutation as engine;
61
61
  use crate::expressions::*;
62
62
  use crate::generator::{Generator, GeneratorConfig, NotInStyle};
63
63
  use crate::parser::Parser;
@@ -186,6 +186,7 @@ pub fn col(name: &str) -> Expr {
186
186
  expr = Expression::Dot(Box::new(DotAccess {
187
187
  this: expr,
188
188
  field: builder_identifier(field),
189
+ inferred_type: None,
189
190
  }));
190
191
  }
191
192
 
@@ -551,6 +552,7 @@ pub fn trim(expr: Expr) -> Expr {
551
552
  position: TrimPosition::Both,
552
553
  sql_standard_syntax: false,
553
554
  position_explicit: false,
555
+ inferred_type: None,
554
556
  })))
555
557
  }
556
558
 
@@ -2783,12 +2785,64 @@ mod tests {
2783
2785
  assert_eq!(sql, "SELECT price * quantity AS total FROM items");
2784
2786
  }
2785
2787
 
2788
+ #[test]
2789
+ fn test_nested_operator_grouping() {
2790
+ assert_eq!(
2791
+ or(col("a").eq(lit(1)), col("b").eq(lit(2)))
2792
+ .and(col("c").eq(lit(3)))
2793
+ .to_sql(),
2794
+ "(a = 1 OR b = 2) AND c = 3"
2795
+ );
2796
+ assert_eq!(
2797
+ col("a")
2798
+ .eq(lit(1))
2799
+ .and(or(col("b").eq(lit(2)), col("c").eq(lit(3))))
2800
+ .to_sql(),
2801
+ "a = 1 AND (b = 2 OR c = 3)"
2802
+ );
2803
+ assert_eq!(col("a").add(col("b")).mul(col("c")).to_sql(), "(a + b) * c");
2804
+ assert_eq!(col("a").mul(col("b").add(col("c"))).to_sql(), "a * (b + c)");
2805
+ assert_eq!(col("a").sub(col("b").sub(col("c"))).to_sql(), "a - (b - c)");
2806
+ assert_eq!(col("a").div(col("b").div(col("c"))).to_sql(), "a / (b / c)");
2807
+ }
2808
+
2786
2809
  #[test]
2787
2810
  fn test_cast() {
2788
2811
  let sql = select([col("id").cast("VARCHAR")]).from("users").to_sql();
2789
2812
  assert_eq!(sql, "SELECT CAST(id AS VARCHAR) FROM users");
2790
2813
  }
2791
2814
 
2815
+ #[test]
2816
+ fn test_cast_int128() {
2817
+ for name in ["HUGEINT", "INT128"] {
2818
+ let Expression::Cast(cast) = col("value").cast(name).0 else {
2819
+ panic!("expected cast");
2820
+ };
2821
+ assert_eq!(cast.to, DataType::Int128);
2822
+ }
2823
+ }
2824
+
2825
+ #[test]
2826
+ fn test_cast_unsigned_integer_types() {
2827
+ for (name, expected) in [
2828
+ ("UTINYINT", DataType::UInt8),
2829
+ ("UINT8", DataType::UInt8),
2830
+ ("USMALLINT", DataType::UInt16),
2831
+ ("UINT16", DataType::UInt16),
2832
+ ("UINTEGER", DataType::UInt32),
2833
+ ("UINT32", DataType::UInt32),
2834
+ ("UBIGINT", DataType::UInt64),
2835
+ ("UINT64", DataType::UInt64),
2836
+ ("UHUGEINT", DataType::UInt128),
2837
+ ("UINT128", DataType::UInt128),
2838
+ ] {
2839
+ let Expression::Cast(cast) = col("value").cast(name).0 else {
2840
+ panic!("expected cast")
2841
+ };
2842
+ assert_eq!(cast.to, expected, "{name}");
2843
+ }
2844
+ }
2845
+
2792
2846
  #[test]
2793
2847
  fn test_from_starter() {
2794
2848
  let sql = from("users").select_cols(["id", "name"]).to_sql();
@@ -4,7 +4,8 @@
4
4
  //! provides a serializable, immutable expression plan so language bindings can
5
5
  //! share coercion, parsing, and AST-editing semantics without duplicating them.
6
6
 
7
- use crate::builder::{self, engine, Expr};
7
+ use crate::ast_mutation as engine;
8
+ use crate::builder::{self, Expr};
8
9
  use crate::dialects::Dialect;
9
10
  use crate::error::{Error, Result};
10
11
  use crate::expressions::*;