sqlglot 30.20.0__tar.gz → 30.21.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.20.0 → sqlglot-30.21.0}/CHANGELOG.md +69 -0
  2. {sqlglot-30.20.0/sqlglot.egg-info → sqlglot-30.21.0}/PKG-INFO +3 -3
  3. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/_version.py +3 -3
  4. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/athena.py +2 -2
  5. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/dialect.py +18 -0
  6. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/snowflake.py +2 -0
  7. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/query.py +13 -0
  8. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generator.py +36 -1
  9. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/athena.py +1 -1
  10. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/clickhouse.py +1 -0
  11. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/singlestore.py +6 -1
  12. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/spark.py +3 -3
  13. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/spark2.py +10 -0
  14. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/canonicalize_internal_names.py +6 -4
  15. sqlglot-30.21.0/sqlglot/optimizer/pushdown_projections.py +600 -0
  16. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/qualify_columns.py +39 -18
  17. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/resolver.py +16 -12
  18. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/simplify.py +1 -1
  19. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parser.py +8 -4
  20. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/athena.py +5 -2
  21. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/hive.py +37 -1
  22. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/spark.py +2 -0
  23. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/spark2.py +2 -0
  24. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/tokenizer_core.py +110 -4
  25. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/tokens.py +14 -0
  26. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/transforms.py +6 -1
  27. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/duckdb.py +1 -0
  28. {sqlglot-30.20.0 → sqlglot-30.21.0/sqlglot.egg-info}/PKG-INFO +3 -3
  29. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.egg-info/requires.txt +2 -2
  30. sqlglot-30.21.0/sqlglot.egg-info/scm_version.json +8 -0
  31. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_athena.py +33 -0
  32. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_clickhouse.py +9 -0
  33. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_dialect.py +54 -0
  34. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_hive.py +4 -4
  35. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_mysql.py +10 -0
  36. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_postgres.py +15 -0
  37. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_singlestore.py +0 -1
  38. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_spark.py +22 -0
  39. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/annotate_functions.sql +22 -2
  40. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/canonicalize_internal_names.sql +7 -0
  41. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/optimizer.sql +77 -52
  42. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/pushdown_projections.sql +16 -2
  43. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/qualify_columns.sql +39 -0
  44. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +4 -0
  45. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +2 -0
  46. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/simplify.sql +42 -0
  47. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_anonymize.py +7 -0
  48. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_optimizer.py +113 -15
  49. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_transforms.py +24 -5
  50. sqlglot-30.20.0/sqlglot/optimizer/pushdown_projections.py +0 -394
  51. sqlglot-30.20.0/sqlglot.egg-info/scm_version.json +0 -8
  52. {sqlglot-30.20.0 → sqlglot-30.21.0}/.gitignore +0 -0
  53. {sqlglot-30.20.0 → sqlglot-30.21.0}/.gitmodules +0 -0
  54. {sqlglot-30.20.0 → sqlglot-30.21.0}/.gitpod.yml +0 -0
  55. {sqlglot-30.20.0 → sqlglot-30.21.0}/.pre-commit-config.yaml +0 -0
  56. {sqlglot-30.20.0 → sqlglot-30.21.0}/AGENTS.md +0 -0
  57. {sqlglot-30.20.0 → sqlglot-30.21.0}/CLAUDE.md +0 -0
  58. {sqlglot-30.20.0 → sqlglot-30.21.0}/CONTRIBUTING.md +0 -0
  59. {sqlglot-30.20.0 → sqlglot-30.21.0}/LICENSE +0 -0
  60. {sqlglot-30.20.0 → sqlglot-30.21.0}/MANIFEST.in +0 -0
  61. {sqlglot-30.20.0 → sqlglot-30.21.0}/Makefile +0 -0
  62. {sqlglot-30.20.0 → sqlglot-30.21.0}/README.md +0 -0
  63. {sqlglot-30.20.0 → sqlglot-30.21.0}/pyproject.toml +0 -0
  64. {sqlglot-30.20.0 → sqlglot-30.21.0}/setup.cfg +0 -0
  65. {sqlglot-30.20.0 → sqlglot-30.21.0}/setup.py +0 -0
  66. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/__init__.py +0 -0
  67. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/__main__.py +0 -0
  68. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/_typing.py +0 -0
  69. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/anonymize.py +0 -0
  70. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/__init__.py +0 -0
  71. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/bigquery.py +0 -0
  72. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/clickhouse.py +0 -0
  73. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/databricks.py +0 -0
  74. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/dax.py +0 -0
  75. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/doris.py +0 -0
  76. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/dremio.py +0 -0
  77. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/drill.py +0 -0
  78. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/druid.py +0 -0
  79. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/duckdb.py +0 -0
  80. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/dune.py +0 -0
  81. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/exasol.py +0 -0
  82. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/fabric.py +0 -0
  83. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/hive.py +0 -0
  84. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/materialize.py +0 -0
  85. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/mysql.py +0 -0
  86. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/oracle.py +0 -0
  87. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/postgres.py +0 -0
  88. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/presto.py +0 -0
  89. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/prql.py +0 -0
  90. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/redshift.py +0 -0
  91. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/risingwave.py +0 -0
  92. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/singlestore.py +0 -0
  93. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/solr.py +0 -0
  94. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/spark.py +0 -0
  95. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/spark2.py +0 -0
  96. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/sqlite.py +0 -0
  97. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/starrocks.py +0 -0
  98. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/tableau.py +0 -0
  99. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/teradata.py +0 -0
  100. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/trino.py +0 -0
  101. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/dialects/tsql.py +0 -0
  102. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/diff.py +0 -0
  103. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/errors.py +0 -0
  104. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/executor/__init__.py +0 -0
  105. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/executor/context.py +0 -0
  106. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/executor/env.py +0 -0
  107. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/executor/python.py +0 -0
  108. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/executor/table.py +0 -0
  109. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/__init__.py +0 -0
  110. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/aggregate.py +0 -0
  111. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/array.py +0 -0
  112. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/builders.py +0 -0
  113. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/constraints.py +0 -0
  114. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/core.py +0 -0
  115. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/datatypes.py +0 -0
  116. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/ddl.py +0 -0
  117. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/dml.py +0 -0
  118. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/functions.py +0 -0
  119. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/json.py +0 -0
  120. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/math.py +0 -0
  121. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/properties.py +0 -0
  122. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/string.py +0 -0
  123. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/expressions/temporal.py +0 -0
  124. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/__init__.py +0 -0
  125. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/bigquery.py +0 -0
  126. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/databricks.py +0 -0
  127. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/dax.py +0 -0
  128. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/doris.py +0 -0
  129. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/dremio.py +0 -0
  130. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/drill.py +0 -0
  131. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/druid.py +0 -0
  132. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/duckdb.py +0 -0
  133. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/dune.py +0 -0
  134. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/exasol.py +0 -0
  135. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/fabric.py +0 -0
  136. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/hive.py +0 -0
  137. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/materialize.py +0 -0
  138. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/mysql.py +0 -0
  139. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/oracle.py +0 -0
  140. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/postgres.py +0 -0
  141. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/presto.py +0 -0
  142. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/prql.py +0 -0
  143. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/python.py +0 -0
  144. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/redshift.py +0 -0
  145. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/risingwave.py +0 -0
  146. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/snowflake.py +0 -0
  147. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/solr.py +0 -0
  148. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/sqlite.py +0 -0
  149. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/starrocks.py +0 -0
  150. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/tableau.py +0 -0
  151. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/teradata.py +0 -0
  152. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/trino.py +0 -0
  153. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/generators/tsql.py +0 -0
  154. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/helper.py +0 -0
  155. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/jsonpath.py +0 -0
  156. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/lineage.py +0 -0
  157. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/__init__.py +0 -0
  158. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/annotate_types.py +0 -0
  159. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/canonicalize.py +0 -0
  160. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  161. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
  162. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  163. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/helpers.py +0 -0
  164. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  165. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/journal.py +0 -0
  166. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
  167. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/normalize.py +0 -0
  168. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  169. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/optimize_joins.py +0 -0
  170. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/optimizer.py +0 -0
  171. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
  172. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/qualify.py +0 -0
  173. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/qualify_tables.py +0 -0
  174. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/scope.py +0 -0
  175. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  176. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/__init__.py +0 -0
  177. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/base.py +0 -0
  178. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/bigquery.py +0 -0
  179. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/clickhouse.py +0 -0
  180. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/databricks.py +0 -0
  181. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/dax.py +0 -0
  182. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/doris.py +0 -0
  183. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/dremio.py +0 -0
  184. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/drill.py +0 -0
  185. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/druid.py +0 -0
  186. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/duckdb.py +0 -0
  187. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/dune.py +0 -0
  188. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/exasol.py +0 -0
  189. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/fabric.py +0 -0
  190. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/materialize.py +0 -0
  191. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/mysql.py +0 -0
  192. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/oracle.py +0 -0
  193. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/postgres.py +0 -0
  194. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/presto.py +0 -0
  195. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/prql.py +0 -0
  196. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/redshift.py +0 -0
  197. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/risingwave.py +0 -0
  198. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/singlestore.py +0 -0
  199. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/snowflake.py +0 -0
  200. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/solr.py +0 -0
  201. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/sqlite.py +0 -0
  202. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/starrocks.py +0 -0
  203. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/tableau.py +0 -0
  204. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/teradata.py +0 -0
  205. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/trino.py +0 -0
  206. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/parsers/tsql.py +0 -0
  207. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/planner.py +0 -0
  208. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/py.typed +0 -0
  209. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/schema.py +0 -0
  210. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/serde.py +0 -0
  211. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/time.py +0 -0
  212. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/trie.py +0 -0
  213. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/__init__.py +0 -0
  214. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/bigquery.py +0 -0
  215. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/clickhouse.py +0 -0
  216. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/databricks.py +0 -0
  217. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/hive.py +0 -0
  218. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/mysql.py +0 -0
  219. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/postgres.py +0 -0
  220. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/presto.py +0 -0
  221. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/redshift.py +0 -0
  222. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/snowflake.py +0 -0
  223. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/spark.py +0 -0
  224. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/spark2.py +0 -0
  225. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot/typing/tsql.py +0 -0
  226. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.egg-info/SOURCES.txt +0 -0
  227. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.egg-info/dependency_links.txt +0 -0
  228. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.egg-info/scm_file_list.json +0 -0
  229. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.egg-info/top_level.txt +0 -0
  230. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglot.png +0 -0
  231. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglotc/MANIFEST.in +0 -0
  232. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglotc/pyproject.toml +0 -0
  233. {sqlglot-30.20.0 → sqlglot-30.21.0}/sqlglotc/setup.py +0 -0
  234. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/__init__.py +0 -0
  235. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/__init__.py +0 -0
  236. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_bigquery.py +0 -0
  237. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_databricks.py +0 -0
  238. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_dax.py +0 -0
  239. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_doris.py +0 -0
  240. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_dremio.py +0 -0
  241. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_drill.py +0 -0
  242. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_druid.py +0 -0
  243. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_duckdb.py +0 -0
  244. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_dune.py +0 -0
  245. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_exasol.py +0 -0
  246. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_fabric.py +0 -0
  247. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_materialize.py +0 -0
  248. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_oracle.py +0 -0
  249. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_pipe_syntax.py +0 -0
  250. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_presto.py +0 -0
  251. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_prql.py +0 -0
  252. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_redshift.py +0 -0
  253. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_risingwave.py +0 -0
  254. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_snowflake.py +0 -0
  255. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_solr.py +0 -0
  256. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_sqlite.py +0 -0
  257. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_starrocks.py +0 -0
  258. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_tableau.py +0 -0
  259. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_teradata.py +0 -0
  260. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_trino.py +0 -0
  261. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/dialects/test_tsql.py +0 -0
  262. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/identity.sql +0 -0
  263. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/jsonpath/LICENSE +0 -0
  264. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/jsonpath/cts.json +0 -0
  265. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
  266. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  267. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  268. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  269. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  270. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  271. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  272. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/normalize.sql +0 -0
  273. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  274. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  275. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  276. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  277. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  278. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
  279. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  280. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  281. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  282. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  283. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  284. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  285. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  286. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  287. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  288. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  289. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  290. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  291. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  292. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  293. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  294. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  295. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  296. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  297. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  298. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  299. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  300. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  301. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  302. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  303. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  304. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  305. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  306. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  307. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  308. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  309. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  310. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  311. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  312. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  313. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  314. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  315. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/partial.sql +0 -0
  316. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/fixtures/pretty.sql +0 -0
  317. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/gen_fixtures.py +0 -0
  318. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/helpers.py +0 -0
  319. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/leakcheck.py +0 -0
  320. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/sqlglot/__init__.py +0 -0
  321. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_build.py +0 -0
  322. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_dialect_entry_points.py +0 -0
  323. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_dialect_imports.py +0 -0
  324. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_diff.py +0 -0
  325. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_docs.py +0 -0
  326. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_errors.py +0 -0
  327. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_executor.py +0 -0
  328. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_expressions.py +0 -0
  329. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_generator.py +0 -0
  330. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_helper.py +0 -0
  331. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_integration_loader.py +0 -0
  332. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_jsonpath.py +0 -0
  333. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_lineage.py +0 -0
  334. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_parser.py +0 -0
  335. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_schema.py +0 -0
  336. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_serde.py +0 -0
  337. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_time.py +0 -0
  338. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_tokens.py +0 -0
  339. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_transpile.py +0 -0
  340. {sqlglot-30.20.0 → sqlglot-30.21.0}/tests/test_typing.py +0 -0
