sqlglot 27.28.1__tar.gz → 27.29.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 (228) hide show
  1. {sqlglot-27.28.1 → sqlglot-27.29.0}/PKG-INFO +1 -1
  2. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/__init__.py +1 -0
  3. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/_version.py +3 -3
  4. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/bigquery.py +1 -0
  5. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dialect.py +45 -7
  6. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/duckdb.py +17 -3
  7. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/mysql.py +1 -0
  8. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/postgres.py +14 -2
  9. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/snowflake.py +55 -18
  10. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/spark.py +3 -0
  11. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/sqlite.py +1 -0
  12. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/__init__.py +5 -10
  13. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/python.py +1 -29
  14. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/expressions.py +102 -12
  15. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/generator.py +16 -2
  16. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/helper.py +0 -42
  17. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/lineage.py +1 -1
  18. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify.py +5 -5
  19. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify_columns.py +89 -9
  20. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/qualify_tables.py +33 -23
  21. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/simplify.py +12 -7
  22. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/parser.py +16 -8
  23. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/PKG-INFO +1 -1
  24. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_bigquery.py +26 -1
  25. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dialect.py +26 -0
  26. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_duckdb.py +27 -1
  27. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_postgres.py +10 -0
  28. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_snowflake.py +75 -8
  29. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_spark.py +28 -0
  30. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_trino.py +4 -0
  31. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/identity.sql +1 -0
  32. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/annotate_functions.sql +300 -0
  33. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/annotate_types.sql +6 -0
  34. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/normalize.sql +1 -1
  35. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns.sql +7 -0
  36. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns__invalid.sql +2 -0
  37. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_tables.sql +1 -1
  38. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/simplify.sql +32 -0
  39. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_executor.py +91 -46
  40. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_expressions.py +5 -0
  41. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_lineage.py +46 -4
  42. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_optimizer.py +26 -18
  43. {sqlglot-27.28.1 → sqlglot-27.29.0}/.gitignore +0 -0
  44. {sqlglot-27.28.1 → sqlglot-27.29.0}/.gitpod.yml +0 -0
  45. {sqlglot-27.28.1 → sqlglot-27.29.0}/.pre-commit-config.yaml +0 -0
  46. {sqlglot-27.28.1 → sqlglot-27.29.0}/CHANGELOG.md +0 -0
  47. {sqlglot-27.28.1 → sqlglot-27.29.0}/CONTRIBUTING.md +0 -0
  48. {sqlglot-27.28.1 → sqlglot-27.29.0}/LICENSE +0 -0
  49. {sqlglot-27.28.1 → sqlglot-27.29.0}/MANIFEST.in +0 -0
  50. {sqlglot-27.28.1 → sqlglot-27.29.0}/Makefile +0 -0
  51. {sqlglot-27.28.1 → sqlglot-27.29.0}/README.md +0 -0
  52. {sqlglot-27.28.1 → sqlglot-27.29.0}/pyproject.toml +0 -0
  53. {sqlglot-27.28.1 → sqlglot-27.29.0}/setup.cfg +0 -0
  54. {sqlglot-27.28.1 → sqlglot-27.29.0}/setup.py +0 -0
  55. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/__main__.py +0 -0
  56. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/_typing.py +0 -0
  57. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/__init__.py +0 -0
  58. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/athena.py +0 -0
  59. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/clickhouse.py +0 -0
  60. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/databricks.py +0 -0
  61. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/doris.py +0 -0
  62. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dremio.py +0 -0
  63. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/drill.py +0 -0
  64. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/druid.py +0 -0
  65. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/dune.py +0 -0
  66. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/exasol.py +0 -0
  67. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/fabric.py +0 -0
  68. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/hive.py +0 -0
  69. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/materialize.py +0 -0
  70. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/oracle.py +0 -0
  71. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/presto.py +0 -0
  72. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/prql.py +0 -0
  73. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/redshift.py +0 -0
  74. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/risingwave.py +0 -0
  75. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/singlestore.py +0 -0
  76. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/solr.py +0 -0
  77. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/spark2.py +0 -0
  78. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/starrocks.py +0 -0
  79. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/tableau.py +0 -0
  80. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/teradata.py +0 -0
  81. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/trino.py +0 -0
  82. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/dialects/tsql.py +0 -0
  83. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/diff.py +0 -0
  84. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/errors.py +0 -0
  85. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/context.py +0 -0
  86. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/env.py +0 -0
  87. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/executor/table.py +0 -0
  88. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/jsonpath.py +0 -0
  89. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/__init__.py +0 -0
  90. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/annotate_types.py +0 -0
  91. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/canonicalize.py +0 -0
  92. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_ctes.py +0 -0
  93. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_joins.py +0 -0
  94. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/eliminate_subqueries.py +0 -0
  95. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  96. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/merge_subqueries.py +0 -0
  97. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/normalize.py +0 -0
  98. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  99. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/optimize_joins.py +0 -0
  100. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/optimizer.py +0 -0
  101. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/pushdown_predicates.py +0 -0
  102. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/pushdown_projections.py +0 -0
  103. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/scope.py +0 -0
  104. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/optimizer/unnest_subqueries.py +0 -0
  105. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/planner.py +0 -0
  106. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/py.typed +0 -0
  107. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/schema.py +0 -0
  108. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/serde.py +0 -0
  109. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/time.py +0 -0
  110. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/tokens.py +0 -0
  111. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/transforms.py +0 -0
  112. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot/trie.py +0 -0
  113. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/SOURCES.txt +0 -0
  114. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/dependency_links.txt +0 -0
  115. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/requires.txt +0 -0
  116. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.egg-info/top_level.txt +0 -0
  117. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglot.png +0 -0
  118. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/Cargo.lock +0 -0
  119. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/Cargo.toml +0 -0
  120. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/dialect_settings.json +0 -0
  121. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/long.rs +0 -0
  122. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/token_type_settings.json +0 -0
  123. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/tokenizer_dialect_settings.json +0 -0
  124. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/benches/tokenizer_settings.json +0 -0
  125. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/pyproject.toml +0 -0
  126. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/lib.rs +0 -0
  127. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/settings.rs +0 -0
  128. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/token.rs +0 -0
  129. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/tokenizer.rs +0 -0
  130. {sqlglot-27.28.1 → sqlglot-27.29.0}/sqlglotrs/src/trie.rs +0 -0
  131. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/__init__.py +0 -0
  132. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/__init__.py +0 -0
  133. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_athena.py +0 -0
  134. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_clickhouse.py +0 -0
  135. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_databricks.py +0 -0
  136. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_doris.py +0 -0
  137. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dremio.py +0 -0
  138. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_drill.py +0 -0
  139. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_druid.py +0 -0
  140. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_dune.py +0 -0
  141. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_exasol.py +0 -0
  142. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_fabric.py +0 -0
  143. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_hive.py +0 -0
  144. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_materialize.py +0 -0
  145. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_mysql.py +0 -0
  146. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_oracle.py +0 -0
  147. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_pipe_syntax.py +0 -0
  148. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_presto.py +0 -0
  149. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_prql.py +0 -0
  150. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_redshift.py +0 -0
  151. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_risingwave.py +0 -0
  152. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_singlestore.py +0 -0
  153. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_solr.py +0 -0
  154. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_sqlite.py +0 -0
  155. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_starrocks.py +0 -0
  156. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_tableau.py +0 -0
  157. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_teradata.py +0 -0
  158. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/dialects/test_tsql.py +0 -0
  159. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/jsonpath/LICENSE +0 -0
  160. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/jsonpath/cts.json +0 -0
  161. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/canonicalize.sql +0 -0
  162. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_ctes.sql +0 -0
  163. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_joins.sql +0 -0
  164. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/eliminate_subqueries.sql +0 -0
  165. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/isolate_table_selects.sql +0 -0
  166. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/merge_subqueries.sql +0 -0
  167. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/normalize_identifiers.sql +0 -0
  168. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/optimize_joins.sql +0 -0
  169. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/optimizer.sql +0 -0
  170. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_cte_alias_columns.sql +0 -0
  171. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_predicates.sql +0 -0
  172. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/pushdown_projections.sql +0 -0
  173. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns__with_invisible.sql +0 -0
  174. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/qualify_columns_ddl.sql +0 -0
  175. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/quote_identifiers.sql +0 -0
  176. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/call_center.csv.gz +0 -0
  177. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_page.csv.gz +0 -0
  178. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_returns.csv.gz +0 -0
  179. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/catalog_sales.csv.gz +0 -0
  180. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer.csv.gz +0 -0
  181. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer_address.csv.gz +0 -0
  182. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/customer_demographics.csv.gz +0 -0
  183. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/date_dim.csv.gz +0 -0
  184. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/household_demographics.csv.gz +0 -0
  185. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/income_band.csv.gz +0 -0
  186. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/inventory.csv.gz +0 -0
  187. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/item.csv.gz +0 -0
  188. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/promotion.csv.gz +0 -0
  189. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/reason.csv.gz +0 -0
  190. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/ship_mode.csv.gz +0 -0
  191. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store.csv.gz +0 -0
  192. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store_returns.csv.gz +0 -0
  193. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/store_sales.csv.gz +0 -0
  194. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/time_dim.csv.gz +0 -0
  195. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/tpc-ds.sql +0 -0
  196. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/warehouse.csv.gz +0 -0
  197. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_page.csv.gz +0 -0
  198. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_returns.csv.gz +0 -0
  199. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_sales.csv.gz +0 -0
  200. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-ds/web_site.csv.gz +0 -0
  201. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/customer.csv.gz +0 -0
  202. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/lineitem.csv.gz +0 -0
  203. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/nation.csv.gz +0 -0
  204. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/orders.csv.gz +0 -0
  205. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/part.csv.gz +0 -0
  206. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/partsupp.csv.gz +0 -0
  207. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/region.csv.gz +0 -0
  208. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/supplier.csv.gz +0 -0
  209. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/tpc-h/tpc-h.sql +0 -0
  210. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/optimizer/unnest_subqueries.sql +0 -0
  211. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/partial.sql +0 -0
  212. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/fixtures/pretty.sql +0 -0
  213. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/gen_fixtures.py +0 -0
  214. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/helpers.py +0 -0
  215. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_build.py +0 -0
  216. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_dialect_imports.py +0 -0
  217. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_diff.py +0 -0
  218. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_docs.py +0 -0
  219. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_generator.py +0 -0
  220. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_helper.py +0 -0
  221. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_jsonpath.py +0 -0
  222. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_parser.py +0 -0
  223. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_schema.py +0 -0
  224. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_serde.py +0 -0
  225. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_time.py +0 -0
  226. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_tokens.py +0 -0
  227. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_transforms.py +0 -0
  228. {sqlglot-27.28.1 → sqlglot-27.29.0}/tests/test_transpile.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglot
