sqlglot 26.25.3__tar.gz → 26.26.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 (216) hide show
  1. {sqlglot-26.25.3 → sqlglot-26.26.0}/CHANGELOG.md +6 -0
  2. {sqlglot-26.25.3 → sqlglot-26.26.0}/PKG-INFO +2 -1
  3. {sqlglot-26.25.3 → sqlglot-26.26.0}/README.md +1 -0
  4. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/_version.py +2 -2
  5. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/bigquery.py +10 -0
  6. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/clickhouse.py +1 -0
  7. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/postgres.py +11 -1
  8. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/risingwave.py +4 -0
  9. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/snowflake.py +3 -0
  10. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/spark.py +1 -0
  11. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/sqlite.py +9 -0
  12. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/starrocks.py +16 -1
  13. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/expressions.py +36 -9
  14. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/generator.py +1 -3
  15. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/parser.py +83 -3
  16. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.egg-info/PKG-INFO +2 -1
  17. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/src/token.rs +23 -1
  18. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_dialect.py +114 -0
  19. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_duckdb.py +20 -7
  20. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_postgres.py +13 -0
  21. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_presto.py +1 -1
  22. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_snowflake.py +43 -6
  23. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_sqlite.py +1 -0
  24. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_starrocks.py +3 -0
  25. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_expressions.py +12 -0
  26. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_tokens.py +7 -0
  27. {sqlglot-26.25.3 → sqlglot-26.26.0}/.gitignore +0 -0
  28. {sqlglot-26.25.3 → sqlglot-26.26.0}/.gitpod.yml +0 -0
  29. {sqlglot-26.25.3 → sqlglot-26.26.0}/.pre-commit-config.yaml +0 -0
  30. {sqlglot-26.25.3 → sqlglot-26.26.0}/CONTRIBUTING.md +0 -0
  31. {sqlglot-26.25.3 → sqlglot-26.26.0}/LICENSE +0 -0
  32. {sqlglot-26.25.3 → sqlglot-26.26.0}/MANIFEST.in +0 -0
  33. {sqlglot-26.25.3 → sqlglot-26.26.0}/Makefile +0 -0
  34. {sqlglot-26.25.3 → sqlglot-26.26.0}/pyproject.toml +0 -0
  35. {sqlglot-26.25.3 → sqlglot-26.26.0}/setup.cfg +0 -0
  36. {sqlglot-26.25.3 → sqlglot-26.26.0}/setup.py +0 -0
  37. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/__init__.py +0 -0
  38. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/__main__.py +0 -0
  39. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/_typing.py +0 -0
  40. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/__init__.py +0 -0
  41. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/athena.py +0 -0
  42. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/databricks.py +0 -0
  43. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/dialect.py +0 -0
  44. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/doris.py +0 -0
  45. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/drill.py +0 -0
  46. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/druid.py +0 -0
  47. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/duckdb.py +0 -0
  48. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/dune.py +0 -0
  49. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/hive.py +0 -0
  50. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/materialize.py +0 -0
  51. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/mysql.py +0 -0
  52. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/oracle.py +0 -0
  53. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/presto.py +0 -0
  54. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/prql.py +0 -0
  55. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/redshift.py +0 -0
  56. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/spark2.py +0 -0
  57. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/tableau.py +0 -0
  58. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/teradata.py +0 -0
  59. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/trino.py +0 -0
  60. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/dialects/tsql.py +0 -0
  61. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/diff.py +0 -0
  62. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/errors.py +0 -0
  63. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/executor/__init__.py +0 -0
  64. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/executor/context.py +0 -0
  65. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/executor/env.py +0 -0
  66. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/executor/python.py +0 -0
  67. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/executor/table.py +0 -0
  68. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/helper.py +0 -0
  69. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/jsonpath.py +0 -0
  70. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/lineage.py +0 -0
  71. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/__init__.py +0 -0
  72. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/annotate_types.py +0 -0
  73. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/canonicalize.py +0 -0
  74. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  75. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
  76. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  77. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  78. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
  79. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/normalize.py +0 -0
  80. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  81. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/optimize_joins.py +0 -0
  82. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/optimizer.py +0 -0
  83. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
  84. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
  85. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/qualify.py +0 -0
  86. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/qualify_columns.py +0 -0
  87. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/qualify_tables.py +0 -0
  88. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/scope.py +0 -0
  89. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/simplify.py +0 -0
  90. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  91. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/planner.py +0 -0
  92. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/py.typed +0 -0
  93. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/schema.py +0 -0
  94. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/serde.py +0 -0
  95. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/time.py +0 -0
  96. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/tokens.py +0 -0
  97. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/transforms.py +0 -0
  98. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot/trie.py +0 -0
  99. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.egg-info/SOURCES.txt +0 -0
  100. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.egg-info/dependency_links.txt +0 -0
  101. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.egg-info/requires.txt +0 -0
  102. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.egg-info/top_level.txt +0 -0
  103. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglot.png +0 -0
  104. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/Cargo.lock +0 -0
  105. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/Cargo.toml +0 -0
  106. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/benches/dialect_settings.json +0 -0
  107. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/benches/long.rs +0 -0
  108. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/benches/token_type_settings.json +0 -0
  109. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
  110. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
  111. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/pyproject.toml +0 -0
  112. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/src/lib.rs +0 -0
  113. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/src/settings.rs +0 -0
  114. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/src/tokenizer.rs +0 -0
  115. {sqlglot-26.25.3 → sqlglot-26.26.0}/sqlglotrs/src/trie.rs +0 -0
  116. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/__init__.py +0 -0
  117. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/__init__.py +0 -0
  118. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_athena.py +0 -0
  119. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_bigquery.py +0 -0
  120. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_clickhouse.py +0 -0
  121. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_databricks.py +0 -0
  122. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_doris.py +0 -0
  123. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_drill.py +0 -0
  124. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_druid.py +0 -0
  125. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_dune.py +0 -0
  126. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_hive.py +0 -0
  127. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_materialize.py +0 -0
  128. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_mysql.py +0 -0
  129. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_oracle.py +0 -0
  130. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_prql.py +0 -0
  131. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_redshift.py +0 -0
  132. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_risingwave.py +0 -0
  133. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_spark.py +0 -0
  134. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_tableau.py +0 -0
  135. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_teradata.py +0 -0
  136. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_trino.py +0 -0
  137. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/dialects/test_tsql.py +0 -0
  138. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/identity.sql +0 -0
  139. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/jsonpath/LICENSE +0 -0
  140. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/jsonpath/cts.json +0 -0
  141. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/annotate_functions.sql +0 -0
  142. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
  143. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  144. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  145. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  146. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  147. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  148. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  149. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/normalize.sql +0 -0
  150. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  151. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  152. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
  153. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  154. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  155. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
  156. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
  157. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
  158. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  159. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
  160. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
  161. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  162. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/simplify.sql +0 -0
  163. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  164. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  165. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  166. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  167. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  168. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  169. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  170. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  171. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  172. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  173. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  174. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  175. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  176. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  177. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  178. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  179. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  180. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  181. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  182. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  183. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  184. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  185. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  186. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  187. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  188. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  189. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  190. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  191. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  192. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  193. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  194. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  195. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  196. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  197. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  198. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/partial.sql +0 -0
  199. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/fixtures/pretty.sql +0 -0
  200. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/gen_fixtures.py +0 -0
  201. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/helpers.py +0 -0
  202. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_build.py +0 -0
  203. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_diff.py +0 -0
  204. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_docs.py +0 -0
  205. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_executor.py +0 -0
  206. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_generator.py +0 -0
  207. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_helper.py +0 -0
  208. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_jsonpath.py +0 -0
  209. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_lineage.py +0 -0
  210. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_optimizer.py +0 -0
  211. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_parser.py +0 -0
  212. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_schema.py +0 -0
  213. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_serde.py +0 -0
  214. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_time.py +0 -0
  215. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_transforms.py +0 -0
  216. {sqlglot-26.25.3 → sqlglot-26.26.0}/tests/test_transpile.py +0 -0
