sqlglot 27.10.0__tar.gz → 27.11.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 (226) hide show
  1. {sqlglot-27.10.0 → sqlglot-27.11.0}/CHANGELOG.md +39 -0
  2. {sqlglot-27.10.0 → sqlglot-27.11.0}/PKG-INFO +2 -2
  3. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/_version.py +3 -3
  4. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/bigquery.py +83 -3
  5. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/dremio.py +29 -4
  6. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/singlestore.py +155 -1
  7. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/snowflake.py +1 -0
  8. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/spark2.py +2 -0
  9. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/sqlite.py +1 -0
  10. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/expressions.py +98 -0
  11. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/generator.py +12 -2
  12. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/tokens.py +1 -1
  13. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.egg-info/PKG-INFO +2 -2
  14. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.egg-info/requires.txt +1 -1
  15. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/Cargo.lock +1 -1
  16. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/Cargo.toml +1 -1
  17. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/src/tokenizer.rs +1 -1
  18. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_bigquery.py +55 -0
  19. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_databricks.py +1 -0
  20. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_dialect.py +173 -0
  21. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_dremio.py +27 -0
  22. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_duckdb.py +12 -0
  23. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_oracle.py +10 -0
  24. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_singlestore.py +246 -0
  25. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_snowflake.py +1 -0
  26. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_spark.py +10 -0
  27. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/identity.sql +5 -0
  28. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/annotate_functions.sql +284 -0
  29. {sqlglot-27.10.0 → sqlglot-27.11.0}/.gitignore +0 -0
  30. {sqlglot-27.10.0 → sqlglot-27.11.0}/.gitpod.yml +0 -0
  31. {sqlglot-27.10.0 → sqlglot-27.11.0}/.pre-commit-config.yaml +0 -0
  32. {sqlglot-27.10.0 → sqlglot-27.11.0}/CONTRIBUTING.md +0 -0
  33. {sqlglot-27.10.0 → sqlglot-27.11.0}/LICENSE +0 -0
  34. {sqlglot-27.10.0 → sqlglot-27.11.0}/MANIFEST.in +0 -0
  35. {sqlglot-27.10.0 → sqlglot-27.11.0}/Makefile +0 -0
  36. {sqlglot-27.10.0 → sqlglot-27.11.0}/README.md +0 -0
  37. {sqlglot-27.10.0 → sqlglot-27.11.0}/pyproject.toml +0 -0
  38. {sqlglot-27.10.0 → sqlglot-27.11.0}/setup.cfg +0 -0
  39. {sqlglot-27.10.0 → sqlglot-27.11.0}/setup.py +0 -0
  40. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/__init__.py +0 -0
  41. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/__main__.py +0 -0
  42. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/_typing.py +0 -0
  43. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/__init__.py +0 -0
  44. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/athena.py +0 -0
  45. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/clickhouse.py +0 -0
  46. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/databricks.py +0 -0
  47. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/dialect.py +0 -0
  48. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/doris.py +0 -0
  49. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/drill.py +0 -0
  50. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/druid.py +0 -0
  51. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/duckdb.py +0 -0
  52. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/dune.py +0 -0
  53. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/exasol.py +0 -0
  54. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/fabric.py +0 -0
  55. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/hive.py +0 -0
  56. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/materialize.py +0 -0
  57. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/mysql.py +0 -0
  58. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/oracle.py +0 -0
  59. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/postgres.py +0 -0
  60. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/presto.py +0 -0
  61. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/prql.py +0 -0
  62. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/redshift.py +0 -0
  63. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/risingwave.py +0 -0
  64. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/spark.py +0 -0
  65. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/starrocks.py +0 -0
  66. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/tableau.py +0 -0
  67. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/teradata.py +0 -0
  68. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/trino.py +0 -0
  69. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/dialects/tsql.py +0 -0
  70. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/diff.py +0 -0
  71. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/errors.py +0 -0
  72. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/executor/__init__.py +0 -0
  73. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/executor/context.py +0 -0
  74. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/executor/env.py +0 -0
  75. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/executor/python.py +0 -0
  76. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/executor/table.py +0 -0
  77. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/helper.py +0 -0
  78. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/jsonpath.py +0 -0
  79. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/lineage.py +0 -0
  80. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/__init__.py +0 -0
  81. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/annotate_types.py +0 -0
  82. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/canonicalize.py +0 -0
  83. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  84. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
  85. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  86. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  87. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
  88. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/normalize.py +0 -0
  89. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  90. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/optimize_joins.py +0 -0
  91. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/optimizer.py +0 -0
  92. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
  93. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
  94. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/qualify.py +0 -0
  95. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/qualify_columns.py +0 -0
  96. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/qualify_tables.py +0 -0
  97. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/scope.py +0 -0
  98. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/simplify.py +0 -0
  99. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  100. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/parser.py +0 -0
  101. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/planner.py +0 -0
  102. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/py.typed +0 -0
  103. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/schema.py +0 -0
  104. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/serde.py +0 -0
  105. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/time.py +0 -0
  106. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/transforms.py +0 -0
  107. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot/trie.py +0 -0
  108. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.egg-info/SOURCES.txt +0 -0
  109. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.egg-info/dependency_links.txt +0 -0
  110. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.egg-info/top_level.txt +0 -0
  111. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglot.png +0 -0
  112. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/benches/dialect_settings.json +0 -0
  113. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/benches/long.rs +0 -0
  114. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/benches/token_type_settings.json +0 -0
  115. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
  116. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
  117. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/pyproject.toml +0 -0
  118. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/src/lib.rs +0 -0
  119. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/src/settings.rs +0 -0
  120. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/src/token.rs +0 -0
  121. {sqlglot-27.10.0 → sqlglot-27.11.0}/sqlglotrs/src/trie.rs +0 -0
  122. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/__init__.py +0 -0
  123. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/__init__.py +0 -0
  124. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_athena.py +0 -0
  125. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_clickhouse.py +0 -0
  126. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_doris.py +0 -0
  127. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_drill.py +0 -0
  128. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_druid.py +0 -0
  129. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_dune.py +0 -0
  130. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_exasol.py +0 -0
  131. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_fabric.py +0 -0
  132. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_hive.py +0 -0
  133. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_materialize.py +0 -0
  134. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_mysql.py +0 -0
  135. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_pipe_syntax.py +0 -0
  136. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_postgres.py +0 -0
  137. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_presto.py +0 -0
  138. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_prql.py +0 -0
  139. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_redshift.py +0 -0
  140. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_risingwave.py +0 -0
  141. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_sqlite.py +0 -0
  142. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_starrocks.py +0 -0
  143. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_tableau.py +0 -0
  144. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_teradata.py +0 -0
  145. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_trino.py +0 -0
  146. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/dialects/test_tsql.py +0 -0
  147. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/jsonpath/LICENSE +0 -0
  148. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/jsonpath/cts.json +0 -0
  149. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/annotate_types.sql +0 -0
  150. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  151. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  152. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  153. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  154. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  155. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  156. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/normalize.sql +0 -0
  157. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  158. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  159. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
  160. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  161. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  162. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
  163. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
  164. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
  165. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  166. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
  167. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
  168. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  169. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/simplify.sql +0 -0
  170. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  171. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  172. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  173. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  174. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  175. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  176. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  177. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  178. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  179. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  180. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  181. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  182. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  183. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  184. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  185. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  186. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  187. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  188. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  189. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  190. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  191. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  192. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  193. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  194. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  195. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  196. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  197. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  198. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  199. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  200. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  201. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  202. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  203. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  204. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  205. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/partial.sql +0 -0
  206. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/fixtures/pretty.sql +0 -0
  207. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/gen_fixtures.py +0 -0
  208. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/helpers.py +0 -0
  209. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_build.py +0 -0
  210. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_dialect_imports.py +0 -0
  211. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_diff.py +0 -0
  212. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_docs.py +0 -0
  213. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_executor.py +0 -0
  214. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_expressions.py +0 -0
  215. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_generator.py +0 -0
  216. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_helper.py +0 -0
  217. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_jsonpath.py +0 -0
  218. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_lineage.py +0 -0
  219. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_optimizer.py +0 -0
  220. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_parser.py +0 -0
  221. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_schema.py +0 -0
  222. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_serde.py +0 -0
  223. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_time.py +0 -0
  224. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_tokens.py +0 -0
  225. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_transforms.py +0 -0
  226. {sqlglot-27.10.0 → sqlglot-27.11.0}/tests/test_transpile.py +0 -0
@@ -1,6 +1,44 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v27.10.0] - 2025-08-28
5
+ ### :boom: BREAKING CHANGES
6
+ - due to [`de2fe15`](https://github.com/tobymao/sqlglot/commit/de2fe1503b5bb003431d1f0c7b9ae87932a6cc1c) - annotate type for bq CONTAINS_SUBSTR *(PR [#5705](https://github.com/tobymao/sqlglot/pull/5705) by [@geooo109](https://github.com/geooo109))*:
7
+
8
+ annotate type for bq CONTAINS_SUBSTR (#5705)
9
+
10
+ - due to [`770888f`](https://github.com/tobymao/sqlglot/commit/770888f4e9a9061329e3c416f968f7dd9639fb81) - annotate type for bq NORMALIZE *(PR [#5711](https://github.com/tobymao/sqlglot/pull/5711) by [@geooo109](https://github.com/geooo109))*:
11
+
12
+ annotate type for bq NORMALIZE (#5711)
13
+
14
+ - due to [`506033f`](https://github.com/tobymao/sqlglot/commit/506033f299f7a4c28f6efd8bf715be5dcf73e929) - parse and annotate type for bq NORMALIZE_AND_CASEFOLD *(PR [#5712](https://github.com/tobymao/sqlglot/pull/5712) by [@geooo109](https://github.com/geooo109))*:
15
+
16
+ parse and annotate type for bq NORMALIZE_AND_CASEFOLD (#5712)
17
+
18
+ - due to [`848aea1`](https://github.com/tobymao/sqlglot/commit/848aea1dbaaeb580b633796dcca06c28314b9c3e) - parse and annotate type for bq OCTET_LENGTH *(PR [#5713](https://github.com/tobymao/sqlglot/pull/5713) by [@geooo109](https://github.com/geooo109))*:
19
+
20
+ parse and annotate type for bq OCTET_LENGTH (#5713)
21
+
22
+ - due to [`727bf83`](https://github.com/tobymao/sqlglot/commit/727bf8378f232188d35834d980b035552999ea3b) - add support for REVOKE DDL *(PR [#5703](https://github.com/tobymao/sqlglot/pull/5703) by [@newtonapple](https://github.com/newtonapple))*:
23
+
24
+ add support for REVOKE DDL (#5703)
25
+
26
+
27
+ ### :sparkles: New Features
28
+ - [`f6f8f56`](https://github.com/tobymao/sqlglot/commit/f6f8f56a59d550dfc7dfcab0c3b9a6885c7e758a) - **singlestore**: Fixed parsing/generation of exp.JSONFormat *(PR [#5706](https://github.com/tobymao/sqlglot/pull/5706) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
29
+ - [`de2fe15`](https://github.com/tobymao/sqlglot/commit/de2fe1503b5bb003431d1f0c7b9ae87932a6cc1c) - **optimizer**: annotate type for bq CONTAINS_SUBSTR *(PR [#5705](https://github.com/tobymao/sqlglot/pull/5705) by [@geooo109](https://github.com/geooo109))*
30
+ - [`a78146e`](https://github.com/tobymao/sqlglot/commit/a78146e37bfc972050b4467c39769407061e9bc3) - **singlestore**: Fixed parsing/generation of exp.DateBin *(PR [#5709](https://github.com/tobymao/sqlglot/pull/5709) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
31
+ - [`ab0c985`](https://github.com/tobymao/sqlglot/commit/ab0c985424ae9d9340eafd15ecdc9b31bdd8837c) - **singlestore**: Marked exp.Reduce finish argument as unsupported *(PR [#5707](https://github.com/tobymao/sqlglot/pull/5707) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
32
+ - [`770888f`](https://github.com/tobymao/sqlglot/commit/770888f4e9a9061329e3c416f968f7dd9639fb81) - **optimizer**: annotate type for bq NORMALIZE *(PR [#5711](https://github.com/tobymao/sqlglot/pull/5711) by [@geooo109](https://github.com/geooo109))*
33
+ - [`506033f`](https://github.com/tobymao/sqlglot/commit/506033f299f7a4c28f6efd8bf715be5dcf73e929) - **optimizer**: parse and annotate type for bq NORMALIZE_AND_CASEFOLD *(PR [#5712](https://github.com/tobymao/sqlglot/pull/5712) by [@geooo109](https://github.com/geooo109))*
34
+ - [`848aea1`](https://github.com/tobymao/sqlglot/commit/848aea1dbaaeb580b633796dcca06c28314b9c3e) - **optimizer**: parse and annotate type for bq OCTET_LENGTH *(PR [#5713](https://github.com/tobymao/sqlglot/pull/5713) by [@geooo109](https://github.com/geooo109))*
35
+ - [`727bf83`](https://github.com/tobymao/sqlglot/commit/727bf8378f232188d35834d980b035552999ea3b) - add support for REVOKE DDL *(PR [#5703](https://github.com/tobymao/sqlglot/pull/5703) by [@newtonapple](https://github.com/newtonapple))*
36
+
37
+ ### :bug: Bug Fixes
38
+ - [`0427c7b`](https://github.com/tobymao/sqlglot/commit/0427c7b7aa9f8161324085a98c5f531fa35c8b0c) - **optimizer**: qualify columns for AggFunc with DISTINCT *(PR [#5708](https://github.com/tobymao/sqlglot/pull/5708) by [@geooo109](https://github.com/geooo109))*
39
+ - :arrow_lower_right: *fixes issue [#5698](https://github.com/tobymao/sqlglot/issues/5698) opened by [@georgesittas](https://github.com/georgesittas)*
40
+
41
+
4
42
  ## [v27.9.0] - 2025-08-27
5
43
  ### :boom: BREAKING CHANGES
6
44
  - due to [`7b180bd`](https://github.com/tobymao/sqlglot/commit/7b180bdc3da9e39946c22970bd2523f7d8beaf29) - raise if query modifier is specified multiple times *(PR [#5608](https://github.com/tobymao/sqlglot/pull/5608) by [@georgesittas](https://github.com/georgesittas))*:
@@ -6774,3 +6812,4 @@ Changelog
6774
6812
  [v27.7.0]: https://github.com/tobymao/sqlglot/compare/v27.6.0...v27.7.0
6775
6813
  [v27.8.0]: https://github.com/tobymao/sqlglot/compare/v27.7.0...v27.8.0
6776
6814
  [v27.9.0]: https://github.com/tobymao/sqlglot/compare/v27.8.0...v27.9.0
6815
+ [v27.10.0]: https://github.com/tobymao/sqlglot/compare/v27.9.0...v27.10.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 27.10.0
3
+ Version: 27.11.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
@@ -33,7 +33,7 @@ Requires-Dist: typing_extensions; extra == "dev"
33
33
  Requires-Dist: maturin<2.0,>=1.4; extra == "dev"
34
34
  Requires-Dist: pyperf; extra == "dev"
35
35
  Provides-Extra: rs
36
- Requires-Dist: sqlglotrs==0.6.1; extra == "rs"
36
+ Requires-Dist: sqlglotrs==0.6.2; extra == "rs"
37
37
  Dynamic: license-file
38
38
  Dynamic: provides-extra
39
39
 
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '27.10.0'
32
- __version_tuple__ = version_tuple = (27, 10, 0)
31
+ __version__ = version = '27.11.0'
32
+ __version_tuple__ = version_tuple = (27, 11, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g727bf8378'
34
+ __commit_id__ = commit_id = 'g41521e31b'
@@ -4,6 +4,9 @@ import logging
4
4
  import re
5
5
  import typing as t
6
6
 
7
+
8
+ from sqlglot.optimizer.annotate_types import TypeAnnotator
9
+
7
10
  from sqlglot import exp, generator, jsonpath, parser, tokens, transforms
8
11
  from sqlglot._typing import E
9
12
  from sqlglot.dialects.dialect import (
@@ -172,6 +175,18 @@ def _build_to_hex(args: t.List) -> exp.Hex | exp.MD5:
172
175
  return exp.MD5(this=arg.this) if isinstance(arg, exp.MD5Digest) else exp.LowerHex(this=arg)
173
176
 
174
177
 
178
+ def _build_json_strip_nulls(args: t.List) -> exp.JSONStripNulls:
179
+ expression = exp.JSONStripNulls(this=seq_get(args, 0))
180
+
181
+ for arg in args[1:]:
182
+ if isinstance(arg, exp.Kwarg):
183
+ expression.set(arg.this.name.lower(), arg)
184
+ else:
185
+ expression.set("expression", arg)
186
+
187
+ return expression
188
+
189
+
175
190
  def _array_contains_sql(self: BigQuery.Generator, expression: exp.ArrayContains) -> str:
176
191
  return self.sql(
177
192
  exp.Exists(
@@ -295,6 +310,24 @@ def _annotate_math_functions(self: TypeAnnotator, expression: E) -> E:
295
310
  return expression
296
311
 
297
312
 
313
+ def _annotate_perncentile_cont(
314
+ self: TypeAnnotator, expression: exp.PercentileCont
315
+ ) -> exp.PercentileCont:
316
+ """
317
+ +------------+-----------+------------+---------+
318
+ | INPUT | NUMERIC | BIGNUMERIC | FLOAT64 |
319
+ +------------+-----------+------------+---------+
320
+ | NUMERIC | NUMERIC | BIGNUMERIC | FLOAT64 |
321
+ | BIGNUMERIC | BIGNUMERIC| BIGNUMERIC | FLOAT64 |
322
+ | FLOAT64 | FLOAT64 | FLOAT64 | FLOAT64 |
323
+ +------------+-----------+------------+---------+
324
+ """
325
+ self._annotate_args(expression)
326
+
327
+ self._set_type(expression, self._maybe_coerce(expression.this.type, expression.expression.type))
328
+ return expression
329
+
330
+
298
331
  def _annotate_by_args_approx_top(self: TypeAnnotator, expression: exp.ApproxTopK) -> exp.ApproxTopK:
299
332
  self._annotate_args(expression)
300
333
 
@@ -453,6 +486,13 @@ class BigQuery(Dialect):
453
486
  # All set operations require either a DISTINCT or ALL specifier
454
487
  SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None)
455
488
 
489
+ # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont
490
+ COERCES_TO = {
491
+ **TypeAnnotator.COERCES_TO,
492
+ exp.DataType.Type.BIGDECIMAL: {exp.DataType.Type.DOUBLE},
493
+ }
494
+ COERCES_TO[exp.DataType.Type.DECIMAL] |= {exp.DataType.Type.BIGDECIMAL}
495
+
456
496
  # BigQuery maps Type.TIMESTAMP to DATETIME, so we need to amend the inferred types
457
497
  TYPE_TO_EXPRESSIONS = {
458
498
  **Dialect.TYPE_TO_EXPRESSIONS,
@@ -511,37 +551,68 @@ class BigQuery(Dialect):
511
551
  exp.Corr: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
512
552
  exp.CovarPop: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
513
553
  exp.CovarSamp: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
554
+ exp.CumeDist: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
514
555
  exp.DateFromUnixDate: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DATE),
515
556
  exp.DateTrunc: lambda self, e: self._annotate_by_args(e, "this"),
557
+ exp.DenseRank: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
516
558
  exp.FarmFingerprint: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
559
+ exp.FirstValue: lambda self, e: self._annotate_by_args(e, "this"),
517
560
  exp.Unhex: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BINARY),
518
561
  exp.Float64: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
562
+ exp.Format: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
519
563
  exp.GenerateTimestampArray: lambda self, e: self._annotate_with_type(
520
564
  e, exp.DataType.build("ARRAY<TIMESTAMP>", dialect="bigquery")
521
565
  ),
522
566
  exp.Grouping: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
567
+ exp.IgnoreNulls: lambda self, e: self._annotate_by_args(e, "this"),
523
568
  exp.JSONArray: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
569
+ exp.JSONArrayAppend: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
570
+ exp.JSONArrayInsert: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
524
571
  exp.JSONBool: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BOOLEAN),
525
572
  exp.JSONExtractScalar: lambda self, e: self._annotate_with_type(
526
573
  e, exp.DataType.Type.VARCHAR
527
574
  ),
528
- exp.JSONValueArray: lambda self, e: self._annotate_with_type(
529
- e, exp.DataType.build("ARRAY<VARCHAR>")
575
+ exp.JSONExtract: lambda self, e: self._annotate_by_args(e, "this"),
576
+ exp.JSONExtractArray: lambda self, e: self._annotate_by_args(e, "this", array=True),
577
+ exp.JSONFormat: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
578
+ exp.JSONKeysAtDepth: lambda self, e: self._annotate_with_type(
579
+ e, exp.DataType.build("ARRAY<VARCHAR>", dialect="bigquery")
530
580
  ),
581
+ exp.JSONObject: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
582
+ exp.JSONRemove: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
583
+ exp.JSONSet: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
584
+ exp.JSONStripNulls: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.JSON),
531
585
  exp.JSONType: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
586
+ exp.JSONValueArray: lambda self, e: self._annotate_with_type(
587
+ e, exp.DataType.build("ARRAY<VARCHAR>", dialect="bigquery")
588
+ ),
532
589
  exp.Lag: lambda self, e: self._annotate_by_args(e, "this", "default"),
590
+ exp.Lead: lambda self, e: self._annotate_by_args(e, "this"),
533
591
  exp.LowerHex: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
592
+ exp.LaxBool: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BOOLEAN),
593
+ exp.LaxFloat64: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
594
+ exp.LaxInt64: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
595
+ exp.LaxString: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
534
596
  exp.MD5Digest: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BINARY),
535
597
  exp.Normalize: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.VARCHAR),
598
+ exp.NthValue: lambda self, e: self._annotate_by_args(e, "this"),
599
+ exp.Ntile: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
536
600
  exp.ParseTime: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.TIME),
537
601
  exp.ParseDatetime: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DATETIME),
538
602
  exp.ParseBignumeric: lambda self, e: self._annotate_with_type(
539
603
  e, exp.DataType.Type.BIGDECIMAL
540
604
  ),
541
605
  exp.ParseNumeric: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DECIMAL),
606
+ exp.PercentileCont: lambda self, e: _annotate_perncentile_cont(self, e),
607
+ exp.PercentileDisc: lambda self, e: self._annotate_by_args(e, "this"),
608
+ exp.PercentRank: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.DOUBLE),
609
+ exp.Rank: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
542
610
  exp.RegexpExtractAll: lambda self, e: self._annotate_by_args(e, "this", array=True),
611
+ exp.RegexpInstr: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
543
612
  exp.Replace: lambda self, e: self._annotate_by_args(e, "this"),
613
+ exp.RespectNulls: lambda self, e: self._annotate_by_args(e, "this"),
544
614
  exp.Reverse: lambda self, e: self._annotate_by_args(e, "this"),
615
+ exp.RowNumber: lambda self, e: self._annotate_with_type(e, exp.DataType.Type.BIGINT),
545
616
  exp.SafeConvertBytesToString: lambda self, e: self._annotate_with_type(
546
617
  e, exp.DataType.Type.VARCHAR
547
618
  ),
@@ -682,8 +753,11 @@ class BigQuery(Dialect):
682
753
  "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list,
683
754
  "JSON_EXTRACT_SCALAR": _build_extract_json_with_default_path(exp.JSONExtractScalar),
684
755
  "JSON_EXTRACT_ARRAY": _build_extract_json_with_default_path(exp.JSONExtractArray),
756
+ "JSON_EXTRACT_STRING_ARRAY": _build_extract_json_with_default_path(exp.JSONValueArray),
757
+ "JSON_KEYS": exp.JSONKeysAtDepth.from_arg_list,
685
758
  "JSON_QUERY": parser.build_extract_json_with_path(exp.JSONExtract),
686
759
  "JSON_QUERY_ARRAY": _build_extract_json_with_default_path(exp.JSONExtractArray),
760
+ "JSON_STRIP_NULLS": _build_json_strip_nulls,
687
761
  "JSON_VALUE": _build_extract_json_with_default_path(exp.JSONExtractScalar),
688
762
  "JSON_VALUE_ARRAY": _build_extract_json_with_default_path(exp.JSONValueArray),
689
763
  "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
@@ -798,9 +872,13 @@ class BigQuery(Dialect):
798
872
  "SAFE_ORDINAL": (1, True),
799
873
  }
800
874
 
801
- def _parse_for_in(self) -> exp.ForIn:
875
+ def _parse_for_in(self) -> t.Union[exp.ForIn, exp.Command]:
876
+ index = self._index
802
877
  this = self._parse_range()
803
878
  self._match_text_seq("DO")
879
+ if self._match(TokenType.COMMAND):
880
+ self._retreat(index)
881
+ return self._parse_as_command(self._prev)
804
882
  return self.expression(exp.ForIn, this=this, expression=self._parse_statement())
805
883
 
806
884
  def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
@@ -1197,6 +1275,8 @@ class BigQuery(Dialect):
1197
1275
  exp.JSONExtractArray: _json_extract_sql,
1198
1276
  exp.JSONExtractScalar: _json_extract_sql,
1199
1277
  exp.JSONFormat: rename_func("TO_JSON_STRING"),
1278
+ exp.JSONKeysAtDepth: rename_func("JSON_KEYS"),
1279
+ exp.JSONValueArray: rename_func("JSON_VALUE_ARRAY"),
1200
1280
  exp.Levenshtein: _levenshtein_sql,
1201
1281
  exp.Max: max_or_greatest,
1202
1282
  exp.MD5: lambda self, e: self.func("TO_HEX", self.func("MD5", e.this)),
@@ -74,6 +74,27 @@ def build_date_delta_with_cast_interval(
74
74
  return _builder
75
75
 
76
76
 
77
+ def datetype_handler(args: t.List[exp.Expression], dialect: DialectType) -> exp.Expression:
78
+ year, month, day = args
79
+
80
+ if all(isinstance(arg, exp.Literal) and arg.is_int for arg in (year, month, day)):
81
+ date_str = f"{int(year.this):04d}-{int(month.this):02d}-{int(day.this):02d}"
82
+ return exp.Date(this=exp.Literal.string(date_str))
83
+
84
+ return exp.Cast(
85
+ this=exp.Concat(
86
+ expressions=[
87
+ year,
88
+ exp.Literal.string("-"),
89
+ month,
90
+ exp.Literal.string("-"),
91
+ day,
92
+ ]
93
+ ),
94
+ to=exp.DataType.build("DATE"),
95
+ )
96
+
97
+
77
98
  class Dremio(Dialect):
78
99
  SUPPORTS_USER_DEFINED_TYPES = False
79
100
  CONCAT_COALESCE = True
@@ -145,12 +166,16 @@ class Dremio(Dialect):
145
166
 
146
167
  FUNCTIONS = {
147
168
  **parser.Parser.FUNCTIONS,
148
- "TO_CHAR": to_char_is_numeric_handler,
149
- "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "dremio"),
150
- "TO_DATE": build_formatted_time(exp.TsOrDsToDate, "dremio"),
169
+ "ARRAY_GENERATE_RANGE": exp.GenerateSeries.from_arg_list,
151
170
  "DATE_ADD": build_date_delta_with_cast_interval(exp.DateAdd),
171
+ "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "dremio"),
152
172
  "DATE_SUB": build_date_delta_with_cast_interval(exp.DateSub),
153
- "ARRAY_GENERATE_RANGE": exp.GenerateSeries.from_arg_list,
173
+ "REGEXP_MATCHES": exp.RegexpLike.from_arg_list,
174
+ "REPEATSTR": exp.Repeat.from_arg_list,
175
+ "TO_CHAR": to_char_is_numeric_handler,
176
+ "TO_DATE": build_formatted_time(exp.TsOrDsToDate, "dremio"),
177
+ "DATE_PART": exp.Extract.from_arg_list,
178
+ "DATETYPE": datetype_handler,
154
179
  }
155
180
 
156
181
  def _parse_current_date_utc(self) -> exp.Cast:
@@ -10,8 +10,11 @@ from sqlglot.dialects.dialect import (
10
10
  rename_func,
11
11
  bool_xor_sql,
12
12
  count_if_to_sum,
13
+ timestamptrunc_sql,
14
+ date_add_interval_sql,
15
+ timestampdiff_sql,
13
16
  )
14
- from sqlglot.dialects.mysql import MySQL
17
+ from sqlglot.dialects.mysql import MySQL, _remove_ts_or_ds_to_date, date_add_sql
15
18
  from sqlglot.expressions import DataType
16
19
  from sqlglot.generator import unsupported_args
17
20
  from sqlglot.helper import seq_get
@@ -55,6 +58,7 @@ class SingleStore(MySQL):
55
58
  **MySQL.Tokenizer.KEYWORDS,
56
59
  "BSON": TokenType.JSONB,
57
60
  "GEOGRAPHYPOINT": TokenType.GEOGRAPHYPOINT,
61
+ "TIMESTAMP": TokenType.TIMESTAMP,
58
62
  ":>": TokenType.COLON_GT,
59
63
  "!:>": TokenType.NCOLON_GT,
60
64
  "::$": TokenType.DCOLONDOLLAR,
@@ -159,6 +163,11 @@ class SingleStore(MySQL):
159
163
  this=seq_get(args, 0),
160
164
  format=MySQL.format_time(exp.Literal.string("%W")),
161
165
  ),
166
+ "TIMESTAMPDIFF": lambda args: exp.TimestampDiff(
167
+ this=seq_get(args, 2),
168
+ expression=seq_get(args, 1),
169
+ unit=seq_get(args, 0),
170
+ ),
162
171
  "APPROX_COUNT_DISTINCT": exp.Hll.from_arg_list,
163
172
  "APPROX_PERCENTILE": lambda args, dialect: exp.ApproxQuantile(
164
173
  this=seq_get(args, 0),
@@ -189,6 +198,7 @@ class SingleStore(MySQL):
189
198
  CAST_COLUMN_OPERATORS = {TokenType.COLON_GT, TokenType.NCOLON_GT}
190
199
 
191
200
  COLUMN_OPERATORS = {
201
+ **MySQL.Parser.COLUMN_OPERATORS,
192
202
  TokenType.COLON_GT: lambda self, this, to: self.expression(
193
203
  exp.Cast,
194
204
  this=this,
@@ -209,6 +219,11 @@ class SingleStore(MySQL):
209
219
  exp.JSONExtractScalar, json_type="DOUBLE"
210
220
  )([this, exp.Literal.string(path.name)]),
211
221
  }
222
+ COLUMN_OPERATORS.pop(TokenType.ARROW)
223
+ COLUMN_OPERATORS.pop(TokenType.DARROW)
224
+ COLUMN_OPERATORS.pop(TokenType.HASH_ARROW)
225
+ COLUMN_OPERATORS.pop(TokenType.DHASH_ARROW)
226
+ COLUMN_OPERATORS.pop(TokenType.PLACEHOLDER)
212
227
 
213
228
  class Generator(MySQL.Generator):
214
229
  SUPPORTED_JSON_PATH_PARTS = {
@@ -277,6 +292,28 @@ class SingleStore(MySQL):
277
292
  exp.DateBin: unsupported_args("unit", "zone")(
278
293
  lambda self, e: self.func("TIME_BUCKET", e.this, e.expression, e.args.get("origin"))
279
294
  ),
295
+ exp.TimeStrToDate: lambda self, e: self.sql(exp.cast(e.this, exp.DataType.Type.DATE)),
296
+ exp.FromTimeZone: lambda self, e: self.func(
297
+ "CONVERT_TZ", e.this, e.args.get("zone"), "'UTC'"
298
+ ),
299
+ exp.DiToDate: lambda self,
300
+ e: f"STR_TO_DATE({self.sql(e, 'this')}, {SingleStore.DATEINT_FORMAT})",
301
+ exp.DateToDi: lambda self,
302
+ e: f"(DATE_FORMAT({self.sql(e, 'this')}, {SingleStore.DATEINT_FORMAT}) :> INT)",
303
+ exp.TsOrDiToDi: lambda self,
304
+ e: f"(DATE_FORMAT({self.sql(e, 'this')}, {SingleStore.DATEINT_FORMAT}) :> INT)",
305
+ exp.Time: unsupported_args("zone")(lambda self, e: f"{self.sql(e, 'this')} :> TIME"),
306
+ exp.DatetimeAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
307
+ exp.DatetimeTrunc: unsupported_args("zone")(timestamptrunc_sql()),
308
+ exp.DatetimeSub: date_add_interval_sql("DATE", "SUB"),
309
+ exp.DatetimeDiff: timestampdiff_sql,
310
+ exp.DateTrunc: unsupported_args("zone")(timestamptrunc_sql()),
311
+ exp.DateDiff: unsupported_args("zone")(
312
+ lambda self, e: timestampdiff_sql(self, e)
313
+ if e.unit is not None
314
+ else self.func("DATEDIFF", e.this, e.expression)
315
+ ),
316
+ exp.TimestampTrunc: unsupported_args("zone")(timestamptrunc_sql()),
280
317
  exp.JSONExtract: unsupported_args(
281
318
  "only_json_types",
282
319
  "expressions",
@@ -353,6 +390,94 @@ class SingleStore(MySQL):
353
390
  }
354
391
  TRANSFORMS.pop(exp.JSONExtractScalar)
355
392
 
393
+ UNSUPPORTED_TYPES = {
394
+ exp.DataType.Type.ARRAY,
395
+ exp.DataType.Type.AGGREGATEFUNCTION,
396
+ exp.DataType.Type.SIMPLEAGGREGATEFUNCTION,
397
+ exp.DataType.Type.BIGSERIAL,
398
+ exp.DataType.Type.BPCHAR,
399
+ exp.DataType.Type.DATEMULTIRANGE,
400
+ exp.DataType.Type.DATERANGE,
401
+ exp.DataType.Type.DYNAMIC,
402
+ exp.DataType.Type.HLLSKETCH,
403
+ exp.DataType.Type.HSTORE,
404
+ exp.DataType.Type.IMAGE,
405
+ exp.DataType.Type.INET,
406
+ exp.DataType.Type.INT128,
407
+ exp.DataType.Type.INT256,
408
+ exp.DataType.Type.INT4MULTIRANGE,
409
+ exp.DataType.Type.INT4RANGE,
410
+ exp.DataType.Type.INT8MULTIRANGE,
411
+ exp.DataType.Type.INT8RANGE,
412
+ exp.DataType.Type.INTERVAL,
413
+ exp.DataType.Type.IPADDRESS,
414
+ exp.DataType.Type.IPPREFIX,
415
+ exp.DataType.Type.IPV4,
416
+ exp.DataType.Type.IPV6,
417
+ exp.DataType.Type.LIST,
418
+ exp.DataType.Type.MAP,
419
+ exp.DataType.Type.LOWCARDINALITY,
420
+ exp.DataType.Type.MONEY,
421
+ exp.DataType.Type.MULTILINESTRING,
422
+ exp.DataType.Type.NAME,
423
+ exp.DataType.Type.NESTED,
424
+ exp.DataType.Type.NOTHING,
425
+ exp.DataType.Type.NULL,
426
+ exp.DataType.Type.NUMMULTIRANGE,
427
+ exp.DataType.Type.NUMRANGE,
428
+ exp.DataType.Type.OBJECT,
429
+ exp.DataType.Type.RANGE,
430
+ exp.DataType.Type.ROWVERSION,
431
+ exp.DataType.Type.SERIAL,
432
+ exp.DataType.Type.SMALLSERIAL,
433
+ exp.DataType.Type.SMALLMONEY,
434
+ exp.DataType.Type.STRUCT,
435
+ exp.DataType.Type.SUPER,
436
+ exp.DataType.Type.TIMETZ,
437
+ exp.DataType.Type.TIMESTAMPNTZ,
438
+ exp.DataType.Type.TIMESTAMPLTZ,
439
+ exp.DataType.Type.TIMESTAMPTZ,
440
+ exp.DataType.Type.TIMESTAMP_NS,
441
+ exp.DataType.Type.TSMULTIRANGE,
442
+ exp.DataType.Type.TSRANGE,
443
+ exp.DataType.Type.TSTZMULTIRANGE,
444
+ exp.DataType.Type.TSTZRANGE,
445
+ exp.DataType.Type.UINT128,
446
+ exp.DataType.Type.UINT256,
447
+ exp.DataType.Type.UNION,
448
+ exp.DataType.Type.UNKNOWN,
449
+ exp.DataType.Type.USERDEFINED,
450
+ exp.DataType.Type.UUID,
451
+ exp.DataType.Type.VARIANT,
452
+ exp.DataType.Type.XML,
453
+ exp.DataType.Type.TDIGEST,
454
+ }
455
+
456
+ TYPE_MAPPING = {
457
+ **MySQL.Generator.TYPE_MAPPING,
458
+ exp.DataType.Type.BIGDECIMAL: "DECIMAL",
459
+ exp.DataType.Type.BIT: "BOOLEAN",
460
+ exp.DataType.Type.DATE32: "DATE",
461
+ exp.DataType.Type.DATETIME64: "DATETIME",
462
+ exp.DataType.Type.DECIMAL32: "DECIMAL",
463
+ exp.DataType.Type.DECIMAL64: "DECIMAL",
464
+ exp.DataType.Type.DECIMAL128: "DECIMAL",
465
+ exp.DataType.Type.DECIMAL256: "DECIMAL",
466
+ exp.DataType.Type.ENUM8: "ENUM",
467
+ exp.DataType.Type.ENUM16: "ENUM",
468
+ exp.DataType.Type.FIXEDSTRING: "TEXT",
469
+ exp.DataType.Type.GEOMETRY: "GEOGRAPHY",
470
+ exp.DataType.Type.POINT: "GEOGRAPHYPOINT",
471
+ exp.DataType.Type.RING: "GEOGRAPHY",
472
+ exp.DataType.Type.LINESTRING: "GEOGRAPHY",
473
+ exp.DataType.Type.POLYGON: "GEOGRAPHY",
474
+ exp.DataType.Type.MULTIPOLYGON: "GEOGRAPHY",
475
+ exp.DataType.Type.JSONB: "BSON",
476
+ exp.DataType.Type.TIMESTAMP: "TIMESTAMP",
477
+ exp.DataType.Type.TIMESTAMP_S: "TIMESTAMP",
478
+ exp.DataType.Type.TIMESTAMP_MS: "TIMESTAMP(6)",
479
+ }
480
+
356
481
  # https://docs.singlestore.com/cloud/reference/sql-reference/restricted-keywords/list-of-restricted-keywords/
357
482
  RESERVED_KEYWORDS = {
358
483
  "abs",
@@ -1452,3 +1577,32 @@ class SingleStore(MySQL):
1452
1577
  expression.expression,
1453
1578
  self.func("TO_JSON", expression.this),
1454
1579
  )
1580
+
1581
+ @unsupported_args("kind", "nested", "values")
1582
+ def datatype_sql(self, expression: exp.DataType) -> str:
1583
+ if expression.is_type(exp.DataType.Type.VARBINARY) and not expression.expressions:
1584
+ # `VARBINARY` must always have a size - if it doesn't, we always generate `BLOB`
1585
+ return "BLOB"
1586
+ if expression.is_type(
1587
+ exp.DataType.Type.DECIMAL32,
1588
+ exp.DataType.Type.DECIMAL64,
1589
+ exp.DataType.Type.DECIMAL128,
1590
+ exp.DataType.Type.DECIMAL256,
1591
+ ):
1592
+ scale = self.expressions(expression, flat=True)
1593
+
1594
+ if expression.is_type(exp.DataType.Type.DECIMAL32):
1595
+ precision = "9"
1596
+ elif expression.is_type(exp.DataType.Type.DECIMAL64):
1597
+ precision = "18"
1598
+ elif expression.is_type(exp.DataType.Type.DECIMAL128):
1599
+ precision = "38"
1600
+ else:
1601
+ # 65 is a maximum precision supported in SingleStore
1602
+ precision = "65"
1603
+ if scale is not None:
1604
+ return f"DECIMAL({precision}, {scale[0]})"
1605
+ else:
1606
+ return f"DECIMAL({precision})"
1607
+
1608
+ return super().datatype_sql(expression)
@@ -552,6 +552,7 @@ class Snowflake(Dialect):
552
552
 
553
553
  ID_VAR_TOKENS = {
554
554
  *parser.Parser.ID_VAR_TOKENS,
555
+ TokenType.EXCEPT,
555
556
  TokenType.MATCH_CONDITION,
556
557
  }
557
558
 
@@ -187,6 +187,7 @@ class Spark2(Hive):
187
187
  "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
188
188
  "DOUBLE": _build_as_cast("double"),
189
189
  "FLOAT": _build_as_cast("float"),
190
+ "FORMAT_STRING": exp.Format.from_arg_list,
190
191
  "FROM_UTC_TIMESTAMP": lambda args, dialect: exp.AtTimeZone(
191
192
  this=exp.cast(
192
193
  seq_get(args, 0) or exp.Var(this=""),
@@ -292,6 +293,7 @@ class Spark2(Hive):
292
293
  # (DAY_OF_WEEK(datetime) % 7) + 1 is equivalent to DAYOFWEEK_ISO(datetime)
293
294
  exp.DayOfWeekIso: lambda self, e: f"(({self.func('DAYOFWEEK', e.this)} % 7) + 1)",
294
295
  exp.DayOfYear: rename_func("DAYOFYEAR"),
296
+ exp.Format: rename_func("FORMAT_STRING"),
295
297
  exp.From: transforms.preprocess([_unalias_pivot]),
296
298
  exp.FromTimeZone: lambda self, e: self.func(
297
299
  "TO_UTC_TIMESTAMP", e.this, e.args.get("zone")
@@ -156,6 +156,7 @@ class SQLite(Dialect):
156
156
  EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE = False
157
157
  SUPPORTS_MEDIAN = False
158
158
  JSON_KEY_VALUE_PAIR_SEP = ","
159
+ PARSE_JSON_NAME: t.Optional[str] = None
159
160
 
160
161
  SUPPORTED_JSON_PATH_PARTS = {
161
162
  exp.JSONPathKey,