3
- Version: 27.28.1
3
+ Version: 27.29.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
@@ -29,6 +29,7 @@ from sqlglot.expressions import (
29
29
  condition as condition,
30
30
  delete as delete,
31
31
  except_ as except_,
32
+ find_tables as find_tables,
32
33
  from_ as from_,
33
34
  func as func,
34
35
  insert as insert,
@@ -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.28.1'
32
- __version_tuple__ = version_tuple = (27, 28, 1)
31
+ __version__ = version = '27.29.0'
32
+ __version_tuple__ = version_tuple = (27, 29, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g0c5387499'
34
+ __commit_id__ = commit_id = 'g7f550f22d'
@@ -508,6 +508,7 @@ class BigQuery(Dialect):
508
508
  exp.FarmFingerprint,
509
509
  exp.Grouping,
510
510
  exp.LaxInt64,
511
+ exp.Length,
511
512
  exp.Ntile,
512
513
  exp.Rank,
513
514
  exp.RangeBucket,
@@ -44,9 +44,11 @@ DATETIME_DELTA = t.Union[
44
44
  exp.DatetimeSub,
45
45
  exp.TimeAdd,
46
46
  exp.TimeSub,
47
+ exp.TimestampAdd,
47
48
  exp.TimestampSub,
48
49
  exp.TsOrDsAdd,
49
50
  ]
51
+ DATETIME_ADD = (exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd, exp.TimestampAdd)
50
52
 
51
53
  if t.TYPE_CHECKING:
52
54
  from sqlglot._typing import B, E, F
@@ -539,6 +541,10 @@ class Dialect(metaclass=_Dialect):
539
541
  # STRING type (Snowflake's case) or can be of any type
540
542
  TRY_CAST_REQUIRES_STRING: t.Optional[bool] = None
541
543
 
544
+ # Whether the double negation can be applied
545
+ # Not safe with MySQL and SQLite due to type coercion (may not return boolean)
546
+ SAFE_TO_ELIMINATE_DOUBLE_NEGATION = True
547
+
542
548
  # --- Autofilled ---
543
549
 
544
550
  tokenizer_class = Tokenizer
@@ -765,8 +771,12 @@ class Dialect(metaclass=_Dialect):
765
771
  exp.TimeAdd,
766
772
  exp.TimeSub,
767
773
  },
774
+ exp.DataType.Type.TIMESTAMPLTZ: {
775
+ exp.TimestampLtzFromParts,
776
+ },
768
777
  exp.DataType.Type.TIMESTAMPTZ: {
769
778
  exp.CurrentTimestampLTZ,
779
+ exp.TimestampTzFromParts,
770
780
  },
771
781
  exp.DataType.Type.TIMESTAMP: {
772
782
  exp.CurrentTimestamp,
@@ -778,10 +788,17 @@ class Dialect(metaclass=_Dialect):
778
788
  },
779
789
  exp.DataType.Type.TINYINT: {
780
790
  exp.Day,
781
- exp.Month,
791
+ exp.DayOfWeek,
792
+ exp.DayOfWeekIso,
793
+ exp.DayOfMonth,
794
+ exp.DayOfYear,
782
795
  exp.Week,
783
- exp.Year,
796
+ exp.WeekOfYear,
797
+ exp.Month,
784
798
  exp.Quarter,
799
+ exp.Year,
800
+ exp.YearOfWeek,
801
+ exp.YearOfWeekIso,
785
802
  },
786
803
  exp.DataType.Type.VARCHAR: {
787
804
  exp.ArrayConcat,
@@ -1682,11 +1699,7 @@ def date_delta_to_binary_interval_op(
1682
1699
  def date_delta_to_binary_interval_op_sql(self: Generator, expression: DATETIME_DELTA) -> str:
1683
1700
  this = expression.this
1684
1701
  unit = unit_to_var(expression)
1685
- op = (
1686
- "+"
1687
- if isinstance(expression, (exp.DateAdd, exp.TimeAdd, exp.DatetimeAdd, exp.TsOrDsAdd))
1688
- else "-"
1689
- )
1702
+ op = "+" if isinstance(expression, DATETIME_ADD) else "-"
1690
1703
 
1691
1704
  to_type: t.Optional[exp.DATA_TYPE] = None
1692
1705
  if cast:
@@ -1965,6 +1978,15 @@ def sequence_sql(self: Generator, expression: exp.GenerateSeries | exp.GenerateD
1965
1978
  return self.func("SEQUENCE", start, end, step)
1966
1979
 
1967
1980
 
1981
+ def build_like(expr_type: t.Type[E]) -> t.Callable[[t.List], E | exp.Escape]:
1982
+ def _builder(args: t.List) -> E | exp.Escape:
1983
+ like_expr = expr_type(this=seq_get(args, 0), expression=seq_get(args, 1))
1984
+ escape = seq_get(args, 2)
1985
+ return exp.Escape(this=like_expr, expression=escape) if escape else like_expr
1986
+
1987
+ return _builder
1988
+
1989
+
1968
1990
  def build_regexp_extract(expr_type: t.Type[E]) -> t.Callable[[t.List, Dialect], E]:
1969
1991
  def _builder(args: t.List, dialect: Dialect) -> E:
1970
1992
  return expr_type(
@@ -2075,3 +2097,19 @@ def build_replace_with_optional_replacement(args: t.List) -> exp.Replace:
2075
2097
  expression=seq_get(args, 1),
2076
2098
  replacement=seq_get(args, 2) or exp.Literal.string(""),
2077
2099
  )
2100
+
2101
+
2102
+ def regexp_replace_global_modifier(expression: exp.RegexpReplace) -> exp.Expression | None:
2103
+ modifiers = expression.args.get("modifiers")
2104
+ single_replace = expression.args.get("single_replace")
2105
+ occurrence = expression.args.get("occurrence")
2106
+
2107
+ if not single_replace and (not occurrence or (occurrence.is_int and occurrence.to_py() == 0)):
2108
+ if not modifiers or modifiers.is_string:
2109
+ # Append 'g' to the modifiers if they are not provided since
2110
+ # the semantics of REGEXP_REPLACE from the input dialect
2111
+ # is to replace all occurrences of the pattern.
2112
+ value = "" if not modifiers else modifiers.name
2113
+ modifiers = exp.Literal.string(value + "g")
2114
+
2115
+ return modifiers
@@ -39,6 +39,7 @@ from sqlglot.dialects.dialect import (
39
39
  explode_to_unnest_sql,
40
40
  no_make_interval_sql,
41
41
  groupconcat_sql,
42
+ regexp_replace_global_modifier,
42
43
  )
43
44
  from sqlglot.generator import unsupported_args
44
45
  from sqlglot.helper import seq_get
@@ -414,6 +415,7 @@ class DuckDB(Dialect):
414
415
  "LIST_SORT": exp.SortArray.from_arg_list,
415
416
  "LIST_TRANSFORM": exp.Transform.from_arg_list,
416
417
  "LIST_VALUE": lambda args: exp.Array(expressions=args),
418
+ "MAKE_DATE": exp.DateFromParts.from_arg_list,
417
419
  "MAKE_TIME": exp.TimeFromParts.from_arg_list,
418
420
  "MAKE_TIMESTAMP": _build_make_timestamp,
419
421
  "QUANTILE_CONT": exp.PercentileCont.from_arg_list,
@@ -427,6 +429,7 @@ class DuckDB(Dialect):
427
429
  expression=seq_get(args, 1),
428
430
  replacement=seq_get(args, 2),
429
431
  modifiers=seq_get(args, 3),
432
+ single_replace=True,
430
433
  ),
431
434
  "SHA256": lambda args: exp.SHA2(this=seq_get(args, 0), length=exp.Literal.number(256)),
432
435
  "STRFTIME": build_formatted_time(exp.TimeToStr, "duckdb"),
@@ -695,7 +698,6 @@ class DuckDB(Dialect):
695
698
  exp.BitwiseXorAgg: rename_func("BIT_XOR"),
696
699
  exp.CommentColumnConstraint: no_comment_column_constraint_sql,
697
700
  exp.CosineDistance: rename_func("LIST_COSINE_DISTANCE"),
698
- exp.CurrentDate: lambda *_: "CURRENT_DATE",
699
701
  exp.CurrentTime: lambda *_: "CURRENT_TIME",
700
702
  exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
701
703
  exp.DayOfMonth: rename_func("DAYOFMONTH"),
@@ -754,7 +756,7 @@ class DuckDB(Dialect):
754
756
  e.this,
755
757
  e.expression,
756
758
  e.args.get("replacement"),
757
- e.args.get("modifiers"),
759
+ regexp_replace_global_modifier(e),
758
760
  ),
759
761
  exp.RegexpLike: rename_func("REGEXP_MATCHES"),
760
762
  exp.RegexpILike: lambda self, e: self.func(
@@ -779,9 +781,11 @@ class DuckDB(Dialect):
779
781
  exp.Time: no_time_sql,
780
782
  exp.TimeDiff: _timediff_sql,
781
783
  exp.Timestamp: no_timestamp_sql,
784
+ exp.TimestampAdd: date_delta_to_binary_interval_op(),
782
785
  exp.TimestampDiff: lambda self, e: self.func(
783
786
  "DATE_DIFF", exp.Literal.string(e.unit), e.expression, e.this
784
787
  ),
788
+ exp.TimestampSub: date_delta_to_binary_interval_op(),
785
789
  exp.TimestampTrunc: timestamptrunc_sql(),
786
790
  exp.TimeStrToDate: lambda self, e: self.sql(exp.cast(e.this, exp.DataType.Type.DATE)),
787
791
  exp.TimeStrToTime: timestrtotime_sql,
@@ -799,7 +803,7 @@ class DuckDB(Dialect):
799
803
  exp.cast(e.expression, exp.DataType.Type.TIMESTAMP),
800
804
  exp.cast(e.this, exp.DataType.Type.TIMESTAMP),
801
805
  ),
802
- exp.UnixMicros: rename_func("EPOCH_US"),
806
+ exp.UnixMicros: lambda self, e: self.func("EPOCH_US", _implicit_datetime_cast(e.this)),
803
807
  exp.UnixToStr: lambda self, e: self.func(
804
808
  "STRFTIME", self.func("TO_TIMESTAMP", e.this), self.format_time(e)
805
809
  ),
@@ -989,6 +993,16 @@ class DuckDB(Dialect):
989
993
  return f"CAST({self.func('TRY_STRPTIME', expression.this, formatted_time)} AS DATE)"
990
994
  return f"CAST({str_to_time_sql(self, expression)} AS DATE)"
991
995
 
996
+ def currentdate_sql(self, expression: exp.CurrentDate) -> str:
997
+ if not expression.this:
998
+ return "CURRENT_DATE"
999
+
1000
+ expr = exp.Cast(
1001
+ this=exp.AtTimeZone(this=exp.CurrentTimestamp(), zone=expression.this),
1002
+ to=exp.DataType(this=exp.DataType.Type.DATE),
1003
+ )
1004
+ return self.sql(expr)
1005
+
992
1006
  def parsejson_sql(self, expression: exp.ParseJSON) -> str:
993
1007
  arg = expression.this
994
1008
  if expression.args.get("safe"):
@@ -163,6 +163,7 @@ class MySQL(Dialect):
163
163
  SUPPORTS_USER_DEFINED_TYPES = False
164
164
  SUPPORTS_SEMI_ANTI_JOIN = False
165
165
  SAFE_DIVISION = True
166
+ SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
166
167
 
167
168
  # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions
168
169
  TIME_MAPPING = {
@@ -37,6 +37,7 @@ from sqlglot.dialects.dialect import (
37
37
  count_if_to_sum,
38
38
  groupconcat_sql,
39
39
  Version,
40
+ regexp_replace_global_modifier,
40
41
  )
41
42
  from sqlglot.generator import unsupported_args
42
43
  from sqlglot.helper import is_int, seq_get
@@ -203,6 +204,7 @@ def _build_regexp_replace(args: t.List, dialect: DialectType = None) -> exp.Rege
203
204
  # Any one of `start`, `N` and `flags` can be column references, meaning that
204
205
  # unless we can statically see that the last argument is a non-integer string
205
206
  # (eg. not '0'), then it's not possible to construct the correct AST
207
+ regexp_replace = None
206
208
  if len(args) > 3:
207
209
  last = args[-1]
208
210
  if not is_int(last.name):
@@ -214,9 +216,10 @@ def _build_regexp_replace(args: t.List, dialect: DialectType = None) -> exp.Rege
214
216
  if last.is_type(*exp.DataType.TEXT_TYPES):
215
217
  regexp_replace = exp.RegexpReplace.from_arg_list(args[:-1])
216
218
  regexp_replace.set("modifiers", last)
217
- return regexp_replace
218
219
 
219
- return exp.RegexpReplace.from_arg_list(args)
220
+ regexp_replace = regexp_replace or exp.RegexpReplace.from_arg_list(args)
221
+ regexp_replace.set("single_replace", True)
222
+ return regexp_replace
220
223
 
221
224
 
222
225
  def _unix_to_time_sql(self: Postgres.Generator, expression: exp.UnixToTime) -> str:
@@ -651,6 +654,15 @@ class Postgres(Dialect):
651
654
  exp.Rand: rename_func("RANDOM"),
652
655
  exp.RegexpLike: lambda self, e: self.binary(e, "~"),
653
656
  exp.RegexpILike: lambda self, e: self.binary(e, "~*"),
657
+ exp.RegexpReplace: lambda self, e: self.func(
658
+ "REGEXP_REPLACE",
659
+ e.this,
660
+ e.expression,
661
+ e.args.get("replacement"),
662
+ e.args.get("position"),
663
+ e.args.get("occurrence"),
664
+ regexp_replace_global_modifier(e),
665
+ ),
654
666
  exp.Select: transforms.preprocess(
655
667
  [
656
668
  transforms.eliminate_semi_and_anti_joins,
@@ -8,10 +8,10 @@ from sqlglot.dialects.dialect import (
8
8
  NormalizationStrategy,
9
9
  annotate_with_type_lambda,
10
10
  build_timetostr_or_tochar,
11
+ build_like,
11
12
  binary_from_function,
12
13
  build_default_decimal_type,
13
14
  build_replace_with_optional_replacement,
14
- build_timestamp_from_parts,
15
15
  date_delta_sql,
16
16
  date_trunc_to_time,
17
17
  datestrtodate_sql,
@@ -362,15 +362,6 @@ def _build_regexp_extract(expr_type: t.Type[E]) -> t.Callable[[t.List], E]:
362
362
  return _builder
363
363
 
364
364
 
365
- def _build_like(expr_type: t.Type[E]) -> t.Callable[[t.List], E | exp.Escape]:
366
- def _builder(args: t.List) -> E | exp.Escape:
367
- like_expr = expr_type(this=args[0], expression=args[1])
368
- escape = seq_get(args, 2)
369
- return exp.Escape(this=like_expr, expression=escape) if escape else like_expr
370
-
371
- return _builder
372
-
373
-
374
365
  def _regexpextract_sql(self, expression: exp.RegexpExtract | exp.RegexpExtractAll) -> str:
375
366
  # Other dialects don't support all of the following parameters, so we need to
376
367
  # generate default values as necessary to ensure the transpilation is correct
@@ -551,6 +542,34 @@ def _annotate_reverse(self: TypeAnnotator, expression: exp.Reverse) -> exp.Rever
551
542
  return expression
552
543
 
553
544
 
545
+ def _annotate_timestamp_from_parts(
546
+ self: TypeAnnotator, expression: exp.TimestampFromParts
547
+ ) -> exp.TimestampFromParts:
548
+ """Annotate TimestampFromParts with correct type based on arguments.
549
+ TIMESTAMP_FROM_PARTS with time_zone -> TIMESTAMPTZ
550
+ TIMESTAMP_FROM_PARTS without time_zone -> TIMESTAMP (defaults to TIMESTAMP_NTZ)
551
+ """
552
+ self._annotate_args(expression)
553
+
554
+ if expression.args.get("zone"):
555
+ self._set_type(expression, exp.DataType.Type.TIMESTAMPTZ)
556
+ else:
557
+ self._set_type(expression, exp.DataType.Type.TIMESTAMP)
558
+
559
+ return expression
560
+
561
+
562
+ def _build_timestamp_from_parts(args: t.List) -> exp.Func:
563
+ """Build TimestampFromParts with support for both syntaxes:
564
+ 1. TIMESTAMP_FROM_PARTS(year, month, day, hour, minute, second [, nanosecond] [, time_zone])
565
+ 2. TIMESTAMP_FROM_PARTS(date_expr, time_expr) - Snowflake specific
566
+ """
567
+ if len(args) == 2:
568
+ return exp.TimestampFromParts(this=seq_get(args, 0), expression=seq_get(args, 1))
569
+
570
+ return exp.TimestampFromParts.from_arg_list(args)
571
+
572
+
554
573
  def _annotate_date_or_time_add(self: TypeAnnotator, expression: E) -> E:
555
574
  self._annotate_args(expression)
556
575
 
@@ -588,6 +607,8 @@ class Snowflake(Dialect):
588
607
  exp.Degrees,
589
608
  exp.Exp,
590
609
  exp.MonthsBetween,
610
+ exp.RegrValx,
611
+ exp.RegrValy,
591
612
  exp.Sin,
592
613
  exp.Sinh,
593
614
  exp.Tan,
@@ -680,6 +701,10 @@ class Snowflake(Dialect):
680
701
  exp.DataType.Type.BOOLEAN: {
681
702
  *Dialect.TYPE_TO_EXPRESSIONS[exp.DataType.Type.BOOLEAN],
682
703
  exp.Boolnot,
704
+ exp.Booland,
705
+ exp.Boolor,
706
+ exp.EqualNull,
707
+ exp.IsNullValue,
683
708
  exp.Search,
684
709
  },
685
710
  exp.DataType.Type.DATE: {
@@ -734,8 +759,11 @@ class Snowflake(Dialect):
734
759
  else exp.DataType.Type.TIMESTAMPTZ,
735
760
  ),
736
761
  exp.DateAdd: _annotate_date_or_time_add,
737
- exp.Reverse: _annotate_reverse,
738
762
  exp.TimeAdd: _annotate_date_or_time_add,
763
+ exp.GreatestIgnoreNulls: lambda self, e: self._annotate_by_args(e, "expressions"),
764
+ exp.LeastIgnoreNulls: lambda self, e: self._annotate_by_args(e, "expressions"),
765
+ exp.Reverse: _annotate_reverse,
766
+ exp.TimestampFromParts: _annotate_timestamp_from_parts,
739
767
  }
740
768
 
741
769
  TIME_MAPPING = {
@@ -889,10 +917,10 @@ class Snowflake(Dialect):
889
917
  "TIMEDIFF": _build_datediff,
890
918
  "TIMESTAMPADD": _build_date_time_add(exp.DateAdd),
891
919
  "TIMESTAMPDIFF": _build_datediff,
892
- "TIMESTAMPFROMPARTS": build_timestamp_from_parts,
893
- "TIMESTAMP_FROM_PARTS": build_timestamp_from_parts,
894
- "TIMESTAMPNTZFROMPARTS": build_timestamp_from_parts,
895
- "TIMESTAMP_NTZ_FROM_PARTS": build_timestamp_from_parts,
920
+ "TIMESTAMPFROMPARTS": _build_timestamp_from_parts,
921
+ "TIMESTAMP_FROM_PARTS": _build_timestamp_from_parts,
922
+ "TIMESTAMPNTZFROMPARTS": _build_timestamp_from_parts,
923
+ "TIMESTAMP_NTZ_FROM_PARTS": _build_timestamp_from_parts,
896
924
  "TRY_PARSE_JSON": lambda args: exp.ParseJSON(this=seq_get(args, 0), safe=True),
897
925
  "TRY_TO_DATE": _build_datetime("TRY_TO_DATE", exp.DataType.Type.DATE, safe=True),
898
926
  "TRY_TO_TIME": _build_datetime("TRY_TO_TIME", exp.DataType.Type.TIME, safe=True),
@@ -916,9 +944,11 @@ class Snowflake(Dialect):
916
944
  "TO_JSON": exp.JSONFormat.from_arg_list,
917
945
  "VECTOR_L2_DISTANCE": exp.EuclideanDistance.from_arg_list,
918
946
  "ZEROIFNULL": _build_if_from_zeroifnull,
919
- "LIKE": _build_like(exp.Like),
920
- "ILIKE": _build_like(exp.ILike),
947
+ "LIKE": build_like(exp.Like),
948
+ "ILIKE": build_like(exp.ILike),
921
949
  "SEARCH": _build_search,
950
+ "WEEKISO": exp.WeekOfYear.from_arg_list,
951
+ "WEEKOFYEAR": exp.Week.from_arg_list,
922
952
  }
923
953
  FUNCTIONS.pop("PREDICT")
924
954
 
@@ -1624,9 +1654,16 @@ class Snowflake(Dialect):
1624
1654
  exp.UnixToTime: rename_func("TO_TIMESTAMP"),
1625
1655
  exp.Uuid: rename_func("UUID_STRING"),
1626
1656
  exp.VarMap: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),
1627
- exp.WeekOfYear: rename_func("WEEKOFYEAR"),
1657
+ exp.Booland: rename_func("BOOLAND"),
1658
+ exp.Boolor: rename_func("BOOLOR"),
1659
+ exp.WeekOfYear: rename_func("WEEKISO"),
1660
+ exp.YearOfWeek: rename_func("YEAROFWEEK"),
1661
+ exp.YearOfWeekIso: rename_func("YEAROFWEEKISO"),
1628
1662
  exp.Xor: rename_func("BOOLXOR"),
1629
1663
  exp.ByteLength: rename_func("OCTET_LENGTH"),
1664
+ exp.ArrayConcatAgg: lambda self, e: self.func(
1665
+ "ARRAY_FLATTEN", exp.ArrayAgg(this=e.this)
1666
+ ),
1630
1667
  }
1631
1668
 
1632
1669
  SUPPORTED_JSON_PATH_PARTS = {
@@ -6,6 +6,7 @@ from sqlglot import exp
6
6
  from sqlglot.dialects.dialect import (
7
7
  Version,
8
8
  rename_func,
9
+ build_like,
9
10
  unit_to_var,
10
11
  timestampdiff_sql,
11
12
  build_date_delta,
@@ -147,6 +148,8 @@ class Spark(Spark2):
147
148
  offset=1,
148
149
  safe=True,
149
150
  ),
151
+ "LIKE": build_like(exp.Like),
152
+ "ILIKE": build_like(exp.ILike),
150
153
  }
151
154
 
152
155
  PLACEHOLDER_PARSERS = {
@@ -89,6 +89,7 @@ class SQLite(Dialect):
89
89
  SUPPORTS_SEMI_ANTI_JOIN = False
90
90
  TYPED_DIVISION = True
91
91
  SAFE_DIVISION = True
92
+ SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
92
93
 
93
94
  class Tokenizer(tokens.Tokenizer):
94
95
  IDENTIFIERS = ['"', ("[", "]"), "`"]
@@ -31,7 +31,6 @@ if t.TYPE_CHECKING:
31
31
  def execute(
32
32
  sql: str | Expression,
33
33
  schema: t.Optional[t.Dict | Schema] = None,
34
- read: DialectType = None,
35
34
  dialect: DialectType = None,
36
35
  tables: t.Optional[t.Dict] = None,
37
36
  ) -> Table:
@@ -45,15 +44,13 @@ def execute(
45
44
  1. {table: {col: type}}
46
45
  2. {db: {table: {col: type}}}
47
46
  3. {catalog: {db: {table: {col: type}}}}
48
- read: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
49
- dialect: the SQL dialect (alias for read).
47
+ dialect: the SQL dialect to apply during parsing (eg. "spark", "hive", "presto", "mysql").
50
48
  tables: additional tables to register.
51
49
 
52
50
  Returns:
53
51
  Simple columnar data structure.
54
52
  """
55
- read = read or dialect
56
- tables_ = ensure_tables(tables, dialect=read)
53
+ tables_ = ensure_tables(tables, dialect=dialect)
57
54
 
58
55
  if not schema:
59
56
  schema = {}
@@ -66,19 +63,17 @@ def execute(
66
63
  for column in table.columns:
67
64
  value = table[0][column]
68
65
  column_type = (
69
- annotate_types(exp.convert(value), dialect=read).type or type(value).__name__
66
+ annotate_types(exp.convert(value), dialect=dialect).type or type(value).__name__
70
67
  )
71
68
  nested_set(schema, [*keys, column], column_type)
72
69
 
73
- schema = ensure_schema(schema, dialect=read)
70
+ schema = ensure_schema(schema, dialect=dialect)
74
71
 
75
72
  if tables_.supported_table_args and tables_.supported_table_args != schema.supported_table_args:
76
73
  raise ExecuteError("Tables must support the same table args as schema")
77
74
 
78
75
  now = time.time()
79
- expression = optimize(
80
- sql, schema, leave_tables_isolated=True, infer_csv_schemas=True, dialect=read
81
- )
76
+ expression = optimize(sql, schema, leave_tables_isolated=True, dialect=dialect)
82
77
 
83
78
  logger.debug("Optimization finished: %f", time.time() - now)
84
79
  logger.debug("Optimized SQL: %s", expression.sql(pretty=True))
@@ -1,4 +1,3 @@
1
- import ast
2
1
  import collections
3
2
  import itertools
4
3
  import math
@@ -9,7 +8,7 @@ from sqlglot.errors import ExecuteError
9
8
  from sqlglot.executor.context import Context
10
9
  from sqlglot.executor.env import ENV
11
10
  from sqlglot.executor.table import RowReader, Table
12
- from sqlglot.helper import csv_reader, subclasses
11
+ from sqlglot.helper import subclasses
13
12
 
14
13
 
15
14
  class PythonExecutor:
@@ -97,9 +96,6 @@ class PythonExecutor:
97
96
  if not step.projections and not step.condition:
98
97
  return self.context({step.name: context.tables[source]})
99
98
  table_iter = context.table_iter(source)
100
- elif isinstance(step.source, exp.Table) and isinstance(step.source.this, exp.ReadCSV):
101
- table_iter = self.scan_csv(step)
102
- context = next(table_iter)
103
99
  else:
104
100
  context, table_iter = self.scan_table(step)
105
101
 
@@ -132,30 +128,6 @@ class PythonExecutor:
132
128
  context = self.context({step.source.alias_or_name: table})
133
129
  return context, iter(table)
134
130
 
135
- def scan_csv(self, step):
136
- alias = step.source.alias
137
- source = step.source.this
138
-
139
- with csv_reader(source) as reader:
140
- columns = next(reader)
141
- table = Table(columns)
142
- context = self.context({alias: table})
143
- yield context
144
- types = []
145
- for row in reader:
146
- if not types:
147
- for v in row:
148
- try:
149
- types.append(type(ast.literal_eval(v)))
150
- except (ValueError, SyntaxError):
151
- types.append(str)
152
-
153
- # We can't cast empty values ('') to non-string types, so we convert them to None instead
154
- context.set_row(
155
- tuple(None if (t is not str and v == "") else t(v) for t, v in zip(types, row))
156
- )
157
- yield context.table.reader
158
-
159
131
  def join(self, step, context):
160
132
  source = step.source_name
161
133