@@ -1,6 +1,11 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v26.25.3] - 2025-06-04
5
+ ### :sparkles: New Features
6
+ - [`964b4a1`](https://github.com/tobymao/sqlglot/commit/964b4a1e367e00e243b80edf677cd48d453ed31e) - add line/col position for Star *(commit by [@georgesittas](https://github.com/georgesittas))*
7
+
8
+
4
9
  ## [v26.25.2] - 2025-06-04
5
10
  ### :sparkles: New Features
6
11
  - [`8b5129f`](https://github.com/tobymao/sqlglot/commit/8b5129f288880032f0bf9d649984d82314039af1) - **postgres**: improve pretty-formatting of ARRAY[...] *(commit by [@georgesittas](https://github.com/georgesittas))*
@@ -4788,3 +4793,4 @@ Changelog
4788
4793
  [v26.25.0]: https://github.com/tobymao/sqlglot/compare/v26.24.0...v26.25.0
4789
4794
  [v26.25.1]: https://github.com/tobymao/sqlglot/compare/v26.25.0...v26.25.1
4790
4795
  [v26.25.2]: https://github.com/tobymao/sqlglot/compare/v26.25.1...v26.25.2
4796
+ [v26.25.3]: https://github.com/tobymao/sqlglot/compare/v26.25.2...v26.25.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 26.25.3
3
+ Version: 26.26.0
4
4
  Summary: An easily customizable SQL parser and transpiler
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License: MIT License
@@ -558,6 +558,7 @@ See also: [Writing a Python SQL engine from scratch](https://github.com/tobymao/
558
558
  * [Dagster](https://github.com/dagster-io/dagster)
559
559
  * [Fugue](https://github.com/fugue-project/fugue)
560
560
  * [Ibis](https://github.com/ibis-project/ibis)
561
+ * [dlt](https://github.com/dlt-hub/dlt)
561
562
  * [mysql-mimic](https://github.com/kelsin/mysql-mimic)
562
563
  * [Querybook](https://github.com/pinterest/querybook)
563
564
  * [Quokka](https://github.com/marsupialtail/quokka)
@@ -497,6 +497,7 @@ See also: [Writing a Python SQL engine from scratch](https://github.com/tobymao/
497
497
  * [Dagster](https://github.com/dagster-io/dagster)
498
498
  * [Fugue](https://github.com/fugue-project/fugue)
499
499
  * [Ibis](https://github.com/ibis-project/ibis)
500
+ * [dlt](https://github.com/dlt-hub/dlt)
500
501
  * [mysql-mimic](https://github.com/kelsin/mysql-mimic)
501
502
  * [Querybook](https://github.com/pinterest/querybook)
502
503
  * [Quokka](https://github.com/marsupialtail/quokka)
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '26.25.3'
21
- __version_tuple__ = version_tuple = (26, 25, 3)
20
+ __version__ = version = '26.26.0'
21
+ __version_tuple__ = version_tuple = (26, 26, 0)
@@ -525,6 +525,16 @@ class BigQuery(Dialect):
525
525
  LOG_DEFAULTS_TO_LN = True
526
526
  SUPPORTS_IMPLICIT_UNNEST = True
527
527
 
528
+ # BigQuery does not allow ASC/DESC to be used as an identifier
529
+ ID_VAR_TOKENS = parser.Parser.ID_VAR_TOKENS - {TokenType.ASC, TokenType.DESC}
530
+ ALIAS_TOKENS = parser.Parser.ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
531
+ TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
532
+ COMMENT_TABLE_ALIAS_TOKENS = parser.Parser.COMMENT_TABLE_ALIAS_TOKENS - {
533
+ TokenType.ASC,
534
+ TokenType.DESC,
535
+ }
536
+ UPDATE_ALIAS_TOKENS = parser.Parser.UPDATE_ALIAS_TOKENS - {TokenType.ASC, TokenType.DESC}
537
+
528
538
  FUNCTIONS = {
529
539
  **parser.Parser.FUNCTIONS,
530
540
  "CONTAINS_SUBSTR": _build_contains_substring,
@@ -1096,6 +1096,7 @@ class ClickHouse(Dialect):
1096
1096
  exp.RegexpLike: lambda self, e: self.func("match", e.this, e.expression),
1097
1097
  exp.Rand: rename_func("randCanonical"),
1098
1098
  exp.StartsWith: rename_func("startsWith"),
1099
+ exp.EndsWith: rename_func("endsWith"),
1099
1100
  exp.StrPosition: lambda self, e: strposition_sql(
1100
1101
  self,
1101
1102
  e,
@@ -36,6 +36,7 @@ from sqlglot.dialects.dialect import (
36
36
  strposition_sql,
37
37
  count_if_to_sum,
38
38
  groupconcat_sql,
39
+ Version,
39
40
  )
40
41
  from sqlglot.generator import unsupported_args
41
42
  from sqlglot.helper import is_int, seq_get
@@ -255,6 +256,15 @@ def _levenshtein_sql(self: Postgres.Generator, expression: exp.Levenshtein) -> s
255
256
  return rename_func(name)(self, expression)
256
257
 
257
258
 
259
+ def _versioned_anyvalue_sql(self: Postgres.Generator, expression: exp.AnyValue) -> str:
260
+ # https://www.postgresql.org/docs/16/functions-aggregate.html
261
+ # https://www.postgresql.org/about/featurematrix/
262
+ if self.dialect.version < Version("16.0"):
263
+ return any_value_to_max_sql(self, expression)
264
+
265
+ return rename_func("ANY_VALUE")(self, expression)
266
+
267
+
258
268
  class Postgres(Dialect):
259
269
  INDEX_OFFSET = 1
260
270
  TYPED_DIVISION = True
@@ -546,7 +556,7 @@ class Postgres(Dialect):
546
556
 
547
557
  TRANSFORMS = {
548
558
  **generator.Generator.TRANSFORMS,
549
- exp.AnyValue: any_value_to_max_sql,
559
+ exp.AnyValue: _versioned_anyvalue_sql,
550
560
  exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
551
561
  exp.ArrayFilter: filter_array_using_unnest,
552
562
  exp.BitwiseXor: lambda self, e: self.binary(e, "#"),
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
  from sqlglot.dialects.postgres import Postgres
3
+ from sqlglot.generator import Generator
3
4
  from sqlglot.tokens import TokenType
4
5
  import typing as t
5
6
 
@@ -72,3 +73,6 @@ class RisingWave(Postgres):
72
73
  }
73
74
 
74
75
  EXPRESSION_PRECEDES_PROPERTIES_CREATABLES = {"SINK"}
76
+
77
+ def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
78
+ return Generator.computedcolumnconstraint_sql(self, expression)
@@ -1019,6 +1019,7 @@ class Snowflake(Dialect):
1019
1019
  exp.ArgMin: rename_func("MIN_BY"),
1020
1020
  exp.ArrayConcat: lambda self, e: self.arrayconcat_sql(e, name="ARRAY_CAT"),
1021
1021
  exp.ArrayContains: lambda self, e: self.func("ARRAY_CONTAINS", e.expression, e.this),
1022
+ exp.ArrayIntersect: rename_func("ARRAY_INTERSECTION"),
1022
1023
  exp.AtTimeZone: lambda self, e: self.func(
1023
1024
  "CONVERT_TIMEZONE", e.args.get("zone"), e.this
1024
1025
  ),
@@ -1094,11 +1095,13 @@ class Snowflake(Dialect):
1094
1095
  exp.SHA: rename_func("SHA1"),
1095
1096
  exp.StarMap: rename_func("OBJECT_CONSTRUCT"),
1096
1097
  exp.StartsWith: rename_func("STARTSWITH"),
1098
+ exp.EndsWith: rename_func("ENDSWITH"),
1097
1099
  exp.StrPosition: lambda self, e: strposition_sql(
1098
1100
  self, e, func_name="CHARINDEX", supports_position=True
1099
1101
  ),
1100
1102
  exp.StrToDate: lambda self, e: self.func("DATE", e.this, self.format_time(e)),
1101
1103
  exp.Stuff: rename_func("INSERT"),
1104
+ exp.StPoint: rename_func("ST_MAKEPOINT"),
1102
1105
  exp.TimeAdd: date_delta_sql("TIMEADD"),
1103
1106
  exp.Timestamp: no_timestamp_sql,
1104
1107
  exp.TimestampAdd: date_delta_sql("TIMESTAMPADD"),
@@ -163,6 +163,7 @@ class Spark(Spark2):
163
163
  move_partitioned_by_to_schema_columns,
164
164
  ]
165
165
  ),
166
+ exp.EndsWith: rename_func("ENDSWITH"),
166
167
  exp.PartitionedByProperty: lambda self,
167
168
  e: f"PARTITIONED BY {self.wrap(self.expressions(sqls=[_normalize_partition(e) for e in e.this.expressions], skip_first=True))}",
168
169
  exp.StartsWith: rename_func("STARTSWITH"),
@@ -99,6 +99,8 @@ class SQLite(Dialect):
99
99
  KEYWORDS = tokens.Tokenizer.KEYWORDS.copy()
100
100
  KEYWORDS.pop("/*+")
101
101
 
102
+ COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE}
103
+
102
104
  class Parser(parser.Parser):
103
105
  FUNCTIONS = {
104
106
  **parser.Parser.FUNCTIONS,
@@ -307,3 +309,10 @@ class SQLite(Dialect):
307
309
  @unsupported_args("this")
308
310
  def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
309
311
  return "'main'"
312
+
313
+ def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
314
+ self.unsupported("SQLite does not support IGNORE NULLS.")
315
+ return self.sql(expression.this)
316
+
317
+ def respectnulls_sql(self, expression: exp.RespectNulls) -> str:
318
+ return self.sql(expression.this)
@@ -17,6 +17,19 @@ from sqlglot.helper import seq_get
17
17
  from sqlglot.tokens import TokenType
18
18
 
19
19
 
20
+ # https://docs.starrocks.io/docs/sql-reference/sql-functions/spatial-functions/st_distance_sphere/
21
+ def st_distance_sphere(self, expression: exp.StDistance) -> str:
22
+ point1 = expression.this
23
+ point2 = expression.expression
24
+
25
+ point1_x = self.func("ST_X", point1)
26
+ point1_y = self.func("ST_Y", point1)
27
+ point2_x = self.func("ST_X", point2)
28
+ point2_y = self.func("ST_Y", point2)
29
+
30
+ return self.func("ST_Distance_Sphere", point1_x, point1_y, point2_x, point2_y)
31
+
32
+
20
33
  class StarRocks(MySQL):
21
34
  STRICT_JSON_PATH_SYNTAX = False
22
35
 
@@ -132,6 +145,8 @@ class StarRocks(MySQL):
132
145
  TRANSFORMS = {
133
146
  **MySQL.Generator.TRANSFORMS,
134
147
  exp.Array: inline_array_sql,
148
+ exp.ArrayAgg: rename_func("ARRAY_AGG"),
149
+ exp.ArrayFilter: rename_func("ARRAY_FILTER"),
135
150
  exp.ArrayToString: rename_func("ARRAY_JOIN"),
136
151
  exp.ApproxDistinct: approx_count_distinct_sql,
137
152
  exp.DateDiff: lambda self, e: self.func(
@@ -141,12 +156,12 @@ class StarRocks(MySQL):
141
156
  exp.JSONExtract: arrow_json_extract_sql,
142
157
  exp.Property: property_sql,
143
158
  exp.RegexpLike: rename_func("REGEXP"),
159
+ exp.StDistance: st_distance_sphere,
144
160
  exp.StrToUnix: lambda self, e: self.func("UNIX_TIMESTAMP", e.this, self.format_time(e)),
145
161
  exp.TimestampTrunc: lambda self, e: self.func("DATE_TRUNC", unit_to_str(e), e.this),
146
162
  exp.TimeStrToDate: rename_func("TO_DATE"),
147
163
  exp.UnixToStr: lambda self, e: self.func("FROM_UNIXTIME", e.this, self.format_time(e)),
148
164
  exp.UnixToTime: rename_func("FROM_UNIXTIME"),
149
- exp.ArrayFilter: rename_func("ARRAY_FILTER"),
150
165
  }
151
166
 
152
167
  TRANSFORMS.pop(exp.DateTrunc)
@@ -31,6 +31,7 @@ from sqlglot.helper import (
31
31
  ensure_collection,
32
32
  ensure_list,
33
33
  seq_get,
34
+ split_num_words,
34
35
  subclasses,
35
36
  to_bool,
36
37
  )
@@ -1993,11 +1994,6 @@ class OnUpdateColumnConstraint(ColumnConstraintKind):
1993
1994
  pass
1994
1995
 
1995
1996
 
1996
- # https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1997
- class TransformColumnConstraint(ColumnConstraintKind):
1998
- pass
1999
-
2000
-
2001
1997
  class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2002
1998
  arg_types = {"desc": False, "options": False}
2003
1999
 
@@ -5570,6 +5566,21 @@ class ArrayToString(Func):
5570
5566
  _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5571
5567
 
5572
5568
 
5569
+ class ArrayIntersect(Func):
5570
+ arg_types = {"expressions": True}
5571
+ is_var_len_args = True
5572
+ _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
5573
+
5574
+
5575
+ class StPoint(Func):
5576
+ arg_types = {"this": True, "expression": True, "null": False}
5577
+ _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
5578
+
5579
+
5580
+ class StDistance(Func):
5581
+ arg_types = {"this": True, "expression": True, "use_spheroid": False}
5582
+
5583
+
5573
5584
  # https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5574
5585
  class String(Func):
5575
5586
  arg_types = {"this": True, "zone": False}
@@ -6706,6 +6717,11 @@ class StartsWith(Func):
6706
6717
  arg_types = {"this": True, "expression": True}
6707
6718
 
6708
6719
 
6720
+ class EndsWith(Func):
6721
+ _sql_names = ["ENDS_WITH", "ENDSWITH"]
6722
+ arg_types = {"this": True, "expression": True}
6723
+
6724
+
6709
6725
  class StrPosition(Func):
6710
6726
  arg_types = {
6711
6727
  "this": True,
@@ -7366,7 +7382,7 @@ def _apply_set_operation(
7366
7382
  **opts,
7367
7383
  ) -> S:
7368
7384
  return reduce(
7369
- lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7385
+ lambda x, y: set_operation(this=x, expression=y, distinct=distinct, **opts),
7370
7386
  (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7371
7387
  )
7372
7388
 
@@ -7962,7 +7978,15 @@ def to_table(
7962
7978
  if isinstance(sql_path, Table):
7963
7979
  return maybe_copy(sql_path, copy=copy)
7964
7980
 
7965
- table = maybe_parse(sql_path, into=Table, dialect=dialect)
7981
+ try:
7982
+ table = maybe_parse(sql_path, into=Table, dialect=dialect)
7983
+ except ParseError:
7984
+ catalog, db, this = split_num_words(sql_path, ".", 3)
7985
+
7986
+ if not this:
7987
+ raise
7988
+
7989
+ table = table_(this, db=db, catalog=catalog)
7966
7990
 
7967
7991
  for k, v in kwargs.items():
7968
7992
  table.set(k, v)
@@ -8110,7 +8134,7 @@ def column(
8110
8134
 
8111
8135
  @t.overload
8112
8136
  def column(
8113
- col: str | Identifier,
8137
+ col: str | Identifier | Star,
8114
8138
  table: t.Optional[str | Identifier] = None,
8115
8139
  db: t.Optional[str | Identifier] = None,
8116
8140
  catalog: t.Optional[str | Identifier] = None,
@@ -8147,8 +8171,11 @@ def column(
8147
8171
  Returns:
8148
8172
  The new Column instance.
8149
8173
  """
8174
+ if not isinstance(col, Star):
8175
+ col = to_identifier(col, quoted=quoted, copy=copy)
8176
+
8150
8177
  this = Column(
8151
- this=to_identifier(col, quoted=quoted, copy=copy),
8178
+ this=col,
8152
8179
  table=to_identifier(table, quoted=quoted, copy=copy),
8153
8180
  db=to_identifier(db, quoted=quoted, copy=copy),
8154
8181
  catalog=to_identifier(catalog, quoted=quoted, copy=copy),
@@ -1018,6 +1018,7 @@ class Generator(metaclass=_Generator):
1018
1018
  persisted = " PERSISTED"
1019
1019
  else:
1020
1020
  persisted = ""
1021
+
1021
1022
  return f"AS {this}{persisted}"
1022
1023
 
1023
1024
  def autoincrementcolumnconstraint_sql(self, _) -> str:
@@ -1079,9 +1080,6 @@ class Generator(metaclass=_Generator):
1079
1080
  def notnullcolumnconstraint_sql(self, expression: exp.NotNullColumnConstraint) -> str:
1080
1081
  return f"{'' if expression.args.get('allow_null') else 'NOT '}NULL"
1081
1082
 
1082
- def transformcolumnconstraint_sql(self, expression: exp.TransformColumnConstraint) -> str:
1083
- return f"AS {self.sql(expression, 'this')}"
1084
-
1085
1083
  def primarykeycolumnconstraint_sql(self, expression: exp.PrimaryKeyColumnConstraint) -> str:
1086
1084
  desc = expression.args.get("desc")
1087
1085
  if desc is not None:
@@ -936,6 +936,7 @@ class Parser(metaclass=_Parser):
936
936
  "ORDER BY": lambda self, query: query.order_by(self._parse_order(), copy=False),
937
937
  "LIMIT": lambda self, query: self._parse_pipe_syntax_limit(query),
938
938
  "OFFSET": lambda self, query: query.offset(self._parse_offset(), copy=False),
939
+ "AGGREGATE": lambda self, query: self._parse_pipe_syntax_aggregate(query),
939
940
  }
940
941
 
941
942
  PROPERTY_PARSERS: t.Dict[str, t.Callable] = {
@@ -1143,6 +1144,78 @@ class Parser(metaclass=_Parser):
1143
1144
  query.offset(offset, copy=False)
1144
1145
  return query
1145
1146
 
1147
+ def _parse_pipe_syntax_aggregate_fields(self) -> t.Optional[exp.Expression]:
1148
+ this = self._parse_assignment()
1149
+ if self._match_text_seq("GROUP", "AND", advance=False):
1150
+ return this
1151
+
1152
+ this = self._parse_alias(this)
1153
+
1154
+ if self._match_set((TokenType.ASC, TokenType.DESC), advance=False):
1155
+ return self._parse_ordered(lambda: this)
1156
+
1157
+ return this
1158
+
1159
+ def _parse_pipe_syntax_aggregate_group_order_by(
1160
+ self, query: exp.Query, group_by_exists: bool = True
1161
+ ) -> exp.Query:
1162
+ expr = self._parse_csv(self._parse_pipe_syntax_aggregate_fields)
1163
+ aggregates_or_groups, orders = [], []
1164
+ for element in expr:
1165
+ if isinstance(element, exp.Ordered):
1166
+ this = element.this
1167
+ if isinstance(this, exp.Alias):
1168
+ element.set("this", this.args["alias"])
1169
+ orders.append(element)
1170
+ else:
1171
+ this = element
1172
+ aggregates_or_groups.append(this)
1173
+
1174
+ if group_by_exists and isinstance(query, exp.Select):
1175
+ query = query.select(*aggregates_or_groups, copy=False).group_by(
1176
+ *[element.args.get("alias", element) for element in aggregates_or_groups],
1177
+ copy=False,
1178
+ )
1179
+ else:
1180
+ query = exp.select(*aggregates_or_groups, copy=False).from_(
1181
+ query.subquery(copy=False), copy=False
1182
+ )
1183
+
1184
+ if orders:
1185
+ return query.order_by(*orders, copy=False)
1186
+
1187
+ return query
1188
+
1189
+ def _parse_pipe_syntax_aggregate(self, query: exp.Query) -> exp.Query:
1190
+ self._match_text_seq("AGGREGATE")
1191
+ query = self._parse_pipe_syntax_aggregate_group_order_by(query, group_by_exists=False)
1192
+
1193
+ if self._match(TokenType.GROUP_BY) or (
1194
+ self._match_text_seq("GROUP", "AND") and self._match(TokenType.ORDER_BY)
1195
+ ):
1196
+ return self._parse_pipe_syntax_aggregate_group_order_by(query)
1197
+
1198
+ return query
1199
+
1200
+ def _parse_pipe_syntax_set_operator(
1201
+ self, query: t.Optional[exp.Query]
1202
+ ) -> t.Optional[exp.Query]:
1203
+ first_setop = self.parse_set_operation(this=query)
1204
+
1205
+ if not first_setop or not query:
1206
+ return None
1207
+
1208
+ first_setop.this.pop()
1209
+ distinct = first_setop.args.pop("distinct")
1210
+
1211
+ setops = [first_setop.expression.pop(), *self._parse_expressions()]
1212
+
1213
+ if isinstance(first_setop, exp.Union):
1214
+ return query.union(*setops, distinct=distinct, **first_setop.args)
1215
+ if isinstance(first_setop, exp.Except):
1216
+ return query.except_(*setops, distinct=distinct, **first_setop.args)
1217
+ return query.intersect(*setops, distinct=distinct, **first_setop.args)
1218
+
1146
1219
  def _parse_partitioned_by_bucket_or_truncate(self) -> exp.Expression:
1147
1220
  klass = (
1148
1221
  exp.PartitionedByBucket
@@ -5900,7 +5973,7 @@ class Parser(metaclass=_Parser):
5900
5973
  constraints.append(
5901
5974
  self.expression(
5902
5975
  exp.ColumnConstraint,
5903
- kind=exp.TransformColumnConstraint(this=self._parse_disjunction()),
5976
+ kind=exp.ComputedColumnConstraint(this=self._parse_disjunction()),
5904
5977
  )
5905
5978
  )
5906
5979
 
@@ -7163,11 +7236,18 @@ class Parser(metaclass=_Parser):
7163
7236
 
7164
7237
  return this
7165
7238
 
7166
- def _parse_pipe_syntax_query(self, query: exp.Select) -> exp.Query:
7239
+ def _parse_pipe_syntax_query(self, query: exp.Query) -> t.Optional[exp.Query]:
7167
7240
  while self._match(TokenType.PIPE_GT):
7241
+ start = self._curr
7168
7242
  parser = self.PIPE_SYNTAX_TRANSFORM_PARSERS.get(self._curr.text.upper())
7169
7243
  if not parser:
7170
- self.raise_error(f"Unsupported pipe syntax operator: '{self._curr.text.upper()}'.")
7244
+ set_op_query = self._parse_pipe_syntax_set_operator(query)
7245
+ if not set_op_query:
7246
+ self._retreat(start)
7247
+ self.raise_error(f"Unsupported pipe syntax operator: '{start.text.upper()}'.")
7248
+ break
7249
+
7250
+ query = set_op_query
7171
7251
  else:
7172
7252
  query = parser(self, query)
7173
7253
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 26.25.3
3
+ Version: 26.26.0
4
4
  Summary: An easily customizable SQL parser and transpiler
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License: MIT License
@@ -558,6 +558,7 @@ See also: [Writing a Python SQL engine from scratch](https://github.com/tobymao/
558
558
  * [Dagster](https://github.com/dagster-io/dagster)
559
559
  * [Fugue](https://github.com/fugue-project/fugue)
560
560
  * [Ibis](https://github.com/ibis-project/ibis)
561
+ * [dlt](https://github.com/dlt-hub/dlt)
561
562
  * [mysql-mimic](https://github.com/kelsin/mysql-mimic)
562
563
  * [Querybook](https://github.com/pinterest/querybook)
563
564
  * [Quokka](https://github.com/marsupialtail/quokka)
@@ -1,7 +1,7 @@
1
1
  use crate::settings::TokenType;
2
2
  use pyo3::prelude::*;
3
3
  use pyo3::types::{PyList, PyString};
4
- use pyo3::{pyclass, Py, PyObject, Python};
4
+ use pyo3::{pyclass, pymethods, Py, PyObject, Python};
5
5
 
6
6
  #[derive(Debug)]
7
7
  #[pyclass]
@@ -57,3 +57,25 @@ impl Token {
57
57
  });
58
58
  }
59
59
  }
60
+
61
+ #[pymethods]
62
+ impl Token {
63
+ fn __repr__(&self, py: Python) -> PyResult<String> {
64
+ let text = self.text.bind(py).to_str()?;
65
+ let comments = self.comments.bind(py);
66
+ let token_type_str = self.token_type_py.bind(py).str()?;
67
+ let comments_repr = comments.repr()?;
68
+ let comments_str = comments_repr.to_str()?;
69
+
70
+ Ok(format!(
71
+ "<Token token_type: {}, text: {}, line: {}, col: {}, start: {}, end: {}, comments: {}>",
72
+ token_type_str,
73
+ text,
74
+ self.line,
75
+ self.col,
76
+ self.start,
77
+ self.end,
78
+ comments_str
79
+ ))
80
+ }
81
+ }
@@ -462,6 +462,16 @@ class TestDialect(Validator):
462
462
  "CAST('127.0.0.1/32' AS INET)",
463
463
  read={"postgres": "INET '127.0.0.1/32'"},
464
464
  )
465
+ self.assertIsNotNone(
466
+ self.validate_identity("CREATE TABLE foo (bar INT AS (foo))").find(
467
+ exp.ComputedColumnConstraint
468
+ )
469
+ )
470
+ self.assertIsNotNone(
471
+ self.validate_identity(
472
+ "CREATE TABLE foo (t1 INT, t2 INT, bar INT AS (t1 * t2 * 2))"
473
+ ).find(exp.ComputedColumnConstraint)
474
+ )
465
475
 
466
476
  def test_ddl(self):
467
477
  self.validate_all(
@@ -1304,6 +1314,32 @@ class TestDialect(Validator):
1304
1314
  },
1305
1315
  )
1306
1316
 
1317
+ self.validate_all(
1318
+ "ARRAY_INTERSECT(x, y)",
1319
+ read={
1320
+ "hive": "ARRAY_INTERSECT(x, y)",
1321
+ "spark2": "ARRAY_INTERSECT(x, y)",
1322
+ "spark": "ARRAY_INTERSECT(x, y)",
1323
+ "databricks": "ARRAY_INTERSECT(x, y)",
1324
+ "presto": "ARRAY_INTERSECT(x, y)",
1325
+ "trino": "ARRAY_INTERSECT(x, y)",
1326
+ "snowflake": "ARRAY_INTERSECTION(x, y)",
1327
+ "starrocks": "ARRAY_INTERSECT(x, y)",
1328
+ },
1329
+ write={
1330
+ "hive": "ARRAY_INTERSECT(x, y)",
1331
+ "spark2": "ARRAY_INTERSECT(x, y)",
1332
+ "spark": "ARRAY_INTERSECT(x, y)",
1333
+ "databricks": "ARRAY_INTERSECT(x, y)",
1334
+ "presto": "ARRAY_INTERSECT(x, y)",
1335
+ "trino": "ARRAY_INTERSECT(x, y)",
1336
+ "snowflake": "ARRAY_INTERSECTION(x, y)",
1337
+ "starrocks": "ARRAY_INTERSECT(x, y)",
1338
+ },
1339
+ )
1340
+
1341
+ self.validate_identity("SELECT ARRAY_INTERSECT(x, y, z)")
1342
+
1307
1343
  def test_order_by(self):
1308
1344
  self.validate_identity(
1309
1345
  "SELECT c FROM t ORDER BY a, b,",
@@ -3528,3 +3564,81 @@ FROM subquery2""",
3528
3564
  f"FROM x |> SELECT x1, x2 |> WHERE x1 > 0 |> WHERE x2 > 0 |> ORDER BY x1, x2 |> {option}",
3529
3565
  f"SELECT x1, x2 FROM (SELECT * FROM x) WHERE x1 > 0 AND x2 > 0 ORDER BY x1, x2 {option}",
3530
3566
  )
3567
+ self.validate_identity(
3568
+ "FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3)",
3569
+ "SELECT SUM(x1), MAX(x2), MIN(x3) FROM (SELECT * FROM x)",
3570
+ )
3571
+ self.validate_identity(
3572
+ "FROM x |> AGGREGATE SUM(x1) AS s_x1 |> SELECT s_x1",
3573
+ "SELECT s_x1 FROM (SELECT SUM(x1) AS s_x1 FROM (SELECT * FROM x))",
3574
+ )
3575
+ self.validate_identity(
3576
+ "FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3) GROUP BY x4, x5",
3577
+ "SELECT SUM(x1), MAX(x2), MIN(x3), x4, x5 FROM (SELECT * FROM x) GROUP BY x4, x5",
3578
+ )
3579
+ self.validate_identity(
3580
+ "FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3) GROUP BY x4 AS a_x4, x5 AS a_x5",
3581
+ "SELECT SUM(x1), MAX(x2), MIN(x3), x4 AS a_x4, x5 AS a_x5 FROM (SELECT * FROM x) GROUP BY a_x4, a_x5",
3582
+ )
3583
+ self.validate_identity(
3584
+ "FROM x |> AGGREGATE SUM(x1) as s_x1 GROUP BY x1 |> SELECT s_x1, x1 as ss_x1",
3585
+ "SELECT s_x1, x1 AS ss_x1 FROM (SELECT SUM(x1) AS s_x1, x1 FROM (SELECT * FROM x) GROUP BY x1)",
3586
+ )
3587
+ self.validate_identity(
3588
+ "FROM x |> AGGREGATE SUM(x1) GROUP", "SELECT SUM(x1) AS GROUP FROM (SELECT * FROM x)"
3589
+ )
3590
+ for order_option in ("ASC", "DESC", "ASC NULLS LAST", "DESC NULLS FIRST"):
3591
+ with self.subTest(f"Testing pipe syntax AGGREGATE for order option: {order_option}"):
3592
+ self.validate_all(
3593
+ f"SELECT SUM(x1) AS x_s FROM (SELECT * FROM x) ORDER BY x_s {order_option}",
3594
+ read={
3595
+ "bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s {order_option}",
3596
+ },
3597
+ )
3598
+ self.validate_all(
3599
+ f"SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM (SELECT * FROM x) GROUP BY g_x1 ORDER BY x_s {order_option}",
3600
+ read={
3601
+ "bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s {order_option} GROUP BY x1 AS g_x1",
3602
+ },
3603
+ )
3604
+ with self.subTest(
3605
+ f"Testing pipe syntax AGGREGATE with GROUP AND ORDER BY for order option: {order_option}"
3606
+ ):
3607
+ self.validate_all(
3608
+ f"SELECT g_x1, x_s FROM (SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM (SELECT * FROM x) GROUP BY g_x1 ORDER BY g_x1 {order_option})",
3609
+ read={
3610
+ "bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s GROUP AND ORDER BY x1 AS g_x1 {order_option} |> SELECT g_x1, x_s",
3611
+ },
3612
+ )
3613
+
3614
+ for op_operator in (
3615
+ "UNION ALL",
3616
+ "UNION DISTINCT",
3617
+ "INTERSECT DISTINCT",
3618
+ "EXCEPT DISTINCT",
3619
+ ):
3620
+ with self.subTest(f"Testing pipe syntax SET OPERATORS: {op_operator}"):
3621
+ self.validate_all(
3622
+ f"FROM x|> {op_operator} (SELECT y1 FROM y), (SELECT z1 FROM z)",
3623
+ write={
3624
+ "bigquery": f"SELECT * FROM x {op_operator} (SELECT y1 FROM y) {op_operator} (SELECT z1 FROM z)",
3625
+ },
3626
+ )
3627
+
3628
+ for op_prefix in ("LEFT OUTER", "FULL OUTER"):
3629
+ for op_operator in (
3630
+ "UNION ALL",
3631
+ "UNION DISTINCT",
3632
+ "INTERSECT DISTINCT",
3633
+ "EXCEPT DISTINCT",
3634
+ ):
3635
+ for suffix_operator in ("BY NAME", "CORRESPONDING"):
3636
+ with self.subTest(
3637
+ f"Testing pipe syntax SET OPERATORS: {op_prefix} {op_operator} {suffix_operator}"
3638
+ ):
3639
+ self.validate_all(
3640
+ f"FROM x|> SELECT x1, x2 FROM x |> {op_prefix} {op_operator} {suffix_operator} (SELECT y1, y2 FROM y), (SELECT z1, z2 FROM z)",
3641
+ write={
3642
+ "bigquery": f"SELECT x1, x2 FROM (SELECT * FROM x) {op_prefix} {op_operator} BY NAME (SELECT y1, y2 FROM y) {op_prefix} {op_operator} BY NAME (SELECT z1, z2 FROM z)",
3643
+ },
3644
+ )