sqlglot 30.21.0__tar.gz → 30.22.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 (340) hide show
  1. {sqlglot-30.21.0 → sqlglot-30.22.0}/CHANGELOG.md +55 -0
  2. {sqlglot-30.21.0 → sqlglot-30.22.0}/Makefile +1 -1
  3. {sqlglot-30.21.0/sqlglot.egg-info → sqlglot-30.22.0}/PKG-INFO +22 -10
  4. {sqlglot-30.21.0 → sqlglot-30.22.0}/README.md +18 -6
  5. {sqlglot-30.21.0 → sqlglot-30.22.0}/setup.py +3 -3
  6. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/__init__.py +5 -0
  7. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/_version.py +3 -3
  8. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/bigquery.py +9 -1
  9. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/clickhouse.py +11 -1
  10. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dialect.py +118 -11
  11. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/doris.py +4 -0
  12. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/drill.py +2 -2
  13. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/duckdb.py +8 -0
  14. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/hive.py +13 -0
  15. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/materialize.py +5 -0
  16. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/mysql.py +15 -1
  17. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/postgres.py +11 -0
  18. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/redshift.py +5 -0
  19. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/risingwave.py +2 -0
  20. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/snowflake.py +3 -0
  21. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/spark.py +1 -0
  22. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/sqlite.py +3 -0
  23. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/starrocks.py +5 -0
  24. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/tsql.py +1 -0
  25. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/env.py +10 -1
  26. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/array.py +15 -1
  27. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/builders.py +1 -1
  28. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/ddl.py +1 -1
  29. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/properties.py +3 -5
  30. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/query.py +28 -3
  31. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/string.py +4 -0
  32. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generator.py +114 -33
  33. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/bigquery.py +4 -2
  34. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/clickhouse.py +20 -0
  35. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/doris.py +1 -0
  36. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dremio.py +1 -0
  37. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/drill.py +7 -0
  38. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/duckdb.py +76 -9
  39. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/hive.py +1 -0
  40. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/materialize.py +6 -1
  41. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/mysql.py +25 -1
  42. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/oracle.py +1 -0
  43. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/postgres.py +15 -1
  44. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/presto.py +9 -0
  45. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/redshift.py +8 -0
  46. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/risingwave.py +2 -1
  47. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/singlestore.py +5 -1
  48. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/snowflake.py +5 -48
  49. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/sqlite.py +2 -1
  50. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/starrocks.py +8 -0
  51. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/trino.py +1 -0
  52. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/tsql.py +12 -4
  53. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/lineage.py +19 -6
  54. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/optimizer.py +5 -2
  55. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/pushdown_predicates.py +24 -18
  56. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify.py +0 -3
  57. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify_columns.py +93 -22
  58. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/qualify_tables.py +32 -8
  59. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/resolver.py +29 -25
  60. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/scope.py +31 -13
  61. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/simplify.py +9 -2
  62. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parser.py +243 -75
  63. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/clickhouse.py +14 -0
  64. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/doris.py +3 -0
  65. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/duckdb.py +3 -2
  66. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/mysql.py +30 -5
  67. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/postgres.py +3 -0
  68. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/snowflake.py +11 -0
  69. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/spark.py +4 -0
  70. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/spark2.py +6 -1
  71. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/starrocks.py +3 -0
  72. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/trino.py +25 -0
  73. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/tsql.py +72 -2
  74. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/planner.py +1 -1
  75. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/schema.py +0 -3
  76. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/tokenizer_core.py +99 -20
  77. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/tokens.py +25 -7
  78. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/transforms.py +7 -0
  79. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/__init__.py +49 -2
  80. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/bigquery.py +2 -20
  81. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/duckdb.py +15 -1
  82. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/hive.py +18 -0
  83. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/postgres.py +21 -1
  84. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/presto.py +0 -2
  85. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/redshift.py +17 -0
  86. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/snowflake.py +19 -3
  87. sqlglot-30.22.0/sqlglot/typing/tsql.py +64 -0
  88. {sqlglot-30.21.0 → sqlglot-30.22.0/sqlglot.egg-info}/PKG-INFO +22 -10
  89. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/requires.txt +3 -3
  90. sqlglot-30.22.0/sqlglot.egg-info/scm_version.json +8 -0
  91. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/pyproject.toml +2 -2
  92. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/setup.py +0 -1
  93. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_bigquery.py +47 -7
  94. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_clickhouse.py +104 -2
  95. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_databricks.py +2 -0
  96. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dialect.py +33 -12
  97. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_duckdb.py +185 -1
  98. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_hive.py +87 -6
  99. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_mysql.py +301 -1
  100. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_oracle.py +26 -1
  101. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_postgres.py +87 -2
  102. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_presto.py +28 -3
  103. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_redshift.py +62 -1
  104. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_risingwave.py +3 -0
  105. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_singlestore.py +19 -4
  106. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_snowflake.py +79 -3
  107. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_spark.py +17 -0
  108. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_starrocks.py +6 -0
  109. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_trino.py +51 -6
  110. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_tsql.py +124 -1
  111. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/annotate_functions.sql +15 -3
  112. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/canonicalize_internal_names.sql +1 -1
  113. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/optimizer.sql +18 -4
  114. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_projections.sql +6 -6
  115. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns.sql +71 -7
  116. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_tables.sql +8 -0
  117. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/simplify.sql +39 -0
  118. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_build.py +6 -2
  119. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_executor.py +37 -2
  120. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_lineage.py +98 -28
  121. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_optimizer.py +179 -98
  122. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_parser.py +6 -0
  123. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_schema.py +31 -1
  124. sqlglot-30.21.0/sqlglot/typing/tsql.py +0 -37
  125. sqlglot-30.21.0/sqlglot.egg-info/scm_version.json +0 -8
  126. {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitignore +0 -0
  127. {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitmodules +0 -0
  128. {sqlglot-30.21.0 → sqlglot-30.22.0}/.gitpod.yml +0 -0
  129. {sqlglot-30.21.0 → sqlglot-30.22.0}/.pre-commit-config.yaml +0 -0
  130. {sqlglot-30.21.0 → sqlglot-30.22.0}/AGENTS.md +0 -0
  131. {sqlglot-30.21.0 → sqlglot-30.22.0}/CLAUDE.md +0 -0
  132. {sqlglot-30.21.0 → sqlglot-30.22.0}/CONTRIBUTING.md +0 -0
  133. {sqlglot-30.21.0 → sqlglot-30.22.0}/LICENSE +0 -0
  134. {sqlglot-30.21.0 → sqlglot-30.22.0}/MANIFEST.in +0 -0
  135. {sqlglot-30.21.0 → sqlglot-30.22.0}/pyproject.toml +0 -0
  136. {sqlglot-30.21.0 → sqlglot-30.22.0}/setup.cfg +0 -0
  137. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/__main__.py +0 -0
  138. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/_typing.py +0 -0
  139. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/anonymize.py +0 -0
  140. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/__init__.py +0 -0
  141. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/athena.py +0 -0
  142. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/databricks.py +0 -0
  143. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dax.py +0 -0
  144. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dremio.py +0 -0
  145. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/druid.py +0 -0
  146. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/dune.py +0 -0
  147. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/exasol.py +0 -0
  148. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/fabric.py +0 -0
  149. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/oracle.py +0 -0
  150. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/presto.py +0 -0
  151. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/prql.py +0 -0
  152. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/singlestore.py +0 -0
  153. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/solr.py +0 -0
  154. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/spark2.py +0 -0
  155. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/tableau.py +0 -0
  156. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/teradata.py +0 -0
  157. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/dialects/trino.py +0 -0
  158. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/diff.py +0 -0
  159. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/errors.py +0 -0
  160. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/__init__.py +0 -0
  161. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/context.py +0 -0
  162. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/python.py +0 -0
  163. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/executor/table.py +0 -0
  164. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/__init__.py +0 -0
  165. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/aggregate.py +0 -0
  166. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/constraints.py +0 -0
  167. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/core.py +0 -0
  168. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/datatypes.py +0 -0
  169. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/dml.py +0 -0
  170. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/functions.py +0 -0
  171. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/json.py +0 -0
  172. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/math.py +0 -0
  173. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/expressions/temporal.py +0 -0
  174. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/__init__.py +0 -0
  175. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/athena.py +0 -0
  176. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/databricks.py +0 -0
  177. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dax.py +0 -0
  178. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/druid.py +0 -0
  179. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/dune.py +0 -0
  180. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/exasol.py +0 -0
  181. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/fabric.py +0 -0
  182. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/prql.py +0 -0
  183. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/python.py +0 -0
  184. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/solr.py +0 -0
  185. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/spark.py +0 -0
  186. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/spark2.py +0 -0
  187. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/tableau.py +0 -0
  188. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/generators/teradata.py +0 -0
  189. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/helper.py +0 -0
  190. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/jsonpath.py +0 -0
  191. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/__init__.py +0 -0
  192. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/annotate_types.py +0 -0
  193. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/canonicalize.py +0 -0
  194. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/canonicalize_internal_names.py +0 -0
  195. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  196. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
  197. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  198. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/helpers.py +0 -0
  199. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  200. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/journal.py +0 -0
  201. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
  202. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/normalize.py +0 -0
  203. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  204. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/optimize_joins.py +0 -0
  205. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
  206. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  207. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/__init__.py +0 -0
  208. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/athena.py +0 -0
  209. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/base.py +0 -0
  210. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/bigquery.py +0 -0
  211. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/databricks.py +0 -0
  212. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dax.py +0 -0
  213. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dremio.py +0 -0
  214. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/drill.py +0 -0
  215. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/druid.py +0 -0
  216. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/dune.py +0 -0
  217. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/exasol.py +0 -0
  218. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/fabric.py +0 -0
  219. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/hive.py +0 -0
  220. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/materialize.py +0 -0
  221. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/oracle.py +0 -0
  222. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/presto.py +0 -0
  223. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/prql.py +0 -0
  224. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/redshift.py +0 -0
  225. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/risingwave.py +0 -0
  226. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/singlestore.py +0 -0
  227. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/solr.py +0 -0
  228. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/sqlite.py +0 -0
  229. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/tableau.py +0 -0
  230. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/parsers/teradata.py +0 -0
  231. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/py.typed +0 -0
  232. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/serde.py +0 -0
  233. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/time.py +0 -0
  234. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/trie.py +0 -0
  235. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/clickhouse.py +0 -0
  236. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/databricks.py +0 -0
  237. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/mysql.py +0 -0
  238. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/spark.py +0 -0
  239. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot/typing/spark2.py +0 -0
  240. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/SOURCES.txt +0 -0
  241. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/dependency_links.txt +0 -0
  242. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/scm_file_list.json +0 -0
  243. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.egg-info/top_level.txt +0 -0
  244. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglot.png +0 -0
  245. {sqlglot-30.21.0 → sqlglot-30.22.0}/sqlglotc/MANIFEST.in +0 -0
  246. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/__init__.py +0 -0
  247. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/__init__.py +0 -0
  248. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_athena.py +0 -0
  249. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dax.py +0 -0
  250. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_doris.py +0 -0
  251. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dremio.py +0 -0
  252. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_drill.py +0 -0
  253. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_druid.py +0 -0
  254. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_dune.py +0 -0
  255. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_exasol.py +0 -0
  256. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_fabric.py +0 -0
  257. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_materialize.py +0 -0
  258. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_pipe_syntax.py +0 -0
  259. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_prql.py +0 -0
  260. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_solr.py +0 -0
  261. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_sqlite.py +0 -0
  262. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_tableau.py +0 -0
  263. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/dialects/test_teradata.py +0 -0
  264. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/identity.sql +0 -0
  265. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/jsonpath/LICENSE +0 -0
  266. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/jsonpath/cts.json +0 -0
  267. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
  268. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  269. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  270. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  271. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  272. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  273. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  274. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/normalize.sql +0 -0
  275. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  276. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  277. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  278. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  279. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
  280. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  281. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
  282. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  283. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  284. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  285. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  286. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  287. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  288. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  289. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  290. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  291. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  292. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  293. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  294. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  295. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  296. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  297. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  298. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  299. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  300. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  301. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  302. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  303. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  304. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  305. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  306. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  307. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  308. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  309. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  310. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  311. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  312. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  313. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  314. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  315. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  316. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  317. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  318. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/partial.sql +0 -0
  319. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/fixtures/pretty.sql +0 -0
  320. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/gen_fixtures.py +0 -0
  321. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/helpers.py +0 -0
  322. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/leakcheck.py +0 -0
  323. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/sqlglot/__init__.py +0 -0
  324. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_anonymize.py +0 -0
  325. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_dialect_entry_points.py +0 -0
  326. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_dialect_imports.py +0 -0
  327. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_diff.py +0 -0
  328. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_docs.py +0 -0
  329. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_errors.py +0 -0
  330. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_expressions.py +0 -0
  331. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_generator.py +0 -0
  332. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_helper.py +0 -0
  333. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_integration_loader.py +0 -0
  334. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_jsonpath.py +0 -0
  335. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_serde.py +0 -0
  336. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_time.py +0 -0
  337. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_tokens.py +0 -0
  338. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_transforms.py +0 -0
  339. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_transpile.py +0 -0
  340. {sqlglot-30.21.0 → sqlglot-30.22.0}/tests/test_typing.py +0 -0
@@ -1,6 +1,60 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v30.21.0] - 2026-09-30
5
+ ### :boom: BREAKING CHANGES
6
+ - due to [`2be1e0e`](https://github.com/tobymao/sqlglot/commit/2be1e0e2addc0ef01cfa3fd3cf2ef751cdbf411d) - annotate `bit_xor` for duckdb *(PR [#8452](https://github.com/tobymao/sqlglot/pull/8452) by [@opencode13241-eng](https://github.com/opencode13241-eng))*:
7
+
8
+ annotate `bit_xor` for duckdb (#8452)
9
+
10
+ - due to [`65a0e22`](https://github.com/tobymao/sqlglot/commit/65a0e22447fcca9ea4a89f6167954fbb872c8e6d) - new projection pushdown algorithm *(PR [#8440](https://github.com/tobymao/sqlglot/pull/8440) by [@georgesittas](https://github.com/georgesittas))*:
11
+
12
+ new projection pushdown algorithm (#8440)
13
+
14
+ - due to [`e3f71dc`](https://github.com/tobymao/sqlglot/commit/e3f71dc1a1186ada4b017a5f2498b8c2b0a8a25b) - decode backslash escape sequences in string literals *(PR [#8456](https://github.com/tobymao/sqlglot/pull/8456) by [@georgesittas](https://github.com/georgesittas))*:
15
+
16
+ decode backslash escape sequences in string literals (#8456)
17
+
18
+ - due to [`b4d9e37`](https://github.com/tobymao/sqlglot/commit/b4d9e37d84a61eeb78e8d652f697e2e0d4d57869) - inherit Trino dialect, parser and generator defaults *(PR [#8464](https://github.com/tobymao/sqlglot/pull/8464) by [@georgesittas](https://github.com/georgesittas))*:
19
+
20
+ inherit Trino dialect, parser and generator defaults (#8464)
21
+
22
+ - due to [`d84f7f3`](https://github.com/tobymao/sqlglot/commit/d84f7f3ee1ff50778c93970b086d59692714dcdc) - preserve BD literal semantics in Hive and Spark *(PR [#8455](https://github.com/tobymao/sqlglot/pull/8455) by [@georgesittas](https://github.com/georgesittas))*:
23
+
24
+ preserve BD literal semantics in Hive and Spark (#8455)
25
+
26
+ - due to [`1122046`](https://github.com/tobymao/sqlglot/commit/11220460d0e78a3c83f14b006239f636e4ddde71) - convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] *(PR [#8460](https://github.com/tobymao/sqlglot/pull/8460) by [@anishmehta24](https://github.com/anishmehta24))*:
27
+
28
+ convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] (#8460)
29
+
30
+
31
+ ### :sparkles: New Features
32
+ - [`2be1e0e`](https://github.com/tobymao/sqlglot/commit/2be1e0e2addc0ef01cfa3fd3cf2ef751cdbf411d) - **optimizer**: annotate `bit_xor` for duckdb *(PR [#8452](https://github.com/tobymao/sqlglot/pull/8452) by [@opencode13241-eng](https://github.com/opencode13241-eng))*
33
+ - [`7e48d16`](https://github.com/tobymao/sqlglot/commit/7e48d16936216f9f93d7a52baef0e482e3fb14e7) - **optimizer**: add #schema fixture directive *(PR [#8435](https://github.com/tobymao/sqlglot/pull/8435) by [@fivetran-kwoodbeck](https://github.com/fivetran-kwoodbeck))*
34
+
35
+ ### :bug: Bug Fixes
36
+ - [`1d40af1`](https://github.com/tobymao/sqlglot/commit/1d40af146d77dcf890ae18c1a59e649bf0862db3) - **optimizer**: unqualified semi/anti join column bound to table joined *(PR [#8430](https://github.com/tobymao/sqlglot/pull/8430) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
37
+ - [`d9b2b96`](https://github.com/tobymao/sqlglot/commit/d9b2b9660be8a6b77a0bb0475f6bf0509c6c6aa0) - **parser**: constraint parsing fixup *(PR [#8457](https://github.com/tobymao/sqlglot/pull/8457) by [@georgesittas](https://github.com/georgesittas))*
38
+ - [`e3f71dc`](https://github.com/tobymao/sqlglot/commit/e3f71dc1a1186ada4b017a5f2498b8c2b0a8a25b) - **snowflake**: decode backslash escape sequences in string literals *(PR [#8456](https://github.com/tobymao/sqlglot/pull/8456) by [@georgesittas](https://github.com/georgesittas))*
39
+ - :arrow_lower_right: *fixes issue [#4344](https://github.com/tobymao/sqlglot/issues/4344) opened by [@dylanscott](https://github.com/dylanscott)*
40
+ - :arrow_lower_right: *fixes issue [#8441](https://github.com/tobymao/sqlglot/issues/8441) opened by [@yvonne-chou-1](https://github.com/yvonne-chou-1)*
41
+ - [`b4d9e37`](https://github.com/tobymao/sqlglot/commit/b4d9e37d84a61eeb78e8d652f697e2e0d4d57869) - **athena**: inherit Trino dialect, parser and generator defaults *(PR [#8464](https://github.com/tobymao/sqlglot/pull/8464) by [@georgesittas](https://github.com/georgesittas))*
42
+ - :arrow_lower_right: *fixes issue [#8458](https://github.com/tobymao/sqlglot/issues/8458) opened by [@deepyaman](https://github.com/deepyaman)*
43
+ - [`d84f7f3`](https://github.com/tobymao/sqlglot/commit/d84f7f3ee1ff50778c93970b086d59692714dcdc) - preserve BD literal semantics in Hive and Spark *(PR [#8455](https://github.com/tobymao/sqlglot/pull/8455) by [@georgesittas](https://github.com/georgesittas))*
44
+ - [`1122046`](https://github.com/tobymao/sqlglot/commit/11220460d0e78a3c83f14b006239f636e4ddde71) - **spark**: convert ARRAY_INSERT position between 0- and 1-based dialects [CLAUDE] *(PR [#8460](https://github.com/tobymao/sqlglot/pull/8460) by [@anishmehta24](https://github.com/anishmehta24))*
45
+ - [`18520e2`](https://github.com/tobymao/sqlglot/commit/18520e2b5bfa3f1d7ed1a261d1bd463132054db1) - **clickhouse**: generate varPop for VariancePop [CLAUDE] *(PR [#8469](https://github.com/tobymao/sqlglot/pull/8469) by [@ekut](https://github.com/ekut))*
46
+ - [`2960bdd`](https://github.com/tobymao/sqlglot/commit/2960bdd7470f1c21518710ed468466b9bab4bb7b) - **optimizer**: preserve tautological aggregate filters [CODEX] *(PR [#8466](https://github.com/tobymao/sqlglot/pull/8466) by [@Boulea7](https://github.com/Boulea7))*
47
+ - [`840b482`](https://github.com/tobymao/sqlglot/commit/840b4823e649e380e1dda30cf21907baebb6c58c) - **postgres**: keep WITH ORDINALITY alias columns on LATERAL UNNEST [GROK] *(PR [#8463](https://github.com/tobymao/sqlglot/pull/8463) by [@00200200](https://github.com/00200200))*
48
+ - :arrow_lower_right: *fixes issue [#8462](https://github.com/tobymao/sqlglot/issues/8462) opened by [@SoTrx](https://github.com/SoTrx)*
49
+ - [`aa70202`](https://github.com/tobymao/sqlglot/commit/aa702020725f4d1591cfb2d308c72937a38e8fd4) - **optimizer**: qualify struct paths with conflicting aliases [CODEX] *(PR [#8467](https://github.com/tobymao/sqlglot/pull/8467) by [@tobymao](https://github.com/tobymao))*
50
+ - [`b54d32f`](https://github.com/tobymao/sqlglot/commit/b54d32f036d4c1158bb889324f4ac6d2846d2701) - **optimizer**: stop struct lookup at nearest alias [CODEX] *(commit by [@tobymao](https://github.com/tobymao))*
51
+ - [`5d16fa8`](https://github.com/tobymao/sqlglot/commit/5d16fa83bfb8f3582eaffa4b99c7d05a061d8a76) - **ci**: publish sqlglot independently of sqlglotc [CODEX] *(commit by [@tobymao](https://github.com/tobymao))*
52
+
53
+ ### :recycle: Refactors
54
+ - [`65a0e22`](https://github.com/tobymao/sqlglot/commit/65a0e22447fcca9ea4a89f6167954fbb872c8e6d) - **optimizer**: new projection pushdown algorithm *(PR [#8440](https://github.com/tobymao/sqlglot/pull/8440) by [@georgesittas](https://github.com/georgesittas))*
55
+ - [`ac940f0`](https://github.com/tobymao/sqlglot/commit/ac940f016a1d398137b4d666db0f191e6c4b6d1f) - **tokenizer**: generalize backslash escape handling, report unterminated escapes *(PR [#8470](https://github.com/tobymao/sqlglot/pull/8470) by [@georgesittas](https://github.com/georgesittas))*
56
+
57
+
4
58
  ## [v30.20.0] - 2026-09-27
5
59
  ### :boom: BREAKING CHANGES
6
60
  - due to [`1d0e3f3`](https://github.com/tobymao/sqlglot/commit/1d0e3f34864037c54cf6bdf45af594db62ad7319) - Fix mysql roundtrip for DATE_ADD and DATE_SUB *(PR [#8417](https://github.com/tobymao/sqlglot/pull/8417) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
@@ -15990,3 +16044,4 @@ pip install "sqlglot[c]" # compiled — faster, but no subclassing
15990
16044
  [v30.18.0]: https://github.com/tobymao/sqlglot/compare/v30.17.0...v30.18.0
15991
16045
  [v30.19.0]: https://github.com/tobymao/sqlglot/compare/v30.18.0...v30.19.0
15992
16046
  [v30.20.0]: https://github.com/tobymao/sqlglot/compare/v30.19.0...v30.20.0
16047
+ [v30.21.0]: https://github.com/tobymao/sqlglot/compare/v30.20.0...v30.21.0
@@ -42,7 +42,7 @@ install-dev:
42
42
  fi; \
43
43
  fi
44
44
 
45
- # sqlglotc requires Python 3.10+ (sqlglot-mypy 1.20+ dropped 3.9). On 3.9
45
+ # sqlglotc requires Python 3.10+ (mypy 2.4+ dropped 3.9). On 3.9
46
46
  # we skip the C build; tests fall back to pure-Python sqlglot.
47
47
  PY_GE_310 := $(shell python -c "import sys; print(int(sys.version_info >= (3, 10)))")
48
48
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 30.21.0
3
+ Version: 30.22.0
4
4
  Summary: An easily customizable SQL parser and transpiler
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License-Expression: MIT
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Provides-Extra: dev
21
21
  Requires-Dist: duckdb>=0.6; extra == "dev"
22
- Requires-Dist: sqlglot-mypy>=2.3.0.post2; python_version >= "3.10" and extra == "dev"
22
+ Requires-Dist: mypy>=2.4.0; python_version >= "3.10" and extra == "dev"
23
23
  Requires-Dist: mypy; python_version < "3.10" and extra == "dev"
24
24
  Requires-Dist: setuptools_scm; extra == "dev"
25
25
  Requires-Dist: pandas; extra == "dev"
@@ -34,10 +34,10 @@ Requires-Dist: types-pytz; extra == "dev"
34
34
  Requires-Dist: typing_extensions; extra == "dev"
35
35
  Requires-Dist: pyperf; extra == "dev"
36
36
  Provides-Extra: c
37
- Requires-Dist: sqlglotc==30.21.0; python_version >= "3.10" and extra == "c"
37
+ Requires-Dist: sqlglotc==30.22.0; python_version >= "3.10" and extra == "c"
38
38
  Provides-Extra: rs
39
39
  Requires-Dist: sqlglotrs==0.13.0; extra == "rs"
40
- Requires-Dist: sqlglotc==30.21.0; python_version >= "3.10" and extra == "rs"
40
+ Requires-Dist: sqlglotc==30.22.0; python_version >= "3.10" and extra == "rs"
41
41
  Dynamic: license-file
42
42
  Dynamic: provides-extra
43
43
 
@@ -87,11 +87,13 @@ From PyPI:
87
87
  # Pure python version
88
88
  pip3 install sqlglot
89
89
 
90
- # C extensions compiled with mypyc
90
+ # C extensions compiled with mypyc (Python 3.10+)
91
91
  # prebuilt wheel if available for your platform, otherwise builds from source
92
92
  pip3 install "sqlglot[c]"
93
93
  ```
94
94
 
95
+ On Python 3.9, `sqlglot[c]` installs the pure Python version.
96
+
95
97
  Or with a local checkout:
96
98
 
97
99
  ```
@@ -581,12 +583,12 @@ make docs-serve
581
583
  ## Run Tests and Lint
582
584
 
583
585
  ```
584
- make style # Only linter checks
586
+ make style # Format, lint, and type-check
585
587
  make unit # Only unit tests (pure Python)
586
588
  make test # Unit and integration tests (pure Python)
587
589
  make unitc # Only unit tests (mypyc compiled)
588
590
  make testc # Unit and integration tests (mypyc compiled)
589
- make check # Full test suite & linter checks
591
+ make check # Full test suite, formatting, linting, and type checks
590
592
  make clean # Remove compiled C artifacts (.so files, build dirs)
591
593
  ```
592
594
 
@@ -616,18 +618,28 @@ sqlglot, sqltree, sqlparse, and sqlfluff are python based whereas sqloxide and p
616
618
  | many_numbers | 0.103898 (1.00) | 0.024483 (0.24) | 0.120119 (1.16) | N/A | N/A | 0.031667 (0.30) | 0.026880 (0.26) |
617
619
 
618
620
  ```
619
- make bench # Run parsing benchmark
621
+ make bench # Run parsing, transpilation, and optimization benchmarks
622
+ make bench-parse # Run parsing benchmark
623
+ make bench-transpile # Run transpilation benchmark
620
624
  make bench-optimize # Run optimization benchmark
621
625
  ```
622
626
 
623
627
  ## Optional Dependencies
624
628
 
625
- SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify literal timedelta expressions. The optimizer will not simplify expressions like the following if the module cannot be found:
629
+ SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify constant date and interval arithmetic. With dateutil installed, the optimizer simplifies:
630
+
631
+ ```sql
632
+ DATE '2021-01-01' + INTERVAL '1' MONTH
633
+ ```
634
+
635
+ to:
626
636
 
627
637
  ```sql
628
- x + interval '1' month
638
+ CAST('2021-02-01' AS DATE)
629
639
  ```
630
640
 
641
+ Without dateutil, the optimizer leaves this arithmetic unevaluated.
642
+
631
643
  ## Supported Dialects
632
644
 
633
645
  | Dialect | Support Level |
@@ -44,11 +44,13 @@ From PyPI:
44
44
  # Pure python version
45
45
  pip3 install sqlglot
46
46
 
47
- # C extensions compiled with mypyc
47
+ # C extensions compiled with mypyc (Python 3.10+)
48
48
  # prebuilt wheel if available for your platform, otherwise builds from source
49
49
  pip3 install "sqlglot[c]"
50
50
  ```
51
51
 
52
+ On Python 3.9, `sqlglot[c]` installs the pure Python version.
53
+
52
54
  Or with a local checkout:
53
55
 
54
56
  ```
@@ -538,12 +540,12 @@ make docs-serve
538
540
  ## Run Tests and Lint
539
541
 
540
542
  ```
541
- make style # Only linter checks
543
+ make style # Format, lint, and type-check
542
544
  make unit # Only unit tests (pure Python)
543
545
  make test # Unit and integration tests (pure Python)
544
546
  make unitc # Only unit tests (mypyc compiled)
545
547
  make testc # Unit and integration tests (mypyc compiled)
546
- make check # Full test suite & linter checks
548
+ make check # Full test suite, formatting, linting, and type checks
547
549
  make clean # Remove compiled C artifacts (.so files, build dirs)
548
550
  ```
549
551
 
@@ -573,18 +575,28 @@ sqlglot, sqltree, sqlparse, and sqlfluff are python based whereas sqloxide and p
573
575
  | many_numbers | 0.103898 (1.00) | 0.024483 (0.24) | 0.120119 (1.16) | N/A | N/A | 0.031667 (0.30) | 0.026880 (0.26) |
574
576
 
575
577
  ```
576
- make bench # Run parsing benchmark
578
+ make bench # Run parsing, transpilation, and optimization benchmarks
579
+ make bench-parse # Run parsing benchmark
580
+ make bench-transpile # Run transpilation benchmark
577
581
  make bench-optimize # Run optimization benchmark
578
582
  ```
579
583
 
580
584
  ## Optional Dependencies
581
585
 
582
- SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify literal timedelta expressions. The optimizer will not simplify expressions like the following if the module cannot be found:
586
+ SQLGlot uses [dateutil](https://github.com/dateutil/dateutil) to simplify constant date and interval arithmetic. With dateutil installed, the optimizer simplifies:
587
+
588
+ ```sql
589
+ DATE '2021-01-01' + INTERVAL '1' MONTH
590
+ ```
591
+
592
+ to:
583
593
 
584
594
  ```sql
585
- x + interval '1' month
595
+ CAST('2021-02-01' AS DATE)
586
596
  ```
587
597
 
598
+ Without dateutil, the optimizer leaves this arithmetic unevaluated.
599
+
588
600
  ## Supported Dialects
589
601
 
590
602
  | Dialect | Support Level |
@@ -7,9 +7,9 @@ setup(
7
7
  extras_require={
8
8
  "dev": [
9
9
  "duckdb>=0.6",
10
- # sqlglot-mypy 1.20+ is the build dep for sqlglotc and only ships
10
+ # mypy 2.4+ is the build dep for sqlglotc and only ships
11
11
  # for py3.10+; on py3.9 just use upstream mypy for type checking.
12
- "sqlglot-mypy >= 2.3.0.post2; python_version >= '3.10'",
12
+ "mypy >= 2.4.0; python_version >= '3.10'",
13
13
  "mypy; python_version < '3.10'",
14
14
  "setuptools_scm",
15
15
  "pandas",
@@ -25,7 +25,7 @@ setup(
25
25
  "pyperf",
26
26
  ],
27
27
  # Compiles from source on the user's machine. Requires Python 3.10+
28
- # because the build dep (sqlglot-mypy 1.20+) dropped 3.9; on 3.9
28
+ # because the build dep (mypy 2.4+) dropped 3.9; on 3.9
29
29
  # `pip install sqlglot[c]` is a no-op and you just get pure-Python sqlglot.
30
30
  "c": [f"sqlglotc=={version}; python_version >= '3.10'"],
31
31
  # Deprecated: the Rust tokenizer has been replaced by sqlglotc.
@@ -81,6 +81,7 @@ def tokenize(sql: str, read: DialectType = None, dialect: DialectType = None) ->
81
81
  Args:
82
82
  sql: the SQL code string to tokenize.
83
83
  read: the SQL dialect to apply during tokenizing (eg. "spark", "hive", "presto", "mysql").
84
+ See `sqlglot.dialects.Dialects` for options.
84
85
  dialect: the SQL dialect (alias for read).
85
86
 
86
87
  Returns:
@@ -101,6 +102,7 @@ def parse(
101
102
  Args:
102
103
  sql: the SQL code string to parse.
103
104
  read: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
105
+ See `sqlglot.dialects.Dialects` for options.
104
106
  dialect: the SQL dialect (alias for read).
105
107
  **opts: other `sqlglot.parser.Parser` options.
106
108
 
@@ -144,6 +146,7 @@ def parse_one(
144
146
  Args:
145
147
  sql: the SQL code string to parse.
146
148
  read: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
149
+ See `sqlglot.dialects.Dialects` for options.
147
150
  dialect: the SQL dialect (alias for read)
148
151
  into: the SQLGlot Expr to parse into.
149
152
  **opts: other `sqlglot.parser.Parser` options.
@@ -180,7 +183,9 @@ def transpile(
180
183
  Args:
181
184
  sql: the SQL code string to transpile.
182
185
  read: the source dialect used to parse the input string (eg. "spark", "hive", "presto", "mysql").
186
+ See `sqlglot.dialects.Dialects` for options.
183
187
  write: the target dialect into which the input should be transformed (eg. "spark", "hive", "presto", "mysql").
188
+ See `sqlglot.dialects.Dialects` for options.
184
189
  identity: if set to `True` and if the target dialect is not specified the source dialect will be used as both:
185
190
  the source and the target dialect.
186
191
  error_level: the desired error level of the parser.
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '30.21.0'
22
- __version_tuple__ = version_tuple = (30, 21, 0)
21
+ __version__ = version = '30.22.0'
22
+ __version_tuple__ = version_tuple = (30, 22, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g5d16fa83b'
24
+ __commit_id__ = commit_id = 'gb8333a81f'
@@ -29,7 +29,7 @@ class BigQuery(Dialect):
29
29
  HEX_LOWERCASE = True
30
30
  FORCE_EARLY_ALIAS_REF_EXPANSION = True
31
31
  EXPAND_ONLY_GROUP_ALIAS_REF = True
32
- PRESERVE_ORIGINAL_NAMES = True
32
+ ORIGINAL_NAME_META_KEY = "bigquery_name"
33
33
  HEX_STRING_IS_INTEGER_TYPE = True
34
34
  BYTE_STRING_IS_BYTES_TYPE = True
35
35
  UUID_IS_STRING_TYPE = True
@@ -168,6 +168,14 @@ class BigQuery(Dialect):
168
168
  }
169
169
 
170
170
  class Tokenizer(tokens.Tokenizer):
171
+ NUMERIC_ESCAPES = {
172
+ "x": (16, 2, 2, 0xFF),
173
+ "X": (16, 2, 2, 0xFF),
174
+ "u": (16, 4, 4, 0xFFFF),
175
+ "U": (16, 8, 8, 0x10FFFF),
176
+ "0": (8, 3, 3, 0xFF),
177
+ }
178
+ DROP_UNKNOWN_ESCAPES = True
171
179
  QUOTES = ["'", '"', '"""', "'''"]
172
180
  COMMENTS = ["--", "#", ("/*", "*/")]
173
181
  IDENTIFIERS = ["`"]
@@ -19,7 +19,7 @@ class ClickHouse(Dialect):
19
19
  SUPPORTS_USER_DEFINED_TYPES = False
20
20
  LOG_BASE_FIRST: bool | None = None
21
21
  FORCE_EARLY_ALIAS_REF_EXPANSION = True
22
- PRESERVE_ORIGINAL_NAMES = True
22
+ ORIGINAL_NAME_META_KEY = "clickhouse_name"
23
23
  NUMBERS_CAN_BE_UNDERSCORE_SEPARATED = True
24
24
  IDENTIFIERS_CAN_START_WITH_DIGIT = True
25
25
  HEX_STRING_IS_INTEGER_TYPE = True
@@ -31,6 +31,13 @@ class ClickHouse(Dialect):
31
31
 
32
32
  UNESCAPED_SEQUENCES = {
33
33
  "\\0": "\0",
34
+ "\\e": "\x1b",
35
+ "\\N": "",
36
+ "\\/": "/",
37
+ '\\"': '"',
38
+ "\\=": "=",
39
+ "\\`": "`",
40
+ **{"\\" + chr(i): chr(i) for i in range(1, 32)},
34
41
  }
35
42
 
36
43
  CREATABLE_KIND_MAPPING = {"DATABASE": "SCHEMA"}
@@ -68,7 +75,10 @@ class ClickHouse(Dialect):
68
75
  return column_aliases
69
76
 
70
77
  class Tokenizer(tokens.Tokenizer):
78
+ NUMERIC_ESCAPES = {"x": (16, 2, 2, 0xFF)}
79
+ NUMERIC_ESCAPES_ARE_BYTES = True
71
80
  COMMENTS = ["--", "#", "#!", ("/*", "*/")]
81
+ COMMENTS_TERMINATE_AT_NEWLINE_ONLY = True
72
82
  IDENTIFIERS = ['"', "`"]
73
83
  IDENTIFIER_ESCAPES = ["\\"]
74
84
  STRING_ESCAPES = ["'", "\\"]
@@ -140,6 +140,19 @@ class NormalizationStrategy(str, AutoName):
140
140
  """Always case-insensitive (uppercase), regardless of quotes."""
141
141
 
142
142
 
143
+ class UsingColumnOrder(str, AutoName):
144
+ """Where star expansion places the columns of a `USING` or `NATURAL` join."""
145
+
146
+ USING_LIST = auto()
147
+ """First, in the order they're listed in USING (SQL standard, e.g. Postgres)."""
148
+
149
+ LEFT_TABLE = auto()
150
+ """First, in the order they appear in the left table (e.g. MySQL)."""
151
+
152
+ IN_PLACE = auto()
153
+ """Where the left table has them (e.g. DuckDB)."""
154
+
155
+
143
156
  # "Strict" dialects (e.g. modern Hive, Spark 3+) map their zero-padded MM/dd/HH/hh/mm/ss to these in
144
157
  # TIME_MAPPING so they roundtrip, since a lax %m/%d renders non-padded there for parse expressions
145
158
  # (see HiveGenerator.format_time).
@@ -343,7 +356,15 @@ class _Dialect(type):
343
356
  # The filter is necessary because of `\\a -> a` in Snowflake; we can't replace `a` with `\a`.
344
357
  v: k
345
358
  for k, v in klass.UNESCAPED_SEQUENCES.items()
346
- if not v.isprintable() or v == "\\"
359
+ # Sequences that only drop the backslash (e.g. "\\\n" -> "\n") aren't needed for generation
360
+ if v == "\\" or (not v.isprintable() and k[1:] != v)
361
+ }
362
+
363
+ identifier_escapes = klass.tokenizer_class.IDENTIFIER_ESCAPES
364
+ klass.IDENTIFIER_ESCAPED_SEQUENCES = {
365
+ v: k
366
+ for k, v in klass.UNESCAPED_SEQUENCES.items()
367
+ if k[0] in identifier_escapes and v in identifier_escapes
347
368
  }
348
369
 
349
370
  # Prefer hex, then octal, then Unicode for numeric control-character escapes.
@@ -428,11 +449,11 @@ class Dialect(metaclass=_Dialect):
428
449
  False: Disables function name normalization.
429
450
  """
430
451
 
431
- PRESERVE_ORIGINAL_NAMES: bool = False
452
+ ORIGINAL_NAME_META_KEY: str | None = None
432
453
  """
433
- Whether the name of the function should be preserved inside the node's metadata,
434
- can be useful for roundtripping deprecated vs new functions that share an AST node
435
- e.g JSON_VALUE vs JSON_EXTRACT_SCALAR in BigQuery
454
+ Dialect-specific metadata key for preserving original function names, or None to disable.
455
+ Only generators using the same key reuse these names, allowing round trips of aliases
456
+ that share an AST node, e.g. JSON_VALUE vs JSON_EXTRACT_SCALAR in BigQuery.
436
457
  """
437
458
 
438
459
  LOG_BASE_FIRST: bool | None = True
@@ -490,6 +511,9 @@ class Dialect(metaclass=_Dialect):
490
511
  BYTE_STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = False
491
512
  """Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES."""
492
513
 
514
+ IDENTIFIER_ESCAPED_SEQUENCES: dict[str, str] = {}
515
+ """Mapping of an identifier escape char (`\\`) to its escaped version (`\\\\`). Set by the metaclass based on the tokenizer's IDENTIFIER_ESCAPES."""
516
+
493
517
  INVERSE_VECTOR_TYPE_ALIASES: dict[str, str] = {}
494
518
  """Mapping of vector type aliases back to their canonical names. Overridden by dialects like SingleStore."""
495
519
 
@@ -651,6 +675,19 @@ class Dialect(metaclass=_Dialect):
651
675
  they must be explicitly selected.
652
676
  """
653
677
 
678
+ USING_COLUMN_ORDER = UsingColumnOrder.USING_LIST
679
+ """
680
+ Where star expansion places the columns of a `USING` or `NATURAL` join.
681
+
682
+ Given `a(a_id, k1, k2)` and `b(k2, b_id, k1)`, `SELECT * FROM a JOIN b USING (k2, k1)` returns:
683
+ - `USING_LIST`: `k2, k1, a_id, b_id`
684
+ - `LEFT_TABLE`: `k1, k2, a_id, b_id`
685
+ - `IN_PLACE`: `a_id, k1, k2, b_id`
686
+
687
+ When join columns come first, this applies at every join: each USING join moves its columns
688
+ ahead of all the columns to its left.
689
+ """
690
+
654
691
  QUERY_RESULTS_ARE_STRUCTS = False
655
692
  """
656
693
  Whether query results are typed as structs in metadata for type inference.
@@ -774,6 +811,9 @@ class Dialect(metaclass=_Dialect):
774
811
  # Whether ADD is present for each column added by ALTER TABLE
775
812
  ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN = True
776
813
 
814
+ # Whether DROP is present for each column dropped by ALTER TABLE
815
+ ALTER_TABLE_DROP_REQUIRED_FOR_EACH_COLUMN = True
816
+
777
817
  # Whether the value/LHS of the TRY_CAST(<value> AS <type>) should strictly be a
778
818
  # STRING type (Snowflake's case) or can be of any type
779
819
  TRY_CAST_REQUIRES_STRING: bool | None = None
@@ -1305,7 +1345,13 @@ def inline_array_sql(self: Generator, expression: exp.Expr) -> str:
1305
1345
 
1306
1346
  def inline_array_unless_query(self: Generator, expression: exp.Expr) -> str:
1307
1347
  elem = seq_get(expression.expressions, 0)
1308
- if isinstance(elem, exp.Expr) and elem.find(exp.Query):
1348
+ if (
1349
+ len(expression.expressions) == 1
1350
+ and isinstance(elem, exp.Query)
1351
+ # value_constructor=True keeps scalar subqueries as array elements. In [(SELECT …)], the
1352
+ # subquery supplies one scalar value; in ARRAY(SELECT …) (BigQuery), the query supplies rows.
1353
+ and not expression.args.get("value_constructor")
1354
+ ):
1309
1355
  return self.func("ARRAY", elem)
1310
1356
  return inline_array_sql(self, expression)
1311
1357
 
@@ -1358,6 +1404,71 @@ def no_map_from_entries_sql(self: Generator, expression: exp.MapFromEntries) ->
1358
1404
  return ""
1359
1405
 
1360
1406
 
1407
+ def no_filter_sql(self: Generator, expression: exp.Filter) -> str:
1408
+ # Rewrite `AGG(x) FILTER (WHERE cond)` into an equivalent conditional aggregation, i.e. wrap
1409
+ # the input values in an IF, which works because aggregate functions skip NULLs
1410
+ agg = expression.this
1411
+ # IGNORE NULLS can wrap the aggregate, but the condition still belongs to its arguments
1412
+ if isinstance(agg, exp.IgnoreNulls):
1413
+ agg = agg.this
1414
+
1415
+ agg_arg = seq_get(agg.expressions, 0) if isinstance(agg, exp.Anonymous) else agg.this
1416
+ cond = expression.expression.this
1417
+
1418
+ if isinstance(agg, exp.WithinGroup):
1419
+ # Ordered-set aggregates take their input from the ORDER BY key, so the
1420
+ # condition has to wrap that instead of the aggregate's own argument
1421
+ if isinstance(agg_arg, (exp.Mode, *exp.PERCENTILES)):
1422
+ for ordered in agg.expression.expressions:
1423
+ key = ordered.this
1424
+ key.replace(exp.If(this=cond.copy(), true=key.copy(), false=exp.null()))
1425
+
1426
+ return self.sql(expression.this)
1427
+
1428
+ # Besides the ordered-set aggregates, these are the only functions that take WITHIN GROUP
1429
+ # and the input values as arguments, so anything else can't be rewritten correctly
1430
+ if isinstance(agg_arg, (exp.ArrayAgg, exp.GroupConcat)):
1431
+ agg_arg = agg_arg.this
1432
+ else:
1433
+ self.unsupported("Unable to rewrite FILTER into the aggregate's arguments")
1434
+ return self.sql(expression.this)
1435
+
1436
+ # Folding the condition into COUNT_IF's predicate avoids an IF that returns a predicate, which
1437
+ # dialects without a boolean type (e.g. T-SQL) reject
1438
+ if isinstance(agg, exp.CountIf) and not isinstance(agg_arg, exp.Distinct):
1439
+ return self.sql(exp.CountIf(this=exp.and_(cond, agg_arg)))
1440
+
1441
+ # `COUNT(*/t.*) FILTER (WHERE cond)` counts qualifying rows, but a star can't be an IF
1442
+ # argument: `IF(cond, *, NULL)` expands to multiple columns once the table has 2+ of
1443
+ # them. Each dialect generates CountIf in its own way instead, e.g. COUNT_IF or COUNTIF.
1444
+ if isinstance(agg, exp.Count) and (agg_arg is None or agg_arg.is_star):
1445
+ return self.sql(exp.CountIf(this=cond))
1446
+
1447
+ # `DISTINCT` and `ORDER BY` are part of the aggregate's own argument list, so the
1448
+ # condition has to wrap the values underneath them rather than the whole clause --
1449
+ # `IF(cond, DISTINCT x, NULL)` is not a call any dialect accepts.
1450
+ if isinstance(agg_arg, exp.Order):
1451
+ agg_arg = agg_arg.this
1452
+
1453
+ if isinstance(agg_arg, exp.Distinct):
1454
+ targets = agg_arg.expressions
1455
+ else:
1456
+ targets = [agg_arg]
1457
+
1458
+ for target in targets:
1459
+ target.replace(exp.If(this=cond.copy(), true=target.copy(), false=exp.null()))
1460
+
1461
+ # In dialects where ARRAY_AGG keeps NULLs (e.g. BigQuery, which even fails on them), the
1462
+ # rows that don't satisfy the condition have to be dropped explicitly
1463
+ if isinstance(agg, exp.ArrayAgg) and self.dialect.ARRAY_AGG_INCLUDES_NULLS:
1464
+ # IGNORE NULLS already drops them, so no extra FILTER (WHERE x IS NOT NULL) is needed
1465
+ agg.set("nulls_excluded", None)
1466
+ if agg is expression.this:
1467
+ return self.sql(exp.IgnoreNulls(this=agg))
1468
+
1469
+ return self.sql(expression.this)
1470
+
1471
+
1361
1472
  def property_sql(self: Generator, expression: exp.Property) -> str:
1362
1473
  return f"{self.property_name(expression, string_key=True)}={self.sql(expression, 'value')}"
1363
1474
 
@@ -1648,11 +1759,7 @@ def build_formatted_time(
1648
1759
  """
1649
1760
 
1650
1761
  def _builder(args: BuilderArgs, dialect: Dialect) -> E:
1651
- target_dialect = (
1652
- t.cast(Dialect, Dialect[dialect_override])
1653
- if isinstance(dialect_override, str)
1654
- else dialect
1655
- )
1762
+ target_dialect = Dialect[dialect_override] if isinstance(dialect_override, str) else dialect
1656
1763
 
1657
1764
  fmt = seq_get(args, 1)
1658
1765
  if not fmt:
@@ -10,6 +10,10 @@ class Doris(MySQL):
10
10
  DATEINT_FORMAT = "'yyyyMMdd'"
11
11
  TIME_FORMAT = "'yyyy-MM-dd HH:mm:ss'"
12
12
 
13
+ class Tokenizer(MySQL.Tokenizer):
14
+ DASH_COMMENT_REQUIRES_BOUNDARY = False
15
+ COMMENTS_TERMINATE_AT_NEWLINE_ONLY = False
16
+
13
17
  Parser = DorisParser
14
18
 
15
19
  Generator = DorisGenerator
@@ -9,7 +9,7 @@ from sqlglot.parsers.drill import DrillParser
9
9
 
10
10
  class Drill(Dialect):
11
11
  NORMALIZE_FUNCTIONS: bool | str = False
12
- PRESERVE_ORIGINAL_NAMES = True
12
+ ORIGINAL_NAME_META_KEY = "drill_name"
13
13
  NULL_ORDERING = "nulls_are_last"
14
14
  DATE_FORMAT = "'yyyy-MM-dd'"
15
15
  DATEINT_FORMAT = "'yyyyMMdd'"
@@ -53,7 +53,7 @@ class Drill(Dialect):
53
53
 
54
54
  class Tokenizer(tokens.Tokenizer):
55
55
  IDENTIFIERS = ["`"]
56
- STRING_ESCAPES = ["\\"]
56
+ STRING_ESCAPES = ["'"]
57
57
 
58
58
  KEYWORDS = tokens.Tokenizer.KEYWORDS.copy()
59
59
  KEYWORDS.pop("/*+")
@@ -6,6 +6,7 @@ from sqlglot import exp, tokens
6
6
  from sqlglot.dialects.dialect import (
7
7
  Dialect,
8
8
  NormalizationStrategy,
9
+ UsingColumnOrder,
9
10
  )
10
11
  from sqlglot.generators.duckdb import DuckDBGenerator, WS_CONTROL_CHARS_TO_DUCK # noqa: F401
11
12
  from sqlglot.parsers.duckdb import DuckDBParser
@@ -22,9 +23,11 @@ class DuckDB(Dialect):
22
23
  SUPPORTS_ORDER_BY_ALL = True
23
24
  SUPPORTS_LIMIT_ALL = True
24
25
  SUPPORTS_FIXED_SIZE_ARRAYS = True
26
+ TABLES_REFERENCEABLE_AS_COLUMNS = True
25
27
  STRICT_JSON_PATH_SYNTAX = False
26
28
  NUMBERS_CAN_BE_UNDERSCORE_SEPARATED = True
27
29
  UUID_IS_STRING_TYPE = False
30
+ USING_COLUMN_ORDER = UsingColumnOrder.IN_PLACE
28
31
 
29
32
  # https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
30
33
  NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
@@ -66,7 +69,12 @@ class DuckDB(Dialect):
66
69
 
67
70
  return super().to_json_path(path)
68
71
 
72
+ UNESCAPED_SEQUENCES = {"\\a": "a", "\\v": "v"}
73
+
69
74
  class Tokenizer(tokens.Tokenizer):
75
+ NUMERIC_ESCAPES = {"x": (16, 1, 2, 0xFF), "0": (8, 1, 3, 0o777)}
76
+ NUMERIC_ESCAPES_ARE_BYTES = True
77
+ DROP_UNKNOWN_ESCAPES = True
70
78
  BYTE_STRINGS = [("e'", "'"), ("E'", "'")]
71
79
  BYTE_STRING_ESCAPES = ["'", "\\"]
72
80
  HEREDOC_STRINGS = ["$"]
@@ -88,7 +88,20 @@ class Hive(Dialect):
88
88
  TokenType.DASH,
89
89
  }
90
90
 
91
+ UNESCAPED_SEQUENCES = {
92
+ "\\0": "\0",
93
+ "\\Z": "\x1a",
94
+ "\\%": "\\%",
95
+ "\\_": "\\_",
96
+ "\\a": "a",
97
+ "\\f": "f",
98
+ "\\v": "v",
99
+ }
100
+
91
101
  class Tokenizer(tokens.Tokenizer):
102
+ NUMERIC_ESCAPES = {"u": (16, 4, 4, 0xFFFF), "0": (8, 3, 3, 0x7F)}
103
+ DROP_UNKNOWN_ESCAPES = True
104
+ LONE_SURROGATE_REPLACEMENT = "?"
92
105
  QUOTES = ["'", '"']
93
106
  IDENTIFIERS = ["`"]
94
107
  STRING_ESCAPES = ["\\"]
@@ -8,6 +8,11 @@ from sqlglot.parsers.materialize import MaterializeParser
8
8
  class Materialize(Postgres):
9
9
  NORMALIZE_NOT_NULL = True
10
10
 
11
+ UNESCAPED_SEQUENCES = {"\\a": "a", "\\v": "v"}
12
+
13
+ class Tokenizer(Postgres.Tokenizer):
14
+ NUMERIC_ESCAPES = {"u": (16, 4, 4, 0xFFFF), "U": (16, 8, 8, 0x10FFFF)}
15
+
11
16
  Parser = MaterializeParser
12
17
 
13
18
  Generator = MaterializeGenerator