polyglot-sql 0.5.1__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 (183) hide show
  1. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/Cargo.lock +5 -5
  2. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/Cargo.toml +1 -1
  3. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/PKG-INFO +12 -4
  4. {polyglot_sql-0.5.1/crates/polyglot-sql-python → polyglot_sql-0.5.2}/README.md +11 -3
  5. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/Cargo.toml +1 -1
  6. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/README.md +17 -3
  7. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lineage.rs +22 -2
  8. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_columns.rs +43 -7
  9. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/query_analysis.rs +153 -5
  10. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/scope.rs +5 -1
  11. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/traversal.rs +15 -2
  12. polyglot_sql-0.5.2/crates/polyglot-sql/tests/query_analysis.rs +340 -0
  13. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2/crates/polyglot-sql-python}/README.md +11 -3
  14. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/index.md +18 -3
  15. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_query_analysis.py +26 -0
  16. polyglot_sql-0.5.1/crates/polyglot-sql/tests/query_analysis.rs +0 -143
  17. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/in_list.rs +0 -0
  18. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/parsing.rs +0 -0
  19. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/rust_parsing.rs +0 -0
  20. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/benches/transpile.rs +0 -0
  21. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/basic_usage.rs +0 -0
  22. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/examples/bench_json.rs +0 -0
  23. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/ast_transforms.rs +0 -0
  24. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/builder.rs +0 -0
  25. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/athena.rs +0 -0
  26. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/bigquery.rs +0 -0
  27. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/clickhouse.rs +0 -0
  28. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/cockroachdb.rs +0 -0
  29. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/databricks.rs +0 -0
  30. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/datafusion.rs +0 -0
  31. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/doris.rs +0 -0
  32. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dremio.rs +0 -0
  33. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/drill.rs +0 -0
  34. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/druid.rs +0 -0
  35. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/duckdb.rs +0 -0
  36. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/dune.rs +0 -0
  37. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/exasol.rs +0 -0
  38. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/fabric.rs +0 -0
  39. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/generic.rs +0 -0
  40. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/hive.rs +0 -0
  41. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/materialize.rs +0 -0
  42. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mod.rs +0 -0
  43. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/mysql.rs +0 -0
  44. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/oracle.rs +0 -0
  45. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/postgres.rs +0 -0
  46. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/presto.rs +0 -0
  47. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/redshift.rs +0 -0
  48. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/risingwave.rs +0 -0
  49. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/singlestore.rs +0 -0
  50. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/snowflake.rs +0 -0
  51. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/solr.rs +0 -0
  52. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/spark.rs +0 -0
  53. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/sqlite.rs +0 -0
  54. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/starrocks.rs +0 -0
  55. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tableau.rs +0 -0
  56. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/teradata.rs +0 -0
  57. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tidb.rs +0 -0
  58. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/trino.rs +0 -0
  59. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/dialects/tsql.rs +0 -0
  60. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/diff.rs +0 -0
  61. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/error.rs +0 -0
  62. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/expressions.rs +0 -0
  63. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_catalog.rs +0 -0
  64. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/function_registry.rs +0 -0
  65. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/generator.rs +0 -0
  66. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/helper.rs +0 -0
  67. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/lib.rs +0 -0
  68. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/openlineage.rs +0 -0
  69. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/annotate_types.rs +0 -0
  70. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/canonicalize.rs +0 -0
  71. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_ctes.rs +0 -0
  72. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/eliminate_joins.rs +0 -0
  73. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/isolate_table_selects.rs +0 -0
  74. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/mod.rs +0 -0
  75. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize.rs +0 -0
  76. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +0 -0
  77. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimize_joins.rs +0 -0
  78. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/optimizer.rs +0 -0
  79. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_predicates.rs +0 -0
  80. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +0 -0
  81. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/qualify_tables.rs +0 -0
  82. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/simplify.rs +0 -0
  83. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/optimizer/subquery.rs +0 -0
  84. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/parser.rs +0 -0
  85. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/planner.rs +0 -0
  86. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/resolver.rs +0 -0
  87. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/schema.rs +0 -0
  88. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/time.rs +0 -0
  89. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/tokens.rs +0 -0
  90. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/transforms.rs +0 -0
  91. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/trie.rs +0 -0
  92. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation/tests.rs +0 -0
  93. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/src/validation.rs +0 -0
  94. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/analyze_failures.rs +0 -0
  95. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/clickhouse_regression.rs +0 -0
  96. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/known_failures.rs +0 -0
  97. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/mod.rs +0 -0
  98. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_data.rs +0 -0
  99. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/common/test_runner.rs +0 -0
  100. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_coverage.rs +0 -0
  101. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_clickhouse_parser.rs +0 -0
  102. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect.rs +0 -0
  103. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_dialect_tests.rs +0 -0
  104. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/ddl.json +0 -0
  105. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/dml.json +0 -0
  106. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/functions.json +0 -0
  107. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/identity.json +0 -0
  108. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/operators.json +0 -0
  109. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/select.json +0 -0
  110. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/transpilation.json +0 -0
  111. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/custom_fixtures/datafusion/types.json +0 -0
  112. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/data_type_api.rs +0 -0
  113. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/deep_nesting_regression.rs +0 -0
  114. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/dialect_matrix.rs +0 -0
  115. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/error_handling.rs +0 -0
  116. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_regression.rs +0 -0
  117. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/fabric_tpch_regression.rs +0 -0
  118. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/identity_roundtrip.rs +0 -0
  119. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue201_regression_test.rs +0 -0
  120. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue210_regression_test.rs +0 -0
  121. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue226_regression_test.rs +0 -0
  122. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/issue227_strict_unsupported.rs +0 -0
  123. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/postgres_sqlite_regression.rs +0 -0
  124. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/snowflake_regression_test.rs +0 -0
  125. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_compat.rs +0 -0
  126. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_dialect_identity.rs +0 -0
  127. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity.rs +0 -0
  128. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_identity_detailed.rs +0 -0
  129. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_parser.rs +0 -0
  130. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_pretty.rs +0 -0
  131. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpilation.rs +0 -0
  132. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/sqlglot_transpile.rs +0 -0
  133. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tpch_transpile_stack.rs +0 -0
  134. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/transform_regression.rs +0 -0
  135. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql/tests/tsql_regression.rs +0 -0
  136. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/Cargo.toml +0 -0
  137. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/README.md +0 -0
  138. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/clickhouse.rs +0 -0
  139. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/duckdb.rs +0 -0
  140. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/src/lib.rs +0 -0
  141. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/clickhouse/extract_functions.py +0 -0
  142. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-function-catalogs/tools/duckdb/extract_functions.py +0 -0
  143. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/Cargo.toml +0 -0
  144. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/docs/api.md +0 -0
  145. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/mkdocs.yml +0 -0
  146. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/annotate_types.rs +0 -0
  147. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/dialects.rs +0 -0
  148. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/diff.rs +0 -0
  149. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/errors.rs +0 -0
  150. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr.rs +0 -0
  151. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/expr_types.rs +0 -0
  152. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/format.rs +0 -0
  153. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/generate.rs +0 -0
  154. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/helpers.rs +0 -0
  155. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lib.rs +0 -0
  156. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/lineage.rs +0 -0
  157. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/openlineage.rs +0 -0
  158. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/optimize.rs +0 -0
  159. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/parse.rs +0 -0
  160. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/query_analysis.rs +0 -0
  161. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/tokenize.rs +0 -0
  162. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transforms.rs +0 -0
  163. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/transpile.rs +0 -0
  164. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/types.rs +0 -0
  165. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/src/validate.rs +0 -0
  166. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/conftest.py +0 -0
  167. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_compat.py +0 -0
  168. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_dialects.py +0 -0
  169. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_diff.py +0 -0
  170. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_expression.py +0 -0
  171. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_format.py +0 -0
  172. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_generate.py +0 -0
  173. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_lineage.py +0 -0
  174. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_optimize.py +0 -0
  175. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_parse.py +0 -0
  176. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transforms.py +0 -0
  177. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_transpile.py +0 -0
  178. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/tests/test_validate.py +0 -0
  179. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/crates/polyglot-sql-python/uv.lock +0 -0
  180. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/pyproject.toml +0 -0
  181. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.py +0 -0
  182. {polyglot_sql-0.5.1 → polyglot_sql-0.5.2}/python/polyglot_sql/__init__.pyi +0 -0
  183. {polyglot_sql-0.5.1 → 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.1"
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.1"
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.1"
634
+ version = "0.5.2"
635
635
 
636
636
  [[package]]
637
637
  name = "polyglot-sql-python"
638
- version = "0.5.1"
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.1"
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.1"
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.1
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
@@ -125,22 +125,30 @@ emission are intentionally out of scope.
125
125
 
126
126
  ```python
127
127
  analysis = polyglot_sql.analyze_query(
128
- "SELECT CAST(total AS TEXT) AS total_text FROM orders",
128
+ "SELECT SUM(o.amount) AS total FROM orders AS o",
129
129
  {
130
130
  "dialect": "generic",
131
131
  "schema": {
132
132
  "tables": [
133
133
  {
134
134
  "name": "orders",
135
- "columns": [{"name": "total", "type": "INT"}],
135
+ "columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
136
136
  }
137
137
  ]
138
138
  },
139
139
  },
140
140
  )
141
- print(analysis["projections"][0]["transformKind"]) # "cast"
141
+ print(analysis["projections"][0]["transformKind"]) # "aggregation"
142
+ print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
143
+ print(analysis["baseTables"][0]["name"]) # "orders"
142
144
  ```
143
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
+
144
152
  ## API Reference
145
153
 
146
154
  All functions are exported from `polyglot_sql`.
@@ -98,22 +98,30 @@ emission are intentionally out of scope.
98
98
 
99
99
  ```python
100
100
  analysis = polyglot_sql.analyze_query(
101
- "SELECT CAST(total AS TEXT) AS total_text FROM orders",
101
+ "SELECT SUM(o.amount) AS total FROM orders AS o",
102
102
  {
103
103
  "dialect": "generic",
104
104
  "schema": {
105
105
  "tables": [
106
106
  {
107
107
  "name": "orders",
108
- "columns": [{"name": "total", "type": "INT"}],
108
+ "columns": [{"name": "amount", "type": "DECIMAL(10,2)"}],
109
109
  }
110
110
  ]
111
111
  },
112
112
  },
113
113
  )
114
- print(analysis["projections"][0]["transformKind"]) # "cast"
114
+ print(analysis["projections"][0]["transformKind"]) # "aggregation"
115
+ print(analysis["projections"][0]["typeHint"]) # "DECIMAL(10, 2)"
116
+ print(analysis["baseTables"][0]["name"]) # "orders"
115
117
  ```
116
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
+
117
125
  ## API Reference
118
126
 
119
127
  All functions are exported from `polyglot_sql`.
@@ -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.1", 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"
@@ -313,21 +313,35 @@ Schema-aware validation emits stable codes such as:
313
313
  ### Compact Query Analysis
314
314
 
315
315
  Use `analyze_query` when you need high-level facts without consuming the full AST
316
- or full lineage graph:
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.
317
321
 
318
322
  ```rust
319
323
  use polyglot_sql::{analyze_query, AnalyzeQueryOptions, DialectType, QueryShape};
320
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
+
321
332
  let analysis = analyze_query(
322
- "SELECT o.total AS total FROM orders o",
333
+ "SELECT SUM(o.amount) AS total FROM orders o",
323
334
  AnalyzeQueryOptions {
324
335
  dialect: DialectType::Generic,
325
- schema: None,
336
+ schema: Some(schema),
326
337
  },
327
338
  ).unwrap();
328
339
 
329
340
  assert_eq!(analysis.shape, QueryShape::Select);
330
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"));
331
345
  ```
332
346
 
333
347
  ### Tokenize
@@ -772,12 +772,32 @@ fn to_node_inner(
772
772
  apply_scope_context(&mut node, scope, source_name, reference_node_name);
773
773
 
774
774
  // 5. Star handling — add downstream for each source
775
- 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());
776
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
+
777
797
  let mut child = LineageNode::new(
778
798
  format!("{}.*", name),
779
799
  Expression::Star(crate::expressions::Star {
780
- table: None,
800
+ table: star.table.clone(),
781
801
  except: None,
782
802
  replace: None,
783
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
  }
@@ -11,11 +11,11 @@ use crate::expressions::{DataType, Expression, TableRef, With};
11
11
  use crate::lineage::{lineage_by_index_from_expression, LineageNode};
12
12
  use crate::optimizer::annotate_types::annotate_types;
13
13
  use crate::optimizer::qualify_columns::{qualify_columns, QualifyColumnsOptions};
14
- use crate::schema::Schema;
14
+ use crate::schema::{MappingSchema, Schema};
15
15
  use crate::scope::{build_scope, Scope, SourceInfo, SourceKind};
16
16
  use crate::traversal::{contains_aggregate, ExpressionWalk};
17
17
  use crate::validation::{mapping_schema_from_validation_schema, ValidationSchema};
18
- use crate::{parse_one, Error, Result};
18
+ use crate::{parse_data_type, parse_one, Error, Result};
19
19
  use serde::{Deserialize, Serialize};
20
20
  use std::collections::HashSet;
21
21
 
@@ -37,6 +37,7 @@ pub struct QueryAnalysis {
37
37
  pub ctes: Vec<String>,
38
38
  pub projections: Vec<ProjectionFact>,
39
39
  pub relations: Vec<RelationFact>,
40
+ pub base_tables: Vec<RelationFact>,
40
41
  pub set_operations: Vec<SetOperationFact>,
41
42
  }
42
43
 
@@ -134,7 +135,7 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
134
135
  let mapping_schema = options
135
136
  .schema
136
137
  .as_ref()
137
- .map(mapping_schema_from_validation_schema);
138
+ .map(|schema| analysis_mapping_schema(schema, options.dialect));
138
139
 
139
140
  if let Some(schema) = mapping_schema.as_ref() {
140
141
  let qualify_options = QualifyColumnsOptions::new().with_dialect(options.dialect);
@@ -142,12 +143,31 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
142
143
  .map_err(|e| Error::internal(format!("query analysis qualification failed: {e}")))?;
143
144
  }
144
145
 
146
+ let annotation_schema = mapping_schema.as_ref().map(|schema| {
147
+ let mut alias_schema = schema.clone();
148
+ add_scope_aliases_to_schema(
149
+ &build_scope(&expression),
150
+ schema,
151
+ &mut alias_schema,
152
+ options.dialect,
153
+ );
154
+ alias_schema
155
+ });
156
+
145
157
  annotate_types(
146
158
  &mut expression,
147
- mapping_schema.as_ref().map(|s| s as _),
159
+ annotation_schema
160
+ .as_ref()
161
+ .map(|schema| schema as &dyn Schema),
148
162
  Some(options.dialect),
149
163
  );
150
- crate::lineage::expand_cte_stars(&mut expression, mapping_schema.as_ref().map(|s| s as _));
164
+ crate::lineage::expand_cte_stars(
165
+ &mut expression,
166
+ annotation_schema
167
+ .as_ref()
168
+ .or(mapping_schema.as_ref())
169
+ .map(|schema| schema as &dyn Schema),
170
+ );
151
171
 
152
172
  let scope = build_scope(&expression);
153
173
  let shape = if is_set_operation(&expression) {
@@ -161,10 +181,106 @@ pub fn analyze_query(sql: &str, options: AnalyzeQueryOptions) -> Result<QueryAna
161
181
  ctes: collect_cte_names(&expression),
162
182
  projections: projection_facts_for_query(&expression, &scope, options.dialect),
163
183
  relations: relation_facts(&scope, mapping_schema.as_ref()),
184
+ base_tables: base_table_facts(&scope, mapping_schema.as_ref()),
164
185
  set_operations: set_operation_facts(&expression, &scope, options.dialect),
165
186
  })
166
187
  }
167
188
 
189
+ fn analysis_mapping_schema(schema: &ValidationSchema, dialect: DialectType) -> MappingSchema {
190
+ let broad_schema = mapping_schema_from_validation_schema(schema);
191
+ let mut mapping_schema = MappingSchema::with_dialect(dialect);
192
+
193
+ for table in &schema.tables {
194
+ let table_names = validation_table_names(table);
195
+ if table_names.is_empty() {
196
+ continue;
197
+ }
198
+
199
+ let fallback_table = table_names[0].as_str();
200
+ let columns: Vec<(String, DataType)> = table
201
+ .columns
202
+ .iter()
203
+ .map(|column| {
204
+ let data_type = parse_analysis_data_type(&column.data_type, dialect)
205
+ .unwrap_or_else(|| {
206
+ broad_schema
207
+ .get_column_type(fallback_table, &column.name)
208
+ .unwrap_or(DataType::Unknown)
209
+ });
210
+ (column.name.to_ascii_lowercase(), data_type)
211
+ })
212
+ .collect();
213
+
214
+ for table_name in table_names {
215
+ let _ = mapping_schema.add_table(&table_name, &columns, Some(dialect));
216
+ }
217
+ }
218
+
219
+ mapping_schema
220
+ }
221
+
222
+ fn validation_table_names(table: &crate::validation::SchemaTable) -> Vec<String> {
223
+ let mut names = Vec::new();
224
+
225
+ names.push(table.name.to_ascii_lowercase());
226
+ if let Some(schema_name) = &table.schema {
227
+ names.push(format!(
228
+ "{}.{}",
229
+ schema_name.to_ascii_lowercase(),
230
+ table.name.to_ascii_lowercase()
231
+ ));
232
+ }
233
+ for alias in &table.aliases {
234
+ names.push(alias.to_ascii_lowercase());
235
+ }
236
+
237
+ names.sort();
238
+ names.dedup();
239
+ names
240
+ }
241
+
242
+ fn parse_analysis_data_type(data_type: &str, dialect: DialectType) -> Option<DataType> {
243
+ let trimmed = data_type.trim();
244
+ if trimmed.is_empty() {
245
+ return None;
246
+ }
247
+ parse_data_type(trimmed, dialect).ok()
248
+ }
249
+
250
+ fn add_scope_aliases_to_schema(
251
+ scope: &Scope,
252
+ source_schema: &MappingSchema,
253
+ target_schema: &mut MappingSchema,
254
+ dialect: DialectType,
255
+ ) {
256
+ for child_scope in scope.traverse() {
257
+ for (source_name, source) in &child_scope.sources {
258
+ if source.kind != SourceKind::Table {
259
+ continue;
260
+ }
261
+ if let Some(table_name) = source_table_name(source) {
262
+ if source_name == &table_name {
263
+ continue;
264
+ }
265
+ if let Ok(column_names) = source_schema.column_names(&table_name) {
266
+ let columns: Vec<(String, DataType)> = column_names
267
+ .iter()
268
+ .map(|column| {
269
+ (
270
+ column.clone(),
271
+ source_schema
272
+ .get_column_type(&table_name, column)
273
+ .unwrap_or(DataType::Unknown),
274
+ )
275
+ })
276
+ .collect();
277
+ let _ = target_schema.add_table(source_name, &columns, Some(dialect));
278
+ }
279
+ }
280
+ }
281
+ }
282
+ }
283
+
168
284
  fn effective_query(expression: Expression) -> Expression {
169
285
  match expression {
170
286
  Expression::Prepare(prepare) => prepare.statement,
@@ -621,6 +737,38 @@ fn collect_relation_facts(
621
737
  }
622
738
  }
623
739
 
740
+ fn base_table_facts(
741
+ scope: &Scope,
742
+ mapping_schema: Option<&crate::schema::MappingSchema>,
743
+ ) -> Vec<RelationFact> {
744
+ let mut relations = Vec::new();
745
+ let mut seen = HashSet::new();
746
+
747
+ for child_scope in scope.traverse() {
748
+ for source in child_scope.sources.values() {
749
+ if source.kind != SourceKind::Table {
750
+ continue;
751
+ }
752
+
753
+ let Some(table_name) = source_table_name(source) else {
754
+ continue;
755
+ };
756
+
757
+ if seen.insert(table_name.clone()) {
758
+ relations.push(RelationFact {
759
+ name: table_name,
760
+ alias: source.alias.clone().or_else(|| source_alias(source)),
761
+ kind: SourceKind::Table,
762
+ columns: source_columns(source, mapping_schema),
763
+ });
764
+ }
765
+ }
766
+ }
767
+
768
+ relations.sort_by(|left, right| left.name.cmp(&right.name));
769
+ relations
770
+ }
771
+
624
772
  fn source_columns(
625
773
  source: &SourceInfo,
626
774
  mapping_schema: Option<&crate::schema::MappingSchema>,
@@ -726,7 +726,11 @@ fn add_table_to_scope(expr: &Expression, scope: &mut Scope) {
726
726
  if let Some(source) = cte_source {
727
727
  scope.add_source_info(name, source.clone());
728
728
  } else {
729
- scope.add_source(name, expr.clone(), false);
729
+ let mut source = SourceInfo::new(expr.clone(), false, SourceKind::Table);
730
+ if let Some(alias) = &table.alias {
731
+ source = source.with_alias(alias.name.clone());
732
+ }
733
+ scope.add_source_info(name, source);
730
734
  }
731
735
  }
732
736
  Expression::Subquery(subquery) => {
@@ -1098,9 +1098,22 @@ pub fn is_select(expr: &Expression) -> bool {
1098
1098
  matches!(expr, Expression::Select(_))
1099
1099
  }
1100
1100
 
1101
- /// Returns `true` if `expr` is an aggregate function ([`Expression::AggregateFunction`]).
1101
+ /// Returns `true` if `expr` is an aggregate function.
1102
1102
  pub fn is_aggregate(expr: &Expression) -> bool {
1103
- matches!(expr, Expression::AggregateFunction(_))
1103
+ matches!(
1104
+ expr,
1105
+ Expression::AggregateFunction(_)
1106
+ | Expression::Count(_)
1107
+ | Expression::Sum(_)
1108
+ | Expression::Avg(_)
1109
+ | Expression::Min(_)
1110
+ | Expression::Max(_)
1111
+ | Expression::GroupConcat(_)
1112
+ | Expression::StringAgg(_)
1113
+ | Expression::ListAgg(_)
1114
+ | Expression::CountIf(_)
1115
+ | Expression::SumIf(_)
1116
+ )
1104
1117
  }
1105
1118
 
1106
1119
  /// Returns `true` if `expr` is a window function ([`Expression::WindowFunction`]).