@@ -1,6 +1,74 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v30.20.0] - 2026-09-27
5
+ ### :boom: BREAKING CHANGES
6
+ - 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))*:
7
+
8
+ Fix mysql roundtrip for DATE_ADD and DATE_SUB (#8417)
9
+
10
+ - due to [`284ea43`](https://github.com/tobymao/sqlglot/commit/284ea43fe773762a1aa1556171bbb4c03a197788) - support IGNORE NULLS and RESPECT NULLS in window functions [CLAUDE] *(PR [#8412](https://github.com/tobymao/sqlglot/pull/8412) by [@UCHPUCHMAK](https://github.com/UCHPUCHMAK))*:
11
+
12
+ support IGNORE NULLS and RESPECT NULLS in window functions [CLAUDE] (#8412)
13
+
14
+ - due to [`abacf31`](https://github.com/tobymao/sqlglot/commit/abacf31d7b12b3bd70cd4a70b25cfcd2ad6c1f0a) - use row-preserving default projection for windowed aggregates *(PR [#8381](https://github.com/tobymao/sqlglot/pull/8381) by [@treysp](https://github.com/treysp))*:
15
+
16
+ use row-preserving default projection for windowed aggregates (#8381)
17
+
18
+ - due to [`a388416`](https://github.com/tobymao/sqlglot/commit/a3884168f639633fa8f64334bf63e4b343bedfe2) - retain json <string> literals closes [#8413](https://github.com/tobymao/sqlglot/pull/8413) *(commit by [@georgesittas](https://github.com/georgesittas))*:
19
+
20
+ retain json <string> literals closes #8413
21
+
22
+ - due to [`20fa8ae`](https://github.com/tobymao/sqlglot/commit/20fa8aedc48fccb780b973987908db63d0f76895) - keep `TRY_TO_NUMBER` safe when it falls back to a cast [CLAUDE] *(PR [#8424](https://github.com/tobymao/sqlglot/pull/8424) by [@anishmehta24](https://github.com/anishmehta24))*:
23
+
24
+ keep `TRY_TO_NUMBER` safe when it falls back to a cast [CLAUDE] (#8424)
25
+
26
+ - due to [`b85a8c8`](https://github.com/tobymao/sqlglot/commit/b85a8c8b0d107410f6689c2ddad0921dbff9ddad) - exponential AST growth prevention in merge_subqueries *(PR [#8427](https://github.com/tobymao/sqlglot/pull/8427) by [@georgesittas](https://github.com/georgesittas))*:
27
+
28
+ exponential AST growth prevention in merge_subqueries (#8427)
29
+
30
+ - due to [`4c11d07`](https://github.com/tobymao/sqlglot/commit/4c11d07af4b533274cabbcae9271234e9a0b039c) - avoid AUTOINCREMENT without a primary key *(PR [#8431](https://github.com/tobymao/sqlglot/pull/8431) by [@georgesittas](https://github.com/georgesittas))*:
31
+
32
+ avoid AUTOINCREMENT without a primary key (#8431)
33
+
34
+ - due to [`d2fbb21`](https://github.com/tobymao/sqlglot/commit/d2fbb215ff6bd548547a151e8838c277aad076c1) - preserve TIMESTAMP_FROM_PARTS time zones ([#8422](https://github.com/tobymao/sqlglot/pull/8422)) *(PR [#8434](https://github.com/tobymao/sqlglot/pull/8434) by [@georgesittas](https://github.com/georgesittas))*:
35
+
36
+ preserve TIMESTAMP_FROM_PARTS time zones (#8422) (#8434)
37
+
38
+ - due to [`afd6b69`](https://github.com/tobymao/sqlglot/commit/afd6b6946267b0b1100f48b299f3d44ff9a13767) - annotate `bit_or` for duckdb *(PR [#8438](https://github.com/tobymao/sqlglot/pull/8438) by [@deepika-kakde](https://github.com/deepika-kakde))*:
39
+
40
+ annotate `bit_or` for duckdb (#8438)
41
+
42
+ - due to [`8bd7686`](https://github.com/tobymao/sqlglot/commit/8bd768664197fbd0ed86158c0eca955c14f43328) - annotate `bit_and` for duckdb *(PR [#8439](https://github.com/tobymao/sqlglot/pull/8439) by [@Anuja006](https://github.com/Anuja006))*:
43
+
44
+ annotate `bit_and` for duckdb (#8439)
45
+
46
+
47
+ ### :sparkles: New Features
48
+ - [`a313c8b`](https://github.com/tobymao/sqlglot/commit/a313c8bee143b4b92c9a068fef72a5fd512bba61) - **parser**: support boolean expressions in update assignments closes [#8428](https://github.com/tobymao/sqlglot/pull/8428) *(commit by [@georgesittas](https://github.com/georgesittas))*
49
+ - [`afd6b69`](https://github.com/tobymao/sqlglot/commit/afd6b6946267b0b1100f48b299f3d44ff9a13767) - **optimizer**: annotate `bit_or` for duckdb *(PR [#8438](https://github.com/tobymao/sqlglot/pull/8438) by [@deepika-kakde](https://github.com/deepika-kakde))*
50
+ - [`8bd7686`](https://github.com/tobymao/sqlglot/commit/8bd768664197fbd0ed86158c0eca955c14f43328) - **optimizer**: annotate `bit_and` for duckdb *(PR [#8439](https://github.com/tobymao/sqlglot/pull/8439) by [@Anuja006](https://github.com/Anuja006))*
51
+
52
+ ### :bug: Bug Fixes
53
+ - [`1d0e3f3`](https://github.com/tobymao/sqlglot/commit/1d0e3f34864037c54cf6bdf45af594db62ad7319) - **mysql**: 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))*
54
+ - :arrow_lower_right: *fixes issue [#8392](https://github.com/tobymao/sqlglot/issues/8392) opened by [@linchangyang-sg](https://github.com/linchangyang-sg)*
55
+ - [`284ea43`](https://github.com/tobymao/sqlglot/commit/284ea43fe773762a1aa1556171bbb4c03a197788) - **starrocks**: support IGNORE NULLS and RESPECT NULLS in window functions [CLAUDE] *(PR [#8412](https://github.com/tobymao/sqlglot/pull/8412) by [@UCHPUCHMAK](https://github.com/UCHPUCHMAK))*
56
+ - [`abacf31`](https://github.com/tobymao/sqlglot/commit/abacf31d7b12b3bd70cd4a70b25cfcd2ad6c1f0a) - **optimizer**: use row-preserving default projection for windowed aggregates *(PR [#8381](https://github.com/tobymao/sqlglot/pull/8381) by [@treysp](https://github.com/treysp))*
57
+ - [`a388416`](https://github.com/tobymao/sqlglot/commit/a3884168f639633fa8f64334bf63e4b343bedfe2) - retain json <string> literals closes [#8413](https://github.com/tobymao/sqlglot/pull/8413) *(commit by [@georgesittas](https://github.com/georgesittas))*
58
+ - [`32a9297`](https://github.com/tobymao/sqlglot/commit/32a9297a24f06035293a2a3e935a7b65ece25755) - **optimizer**: avoid accumulating parentheses when merging repeated references *(PR [#8425](https://github.com/tobymao/sqlglot/pull/8425) by [@georgesittas](https://github.com/georgesittas))*
59
+ - [`20fa8ae`](https://github.com/tobymao/sqlglot/commit/20fa8aedc48fccb780b973987908db63d0f76895) - keep `TRY_TO_NUMBER` safe when it falls back to a cast [CLAUDE] *(PR [#8424](https://github.com/tobymao/sqlglot/pull/8424) by [@anishmehta24](https://github.com/anishmehta24))*
60
+ - [`b85a8c8`](https://github.com/tobymao/sqlglot/commit/b85a8c8b0d107410f6689c2ddad0921dbff9ddad) - **optimizer**: exponential AST growth prevention in merge_subqueries *(PR [#8427](https://github.com/tobymao/sqlglot/pull/8427) by [@georgesittas](https://github.com/georgesittas))*
61
+ - [`8d9f5d0`](https://github.com/tobymao/sqlglot/commit/8d9f5d08cce4b72b4df1a8f6394c2aa043cc7de8) - **parser**: handle singular ROW in FETCH and OFFSET clauses closes [#8429](https://github.com/tobymao/sqlglot/pull/8429) *(commit by [@georgesittas](https://github.com/georgesittas))*
62
+ - [`981e492`](https://github.com/tobymao/sqlglot/commit/981e492413740f7740d2b0288e3da5b4028c767e) - **clickhouse**: preserve GLOBAL JOIN after ON conditions fixes [#8426](https://github.com/tobymao/sqlglot/pull/8426) *(commit by [@georgesittas](https://github.com/georgesittas))*
63
+ - [`4c11d07`](https://github.com/tobymao/sqlglot/commit/4c11d07af4b533274cabbcae9271234e9a0b039c) - **sqlite**: avoid AUTOINCREMENT without a primary key *(PR [#8431](https://github.com/tobymao/sqlglot/pull/8431) by [@georgesittas](https://github.com/georgesittas))*
64
+ - :arrow_lower_right: *fixes issue [#8423](https://github.com/tobymao/sqlglot/issues/8423) opened by [@Rodrigo-Palma](https://github.com/Rodrigo-Palma)*
65
+ - [`87b1402`](https://github.com/tobymao/sqlglot/commit/87b14027372c3820cbf6c89bc8adc2cbf8963404) - **optimizer**: preserve grouping when complementing comparisons *(PR [#8433](https://github.com/tobymao/sqlglot/pull/8433) by [@georgesittas](https://github.com/georgesittas))*
66
+ - :arrow_lower_right: *fixes issue [#8421](https://github.com/tobymao/sqlglot/issues/8421) opened by [@Rodrigo-Palma](https://github.com/Rodrigo-Palma)*
67
+ - [`d2fbb21`](https://github.com/tobymao/sqlglot/commit/d2fbb215ff6bd548547a151e8838c277aad076c1) - **duckdb**: preserve TIMESTAMP_FROM_PARTS time zones ([#8422](https://github.com/tobymao/sqlglot/pull/8422)) *(PR [#8434](https://github.com/tobymao/sqlglot/pull/8434) by [@georgesittas](https://github.com/georgesittas))*
68
+ - :arrow_lower_right: *fixes issue [#8422](https://github.com/tobymao/sqlglot/issues/8422) opened by [@Rodrigo-Palma](https://github.com/Rodrigo-Palma)*
69
+ - [`d01e946`](https://github.com/tobymao/sqlglot/commit/d01e9461a7a3fcbe50a965c7a2ddf55d41aca97d) - **optimizer**: preserve ordinal ordering with duplicate aliases [CODEX] *(PR [#8436](https://github.com/tobymao/sqlglot/pull/8436) by [@tobymao](https://github.com/tobymao))*
70
+
71
+
4
72
  ## [v30.19.0] - 2026-09-22
5
73
  ### :boom: BREAKING CHANGES
6
74
  - due to [`bbb717e`](https://github.com/tobymao/sqlglot/commit/bbb717ebb24c8dcbee94d77c9154e74da1dc6c10) - rename union scope type to set operation for consistency *(PR [#8306](https://github.com/tobymao/sqlglot/pull/8306) by [@georgesittas](https://github.com/georgesittas))*:
@@ -15921,3 +15989,4 @@ pip install "sqlglot[c]" # compiled — faster, but no subclassing
15921
15989
  [v30.17.0]: https://github.com/tobymao/sqlglot/compare/v30.16.0...v30.17.0
15922
15990
  [v30.18.0]: https://github.com/tobymao/sqlglot/compare/v30.17.0...v30.18.0
15923
15991
  [v30.19.0]: https://github.com/tobymao/sqlglot/compare/v30.18.0...v30.19.0
15992
+ [v30.20.0]: https://github.com/tobymao/sqlglot/compare/v30.19.0...v30.20.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 30.20.0
3
+ Version: 30.21.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
@@ -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.20.0; python_version >= "3.10" and extra == "c"
37
+ Requires-Dist: sqlglotc==30.21.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.20.0; python_version >= "3.10" and extra == "rs"
40
+ Requires-Dist: sqlglotc==30.21.0; python_version >= "3.10" and extra == "rs"
41
41
  Dynamic: license-file
42
42
  Dynamic: provides-extra
43
43
 
@@ -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.20.0'
22
- __version_tuple__ = version_tuple = (30, 20, 0)
21
+ __version__ = version = '30.21.0'
22
+ __version_tuple__ = version_tuple = (30, 21, 0)
23
23
 
24
- __commit_id__ = commit_id = 'g8bd768664'
24
+ __commit_id__ = commit_id = 'g5d16fa83b'
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
 
4
4
  from sqlglot import tokens
5
- from sqlglot.dialects.dialect import Dialect, DialectType
5
+ from sqlglot.dialects.dialect import DialectType
6
6
  from sqlglot.generators.athena import AthenaGenerator
7
7
  from sqlglot.parsers.athena import AthenaParser
8
8
  from sqlglot.tokens import TokenType, Token
@@ -10,7 +10,7 @@ from sqlglot.dialects.trino import Trino
10
10
  from sqlglot.dialects.hive import Hive
11
11
 
12
12
 
13
- class Athena(Dialect):
13
+ class Athena(Trino):
14
14
  """
15
15
  Over the years, it looks like AWS has taken various execution engines, bolted on AWS-specific
16
16
  modifications and then built the Athena service around them.
@@ -346,6 +346,24 @@ class _Dialect(type):
346
346
  if not v.isprintable() or v == "\\"
347
347
  }
348
348
 
349
+ # Prefer hex, then octal, then Unicode for numeric control-character escapes.
350
+ numeric_escapes = klass.tokenizer_class.NUMERIC_ESCAPES
351
+ if "x" in numeric_escapes:
352
+ fmt = "\\x{:02x}"
353
+ elif "0" in numeric_escapes:
354
+ fmt = "\\{:03o}"
355
+ elif "u" in numeric_escapes:
356
+ fmt = "\\u{:04x}"
357
+ else:
358
+ fmt = ""
359
+
360
+ if fmt:
361
+ # ASCII controls are 0-31 and DEL (127). Preserve existing escape mappings and
362
+ # leave tab (9), newline (10), and carriage return (13) to their existing handling.
363
+ for code in (*range(32), 127):
364
+ if code not in (9, 10, 13):
365
+ klass.ESCAPED_SEQUENCES.setdefault(chr(code), fmt.format(code))
366
+
349
367
  klass.SUPPORTS_COLUMN_JOIN_MARKS = "(+)" in klass.tokenizer_class.KEYWORDS
350
368
 
351
369
  if enum not in ("", "bigquery", "snowflake"):
@@ -136,6 +136,8 @@ class Snowflake(Dialect):
136
136
 
137
137
  class Tokenizer(tokens.Tokenizer):
138
138
  STRING_ESCAPES = ["\\", "'"]
139
+ NUMERIC_ESCAPES = {"x": (16, 2, 2, 0xFF), "u": (16, 4, 4, 0xFFFF), "0": (8, 1, 3, 0xFF)}
140
+ DROP_UNKNOWN_ESCAPES = True
139
141
  HEX_STRINGS = [("x'", "'"), ("X'", "'")]
140
142
  RAW_STRINGS = ["$$"]
141
143
  COMMENTS = ["--", "//", ("/*", "*/")]
@@ -804,6 +804,19 @@ class Lateral(Expression, UDTF):
804
804
  "ordinality": False,
805
805
  }
806
806
 
807
+ @property
808
+ def selects(self) -> list[Expr]:
809
+ from sqlglot.expressions.array import Unnest
810
+
811
+ columns = super().selects
812
+
813
+ # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
814
+ offset = self.this.args.get("offset") if isinstance(self.this, Unnest) else None
815
+ if isinstance(offset, Identifier):
816
+ columns = columns + [offset]
817
+
818
+ return columns
819
+
807
820
 
808
821
  class TableFromRows(Expression, UDTF):
809
822
  arg_types = {
@@ -2959,7 +2959,20 @@ class Generator:
2959
2959
  op_sql = self.seg(f"LATERAL VIEW{' OUTER' if expression.args.get('outer') else ''}")
2960
2960
  return f"{op_sql}{self.sep()}{this}{table}{columns}"
2961
2961
 
2962
- alias = self.sql(expression, "alias")
2962
+ table_alias = expression.args.get("alias")
2963
+ offset = expression.this.args.get("offset")
2964
+
2965
+ if (
2966
+ self.UNNEST_WITH_ORDINALITY
2967
+ and table_alias
2968
+ and isinstance(expression.this, exp.Unnest)
2969
+ and isinstance(offset, exp.Identifier)
2970
+ ):
2971
+ # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
2972
+ table_alias = table_alias.copy()
2973
+ table_alias.append("columns", offset.copy())
2974
+
2975
+ alias = self.sql(table_alias)
2963
2976
  alias = f" AS {alias}" if alias else ""
2964
2977
 
2965
2978
  ordinality = expression.args.get("ordinality") or ""
@@ -5309,6 +5322,28 @@ class Generator:
5309
5322
  sqlglot.dialects.dialect.unit_to_str(expression),
5310
5323
  )
5311
5324
 
5325
+ def arrayinsert_sql(self, expression: exp.ArrayInsert, index_offset: int = 0) -> str:
5326
+ this = expression.this
5327
+ position = expression.args["position"]
5328
+ offset = index_offset - (expression.args.get("offset") or 0)
5329
+
5330
+ if offset:
5331
+ if position.is_int:
5332
+ value = position.to_py()
5333
+ if value >= 0:
5334
+ position = exp.Literal.number(value + offset)
5335
+ elif offset < 0 and value == -1:
5336
+ # 1-based -1 appends, which a 0-based position can only express as the size
5337
+ position = exp.ArraySize(this=this.copy())
5338
+ else:
5339
+ # Negative positions count from the end, so they shift in the opposite
5340
+ # direction, e.g. 0-based -1 (before the last element) is 1-based -2
5341
+ position = exp.Literal.number(value - offset)
5342
+ else:
5343
+ self.unsupported("ARRAY_INSERT position can only be converted if it's a literal")
5344
+
5345
+ return self.func("ARRAY_INSERT", this, position, expression.expression)
5346
+
5312
5347
  def arrayany_sql(self, expression: exp.ArrayAny) -> str:
5313
5348
  if self.CAN_IMPLEMENT_ARRAY_ANY:
5314
5349
  filtered = exp.ArrayFilter(this=expression.this, expression=expression.expression)
@@ -122,7 +122,7 @@ class AthenaTrinoGenerator(TrinoGenerator):
122
122
  }
123
123
 
124
124
 
125
- class AthenaGenerator(generator.Generator):
125
+ class AthenaGenerator(AthenaTrinoGenerator):
126
126
  SELECT_KINDS: tuple[str, ...] = ()
127
127
  SUPPORTS_DECODE_CASE = False
128
128
 
@@ -370,6 +370,7 @@ class ClickHouseGenerator(generator.Generator):
370
370
  exp.UnixToTime: _unix_to_time_sql,
371
371
  exp.Trim: lambda self, e: trim_sql(self, e, default_trim_type="BOTH"),
372
372
  exp.Variance: rename_func("varSamp"),
373
+ exp.VariancePop: rename_func("varPop"),
373
374
  exp.SchemaCommentProperty: lambda self, e: self.naked_property(e),
374
375
  exp.Stddev: rename_func("stddevSamp"),
375
376
  exp.Chr: rename_func("CHAR"),
@@ -1529,7 +1529,12 @@ class SingleStoreGenerator(MySQLGenerator):
1529
1529
 
1530
1530
  def collate_sql(self, expression: exp.Collate) -> str:
1531
1531
  # SingleStore does not support setting a collation for column in the SELECT query,
1532
- # so we cast column to a LONGTEXT type with specific collation
1532
+ # so we cast column to a LONGTEXT type with specific collation. If the cast is
1533
+ # already there (e.g. when regenerating previously generated SQL), don't add
1534
+ # another one, so that generation stays idempotent.
1535
+ this = expression.this
1536
+ if isinstance(this, exp.Cast) and this.to.this == exp.DType.LONGTEXT:
1537
+ return self.binary(expression, "COLLATE")
1533
1538
  return self.binary(expression, ":> LONGTEXT COLLATE")
1534
1539
 
1535
1540
  def currentdate_sql(self, expression: exp.CurrentDate) -> str:
@@ -95,9 +95,6 @@ class SparkGenerator(Spark2Generator):
95
95
  exp.ArrayConstructCompact: lambda self, e: self.func(
96
96
  "ARRAY_COMPACT", self.func("ARRAY", *e.expressions)
97
97
  ),
98
- exp.ArrayInsert: lambda self, e: self.func(
99
- "ARRAY_INSERT", e.this, e.args.get("position"), e.expression
100
- ),
101
98
  exp.ArrayAppend: array_append_sql("ARRAY_APPEND"),
102
99
  exp.ArrayPrepend: array_append_sql("ARRAY_PREPEND"),
103
100
  exp.BitwiseAndAgg: rename_func("BIT_AND"),
@@ -152,6 +149,9 @@ class SparkGenerator(Spark2Generator):
152
149
  def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
153
150
  return generator.Generator.ignorenulls_sql(self, expression)
154
151
 
152
+ def arrayinsert_sql(self, expression: exp.ArrayInsert, index_offset: int = 0) -> str:
153
+ return super().arrayinsert_sql(expression, index_offset=1)
154
+
155
155
  def bracket_sql(self, expression: exp.Bracket) -> str:
156
156
  if expression.args.get("safe"):
157
157
  key = seq_get(self.bracket_offset_expressions(expression, index_offset=1), 0)
@@ -220,6 +220,16 @@ class Spark2Generator(HiveGenerator):
220
220
 
221
221
  def cast_sql(self, expression: exp.Cast, safe_prefix: str | None = None) -> str:
222
222
  arg = expression.this
223
+ if (
224
+ isinstance(arg, exp.Literal)
225
+ and arg.is_number
226
+ and expression.to.is_type(exp.DType.DECIMAL)
227
+ and len(expression.to.expressions) == 2
228
+ and isinstance(expression.to.expressions[1].this, exp.Neg)
229
+ ):
230
+ # Spark 2 supports negative scales in literals, but not in DECIMAL type syntax.
231
+ return f"{self.sql(arg)}BD"
232
+
223
233
  is_json_extract = isinstance(
224
234
  arg, (exp.JSONExtract, exp.JSONExtractScalar)
225
235
  ) and not arg.args.get("variant_extract")
@@ -205,10 +205,12 @@ def canonicalize_internal_names(expression: E) -> E:
205
205
  ],
206
206
  )
207
207
 
208
- # BigQuery UNNEST ... WITH OFFSET AS <id> declares a pseudo-column via
209
- # the offset arg (not the alias).
210
- if isinstance(alias_holder, exp.Unnest):
211
- offset_id = alias_holder.args.get("offset")
208
+ # UNNEST stores its offset column outside the alias, including under LATERAL.
209
+ unnest = (
210
+ alias_holder.this if isinstance(alias_holder, exp.Lateral) else alias_holder
211
+ )
212
+ if isinstance(unnest, exp.Unnest):
213
+ offset_id = unnest.args.get("offset")
212
214
  if isinstance(offset_id, exp.Identifier) and offset_id.name in name_map:
213
215
  _canon(offset_id, name_map[offset_id.name])
214
216