sqlglot 27.15.0__tar.gz → 27.15.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. {sqlglot-27.15.0 → sqlglot-27.15.2}/CHANGELOG.md +72 -0
  2. {sqlglot-27.15.0 → sqlglot-27.15.2}/PKG-INFO +1 -1
  3. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/_version.py +3 -3
  4. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/duckdb.py +29 -0
  5. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/snowflake.py +20 -1
  6. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/expressions.py +11 -0
  7. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/generator.py +8 -0
  8. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/parser.py +17 -6
  9. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/tokens.py +2 -0
  10. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.egg-info/PKG-INFO +1 -1
  11. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_bigquery.py +9 -0
  12. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_duckdb.py +12 -0
  13. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_postgres.py +4 -0
  14. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_snowflake.py +15 -0
  15. {sqlglot-27.15.0 → sqlglot-27.15.2}/.gitignore +0 -0
  16. {sqlglot-27.15.0 → sqlglot-27.15.2}/.gitpod.yml +0 -0
  17. {sqlglot-27.15.0 → sqlglot-27.15.2}/.pre-commit-config.yaml +0 -0
  18. {sqlglot-27.15.0 → sqlglot-27.15.2}/CONTRIBUTING.md +0 -0
  19. {sqlglot-27.15.0 → sqlglot-27.15.2}/LICENSE +0 -0
  20. {sqlglot-27.15.0 → sqlglot-27.15.2}/MANIFEST.in +0 -0
  21. {sqlglot-27.15.0 → sqlglot-27.15.2}/Makefile +0 -0
  22. {sqlglot-27.15.0 → sqlglot-27.15.2}/README.md +0 -0
  23. {sqlglot-27.15.0 → sqlglot-27.15.2}/pyproject.toml +0 -0
  24. {sqlglot-27.15.0 → sqlglot-27.15.2}/setup.cfg +0 -0
  25. {sqlglot-27.15.0 → sqlglot-27.15.2}/setup.py +0 -0
  26. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/__init__.py +0 -0
  27. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/__main__.py +0 -0
  28. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/_typing.py +0 -0
  29. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/__init__.py +0 -0
  30. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/athena.py +0 -0
  31. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/bigquery.py +0 -0
  32. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/clickhouse.py +0 -0
  33. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/databricks.py +0 -0
  34. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/dialect.py +0 -0
  35. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/doris.py +0 -0
  36. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/dremio.py +0 -0
  37. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/drill.py +0 -0
  38. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/druid.py +0 -0
  39. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/dune.py +0 -0
  40. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/exasol.py +0 -0
  41. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/fabric.py +0 -0
  42. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/hive.py +0 -0
  43. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/materialize.py +0 -0
  44. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/mysql.py +0 -0
  45. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/oracle.py +0 -0
  46. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/postgres.py +0 -0
  47. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/presto.py +0 -0
  48. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/prql.py +0 -0
  49. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/redshift.py +0 -0
  50. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/risingwave.py +0 -0
  51. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/singlestore.py +0 -0
  52. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/spark.py +0 -0
  53. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/spark2.py +0 -0
  54. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/sqlite.py +0 -0
  55. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/starrocks.py +0 -0
  56. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/tableau.py +0 -0
  57. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/teradata.py +0 -0
  58. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/trino.py +0 -0
  59. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/dialects/tsql.py +0 -0
  60. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/diff.py +0 -0
  61. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/errors.py +0 -0
  62. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/executor/__init__.py +0 -0
  63. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/executor/context.py +0 -0
  64. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/executor/env.py +0 -0
  65. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/executor/python.py +0 -0
  66. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/executor/table.py +0 -0
  67. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/helper.py +0 -0
  68. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/jsonpath.py +0 -0
  69. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/lineage.py +0 -0
  70. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/__init__.py +0 -0
  71. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/annotate_types.py +0 -0
  72. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/canonicalize.py +0 -0
  73. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  74. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/eliminate_joins.py +0 -0
  75. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  76. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  77. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/merge_subqueries.py +0 -0
  78. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/normalize.py +0 -0
  79. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  80. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/optimize_joins.py +0 -0
  81. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/optimizer.py +0 -0
  82. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/pushdown_predicates.py +0 -0
  83. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/pushdown_projections.py +0 -0
  84. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/qualify.py +0 -0
  85. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/qualify_columns.py +0 -0
  86. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/qualify_tables.py +0 -0
  87. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/scope.py +0 -0
  88. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/simplify.py +0 -0
  89. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  90. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/planner.py +0 -0
  91. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/py.typed +0 -0
  92. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/schema.py +0 -0
  93. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/serde.py +0 -0
  94. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/time.py +0 -0
  95. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/transforms.py +0 -0
  96. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot/trie.py +0 -0
  97. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.egg-info/SOURCES.txt +0 -0
  98. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.egg-info/dependency_links.txt +0 -0
  99. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.egg-info/requires.txt +0 -0
  100. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.egg-info/top_level.txt +0 -0
  101. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglot.png +0 -0
  102. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/Cargo.lock +0 -0
  103. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/Cargo.toml +0 -0
  104. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/benches/dialect_settings.json +0 -0
  105. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/benches/long.rs +0 -0
  106. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/benches/token_type_settings.json +0 -0
  107. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
  108. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/benches/tokenizer_settings.json +0 -0
  109. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/pyproject.toml +0 -0
  110. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/src/lib.rs +0 -0
  111. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/src/settings.rs +0 -0
  112. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/src/token.rs +0 -0
  113. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/src/tokenizer.rs +0 -0
  114. {sqlglot-27.15.0 → sqlglot-27.15.2}/sqlglotrs/src/trie.rs +0 -0
  115. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/__init__.py +0 -0
  116. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/__init__.py +0 -0
  117. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_athena.py +0 -0
  118. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_clickhouse.py +0 -0
  119. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_databricks.py +0 -0
  120. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_dialect.py +0 -0
  121. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_doris.py +0 -0
  122. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_dremio.py +0 -0
  123. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_drill.py +0 -0
  124. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_druid.py +0 -0
  125. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_dune.py +0 -0
  126. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_exasol.py +0 -0
  127. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_fabric.py +0 -0
  128. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_hive.py +0 -0
  129. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_materialize.py +0 -0
  130. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_mysql.py +0 -0
  131. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_oracle.py +0 -0
  132. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_pipe_syntax.py +0 -0
  133. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_presto.py +0 -0
  134. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_prql.py +0 -0
  135. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_redshift.py +0 -0
  136. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_risingwave.py +0 -0
  137. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_singlestore.py +0 -0
  138. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_spark.py +0 -0
  139. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_sqlite.py +0 -0
  140. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_starrocks.py +0 -0
  141. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_tableau.py +0 -0
  142. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_teradata.py +0 -0
  143. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_trino.py +0 -0
  144. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/dialects/test_tsql.py +0 -0
  145. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/identity.sql +0 -0
  146. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/jsonpath/LICENSE +0 -0
  147. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/jsonpath/cts.json +0 -0
  148. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/annotate_functions.sql +0 -0
  149. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/annotate_types.sql +0 -0
  150. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  151. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  152. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  153. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  154. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  155. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  156. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/normalize.sql +0 -0
  157. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  158. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  159. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/optimizer.sql +0 -0
  160. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  161. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  162. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
  163. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/qualify_columns.sql +0 -0
  164. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/qualify_columns__invalid.sql +0 -0
  165. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  166. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
  167. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/qualify_tables.sql +0 -0
  168. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  169. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/simplify.sql +0 -0
  170. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  171. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  172. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  173. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  174. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  175. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  176. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  177. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  178. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  179. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  180. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  181. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  182. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  183. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  184. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  185. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  186. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  187. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  188. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  189. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  190. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  191. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  192. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  193. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  194. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  195. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  196. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  197. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  198. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  199. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  200. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  201. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  202. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  203. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  204. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  205. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/partial.sql +0 -0
  206. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/fixtures/pretty.sql +0 -0
  207. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/gen_fixtures.py +0 -0
  208. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/helpers.py +0 -0
  209. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_build.py +0 -0
  210. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_dialect_imports.py +0 -0
  211. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_diff.py +0 -0
  212. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_docs.py +0 -0
  213. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_executor.py +0 -0
  214. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_expressions.py +0 -0
  215. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_generator.py +0 -0
  216. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_helper.py +0 -0
  217. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_jsonpath.py +0 -0
  218. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_lineage.py +0 -0
  219. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_optimizer.py +0 -0
  220. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_parser.py +0 -0
  221. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_schema.py +0 -0
  222. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_serde.py +0 -0
  223. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_time.py +0 -0
  224. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_tokens.py +0 -0
  225. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_transforms.py +0 -0
  226. {sqlglot-27.15.0 → sqlglot-27.15.2}/tests/test_transpile.py +0 -0
@@ -1,6 +1,76 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [v27.15.1] - 2025-09-17
5
+ ### :sparkles: New Features
6
+ - [`1ee026d`](https://github.com/tobymao/sqlglot/commit/1ee026d22d4f6c3613c1809a6738cdea846c48a9) - **postgres**: support `SUBSTRING(value FOR length FROM start)` variant *(commit by [@georgesittas](https://github.com/georgesittas))*
7
+
8
+
9
+ ## [v27.15.0] - 2025-09-17
10
+ ### :boom: BREAKING CHANGES
11
+ - due to [`96ae7a3`](https://github.com/tobymao/sqlglot/commit/96ae7a3bcbf9de1932150baa0bd704d4ce05c9f7) - Annotate and add tests for snowflake REPEAT and SPLIT functions *(PR [#5875](https://github.com/tobymao/sqlglot/pull/5875) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
12
+
13
+ Annotate and add tests for snowflake REPEAT and SPLIT functions (#5875)
14
+
15
+ - due to [`f2d3bf7`](https://github.com/tobymao/sqlglot/commit/f2d3bf74e804e5a5e2ac6ca94210ba04df07e7f3) - annotate types for Snowflake UUID_STRING function *(PR [#5881](https://github.com/tobymao/sqlglot/pull/5881) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
16
+
17
+ annotate types for Snowflake UUID_STRING function (#5881)
18
+
19
+ - due to [`ec80ff3`](https://github.com/tobymao/sqlglot/commit/ec80ff34957c3e3f80c44175383b06cf72988a68) - make dump a list instead of a nested dict to avoid all recursion errors *(PR [#5885](https://github.com/tobymao/sqlglot/pull/5885) by [@tobymao](https://github.com/tobymao))*:
20
+
21
+ make dump a list instead of a nested dict to avoid all recursion errors (#5885)
22
+
23
+ - due to [`2fdaccd`](https://github.com/tobymao/sqlglot/commit/2fdaccd1a9045bda3d529025a4706c397b8a836f) - annotate types for Snowflake SHA1, SHA2 functions *(PR [#5884](https://github.com/tobymao/sqlglot/pull/5884) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
24
+
25
+ annotate types for Snowflake SHA1, SHA2 functions (#5884)
26
+
27
+ - due to [`faba309`](https://github.com/tobymao/sqlglot/commit/faba30905390e5efaf0ba9a05aab9ac2724b1b85) - annotate types for Snowflake AI_AGG function *(PR [#5894](https://github.com/tobymao/sqlglot/pull/5894) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
28
+
29
+ annotate types for Snowflake AI_AGG function (#5894)
30
+
31
+ - due to [`304bec5`](https://github.com/tobymao/sqlglot/commit/304bec5f7342501ad28ea4cd0a4b9aa092f2192f) - Annotate snowflake MD5 functions *(PR [#5883](https://github.com/tobymao/sqlglot/pull/5883) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*:
32
+
33
+ Annotate snowflake MD5 functions (#5883)
34
+
35
+ - due to [`c0180ec`](https://github.com/tobymao/sqlglot/commit/c0180ec163a43836fed754efcb6f26ad37cdae50) - annotate types for Snowflake AI_SUMMARIZE_AGG function *(PR [#5902](https://github.com/tobymao/sqlglot/pull/5902) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*:
36
+
37
+ annotate types for Snowflake AI_SUMMARIZE_AGG function (#5902)
38
+
39
+ - due to [`f5409df`](https://github.com/tobymao/sqlglot/commit/f5409df64ed6069880669878db687e4b98c3e280) - use column name in struct type annotation *(PR [#5903](https://github.com/tobymao/sqlglot/pull/5903) by [@georgesittas](https://github.com/georgesittas))*:
40
+
41
+ use column name in struct type annotation (#5903)
42
+
43
+
44
+ ### :sparkles: New Features
45
+ - [`cd818ba`](https://github.com/tobymao/sqlglot/commit/cd818bad51e93ec349b97675e4c1f5bd7c4c1522) - **singlestore**: Fixed generation/parsing of computed collumns *(PR [#5878](https://github.com/tobymao/sqlglot/pull/5878) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
46
+ - [`5d1f241`](https://github.com/tobymao/sqlglot/commit/5d1f241209197419111e9eda37fb6f2a5ec2bc4b) - **tsql**: support JSON_ARRAYAGG *(PR [#5879](https://github.com/tobymao/sqlglot/pull/5879) by [@geooo109](https://github.com/geooo109))*
47
+ - [`96ae7a3`](https://github.com/tobymao/sqlglot/commit/96ae7a3bcbf9de1932150baa0bd704d4ce05c9f7) - **optimizer**: Annotate and add tests for snowflake REPEAT and SPLIT functions *(PR [#5875](https://github.com/tobymao/sqlglot/pull/5875) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
48
+ - [`0fe6a25`](https://github.com/tobymao/sqlglot/commit/0fe6a25e366dcbc5a4a0878b285d147a6aa00412) - **postgres**: support JSON_AGG *(PR [#5880](https://github.com/tobymao/sqlglot/pull/5880) by [@geooo109](https://github.com/geooo109))*
49
+ - [`854eeeb`](https://github.com/tobymao/sqlglot/commit/854eeeb5b25954cc26b91135d58eb8370271f1de) - **optimizer**: annotate types for Snowflake REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR functions *(PR [#5876](https://github.com/tobymao/sqlglot/pull/5876) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
50
+ - [`f2d3bf7`](https://github.com/tobymao/sqlglot/commit/f2d3bf74e804e5a5e2ac6ca94210ba04df07e7f3) - **optimizer**: annotate types for Snowflake UUID_STRING function *(PR [#5881](https://github.com/tobymao/sqlglot/pull/5881) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
51
+ - [`5b9463a`](https://github.com/tobymao/sqlglot/commit/5b9463ad11a49c821585985c35394ebb30e827dd) - **mysql**: add support for binary `MOD` operator fixes [#5887](https://github.com/tobymao/sqlglot/pull/5887) *(commit by [@georgesittas](https://github.com/georgesittas))*
52
+ - [`d24eabc`](https://github.com/tobymao/sqlglot/commit/d24eabcbe30dc0f7c2dbae346e429efef58b5680) - **bigquery**: Add support for ML.GENERATE_TEXT_EMBEDDING(...) *(PR [#5891](https://github.com/tobymao/sqlglot/pull/5891) by [@VaggelisD](https://github.com/VaggelisD))*
53
+ - [`950a3fa`](https://github.com/tobymao/sqlglot/commit/950a3fa6d6307f7713f40117655da2f9710ebfa9) - **mysql**: SOUNDS LIKE, SUBSTR *(PR [#5886](https://github.com/tobymao/sqlglot/pull/5886) by [@vuvova](https://github.com/vuvova))*
54
+ - [`688afc5`](https://github.com/tobymao/sqlglot/commit/688afc55ab08588636eba92893c603ca68e43e6e) - **singlestore**: Fixed generation of exp.National *(PR [#5890](https://github.com/tobymao/sqlglot/pull/5890) by [@AdalbertMemSQL](https://github.com/AdalbertMemSQL))*
55
+ - [`c77147e`](https://github.com/tobymao/sqlglot/commit/c77147ebaafa6942f80af75dd6c2d7a62a7e6fe2) - **parser**: Extend support for `IS UNKOWN` across all dialects *(PR [#5888](https://github.com/tobymao/sqlglot/pull/5888) by [@VaggelisD](https://github.com/VaggelisD))*
56
+ - [`ec80ff3`](https://github.com/tobymao/sqlglot/commit/ec80ff34957c3e3f80c44175383b06cf72988a68) - make dump a list instead of a nested dict to avoid all recursion errors *(PR [#5885](https://github.com/tobymao/sqlglot/pull/5885) by [@tobymao](https://github.com/tobymao))*
57
+ - [`2fdaccd`](https://github.com/tobymao/sqlglot/commit/2fdaccd1a9045bda3d529025a4706c397b8a836f) - **optimizer**: annotate types for Snowflake SHA1, SHA2 functions *(PR [#5884](https://github.com/tobymao/sqlglot/pull/5884) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
58
+ - [`faba309`](https://github.com/tobymao/sqlglot/commit/faba30905390e5efaf0ba9a05aab9ac2724b1b85) - **optimizer**: annotate types for Snowflake AI_AGG function *(PR [#5894](https://github.com/tobymao/sqlglot/pull/5894) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
59
+ - [`dd27844`](https://github.com/tobymao/sqlglot/commit/dd2784435c7bdd2ceaaaaa359fcd112ad1f8190c) - **snowflake**: transpile `BYTE_LENGTH` *(PR [#5899](https://github.com/tobymao/sqlglot/pull/5899) by [@ozadari](https://github.com/ozadari))*
60
+ - [`304bec5`](https://github.com/tobymao/sqlglot/commit/304bec5f7342501ad28ea4cd0a4b9aa092f2192f) - **optimizer**: Annotate snowflake MD5 functions *(PR [#5883](https://github.com/tobymao/sqlglot/pull/5883) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
61
+ - [`ec3006d`](https://github.com/tobymao/sqlglot/commit/ec3006d815951fdc1a80d6722ce6f1176417d595) - **optimizer**: Add tests for snowflake NOT ILIKE and NOT LIKE *(PR [#5901](https://github.com/tobymao/sqlglot/pull/5901) by [@fivetran-amrutabhimsenayachit](https://github.com/fivetran-amrutabhimsenayachit))*
62
+ - [`c0180ec`](https://github.com/tobymao/sqlglot/commit/c0180ec163a43836fed754efcb6f26ad37cdae50) - **optimizer**: annotate types for Snowflake AI_SUMMARIZE_AGG function *(PR [#5902](https://github.com/tobymao/sqlglot/pull/5902) by [@fivetran-BradfordPaskewitz](https://github.com/fivetran-BradfordPaskewitz))*
63
+
64
+ ### :bug: Bug Fixes
65
+ - [`1d9e357`](https://github.com/tobymao/sqlglot/commit/1d9e357fb7549635ca25c6c42299880d7864e074) - **optimizer**: expand columns on the LHS of recursive CTEs *(PR [#5872](https://github.com/tobymao/sqlglot/pull/5872) by [@geooo109](https://github.com/geooo109))*
66
+ - :arrow_lower_right: *fixes issue [#5814](https://github.com/tobymao/sqlglot/issues/5814) opened by [@suresh-summation](https://github.com/suresh-summation)*
67
+ - [`7fcc52a`](https://github.com/tobymao/sqlglot/commit/7fcc52a22241c480c22b3e6f843e7a210c75a0ec) - **parser**: Require an explicit alias in EXCLUDE/RENAME/REPLACE star ops *(PR [#5892](https://github.com/tobymao/sqlglot/pull/5892) by [@VaggelisD](https://github.com/VaggelisD))*
68
+ - [`5fdcc65`](https://github.com/tobymao/sqlglot/commit/5fdcc651277ba4e86e11d0c5952a56e40299a998) - **snowflake**: parse OCTET_LENGTH *(PR [#5900](https://github.com/tobymao/sqlglot/pull/5900) by [@geooo109](https://github.com/geooo109))*
69
+ - [`f5409df`](https://github.com/tobymao/sqlglot/commit/f5409df64ed6069880669878db687e4b98c3e280) - **optimizer**: use column name in struct type annotation *(PR [#5903](https://github.com/tobymao/sqlglot/pull/5903) by [@georgesittas](https://github.com/georgesittas))*
70
+ - [`74886d8`](https://github.com/tobymao/sqlglot/commit/74886d82f70c9317af51c77b322e67a6aa260a5e) - **snowflake**: transpile BQ UNNEST with alias *(PR [#5897](https://github.com/tobymao/sqlglot/pull/5897) by [@geooo109](https://github.com/geooo109))*
71
+ - :arrow_lower_right: *fixes issue [#5895](https://github.com/tobymao/sqlglot/issues/5895) opened by [@YuvalOmerRep](https://github.com/YuvalOmerRep)*
72
+
73
+
4
74
  ## [v27.14.0] - 2025-09-11
5
75
  ### :boom: BREAKING CHANGES
6
76
  - due to [`9c8a600`](https://github.com/tobymao/sqlglot/commit/9c8a6001f41816035f391d046eb9692d6f13cefc) - correct parsing of TO_VARCHAR *(PR [#5840](https://github.com/tobymao/sqlglot/pull/5840) by [@geooo109](https://github.com/geooo109))*:
@@ -7263,3 +7333,5 @@ Changelog
7263
7333
  [v27.13.1]: https://github.com/tobymao/sqlglot/compare/v27.13.0...v27.13.1
7264
7334
  [v27.13.2]: https://github.com/tobymao/sqlglot/compare/v27.13.1...v27.13.2
7265
7335
  [v27.14.0]: https://github.com/tobymao/sqlglot/compare/v27.13.2...v27.14.0
7336
+ [v27.15.0]: https://github.com/tobymao/sqlglot/compare/v27.14.0...v27.15.0
7337
+ [v27.15.1]: https://github.com/tobymao/sqlglot/compare/v27.15.0...v27.15.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 27.15.0
3
+ Version: 27.15.2
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
@@ -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.15.0'
32
- __version_tuple__ = version_tuple = (27, 15, 0)
31
+ __version__ = version = '27.15.2'
32
+ __version_tuple__ = version_tuple = (27, 15, 2)
33
33
 
34
- __commit_id__ = commit_id = 'g74886d82f'
34
+ __commit_id__ = commit_id = 'g16f317c04'
@@ -304,6 +304,8 @@ class DuckDB(Dialect):
304
304
  "CHAR": TokenType.TEXT,
305
305
  "DATETIME": TokenType.TIMESTAMPNTZ,
306
306
  "DETACH": TokenType.DETACH,
307
+ "FORCE": TokenType.FORCE,
308
+ "INSTALL": TokenType.INSTALL,
307
309
  "LOGICAL": TokenType.BOOLEAN,
308
310
  "ONLY": TokenType.ONLY,
309
311
  "PIVOT_WIDER": TokenType.PIVOT,
@@ -468,6 +470,8 @@ class DuckDB(Dialect):
468
470
  **parser.Parser.STATEMENT_PARSERS,
469
471
  TokenType.ATTACH: lambda self: self._parse_attach_detach(),
470
472
  TokenType.DETACH: lambda self: self._parse_attach_detach(is_attach=False),
473
+ TokenType.FORCE: lambda self: self._parse_force(),
474
+ TokenType.INSTALL: lambda self: self._parse_install(),
471
475
  TokenType.SHOW: lambda self: self._parse_show(),
472
476
  }
473
477
 
@@ -605,6 +609,24 @@ class DuckDB(Dialect):
605
609
  def _parse_show_duckdb(self, this: str) -> exp.Show:
606
610
  return self.expression(exp.Show, this=this)
607
611
 
612
+ def _parse_force(self) -> exp.Install | exp.Command:
613
+ # FORCE can only be followed by INSTALL or CHECKPOINT
614
+ # In the case of CHECKPOINT, we fallback
615
+ if not self._match(TokenType.INSTALL):
616
+ return self._parse_as_command(self._prev)
617
+
618
+ return self._parse_install(force=True)
619
+
620
+ def _parse_install(self, force: bool = False) -> exp.Install:
621
+ return self.expression(
622
+ exp.Install,
623
+ **{ # type: ignore
624
+ "this": self._parse_id_var(),
625
+ "from": self._parse_var_or_string() if self._match(TokenType.FROM) else None,
626
+ "force": force,
627
+ },
628
+ )
629
+
608
630
  def _parse_primary(self) -> t.Optional[exp.Expression]:
609
631
  if self._match_pair(TokenType.HASH, TokenType.NUMBER):
610
632
  return exp.PositionalColumn(this=exp.Literal.number(self._prev.text))
@@ -928,6 +950,13 @@ class DuckDB(Dialect):
928
950
  def show_sql(self, expression: exp.Show) -> str:
929
951
  return f"SHOW {expression.name}"
930
952
 
953
+ def install_sql(self, expression: exp.Install) -> str:
954
+ force = "FORCE " if expression.args.get("force") else ""
955
+ this = self.sql(expression, "this")
956
+ from_clause = expression.args.get("from")
957
+ from_clause = f" FROM {from_clause}" if from_clause else ""
958
+ return f"{force}INSTALL {this}{from_clause}"
959
+
931
960
  def fromiso8601timestamp_sql(self, expression: exp.FromISO8601Timestamp) -> str:
932
961
  return self.sql(exp.cast(expression.this, exp.DataType.Type.TIMESTAMPTZ))
933
962
 
@@ -746,6 +746,7 @@ class Snowflake(Dialect):
746
746
  "VECTOR_L2_DISTANCE": exp.EuclideanDistance.from_arg_list,
747
747
  "ZEROIFNULL": _build_if_from_zeroifnull,
748
748
  }
749
+ FUNCTIONS.pop("PREDICT")
749
750
 
750
751
  FUNCTION_PARSERS = {
751
752
  **parser.Parser.FUNCTION_PARSERS,
@@ -852,6 +853,13 @@ class Snowflake(Dialect):
852
853
  ),
853
854
  }
854
855
 
856
+ COLUMN_OPERATORS = {
857
+ **parser.Parser.COLUMN_OPERATORS,
858
+ TokenType.EXCLAMATION: lambda self, this, attr: self.expression(
859
+ exp.ModelAttribute, this=this, expression=attr
860
+ ),
861
+ }
862
+
855
863
  def _parse_use(self) -> exp.Use:
856
864
  if self._match_text_seq("SECONDARY", "ROLES"):
857
865
  this = self._match_texts(("ALL", "NONE")) and exp.var(self._prev.text.upper())
@@ -963,7 +971,7 @@ class Snowflake(Dialect):
963
971
  # Keys are strings in Snowflake's objects, see also:
964
972
  # - https://docs.snowflake.com/en/sql-reference/data-types-semistructured
965
973
  # - https://docs.snowflake.com/en/sql-reference/functions/object_construct
966
- return self._parse_slice(self._parse_string())
974
+ return self._parse_slice(self._parse_string()) or self._parse_assignment()
967
975
 
968
976
  return self._parse_slice(self._parse_alias(self._parse_assignment(), explicit=True))
969
977
 
@@ -1254,6 +1262,7 @@ class Snowflake(Dialect):
1254
1262
  SINGLE_TOKENS = {
1255
1263
  **tokens.Tokenizer.SINGLE_TOKENS,
1256
1264
  "$": TokenType.PARAMETER,
1265
+ "!": TokenType.EXCLAMATION,
1257
1266
  }
1258
1267
 
1259
1268
  VAR_SINGLE_TOKENS = {"$"}
@@ -1303,6 +1312,7 @@ class Snowflake(Dialect):
1303
1312
  exp.BitwiseAndAgg: rename_func("BITANDAGG"),
1304
1313
  exp.BitwiseOrAgg: rename_func("BITORAGG"),
1305
1314
  exp.BitwiseXorAgg: rename_func("BITXORAGG"),
1315
+ exp.BitwiseNot: rename_func("BITNOT"),
1306
1316
  exp.BitwiseLeftShift: rename_func("BITSHIFTLEFT"),
1307
1317
  exp.BitwiseRightShift: rename_func("BITSHIFTRIGHT"),
1308
1318
  exp.Create: transforms.preprocess([_flatten_structured_types_unless_iceberg]),
@@ -1623,6 +1633,12 @@ class Snowflake(Dialect):
1623
1633
  return f"CLUSTER BY ({self.expressions(expression, flat=True)})"
1624
1634
 
1625
1635
  def struct_sql(self, expression: exp.Struct) -> str:
1636
+ if len(expression.expressions) == 1:
1637
+ arg = expression.expressions[0]
1638
+ if arg.is_star or (isinstance(arg, exp.ILike) and arg.left.is_star):
1639
+ # Wildcard syntax: https://docs.snowflake.com/en/sql-reference/data-types-semistructured#object
1640
+ return f"{{{self.sql(expression.expressions[0])}}}"
1641
+
1626
1642
  keys = []
1627
1643
  values = []
1628
1644
 
@@ -1796,3 +1812,6 @@ class Snowflake(Dialect):
1796
1812
  return f"{self.sql(this)}:{self.sql(expression, 'expression')}"
1797
1813
 
1798
1814
  return super().dot_sql(expression)
1815
+
1816
+ def modelattribute_sql(self, expression: exp.ModelAttribute) -> str:
1817
+ return f"{self.sql(expression, 'this')}!{self.sql(expression, 'expression')}"
@@ -1584,6 +1584,11 @@ class Detach(Expression):
1584
1584
  arg_types = {"this": True, "exists": False}
1585
1585
 
1586
1586
 
1587
+ # https://duckdb.org/docs/sql/statements/load_and_install.html
1588
+ class Install(Expression):
1589
+ arg_types = {"this": True, "from": False, "force": False}
1590
+
1591
+
1587
1592
  # https://duckdb.org/docs/guides/meta/summarize.html
1588
1593
  class Summarize(Expression):
1589
1594
  arg_types = {"this": True, "table": False}
@@ -7027,6 +7032,12 @@ class MLForecast(Func):
7027
7032
  arg_types = {"this": True, "expression": False, "params_struct": False}
7028
7033
 
7029
7034
 
7035
+ # Represents Snowflake's <model>!<attribute> syntax. For example: SELECT model!PREDICT(INPUT_DATA => {*})
7036
+ # See: https://docs.snowflake.com/en/guides-overview-ml-functions
7037
+ class ModelAttribute(Expression):
7038
+ arg_types = {"this": True, "expression": True}
7039
+
7040
+
7030
7041
  # https://cloud.google.com/bigquery/docs/reference/standard-sql/search_functions#vector_search
7031
7042
  class VectorSearch(Func):
7032
7043
  arg_types = {
@@ -5198,6 +5198,10 @@ class Generator(metaclass=_Generator):
5198
5198
  self.unsupported("Unsupported SHOW statement")
5199
5199
  return ""
5200
5200
 
5201
+ def install_sql(self, expression: exp.Install) -> str:
5202
+ self.unsupported("Unsupported INSTALL statement")
5203
+ return ""
5204
+
5201
5205
  def get_put_sql(self, expression: exp.Put | exp.Get) -> str:
5202
5206
  # Snowflake GET/PUT statements:
5203
5207
  # PUT <file> <internalStage> <properties>
@@ -5302,3 +5306,7 @@ class Generator(metaclass=_Generator):
5302
5306
  starts = f" STARTS {starts}" if starts else ""
5303
5307
 
5304
5308
  return f"REFRESH {method} ON {kind}{every}{starts}"
5309
+
5310
+ def modelattribute_sql(self, expression: exp.ModelAttribute) -> str:
5311
+ self.unsupported("The model!attribute syntax is not supported")
5312
+ return ""
@@ -6975,16 +6975,27 @@ class Parser(metaclass=_Parser):
6975
6975
 
6976
6976
  def _parse_substring(self) -> exp.Substring:
6977
6977
  # Postgres supports the form: substring(string [from int] [for int])
6978
+ # (despite being undocumented, the reverse order also works)
6978
6979
  # https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6979
6980
 
6980
6981
  args = t.cast(t.List[t.Optional[exp.Expression]], self._parse_csv(self._parse_bitwise))
6981
6982
 
6982
- if self._match(TokenType.FROM):
6983
- args.append(self._parse_bitwise())
6984
- if self._match(TokenType.FOR):
6985
- if len(args) == 1:
6986
- args.append(exp.Literal.number(1))
6987
- args.append(self._parse_bitwise())
6983
+ start, length = None, None
6984
+
6985
+ while self._curr:
6986
+ if self._match(TokenType.FROM):
6987
+ start = self._parse_bitwise()
6988
+ elif self._match(TokenType.FOR):
6989
+ if not start:
6990
+ start = exp.Literal.number(1)
6991
+ length = self._parse_bitwise()
6992
+ else:
6993
+ break
6994
+
6995
+ if start:
6996
+ args.append(start)
6997
+ if length:
6998
+ args.append(length)
6988
6999
 
6989
7000
  return self.validate_expression(exp.Substring.from_arg_list(args), args)
6990
7001
 
@@ -88,6 +88,7 @@ class TokenType(AutoName):
88
88
  QMARK_AMP = auto()
89
89
  QMARK_PIPE = auto()
90
90
  HASH_DASH = auto()
91
+ EXCLAMATION = auto()
91
92
 
92
93
  URI_START = auto()
93
94
 
@@ -313,6 +314,7 @@ class TokenType(AutoName):
313
314
  INDEX = auto()
314
315
  INNER = auto()
315
316
  INSERT = auto()
317
+ INSTALL = auto()
316
318
  INTERSECT = auto()
317
319
  INTERVAL = auto()
318
320
  INTO = auto()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 27.15.0
3
+ Version: 27.15.2
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
@@ -2924,6 +2924,15 @@ OPTIONS (
2924
2924
  },
2925
2925
  )
2926
2926
 
2927
+ def test_bitwise_not(self):
2928
+ self.validate_all(
2929
+ "SELECT ~1",
2930
+ write={
2931
+ "bigquery": "SELECT ~1",
2932
+ "snowflake": "SELECT BITNOT(1)",
2933
+ },
2934
+ )
2935
+
2927
2936
  def test_bit_aggs(self):
2928
2937
  self.validate_all(
2929
2938
  "BIT_AND(x)",
@@ -1813,3 +1813,15 @@ class TestDuckDB(Validator):
1813
1813
  self.validate_identity("CREATE SEQUENCE serial START WITH 99 INCREMENT BY -1 MAXVALUE 99")
1814
1814
  self.validate_identity("CREATE SEQUENCE serial START WITH 1 MAXVALUE 10 NO CYCLE")
1815
1815
  self.validate_identity("CREATE SEQUENCE serial START WITH 1 MAXVALUE 10 CYCLE")
1816
+
1817
+ def test_install(self):
1818
+ ast = self.validate_identity("INSTALL httpfs")
1819
+ ast.assert_is(exp.Install).name == "httpfs"
1820
+ assert isinstance(ast.this, exp.Identifier)
1821
+
1822
+ self.validate_identity("INSTALL httpfs FROM community")
1823
+ self.validate_identity("INSTALL httpfs FROM 'https://extensions.duckdb.org'")
1824
+ self.validate_identity("FORCE INSTALL httpfs").assert_is(exp.Install).name == "httpfs"
1825
+ self.validate_identity("FORCE INSTALL httpfs FROM community")
1826
+ self.validate_identity("FORCE INSTALL httpfs FROM 'https://extensions.duckdb.org'")
1827
+ self.validate_identity("FORCE CHECKPOINT db", check_command_warning=True)
@@ -158,6 +158,10 @@ class TestPostgres(Validator):
158
158
  "pg_catalog.PG_TABLE_IS_VISIBLE(c.oid) "
159
159
  "ORDER BY 2, 3"
160
160
  )
161
+ self.validate_identity(
162
+ "SELECT SUBSTRING('Thomas' FOR 3 FROM 2)",
163
+ "SELECT SUBSTRING('Thomas' FROM 2 FOR 3)",
164
+ )
161
165
  self.validate_identity(
162
166
  "SELECT ARRAY[1, 2, 3] <@ ARRAY[1, 2]",
163
167
  "SELECT ARRAY[1, 2] @> ARRAY[1, 2, 3]",
@@ -29,6 +29,11 @@ class TestSnowflake(Validator):
29
29
  expr.selects[0].assert_is(exp.AggFunc)
30
30
  self.assertEqual(expr.sql(dialect="snowflake"), "SELECT APPROX_TOP_K(C4, 3, 5) FROM t")
31
31
 
32
+ self.validate_identity("SELECT {*} FROM my_table")
33
+ self.validate_identity("SELECT {my_table.*} FROM my_table")
34
+ self.validate_identity("SELECT {* ILIKE 'col1%'} FROM my_table")
35
+ self.validate_identity("SELECT {* EXCLUDE (col1)} FROM my_table")
36
+ self.validate_identity("SELECT {* EXCLUDE (col1, col2)} FROM my_table")
32
37
  self.validate_identity("SELECT a, b, COUNT(*) FROM x GROUP BY ALL LIMIT 100")
33
38
  self.validate_identity("STRTOK_TO_ARRAY('a b c')")
34
39
  self.validate_identity("STRTOK_TO_ARRAY('a.b.c', '.')")
@@ -3139,3 +3144,13 @@ FROM SEMANTIC_VIEW(
3139
3144
  self.validate_identity("MD5_BINARY(col)")
3140
3145
  self.validate_identity("MD5_NUMBER_LOWER64(col)")
3141
3146
  self.validate_identity("MD5_NUMBER_UPPER64(col)")
3147
+
3148
+ def test_model_attribute(self):
3149
+ self.validate_identity("SELECT model!mladmin")
3150
+ self.validate_identity("SELECT model!PREDICT(1)")
3151
+ self.validate_identity("SELECT m!PREDICT(INPUT_DATA => {*}) AS p FROM tbl")
3152
+ self.validate_identity("SELECT m!PREDICT(INPUT_DATA => {tbl.*}) AS p FROM tbl")
3153
+ self.validate_identity("x.y.z!PREDICT(foo, bar, baz, bla)")
3154
+ self.validate_identity(
3155
+ "SELECT * FROM TABLE(model_trained_with_labeled_data!DETECT_ANOMALIES(INPUT_DATA => TABLE(view_with_data_to_analyze), TIMESTAMP_COLNAME => 'date', TARGET_COLNAME => 'sales', CONFIG_OBJECT => OBJECT_CONSTRUCT('prediction_interval', 0.99)))"
3156
+ )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes