1
0
Fork 0

Merging upstream version 18.11.2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:04:58 +01:00
parent 15b8b39545
commit c37998973e
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
88 changed files with 52059 additions and 46960 deletions

View file

@ -1,6 +1,132 @@
Changelog Changelog
========= =========
## [v18.11.1] - 2023-10-03
### :bug: Bug Fixes
- [`f777155`](https://github.com/tobymao/sqlglot/commit/f777155eb6249a51290d38eaa1dfa1f867a38602) - unescape escape sequences on read, re-escape them on generation *(PR [#2367](https://github.com/tobymao/sqlglot/pull/2367) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2325](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`0d1e674`](https://github.com/tobymao/sqlglot/commit/0d1e674015a6ff3eca90a6b6263119ad01a55db6) - **optimizer**: handle edge case in DATE_TRUNC simplification *(PR [#2368](https://github.com/tobymao/sqlglot/pull/2368) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
## [v18.11.0] - 2023-10-03
### :sparkles: New Features
- [`e4da5d7`](https://github.com/tobymao/sqlglot/commit/e4da5d732d8b3add5c73a0aee66838a806a8e506) - **clickhouse**: add support for SAMPLE BY property in CREATE DDL *(PR [#2355](https://github.com/tobymao/sqlglot/pull/2355) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2352](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`8dc2a9c`](https://github.com/tobymao/sqlglot/commit/8dc2a9ccbec63b9a2dec577547e301046a02a4d8) - add the ability to set meta in sql comments *(PR [#2351](https://github.com/tobymao/sqlglot/pull/2351) by [@tobymao](https://github.com/tobymao))*
- [`d2047ec`](https://github.com/tobymao/sqlglot/commit/d2047ec67d486e42506db7d0f1a642a5e6c40c11) - **snowflake**: add support for staged file file_format clause *(PR [#2359](https://github.com/tobymao/sqlglot/pull/2359) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`55e2d15`](https://github.com/tobymao/sqlglot/commit/55e2d15519830a91a420c5ad3315b75ddd2087ce) - switch identifier normalization off using comments *(PR [#2361](https://github.com/tobymao/sqlglot/pull/2361) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
### :bug: Bug Fixes
- [`1df9333`](https://github.com/tobymao/sqlglot/commit/1df93336d49a12f4ac00b0da45c05c07735ffa11) - **parser**: exclude set operators from unnest offset alias token set *(PR [#2349](https://github.com/tobymao/sqlglot/pull/2349) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2348](undefined) opened by [@sean-rose](https://github.com/sean-rose)*
- [`a794bfe`](https://github.com/tobymao/sqlglot/commit/a794bfef771ced62dd3720a9d3bd49e9e99bd020) - **hive**: don't generate WithDataProperty *(PR [#2350](https://github.com/tobymao/sqlglot/pull/2350) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`5fb7174`](https://github.com/tobymao/sqlglot/commit/5fb71743d9274b7e0e825a761be3672c6299e453) - fix perf issues with nested left joins *(commit by [@tobymao](https://github.com/tobymao))*
- [`ac4e572`](https://github.com/tobymao/sqlglot/commit/ac4e572be99a636ea013db3c33bf01bc80732d57) - handle strings in Table.parts, use dialect for parsing in table_name *(PR [#2353](https://github.com/tobymao/sqlglot/pull/2353) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`e8273e2`](https://github.com/tobymao/sqlglot/commit/e8273e26b2300e7782c33c9858b0217af3570e4c) - **hive**: don't generate BYTE when transpiling Oracle's VARCHAR(5 BYTE) *(PR [#2358](https://github.com/tobymao/sqlglot/pull/2358) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2356](undefined) opened by [@CaryMoore-DB](https://github.com/CaryMoore-DB)*
- [`2bc30a5`](https://github.com/tobymao/sqlglot/commit/2bc30a5de6c642a49e8ad66dbc5c6f6c82cb77d9) - **mysql**: DATE_ADD for datetimes *(PR [#2360](https://github.com/tobymao/sqlglot/pull/2360) by [@barakalon](https://github.com/barakalon))*
- [`a270c15`](https://github.com/tobymao/sqlglot/commit/a270c15480e2db592b0a2f13c8fb3edb8587cdaa) - **redshift**: treat single quote as an escape character *(PR [#2365](https://github.com/tobymao/sqlglot/pull/2365) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2364](undefined) opened by [@erdrix](https://github.com/erdrix)*
- [`0e93890`](https://github.com/tobymao/sqlglot/commit/0e93890670596b5cf97d66eabb84bd0be4f0bb13) - **optimizer**: don't merge CTEs with EXPLODE projections into outer scopes *(PR [#2366](https://github.com/tobymao/sqlglot/pull/2366) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
## [v18.10.1] - 2023-09-29
### :sparkles: New Features
- [`4665016`](https://github.com/tobymao/sqlglot/commit/466501635d131a91812684441fdfbbfede53a242) - **postgres**: struct_extract *(commit by [@tobymao](https://github.com/tobymao))*
### :bug: Bug Fixes
- [`17e39d0`](https://github.com/tobymao/sqlglot/commit/17e39d04916e3e406307ed8922cb2597b4a6998a) - **snowflake**: fix staged table path parsing *(PR [#2346](https://github.com/tobymao/sqlglot/pull/2346) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
## [v18.10.0] - 2023-09-29
### :sparkles: New Features
- [`090724d`](https://github.com/tobymao/sqlglot/commit/090724da9ed7a9c1c0b8024b68340a15b0b64ff0) - add `eliminate_qualify` to clickhouse, mysql, oracle, postgres, and tsql dialects *(PR [#2339](https://github.com/tobymao/sqlglot/pull/2339) by [@cpcloud](https://github.com/cpcloud))*
- [`e2c8366`](https://github.com/tobymao/sqlglot/commit/e2c83665f81db2af934f1ae831748578bcef8216) - **executor**: add support for TRIM, fix TRIM CSV-style parsing order *(PR [#2342](https://github.com/tobymao/sqlglot/pull/2342) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2341](undefined) opened by [@skyserenaa](https://github.com/skyserenaa)*
### :bug: Bug Fixes
- [`fcc2d8f`](https://github.com/tobymao/sqlglot/commit/fcc2d8f4d3077c9f8fd59fbd906cbdf8985bac8c) - **mysql,optimizer**: TO_DAYS transpilation and more date casting *(PR [#2334](https://github.com/tobymao/sqlglot/pull/2334) by [@barakalon](https://github.com/barakalon))*
## [v18.9.0] - 2023-09-28
### :boom: BREAKING CHANGES
- due to [`f0e5eb6`](https://github.com/tobymao/sqlglot/commit/f0e5eb6a904d8ee4420c6a9acf489db9b7fa108f) - revert escape sequence changes introduced in [#2230](https://github.com/tobymao/sqlglot/pull/2230) *(PR [#2336](https://github.com/tobymao/sqlglot/pull/2336) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
revert escape sequence changes introduced in #2230 (#2336)
### :sparkles: New Features
- [`f80501c`](https://github.com/tobymao/sqlglot/commit/f80501ce1d262587856201e2ef2c625dbd446959) - **presto**: group_concat -> array_join closes [#2331](https://github.com/tobymao/sqlglot/pull/2331) *(commit by [@tobymao](https://github.com/tobymao))*
- [`8af4054`](https://github.com/tobymao/sqlglot/commit/8af4054d4e96b62309b1543d51548728bdba520f) - **snowflake**: add support for staged file table syntax *(PR [#2333](https://github.com/tobymao/sqlglot/pull/2333) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2330](undefined) opened by [@ShayYaari](https://github.com/ShayYaari)*
- [`bcd342a`](https://github.com/tobymao/sqlglot/commit/bcd342a739f5202737be147b98ec7852373d2a86) - **mysql**: add unsigned decimal type *(PR [#2340](https://github.com/tobymao/sqlglot/pull/2340) by [@Nitrino](https://github.com/Nitrino))*
### :bug: Bug Fixes
- [`58c7849`](https://github.com/tobymao/sqlglot/commit/58c7849042178ed6b46e39edf9a98fd101ac2bf3) - **clickhouse**: don't generate parentheses, match R_PAREN conditionally *(PR [#2332](https://github.com/tobymao/sqlglot/pull/2332) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`f0e5eb6`](https://github.com/tobymao/sqlglot/commit/f0e5eb6a904d8ee4420c6a9acf489db9b7fa108f) - revert escape sequence changes introduced in [#2230](https://github.com/tobymao/sqlglot/pull/2230) *(PR [#2336](https://github.com/tobymao/sqlglot/pull/2336) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`5ea5438`](https://github.com/tobymao/sqlglot/commit/5ea54385b6cbeafbfdf89ff414b6c2638445af61) - **snowflake**: allow window to be used as a table alias *(PR [#2337](https://github.com/tobymao/sqlglot/pull/2337) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2335](undefined) opened by [@arunbalasubramani](https://github.com/arunbalasubramani)*
- [`79c208a`](https://github.com/tobymao/sqlglot/commit/79c208a253020fdc153c85e19869ca32101f2367) - **snowflake, bigquery**: parse COLLATE as a func instead of a binary operator *(PR [#2343](https://github.com/tobymao/sqlglot/pull/2343) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
## [v18.8.0] - 2023-09-26
### :boom: BREAKING CHANGES
- due to [`66d7385`](https://github.com/tobymao/sqlglot/commit/66d738514feaddf3a92095dcdef62c0d43c291f5) - store expressions in Offset.expression when using builder fixes [#2312](https://github.com/tobymao/sqlglot/pull/2312) *(commit by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
store expressions in Offset.expression when using builder fixes #2312
- due to [`cdcc564`](https://github.com/tobymao/sqlglot/commit/cdcc564130a01188295948d5562f71d78dbffa12) - make ObjectIdentifier, IntervalSpan and PseudoType DataTypes *(PR [#2315](https://github.com/tobymao/sqlglot/pull/2315) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
make ObjectIdentifier, IntervalSpan and PseudoType DataTypes (#2315)
- due to [`ebdfc59`](https://github.com/tobymao/sqlglot/commit/ebdfc592026db133f4a9828ff88c096a7d6b0f54) - add support for heredoc strings (Postgres, ClickHouse) *(PR [#2328](https://github.com/tobymao/sqlglot/pull/2328) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
add support for heredoc strings (Postgres, ClickHouse) (#2328)
### :sparkles: New Features
- [`c50e74c`](https://github.com/tobymao/sqlglot/commit/c50e74cf78a64d7b461054d4dc35a2e40195277b) - support for percentiles in duckdb, snowflake *(PR [#2302](https://github.com/tobymao/sqlglot/pull/2302) by [@longxiaofei](https://github.com/longxiaofei))*
- [`8ed0a81`](https://github.com/tobymao/sqlglot/commit/8ed0a810ef4ec36ca648ad55b7a873ce04b8da30) - **bigquery**: add support for CREATE TABLE .. COPY DDL syntax *(PR [#2305](https://github.com/tobymao/sqlglot/pull/2305) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2304](undefined) opened by [@razvan-am](https://github.com/razvan-am)*
- [`3cb3131`](https://github.com/tobymao/sqlglot/commit/3cb3131fc9210c46afba2ece8c43fad852106de5) - **clickhouse**: add isnan and startswith renamings *(PR [#2310](https://github.com/tobymao/sqlglot/pull/2310) by [@cpcloud](https://github.com/cpcloud))*
- [`f473e88`](https://github.com/tobymao/sqlglot/commit/f473e88523d2c0a66719e3b8a3e8fcfb6cc5ed3c) - **postgres**: add support for operator classes in CREATE INDEX DDL *(PR [#2317](https://github.com/tobymao/sqlglot/pull/2317) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2278](undefined) opened by [@Nitrino](https://github.com/Nitrino)*
- [`64a7b93`](https://github.com/tobymao/sqlglot/commit/64a7b93a62595201294b0b30a1c791d9ffc6f856) - **optimizer**: canonicalize date arithmetic funcs *(PR [#2320](https://github.com/tobymao/sqlglot/pull/2320) by [@barakalon](https://github.com/barakalon))*
- [`f3d928b`](https://github.com/tobymao/sqlglot/commit/f3d928bd48f7268a43f0803845c734d6e1fedd34) - **optimizer**: ensure boolean predicates on CASE statement *(PR [#2321](https://github.com/tobymao/sqlglot/pull/2321) by [@barakalon](https://github.com/barakalon))*
- [`ebdfc59`](https://github.com/tobymao/sqlglot/commit/ebdfc592026db133f4a9828ff88c096a7d6b0f54) - add support for heredoc strings (Postgres, ClickHouse) *(PR [#2328](https://github.com/tobymao/sqlglot/pull/2328) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2316](undefined) opened by [@pkit](https://github.com/pkit)*
### :bug: Bug Fixes
- [`c51ecb1`](https://github.com/tobymao/sqlglot/commit/c51ecb168a068079f331c0a4c67b5ca61f6674f1) - **clickhouse**: fix incorrect array param generation for clickhouse quantiles *(PR [#2311](https://github.com/tobymao/sqlglot/pull/2311) by [@cpcloud](https://github.com/cpcloud))*
- [`66d7385`](https://github.com/tobymao/sqlglot/commit/66d738514feaddf3a92095dcdef62c0d43c291f5) - store expressions in Offset.expression when using builder fixes [#2312](https://github.com/tobymao/sqlglot/pull/2312) *(commit by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`cdcc564`](https://github.com/tobymao/sqlglot/commit/cdcc564130a01188295948d5562f71d78dbffa12) - make ObjectIdentifier, IntervalSpan and PseudoType DataTypes *(PR [#2315](https://github.com/tobymao/sqlglot/pull/2315) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`aa2c4c3`](https://github.com/tobymao/sqlglot/commit/aa2c4c3dbb07116e595690a56e7bc2d123557545) - **optimizer**: a couple simplify_date_trunc enhancements *(PR [#2319](https://github.com/tobymao/sqlglot/pull/2319) by [@barakalon](https://github.com/barakalon))*
- [`180cd8e`](https://github.com/tobymao/sqlglot/commit/180cd8e21713f01080a6b32c55739f5220f56526) - **clickhouse**: support SAMPLE clause fixes [#2323](https://github.com/tobymao/sqlglot/pull/2323) *(commit by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`8242a2c`](https://github.com/tobymao/sqlglot/commit/8242a2c65466ab7245a4a9573403787a262d0bbc) - **mysql**: transpile CHAR *(PR [#2329](https://github.com/tobymao/sqlglot/pull/2329) by [@barakalon](https://github.com/barakalon))*
### :wrench: Chores
- [`363e102`](https://github.com/tobymao/sqlglot/commit/363e10244e8afadca18ffbb303cd6c1765fe1a46) - fix type *(commit by [@tobymao](https://github.com/tobymao))*
## [v18.7.0] - 2023-09-22
### :sparkles: New Features
- [`f1b6546`](https://github.com/tobymao/sqlglot/commit/f1b6546b463b2a6aa075bf31f54d3aa8a59b748f) - add iter for expressions *(commit by [@tobymao](https://github.com/tobymao))*
- [`13877fe`](https://github.com/tobymao/sqlglot/commit/13877fe117c2811c2cd4d277c585f0cd4715f18a) - **optimizer**: replace date funcs *(PR [#2299](https://github.com/tobymao/sqlglot/pull/2299) by [@barakalon](https://github.com/barakalon))*
### :bug: Bug Fixes
- [`fc793c4`](https://github.com/tobymao/sqlglot/commit/fc793c4ff321808fd359ba3886e236ac7476de0d) - **postgres**: generate ARRAY[] correctly *(PR [#2287](https://github.com/tobymao/sqlglot/pull/2287) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#1457](undefined) opened by [@cmvarmour](https://github.com/cmvarmour)*
- [`06e0869`](https://github.com/tobymao/sqlglot/commit/06e0869e7aa5714d77e6ec763da38d6a422965fa) - unnest complex closes [#2284](https://github.com/tobymao/sqlglot/pull/2284) *(commit by [@tobymao](https://github.com/tobymao))*
- [`5aa7e2a`](https://github.com/tobymao/sqlglot/commit/5aa7e2a8e07cb41ee34c92309d6828e52a4ff64b) - **bigquery**: preserve log argument order when parsing and generation dialects match *(PR [#2293](https://github.com/tobymao/sqlglot/pull/2293) by [@cpcloud](https://github.com/cpcloud))*
- :arrow_lower_right: *fixes issue [#2292](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`44f732d`](https://github.com/tobymao/sqlglot/commit/44f732d56eafb93880790955862bac454edf800f) - **parser**: make kwarg parsing more robust *(PR [#2295](https://github.com/tobymao/sqlglot/pull/2295) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2288](undefined) opened by [@crash-g](https://github.com/crash-g)*
- [`8fe91e2`](https://github.com/tobymao/sqlglot/commit/8fe91e25ff3a8a1c7619b6e50b5d3dcbd6f6521b) - **redshift**: generate correct SQL VALUES clause alias *(PR [#2298](https://github.com/tobymao/sqlglot/pull/2298) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`6429042`](https://github.com/tobymao/sqlglot/commit/642904248523c04f17ee67d7d075237f48a72159) - **bigquery**: anticipate OPTION property after JS UDF definition *(PR [#2297](https://github.com/tobymao/sqlglot/pull/2297) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2290](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`29550c1`](https://github.com/tobymao/sqlglot/commit/29550c131ce2d0209a11cd045a23683b6218c40f) - safedpipe is always varchar *(commit by [@tobymao](https://github.com/tobymao))*
## [v18.6.0] - 2023-09-21 ## [v18.6.0] - 2023-09-21
### :boom: BREAKING CHANGES ### :boom: BREAKING CHANGES
- due to [`8100311`](https://github.com/tobymao/sqlglot/commit/8100311e68d79914dbcd1da0fd56cd963eb8c189) - explode to unnest with multiple explosions *(PR [#2235](https://github.com/tobymao/sqlglot/pull/2235) by [@tobymao](https://github.com/tobymao))*: - due to [`8100311`](https://github.com/tobymao/sqlglot/commit/8100311e68d79914dbcd1da0fd56cd963eb8c189) - explode to unnest with multiple explosions *(PR [#2235](https://github.com/tobymao/sqlglot/pull/2235) by [@tobymao](https://github.com/tobymao))*:
@ -1498,3 +1624,10 @@ Changelog
[v18.5.0]: https://github.com/tobymao/sqlglot/compare/v18.4.1...v18.5.0 [v18.5.0]: https://github.com/tobymao/sqlglot/compare/v18.4.1...v18.5.0
[v18.5.1]: https://github.com/tobymao/sqlglot/compare/v18.5.0...v18.5.1 [v18.5.1]: https://github.com/tobymao/sqlglot/compare/v18.5.0...v18.5.1
[v18.6.0]: https://github.com/tobymao/sqlglot/compare/v18.5.1...v18.6.0 [v18.6.0]: https://github.com/tobymao/sqlglot/compare/v18.5.1...v18.6.0
[v18.7.0]: https://github.com/tobymao/sqlglot/compare/v18.6.0...v18.7.0
[v18.8.0]: https://github.com/tobymao/sqlglot/compare/v18.7.0...v18.8.0
[v18.9.0]: https://github.com/tobymao/sqlglot/compare/v18.8.0...v18.9.0
[v18.10.0]: https://github.com/tobymao/sqlglot/compare/v18.9.0...v18.10.0
[v18.10.1]: https://github.com/tobymao/sqlglot/compare/v18.10.0...v18.10.1
[v18.11.0]: https://github.com/tobymao/sqlglot/compare/v18.10.1...v18.11.0
[v18.11.1]: https://github.com/tobymao/sqlglot/compare/v18.11.0...v18.11.1

File diff suppressed because one or more lines are too long

View file

@ -28,6 +28,19 @@
<h2>API Documentation</h2>
<ul class="memberlist">
<li>
<a class="variable" href="#TYPE_CHECKING">TYPE_CHECKING</a>
</li>
<li>
<a class="variable" href="#version">version</a>
</li>
<li>
<a class="variable" href="#version_tuple">version_tuple</a>
</li>
</ul>
<footer>Copyright (c) 2023 Toby Mao</footer> <footer>Copyright (c) 2023 Toby Mao</footer>
@ -49,13 +62,61 @@
<label class="view-source-button" for="mod-_version-view-source"><span>View Source</span></label> <label class="view-source-button" for="mod-_version-view-source"><span>View Source</span></label>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos">1</span></a><span class="c1"># file generated by setuptools_scm</span> <div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="c1"># file generated by setuptools_scm</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos">2</span></a><span class="c1"># don&#39;t change, don&#39;t track in version control</span> </span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="c1"># don&#39;t change, don&#39;t track in version control</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos">3</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;18.6.0&#39;</span> </span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="n">TYPE_CHECKING</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos">4</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> </span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="k">if</span> <span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a> <span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Tuple</span><span class="p">,</span> <span class="n">Union</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a> <span class="n">VERSION_TUPLE</span> <span class="o">=</span> <span class="n">Tuple</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">],</span> <span class="o">...</span><span class="p">]</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="k">else</span><span class="p">:</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> <span class="n">VERSION_TUPLE</span> <span class="o">=</span> <span class="nb">object</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="n">version</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="n">__version__</span><span class="p">:</span> <span class="nb">str</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;18.11.1&#39;</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
</section>
<section id="TYPE_CHECKING">
<div class="attr variable">
<span class="name">TYPE_CHECKING</span> =
<span class="default_value">False</span>
</div>
<a class="headerlink" href="#TYPE_CHECKING"></a>
</section>
<section id="version">
<div class="attr variable">
<span class="name">version</span><span class="annotation">: str</span> =
<span class="default_value">&#39;18.11.1&#39;</span>
</div>
<a class="headerlink" href="#version"></a>
</section>
<section id="version_tuple">
<div class="attr variable">
<span class="name">version_tuple</span><span class="annotation">: object</span> =
<span class="default_value">(18, 11, 1)</span>
</div>
<a class="headerlink" href="#version_tuple"></a>
</section> </section>
</main> </main>
<script> <script>

View file

@ -777,7 +777,7 @@
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">createDataFrame</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">data</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641746816&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641746816&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="n">Tuple</span><span class="p">]]</span>,</span><span class="param"> <span class="n">schema</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641690752&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">samplingRatio</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">float</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">verifySchema</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span> <span class="name">createDataFrame</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">data</span><span class="p">:</span> <span class="n">Sequence</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879721478480&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879721478480&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="n">Tuple</span><span class="p">]]</span>,</span><span class="param"> <span class="n">schema</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879721383968&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">samplingRatio</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">float</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">verifySchema</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span>
<label class="view-source-button" for="SparkSession.createDataFrame-view-source"><span>View Source</span></label> <label class="view-source-button" for="SparkSession.createDataFrame-view-source"><span>View Source</span></label>
@ -1829,7 +1829,7 @@
<input id="DataFrame.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="DataFrame.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function"> <div class="attr function">
<span class="name">DataFrame</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">spark</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723646523360&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Select">sqlglot.expressions.Select</a></span>,</span><span class="param"> <span class="n">branch_id</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">sequence_id</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">last_op</span><span class="p">:</span> <span class="n">sqlglot</span><span class="o">.</span><span class="n">dataframe</span><span class="o">.</span><span class="n">sql</span><span class="o">.</span><span class="n">operations</span><span class="o">.</span><span class="n">Operation</span> <span class="o">=</span> <span class="o">&lt;</span><span class="n">Operation</span><span class="o">.</span><span class="n">INIT</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">pending_hints</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">output_expression_container</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723646524944&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span>)</span> <span class="name">DataFrame</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">spark</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879724199760&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Select">sqlglot.expressions.Select</a></span>,</span><span class="param"> <span class="n">branch_id</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">sequence_id</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">last_op</span><span class="p">:</span> <span class="n">sqlglot</span><span class="o">.</span><span class="n">dataframe</span><span class="o">.</span><span class="n">sql</span><span class="o">.</span><span class="n">operations</span><span class="o">.</span><span class="n">Operation</span> <span class="o">=</span> <span class="o">&lt;</span><span class="n">Operation</span><span class="o">.</span><span class="n">INIT</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">pending_hints</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">output_expression_container</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879724102464&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span>)</span>
<label class="view-source-button" for="DataFrame.__init__-view-source"><span>View Source</span></label> <label class="view-source-button" for="DataFrame.__init__-view-source"><span>View Source</span></label>
@ -2018,7 +2018,7 @@
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">sql</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">dialect</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723642181744&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">optimize</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>:</span></span> <span class="name">sql</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">dialect</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879720022896&#39;</span><span class="o">&gt;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">optimize</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>:</span></span>
<label class="view-source-button" for="DataFrame.sql-view-source"><span>View Source</span></label> <label class="view-source-button" for="DataFrame.sql-view-source"><span>View Source</span></label>
@ -2773,7 +2773,7 @@ is unlikely to come up.</p>
<div class="decorator">@operation(Operation.FROM)</div> <div class="decorator">@operation(Operation.FROM)</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">fillna</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723642263136&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">subset</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="o">...</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span> <span class="name">fillna</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719639920&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">subset</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="o">...</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span>
<label class="view-source-button" for="DataFrame.fillna-view-source"><span>View Source</span></label> <label class="view-source-button" for="DataFrame.fillna-view-source"><span>View Source</span></label>
@ -2842,7 +2842,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@operation(Operation.FROM)</div> <div class="decorator">@operation(Operation.FROM)</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">replace</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">to_replace</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">bool</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">bool</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">subset</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="n">Collection</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640675040&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640675040&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span> <span class="name">replace</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">to_replace</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">bool</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Dict</span><span class="p">]</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">bool</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">subset</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="n">Collection</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879720333088&#39;</span><span class="o">&gt;</span><span class="p">],</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879720333088&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span>
<label class="view-source-button" for="DataFrame.replace-view-source"><span>View Source</span></label> <label class="view-source-button" for="DataFrame.replace-view-source"><span>View Source</span></label>
@ -3047,7 +3047,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@operation(Operation.NO_OP)</div> <div class="decorator">@operation(Operation.NO_OP)</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">repartition</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">numPartitions</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640834224&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640987104&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span> <span class="name">repartition</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">numPartitions</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879720501456&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879720564960&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#DataFrame">DataFrame</a></span>:</span></span>
<label class="view-source-button" for="DataFrame.repartition-view-source"><span>View Source</span></label> <label class="view-source-button" for="DataFrame.repartition-view-source"><span>View Source</span></label>
@ -3765,7 +3765,7 @@ and check if it matches the type of the value provided. If not then make it null
<input id="Column.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="Column.__init__-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function"> <div class="attr function">
<span class="name">Column</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723644804096&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span></span>)</span> <span class="name">Column</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879722174736&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span></span>)</span>
<label class="view-source-button" for="Column.__init__-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.__init__-view-source"><span>View Source</span></label>
@ -3809,7 +3809,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">ensure_col</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641361440&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">ensure_col</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">value</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718606960&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.ensure_col-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.ensure_col-view-source"><span>View Source</span></label>
@ -3830,7 +3830,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">ensure_cols</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641074208&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n">List</span><span class="p">[</span><span class="n"><a href="#Column">Column</a></span><span class="p">]</span>:</span></span> <span class="name">ensure_cols</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718833936&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n">List</span><span class="p">[</span><span class="n"><a href="#Column">Column</a></span><span class="p">]</span>:</span></span>
<label class="view-source-button" for="Column.ensure_cols-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.ensure_cols-view-source"><span>View Source</span></label>
@ -3851,7 +3851,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">invoke_anonymous_function</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">column</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641354608&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="n">func_name</span><span class="p">:</span> <span class="nb">str</span>,</span><span class="param"> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640624640&#39;</span><span class="o">&gt;</span><span class="p">]</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">invoke_anonymous_function</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">column</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718802608&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="n">func_name</span><span class="p">:</span> <span class="nb">str</span>,</span><span class="param"> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718760704&#39;</span><span class="o">&gt;</span><span class="p">]</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.invoke_anonymous_function-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.invoke_anonymous_function-view-source"><span>View Source</span></label>
@ -3878,7 +3878,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">invoke_expression_over_column</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">column</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641165360&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="n">callable_expression</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">invoke_expression_over_column</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="n">column</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718629728&#39;</span><span class="o">&gt;</span><span class="p">]</span>,</span><span class="param"> <span class="n">callable_expression</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.invoke_expression_over_column-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.invoke_expression_over_column-view-source"><span>View Source</span></label>
@ -3915,7 +3915,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">binary_op</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">klass</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="n">other</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641418848&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">binary_op</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">klass</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="n">other</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718850464&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.binary_op-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.binary_op-view-source"><span>View Source</span></label>
@ -3936,7 +3936,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">inverse_binary_op</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">klass</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="n">other</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641446480&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">inverse_binary_op</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">klass</span><span class="p">:</span> <span class="n">Callable</span>,</span><span class="param"> <span class="n">other</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718860592&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="o">**</span><span class="n">kwargs</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.inverse_binary_op-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.inverse_binary_op-view-source"><span>View Source</span></label>
@ -4502,7 +4502,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">isin</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641655440&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723641655440&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">):</span></span> <span class="name">isin</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719076048&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719076048&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">):</span></span>
<label class="view-source-button" for="Column.isin-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.isin-view-source"><span>View Source</span></label>
@ -4523,7 +4523,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">between</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">lowerBound</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723639598928&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">upperBound</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723639676288&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">between</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">lowerBound</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719199664&#39;</span><span class="o">&gt;</span>,</span><span class="param"> <span class="n">upperBound</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719254144&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.between-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.between-view-source"><span>View Source</span></label>
@ -4558,7 +4558,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">over</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">window</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723639702768&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span> <span class="name">over</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="n">window</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719279088&#39;</span><span class="o">&gt;</span></span><span class="return-annotation">) -> <span class="n"><a href="#Column">Column</a></span>:</span></span>
<label class="view-source-button" for="Column.over-view-source"><span>View Source</span></label> <label class="view-source-button" for="Column.over-view-source"><span>View Source</span></label>
@ -4803,7 +4803,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">partitionBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640181792&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640181792&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span> <span class="name">partitionBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719449648&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719449648&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span>
<label class="view-source-button" for="Window.partitionBy-view-source"><span>View Source</span></label> <label class="view-source-button" for="Window.partitionBy-view-source"><span>View Source</span></label>
@ -4824,7 +4824,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="decorator">@classmethod</div> <div class="decorator">@classmethod</div>
<span class="def">def</span> <span class="def">def</span>
<span class="name">orderBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640214464&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640214464&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span> <span class="name">orderBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">cls</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719450800&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879719450800&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span>
<label class="view-source-button" for="Window.orderBy-view-source"><span>View Source</span></label> <label class="view-source-button" for="Window.orderBy-view-source"><span>View Source</span></label>
@ -5064,7 +5064,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">partitionBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640052544&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723640052544&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span> <span class="name">partitionBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718310320&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879718310320&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span>
<label class="view-source-button" for="WindowSpec.partitionBy-view-source"><span>View Source</span></label> <label class="view-source-button" for="WindowSpec.partitionBy-view-source"><span>View Source</span></label>
@ -5091,7 +5091,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function"> <div class="attr function">
<span class="def">def</span> <span class="def">def</span>
<span class="name">orderBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723639942752&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139723639942752&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span> <span class="name">orderBy</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="bp">self</span>,</span><span class="param"> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879717620032&#39;</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="o">&lt;</span><span class="n">MagicMock</span> <span class="nb">id</span><span class="o">=</span><span class="s1">&#39;139879717620032&#39;</span><span class="o">&gt;</span><span class="p">]]</span></span><span class="return-annotation">) -> <span class="n"><a href="#WindowSpec">WindowSpec</a></span>:</span></span>
<label class="view-source-button" for="WindowSpec.orderBy-view-source"><span>View Source</span></label> <label class="view-source-button" for="WindowSpec.orderBy-view-source"><span>View Source</span></label>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -293,7 +293,8 @@
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="s2">&quot;CURRENTTIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> </span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="s2">&quot;CURRENTTIME&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">,</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="s2">&quot;CURRENTDATE&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">,</span> </span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="s2">&quot;CURRENTDATE&quot;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">,</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="s2">&quot;STRFTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">fmt</span><span class="p">,</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">fmt</span><span class="p">)),</span> </span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="s2">&quot;STRFTIME&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">fmt</span><span class="p">,</span> <span class="n">arg</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromisoformat</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">fmt</span><span class="p">)),</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a><span class="p">}</span> </span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="s2">&quot;TRIM&quot;</span><span class="p">:</span> <span class="n">null_if_any</span><span class="p">(</span><span class="k">lambda</span> <span class="n">this</span><span class="p">,</span> <span class="n">e</span><span class="o">=</span><span class="kc">None</span><span class="p">:</span> <span class="n">this</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="n">e</span><span class="p">)),</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a><span class="p">}</span>
</span></pre></div> </span></pre></div>
@ -595,7 +596,7 @@ def foo(a, b): ...
<div class="attr variable"> <div class="attr variable">
<span class="name">ENV</span> = <span class="name">ENV</span> =
<input id="ENV-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="ENV-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="ENV-view-value"></label><span class="default_value">{&#39;exp&#39;: &lt;module &#39;<a href="../expressions.html">sqlglot.expressions</a>&#39; from &#39;/home/runner/work/sqlglot/sqlglot/sqlglot/expressions.py&#39;&gt;, &#39;ARRAYAGG&#39;: &lt;class &#39;list&#39;&gt;, &#39;AVG&#39;: &lt;function fmean&gt;, &#39;COUNT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAX&#39;: &lt;function max&gt;, &#39;MIN&#39;: &lt;function min&gt;, &#39;SUM&#39;: &lt;function sum&gt;, &#39;ABS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ADD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYANY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BETWEEN&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEAND&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISELEFTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISERIGHTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEXOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CAST&#39;: &lt;function cast&gt;, &#39;COALESCE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SAFECONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCATWS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATEDIFF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATESTRTODATE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DOT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EXTRACT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;IF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTDIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTERVAL&#39;: &lt;function interval&gt;, &#39;LEFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LIKE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LOWER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAP&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MOD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MUL&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;NEQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ORD&#39;: &lt;function ord&gt;, &#39;ORDERED&#39;: &lt;function ordered&gt;, &#39;POW&#39;: &lt;built-in function pow&gt;, &#39;RIGHT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRPOSITION&#39;: &lt;function str_position&gt;, &#39;SUB&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SUBSTRING&#39;: &lt;function substring&gt;, &#39;TIMESTRTOTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;UPPER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;YEAR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MONTH&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DAY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CURRENTDATETIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIMESTAMP&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTDATE&#39;: &lt;built-in method today of type object&gt;, &#39;STRFTIME&#39;: &lt;function &lt;lambda&gt;&gt;}</span> <label class="view-value-button pdoc-button" for="ENV-view-value"></label><span class="default_value">{&#39;exp&#39;: &lt;module &#39;<a href="../expressions.html">sqlglot.expressions</a>&#39; from &#39;/home/runner/work/sqlglot/sqlglot/sqlglot/expressions.py&#39;&gt;, &#39;ARRAYAGG&#39;: &lt;class &#39;list&#39;&gt;, &#39;AVG&#39;: &lt;function fmean&gt;, &#39;COUNT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAX&#39;: &lt;function max&gt;, &#39;MIN&#39;: &lt;function min&gt;, &#39;SUM&#39;: &lt;function sum&gt;, &#39;ABS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ADD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ARRAYANY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BETWEEN&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEAND&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISELEFTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISERIGHTSHIFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;BITWISEXOR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CAST&#39;: &lt;function cast&gt;, &#39;COALESCE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SAFECONCAT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CONCATWS&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATEDIFF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DATESTRTODATE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DOT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;EXTRACT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;GTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;IF&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTDIV&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;INTERVAL&#39;: &lt;function interval&gt;, &#39;LEFT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LIKE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LOWER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;LTE&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MAP&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MOD&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MUL&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;NEQ&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;ORD&#39;: &lt;function ord&gt;, &#39;ORDERED&#39;: &lt;function ordered&gt;, &#39;POW&#39;: &lt;built-in function pow&gt;, &#39;RIGHT&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;STRPOSITION&#39;: &lt;function str_position&gt;, &#39;SUB&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;SUBSTRING&#39;: &lt;function substring&gt;, &#39;TIMESTRTOTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;UPPER&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;YEAR&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;MONTH&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;DAY&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;CURRENTDATETIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIMESTAMP&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTTIME&#39;: &lt;built-in method now of type object&gt;, &#39;CURRENTDATE&#39;: &lt;built-in method today of type object&gt;, &#39;STRFTIME&#39;: &lt;function &lt;lambda&gt;&gt;, &#39;TRIM&#39;: &lt;function &lt;lambda&gt;&gt;}</span>
</div> </div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -36,6 +36,9 @@
<li> <li>
<a class="function" href="#add_text_to_concat">add_text_to_concat</a> <a class="function" href="#add_text_to_concat">add_text_to_concat</a>
</li> </li>
<li>
<a class="function" href="#replace_date_funcs">replace_date_funcs</a>
</li>
<li> <li>
<a class="function" href="#coerce_type">coerce_type</a> <a class="function" href="#coerce_type">coerce_type</a>
</li> </li>
@ -80,92 +83,103 @@
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a> </span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="k">def</span> <span class="nf">canonicalize</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="k">def</span> <span class="nf">canonicalize</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Converts a sql expression into a standard form.</span> </span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Converts a sql expression into a standard form.</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a> </span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="sd"> This method relies on annotate_types because many of the</span> </span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a><span class="sd"> This method relies on annotate_types because many of the</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="sd"> conversions rely on type inference.</span> </span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="sd"> conversions rely on type inference.</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a> </span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="sd"> Args:</span> </span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="sd"> Args:</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="sd"> expression: The expression to canonicalize.</span> </span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a><span class="sd"> expression: The expression to canonicalize.</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">canonicalize</span><span class="p">)</span> </span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">canonicalize</span><span class="p">)</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a> </span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">add_text_to_concat</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">add_text_to_concat</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">coerce_type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">replace_date_funcs</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">coerce_type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a> </span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a> </span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a> </span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="k">def</span> <span class="nf">add_text_to_concat</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Add</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEXT_TYPES</span><span class="p">:</span> </span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="k">def</span> <span class="nf">add_text_to_concat</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Concat</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">])</span> </span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Add</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEXT_TYPES</span><span class="p">:</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Concat</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">])</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a> </span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a> </span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="k">def</span> <span class="nf">coerce_type</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">):</span> </span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="k">def</span> <span class="nf">replace_date_funcs</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">)</span> </span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Date</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expressions</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;zone&quot;</span><span class="p">):</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">):</span> </span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span><span class="p">)</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;low&quot;</span><span class="p">])</span> </span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Extract</span><span class="p">):</span> </span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">)</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a> <span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span><span class="p">:</span> </span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="s2">&quot;datetime&quot;</span><span class="p">)</span> </span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a>
</span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a> </span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a><span class="k">def</span> <span class="nf">coerce_type</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a> </span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">):</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="k">def</span> <span class="nf">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">)</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">):</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">)</span> </span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;low&quot;</span><span class="p">])</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span> </span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Extract</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">is_type</span><span class="p">(</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span> </span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="o">*</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> </span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="p">):</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a> <span class="p">):</span> </span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATETIME</span><span class="p">)</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span> </span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a>
</span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a> </span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a>
</span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a> </span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a>
</span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a><span class="k">def</span> <span class="nf">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a><span class="k">def</span> <span class="nf">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Connector</span><span class="p">):</span> </span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">)</span> </span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">)</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">right</span><span class="p">)</span> </span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> </span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Having</span><span class="p">)):</span> </span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> </span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="p">):</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a> </span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos">65</span></a> </span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a>
</span><span id="L-66"><a href="#L-66"><span class="linenos">66</span></a> </span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a>
</span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a><span class="k">def</span> <span class="nf">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a><span class="k">def</span> <span class="nf">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos">68</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span> </span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Connector</span><span class="p">):</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a> <span class="c1"># Convert ORDER BY a ASC to ORDER BY a</span> </span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">)</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos">70</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">right</span><span class="p">)</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos">71</span></a> </span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a>
</span><span id="L-72"><a href="#L-72"><span class="linenos">72</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Having</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">)):</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos">73</span></a> </span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos">74</span></a> </span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a>
</span><span id="L-75"><a href="#L-75"><span class="linenos">75</span></a><span class="k">def</span> <span class="nf">_coerce_date</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos">76</span></a> <span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">([</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">]):</span> </span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a>
</span><span id="L-77"><a href="#L-77"><span class="linenos">77</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a>
</span><span id="L-78"><a href="#L-78"><span class="linenos">78</span></a> <span class="n">a</span><span class="o">.</span><span class="n">type</span> </span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a><span class="k">def</span> <span class="nf">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos">79</span></a> <span class="ow">and</span> <span class="n">a</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span> </span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos">80</span></a> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">type</span> </span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="c1"># Convert ORDER BY a ASC to ORDER BY a</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos">81</span></a> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">INTERVAL</span><span class="p">)</span> </span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos">82</span></a> <span class="p">):</span> </span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a>
</span><span id="L-83"><a href="#L-83"><span class="linenos">83</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="s2">&quot;date&quot;</span><span class="p">)</span> </span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos">84</span></a> </span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a>
</span><span id="L-85"><a href="#L-85"><span class="linenos">85</span></a> </span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a>
</span><span id="L-86"><a href="#L-86"><span class="linenos">86</span></a><span class="k">def</span> <span class="nf">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a><span class="k">def</span> <span class="nf">_coerce_date</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos">87</span></a> <span class="n">data_type</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">to</span><span class="p">)</span> </span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">([</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">]):</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos">88</span></a> <span class="n">cast</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">node</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">to</span><span class="o">=</span><span class="n">data_type</span><span class="p">)</span> </span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos">89</span></a> <span class="n">cast</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">data_type</span> </span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">a</span><span class="o">.</span><span class="n">type</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos">90</span></a> <span class="n">node</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">cast</span><span class="p">)</span> </span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="ow">and</span> <span class="n">a</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos">91</span></a> </span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">type</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos">92</span></a> </span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="ow">and</span> <span class="n">b</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">INTERVAL</span><span class="p">)</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos">93</span></a><span class="k">def</span> <span class="nf">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span> </span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="p">):</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos">94</span></a> <span class="k">if</span> <span class="n">expression</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">INTEGER_TYPES</span><span class="p">:</span> </span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span><span class="p">)</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos">95</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">NEQ</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">0</span><span class="p">)))</span> </span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a><span class="k">def</span> <span class="nf">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="n">node</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">to</span><span class="o">=</span><span class="n">to</span><span class="p">))</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a><span class="k">def</span> <span class="nf">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Coalesce</span><span class="p">):</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">iter_expressions</span><span class="p">():</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">child</span><span class="p">)</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="k">elif</span> <span class="n">expression</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">INTEGER_TYPES</span><span class="p">:</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">NEQ</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">(),</span> <span class="n">expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">0</span><span class="p">)))</span>
</span></pre></div> </span></pre></div>
@ -193,12 +207,13 @@
</span><span id="canonicalize-18"><a href="#canonicalize-18"><span class="linenos">18</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">canonicalize</span><span class="p">)</span> </span><span id="canonicalize-18"><a href="#canonicalize-18"><span class="linenos">18</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">canonicalize</span><span class="p">)</span>
</span><span id="canonicalize-19"><a href="#canonicalize-19"><span class="linenos">19</span></a> </span><span id="canonicalize-19"><a href="#canonicalize-19"><span class="linenos">19</span></a>
</span><span id="canonicalize-20"><a href="#canonicalize-20"><span class="linenos">20</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">add_text_to_concat</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="canonicalize-20"><a href="#canonicalize-20"><span class="linenos">20</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">add_text_to_concat</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-21"><a href="#canonicalize-21"><span class="linenos">21</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">coerce_type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="canonicalize-21"><a href="#canonicalize-21"><span class="linenos">21</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">replace_date_funcs</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-22"><a href="#canonicalize-22"><span class="linenos">22</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="canonicalize-22"><a href="#canonicalize-22"><span class="linenos">22</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">coerce_type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-23"><a href="#canonicalize-23"><span class="linenos">23</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="canonicalize-23"><a href="#canonicalize-23"><span class="linenos">23</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-24"><a href="#canonicalize-24"><span class="linenos">24</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="canonicalize-24"><a href="#canonicalize-24"><span class="linenos">24</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-25"><a href="#canonicalize-25"><span class="linenos">25</span></a> </span><span id="canonicalize-25"><a href="#canonicalize-25"><span class="linenos">25</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="canonicalize-26"><a href="#canonicalize-26"><span class="linenos">26</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="canonicalize-26"><a href="#canonicalize-26"><span class="linenos">26</span></a>
</span><span id="canonicalize-27"><a href="#canonicalize-27"><span class="linenos">27</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -227,10 +242,33 @@ conversions rely on type inference.</p>
</div> </div>
<a class="headerlink" href="#add_text_to_concat"></a> <a class="headerlink" href="#add_text_to_concat"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="add_text_to_concat-29"><a href="#add_text_to_concat-29"><span class="linenos">29</span></a><span class="k">def</span> <span class="nf">add_text_to_concat</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="add_text_to_concat-30"><a href="#add_text_to_concat-30"><span class="linenos">30</span></a><span class="k">def</span> <span class="nf">add_text_to_concat</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="add_text_to_concat-30"><a href="#add_text_to_concat-30"><span class="linenos">30</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Add</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEXT_TYPES</span><span class="p">:</span> </span><span id="add_text_to_concat-31"><a href="#add_text_to_concat-31"><span class="linenos">31</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Add</span><span class="p">)</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="ow">and</span> <span class="n">node</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEXT_TYPES</span><span class="p">:</span>
</span><span id="add_text_to_concat-31"><a href="#add_text_to_concat-31"><span class="linenos">31</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Concat</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">])</span> </span><span id="add_text_to_concat-32"><a href="#add_text_to_concat-32"><span class="linenos">32</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Concat</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">])</span>
</span><span id="add_text_to_concat-32"><a href="#add_text_to_concat-32"><span class="linenos">32</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="add_text_to_concat-33"><a href="#add_text_to_concat-33"><span class="linenos">33</span></a> <span class="k">return</span> <span class="n">node</span>
</span></pre></div>
</section>
<section id="replace_date_funcs">
<input id="replace_date_funcs-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">
<span class="def">def</span>
<span class="name">replace_date_funcs</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">node</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span></span><span class="return-annotation">) -> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>:</span></span>
<label class="view-source-button" for="replace_date_funcs-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#replace_date_funcs"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="replace_date_funcs-36"><a href="#replace_date_funcs-36"><span class="linenos">36</span></a><span class="k">def</span> <span class="nf">replace_date_funcs</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="replace_date_funcs-37"><a href="#replace_date_funcs-37"><span class="linenos">37</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Date</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expressions</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;zone&quot;</span><span class="p">):</span>
</span><span id="replace_date_funcs-38"><a href="#replace_date_funcs-38"><span class="linenos">38</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATE</span><span class="p">)</span>
</span><span id="replace_date_funcs-39"><a href="#replace_date_funcs-39"><span class="linenos">39</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="replace_date_funcs-40"><a href="#replace_date_funcs-40"><span class="linenos">40</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">)</span>
</span><span id="replace_date_funcs-41"><a href="#replace_date_funcs-41"><span class="linenos">41</span></a> <span class="k">return</span> <span class="n">node</span>
</span></pre></div> </span></pre></div>
@ -248,15 +286,17 @@ conversions rely on type inference.</p>
</div> </div>
<a class="headerlink" href="#coerce_type"></a> <a class="headerlink" href="#coerce_type"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="coerce_type-35"><a href="#coerce_type-35"><span class="linenos">35</span></a><span class="k">def</span> <span class="nf">coerce_type</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="coerce_type-44"><a href="#coerce_type-44"><span class="linenos">44</span></a><span class="k">def</span> <span class="nf">coerce_type</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="coerce_type-36"><a href="#coerce_type-36"><span class="linenos">36</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">):</span> </span><span id="coerce_type-45"><a href="#coerce_type-45"><span class="linenos">45</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">):</span>
</span><span id="coerce_type-37"><a href="#coerce_type-37"><span class="linenos">37</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">)</span> </span><span id="coerce_type-46"><a href="#coerce_type-46"><span class="linenos">46</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">right</span><span class="p">)</span>
</span><span id="coerce_type-38"><a href="#coerce_type-38"><span class="linenos">38</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">):</span> </span><span id="coerce_type-47"><a href="#coerce_type-47"><span class="linenos">47</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">):</span>
</span><span id="coerce_type-39"><a href="#coerce_type-39"><span class="linenos">39</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;low&quot;</span><span class="p">])</span> </span><span id="coerce_type-48"><a href="#coerce_type-48"><span class="linenos">48</span></a> <span class="n">_coerce_date</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;low&quot;</span><span class="p">])</span>
</span><span id="coerce_type-40"><a href="#coerce_type-40"><span class="linenos">40</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Extract</span><span class="p">):</span> </span><span id="coerce_type-49"><a href="#coerce_type-49"><span class="linenos">49</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Extract</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">is_type</span><span class="p">(</span>
</span><span id="coerce_type-41"><a href="#coerce_type-41"><span class="linenos">41</span></a> <span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span><span class="p">:</span> </span><span id="coerce_type-50"><a href="#coerce_type-50"><span class="linenos">50</span></a> <span class="o">*</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span>
</span><span id="coerce_type-42"><a href="#coerce_type-42"><span class="linenos">42</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="s2">&quot;datetime&quot;</span><span class="p">)</span> </span><span id="coerce_type-51"><a href="#coerce_type-51"><span class="linenos">51</span></a> <span class="p">):</span>
</span><span id="coerce_type-43"><a href="#coerce_type-43"><span class="linenos">43</span></a> <span class="k">return</span> <span class="n">node</span> </span><span id="coerce_type-52"><a href="#coerce_type-52"><span class="linenos">52</span></a> <span class="n">_replace_cast</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">DATETIME</span><span class="p">)</span>
</span><span id="coerce_type-53"><a href="#coerce_type-53"><span class="linenos">53</span></a>
</span><span id="coerce_type-54"><a href="#coerce_type-54"><span class="linenos">54</span></a> <span class="k">return</span> <span class="n">node</span>
</span></pre></div> </span></pre></div>
@ -274,15 +314,15 @@ conversions rely on type inference.</p>
</div> </div>
<a class="headerlink" href="#remove_redundant_casts"></a> <a class="headerlink" href="#remove_redundant_casts"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="remove_redundant_casts-46"><a href="#remove_redundant_casts-46"><span class="linenos">46</span></a><span class="k">def</span> <span class="nf">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="remove_redundant_casts-57"><a href="#remove_redundant_casts-57"><span class="linenos">57</span></a><span class="k">def</span> <span class="nf">remove_redundant_casts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="remove_redundant_casts-47"><a href="#remove_redundant_casts-47"><span class="linenos">47</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="remove_redundant_casts-58"><a href="#remove_redundant_casts-58"><span class="linenos">58</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="remove_redundant_casts-48"><a href="#remove_redundant_casts-48"><span class="linenos">48</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">)</span> </span><span id="remove_redundant_casts-59"><a href="#remove_redundant_casts-59"><span class="linenos">59</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">)</span>
</span><span id="remove_redundant_casts-49"><a href="#remove_redundant_casts-49"><span class="linenos">49</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span> </span><span id="remove_redundant_casts-60"><a href="#remove_redundant_casts-60"><span class="linenos">60</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span>
</span><span id="remove_redundant_casts-50"><a href="#remove_redundant_casts-50"><span class="linenos">50</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span> </span><span id="remove_redundant_casts-61"><a href="#remove_redundant_casts-61"><span class="linenos">61</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span>
</span><span id="remove_redundant_casts-51"><a href="#remove_redundant_casts-51"><span class="linenos">51</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> </span><span id="remove_redundant_casts-62"><a href="#remove_redundant_casts-62"><span class="linenos">62</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span> <span class="o">==</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">this</span>
</span><span id="remove_redundant_casts-52"><a href="#remove_redundant_casts-52"><span class="linenos">52</span></a> <span class="p">):</span> </span><span id="remove_redundant_casts-63"><a href="#remove_redundant_casts-63"><span class="linenos">63</span></a> <span class="p">):</span>
</span><span id="remove_redundant_casts-53"><a href="#remove_redundant_casts-53"><span class="linenos">53</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span> </span><span id="remove_redundant_casts-64"><a href="#remove_redundant_casts-64"><span class="linenos">64</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span>
</span><span id="remove_redundant_casts-54"><a href="#remove_redundant_casts-54"><span class="linenos">54</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="remove_redundant_casts-65"><a href="#remove_redundant_casts-65"><span class="linenos">65</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -300,15 +340,15 @@ conversions rely on type inference.</p>
</div> </div>
<a class="headerlink" href="#ensure_bool_predicates"></a> <a class="headerlink" href="#ensure_bool_predicates"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="ensure_bool_predicates-57"><a href="#ensure_bool_predicates-57"><span class="linenos">57</span></a><span class="k">def</span> <span class="nf">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="ensure_bool_predicates-68"><a href="#ensure_bool_predicates-68"><span class="linenos">68</span></a><span class="k">def</span> <span class="nf">ensure_bool_predicates</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="ensure_bool_predicates-58"><a href="#ensure_bool_predicates-58"><span class="linenos">58</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Connector</span><span class="p">):</span> </span><span id="ensure_bool_predicates-69"><a href="#ensure_bool_predicates-69"><span class="linenos">69</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Connector</span><span class="p">):</span>
</span><span id="ensure_bool_predicates-59"><a href="#ensure_bool_predicates-59"><span class="linenos">59</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">)</span> </span><span id="ensure_bool_predicates-70"><a href="#ensure_bool_predicates-70"><span class="linenos">70</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">)</span>
</span><span id="ensure_bool_predicates-60"><a href="#ensure_bool_predicates-60"><span class="linenos">60</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">right</span><span class="p">)</span> </span><span id="ensure_bool_predicates-71"><a href="#ensure_bool_predicates-71"><span class="linenos">71</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">right</span><span class="p">)</span>
</span><span id="ensure_bool_predicates-61"><a href="#ensure_bool_predicates-61"><span class="linenos">61</span></a> </span><span id="ensure_bool_predicates-72"><a href="#ensure_bool_predicates-72"><span class="linenos">72</span></a>
</span><span id="ensure_bool_predicates-62"><a href="#ensure_bool_predicates-62"><span class="linenos">62</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Having</span><span class="p">)):</span> </span><span id="ensure_bool_predicates-73"><a href="#ensure_bool_predicates-73"><span class="linenos">73</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Having</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">)):</span>
</span><span id="ensure_bool_predicates-63"><a href="#ensure_bool_predicates-63"><span class="linenos">63</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> </span><span id="ensure_bool_predicates-74"><a href="#ensure_bool_predicates-74"><span class="linenos">74</span></a> <span class="n">_replace_int_predicate</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="ensure_bool_predicates-64"><a href="#ensure_bool_predicates-64"><span class="linenos">64</span></a> </span><span id="ensure_bool_predicates-75"><a href="#ensure_bool_predicates-75"><span class="linenos">75</span></a>
</span><span id="ensure_bool_predicates-65"><a href="#ensure_bool_predicates-65"><span class="linenos">65</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="ensure_bool_predicates-76"><a href="#ensure_bool_predicates-76"><span class="linenos">76</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -326,12 +366,12 @@ conversions rely on type inference.</p>
</div> </div>
<a class="headerlink" href="#remove_ascending_order"></a> <a class="headerlink" href="#remove_ascending_order"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="remove_ascending_order-68"><a href="#remove_ascending_order-68"><span class="linenos">68</span></a><span class="k">def</span> <span class="nf">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="remove_ascending_order-79"><a href="#remove_ascending_order-79"><span class="linenos">79</span></a><span class="k">def</span> <span class="nf">remove_ascending_order</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="remove_ascending_order-69"><a href="#remove_ascending_order-69"><span class="linenos">69</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span> </span><span id="remove_ascending_order-80"><a href="#remove_ascending_order-80"><span class="linenos">80</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="kc">False</span><span class="p">:</span>
</span><span id="remove_ascending_order-70"><a href="#remove_ascending_order-70"><span class="linenos">70</span></a> <span class="c1"># Convert ORDER BY a ASC to ORDER BY a</span> </span><span id="remove_ascending_order-81"><a href="#remove_ascending_order-81"><span class="linenos">81</span></a> <span class="c1"># Convert ORDER BY a ASC to ORDER BY a</span>
</span><span id="remove_ascending_order-71"><a href="#remove_ascending_order-71"><span class="linenos">71</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="remove_ascending_order-82"><a href="#remove_ascending_order-82"><span class="linenos">82</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;desc&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="remove_ascending_order-72"><a href="#remove_ascending_order-72"><span class="linenos">72</span></a> </span><span id="remove_ascending_order-83"><a href="#remove_ascending_order-83"><span class="linenos">83</span></a>
</span><span id="remove_ascending_order-73"><a href="#remove_ascending_order-73"><span class="linenos">73</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="remove_ascending_order-84"><a href="#remove_ascending_order-84"><span class="linenos">84</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>

View file

@ -251,7 +251,7 @@
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">UNMERGABLE_ARGS</span><span class="p">)</span> </span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">UNMERGABLE_ARGS</span><span class="p">)</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">)</span> </span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">)</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">pivots</span> </span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">pivots</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span> </span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">leave_tables_isolated</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span> </span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">leave_tables_isolated</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span> </span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">)</span> </span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">)</span>
@ -568,7 +568,7 @@ queries if it would result in multiple table selects in a single query:</p>
<div class="attr variable"> <div class="attr variable">
<span class="name">UNMERGABLE_ARGS</span> = <span class="name">UNMERGABLE_ARGS</span> =
<input id="UNMERGABLE_ARGS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1"> <input id="UNMERGABLE_ARGS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;kind&#39;, &#39;having&#39;, &#39;with&#39;, &#39;distribute&#39;, &#39;offset&#39;, &#39;cluster&#39;, &#39;sort&#39;, &#39;format&#39;, &#39;limit&#39;, &#39;settings&#39;, &#39;connect&#39;, &#39;into&#39;, &#39;sample&#39;, &#39;group&#39;, &#39;laterals&#39;, &#39;pivots&#39;, &#39;locks&#39;, &#39;windows&#39;, &#39;match&#39;, &#39;distinct&#39;, &#39;qualify&#39;}</span> <label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;having&#39;, &#39;cluster&#39;, &#39;into&#39;, &#39;group&#39;, &#39;locks&#39;, &#39;sample&#39;, &#39;format&#39;, &#39;qualify&#39;, &#39;with&#39;, &#39;distinct&#39;, &#39;connect&#39;, &#39;pivots&#39;, &#39;laterals&#39;, &#39;windows&#39;, &#39;sort&#39;, &#39;limit&#39;, &#39;distribute&#39;, &#39;settings&#39;, &#39;offset&#39;, &#39;kind&#39;, &#39;match&#39;}</span>
</div> </div>

View file

@ -80,28 +80,44 @@
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span> </span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span> </span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a> </span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd"> Note:</span> </span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span> </span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="sd"> identifier of interest:</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span> </span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a> </span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a><span class="sd"> Example:</span> </span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span> </span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span> </span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="sd"> Note:</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span> </span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span> </span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a><span class="sd"> &#39;FOO&#39;</span> </span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a> </span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a><span class="sd"> Example:</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a><span class="sd"> Args:</span> </span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> expression: The expression to transform.</span> </span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span> </span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a> </span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> Returns:</span> </span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> The transformed expression.</span> </span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> &#39;FOO&#39;</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-43"><a href="#L-43"><span class="linenos">43</span></a>
</span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a><span class="sd"> Args:</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-45"><a href="#L-45"><span class="linenos">45</span></a><span class="sd"> expression: The expression to transform.</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-46"><a href="#L-46"><span class="linenos">46</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos">47</span></a>
</span><span id="L-48"><a href="#L-48"><span class="linenos">48</span></a><span class="sd"> Returns:</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos">49</span></a><span class="sd"> The transformed expression.</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos">50</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos">51</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos">52</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos">53</span></a>
</span><span id="L-54"><a href="#L-54"><span class="linenos">54</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos">55</span></a>
</span><span id="L-56"><a href="#L-56"><span class="linenos">56</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos">57</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos">58</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos">59</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
@ -122,34 +138,58 @@
</span><span id="normalize_identifiers-23"><a href="#normalize_identifiers-23"><span class="linenos">23</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span> </span><span id="normalize_identifiers-23"><a href="#normalize_identifiers-23"><span class="linenos">23</span></a><span class="sd"> Normalize all unquoted identifiers to either lower or upper case, depending</span>
</span><span id="normalize_identifiers-24"><a href="#normalize_identifiers-24"><span class="linenos">24</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span> </span><span id="normalize_identifiers-24"><a href="#normalize_identifiers-24"><span class="linenos">24</span></a><span class="sd"> on the dialect. This essentially makes those identifiers case-insensitive.</span>
</span><span id="normalize_identifiers-25"><a href="#normalize_identifiers-25"><span class="linenos">25</span></a> </span><span id="normalize_identifiers-25"><a href="#normalize_identifiers-25"><span class="linenos">25</span></a>
</span><span id="normalize_identifiers-26"><a href="#normalize_identifiers-26"><span class="linenos">26</span></a><span class="sd"> Note:</span> </span><span id="normalize_identifiers-26"><a href="#normalize_identifiers-26"><span class="linenos">26</span></a><span class="sd"> It&#39;s possible to make this a no-op by adding a special comment next to the</span>
</span><span id="normalize_identifiers-27"><a href="#normalize_identifiers-27"><span class="linenos">27</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span> </span><span id="normalize_identifiers-27"><a href="#normalize_identifiers-27"><span class="linenos">27</span></a><span class="sd"> identifier of interest:</span>
</span><span id="normalize_identifiers-28"><a href="#normalize_identifiers-28"><span class="linenos">28</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span> </span><span id="normalize_identifiers-28"><a href="#normalize_identifiers-28"><span class="linenos">28</span></a>
</span><span id="normalize_identifiers-29"><a href="#normalize_identifiers-29"><span class="linenos">29</span></a> </span><span id="normalize_identifiers-29"><a href="#normalize_identifiers-29"><span class="linenos">29</span></a><span class="sd"> SELECT a /* sqlglot.meta case_sensitive */ FROM table</span>
</span><span id="normalize_identifiers-30"><a href="#normalize_identifiers-30"><span class="linenos">30</span></a><span class="sd"> Example:</span> </span><span id="normalize_identifiers-30"><a href="#normalize_identifiers-30"><span class="linenos">30</span></a>
</span><span id="normalize_identifiers-31"><a href="#normalize_identifiers-31"><span class="linenos">31</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span> </span><span id="normalize_identifiers-31"><a href="#normalize_identifiers-31"><span class="linenos">31</span></a><span class="sd"> In this example, the identifier `a` will not be normalized.</span>
</span><span id="normalize_identifiers-32"><a href="#normalize_identifiers-32"><span class="linenos">32</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span> </span><span id="normalize_identifiers-32"><a href="#normalize_identifiers-32"><span class="linenos">32</span></a>
</span><span id="normalize_identifiers-33"><a href="#normalize_identifiers-33"><span class="linenos">33</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span> </span><span id="normalize_identifiers-33"><a href="#normalize_identifiers-33"><span class="linenos">33</span></a><span class="sd"> Note:</span>
</span><span id="normalize_identifiers-34"><a href="#normalize_identifiers-34"><span class="linenos">34</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span> </span><span id="normalize_identifiers-34"><a href="#normalize_identifiers-34"><span class="linenos">34</span></a><span class="sd"> Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even</span>
</span><span id="normalize_identifiers-35"><a href="#normalize_identifiers-35"><span class="linenos">35</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span> </span><span id="normalize_identifiers-35"><a href="#normalize_identifiers-35"><span class="linenos">35</span></a><span class="sd"> when they&#39;re quoted, so in these cases all identifiers are normalized.</span>
</span><span id="normalize_identifiers-36"><a href="#normalize_identifiers-36"><span class="linenos">36</span></a><span class="sd"> &#39;FOO&#39;</span> </span><span id="normalize_identifiers-36"><a href="#normalize_identifiers-36"><span class="linenos">36</span></a>
</span><span id="normalize_identifiers-37"><a href="#normalize_identifiers-37"><span class="linenos">37</span></a> </span><span id="normalize_identifiers-37"><a href="#normalize_identifiers-37"><span class="linenos">37</span></a><span class="sd"> Example:</span>
</span><span id="normalize_identifiers-38"><a href="#normalize_identifiers-38"><span class="linenos">38</span></a><span class="sd"> Args:</span> </span><span id="normalize_identifiers-38"><a href="#normalize_identifiers-38"><span class="linenos">38</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="normalize_identifiers-39"><a href="#normalize_identifiers-39"><span class="linenos">39</span></a><span class="sd"> expression: The expression to transform.</span> </span><span id="normalize_identifiers-39"><a href="#normalize_identifiers-39"><span class="linenos">39</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&#39;SELECT Bar.A AS A FROM &quot;Foo&quot;.Bar&#39;)</span>
</span><span id="normalize_identifiers-40"><a href="#normalize_identifiers-40"><span class="linenos">40</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span> </span><span id="normalize_identifiers-40"><a href="#normalize_identifiers-40"><span class="linenos">40</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(expression).sql()</span>
</span><span id="normalize_identifiers-41"><a href="#normalize_identifiers-41"><span class="linenos">41</span></a> </span><span id="normalize_identifiers-41"><a href="#normalize_identifiers-41"><span class="linenos">41</span></a><span class="sd"> &#39;SELECT bar.a AS a FROM &quot;Foo&quot;.bar&#39;</span>
</span><span id="normalize_identifiers-42"><a href="#normalize_identifiers-42"><span class="linenos">42</span></a><span class="sd"> Returns:</span> </span><span id="normalize_identifiers-42"><a href="#normalize_identifiers-42"><span class="linenos">42</span></a><span class="sd"> &gt;&gt;&gt; normalize_identifiers(&quot;foo&quot;, dialect=&quot;snowflake&quot;).sql(dialect=&quot;snowflake&quot;)</span>
</span><span id="normalize_identifiers-43"><a href="#normalize_identifiers-43"><span class="linenos">43</span></a><span class="sd"> The transformed expression.</span> </span><span id="normalize_identifiers-43"><a href="#normalize_identifiers-43"><span class="linenos">43</span></a><span class="sd"> &#39;FOO&#39;</span>
</span><span id="normalize_identifiers-44"><a href="#normalize_identifiers-44"><span class="linenos">44</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="normalize_identifiers-44"><a href="#normalize_identifiers-44"><span class="linenos">44</span></a>
</span><span id="normalize_identifiers-45"><a href="#normalize_identifiers-45"><span class="linenos">45</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span> </span><span id="normalize_identifiers-45"><a href="#normalize_identifiers-45"><span class="linenos">45</span></a><span class="sd"> Args:</span>
</span><span id="normalize_identifiers-46"><a href="#normalize_identifiers-46"><span class="linenos">46</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="normalize_identifiers-46"><a href="#normalize_identifiers-46"><span class="linenos">46</span></a><span class="sd"> expression: The expression to transform.</span>
</span><span id="normalize_identifiers-47"><a href="#normalize_identifiers-47"><span class="linenos">47</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="normalize_identifiers-47"><a href="#normalize_identifiers-47"><span class="linenos">47</span></a><span class="sd"> dialect: The dialect to use in order to decide how to normalize identifiers.</span>
</span><span id="normalize_identifiers-48"><a href="#normalize_identifiers-48"><span class="linenos">48</span></a>
</span><span id="normalize_identifiers-49"><a href="#normalize_identifiers-49"><span class="linenos">49</span></a><span class="sd"> Returns:</span>
</span><span id="normalize_identifiers-50"><a href="#normalize_identifiers-50"><span class="linenos">50</span></a><span class="sd"> The transformed expression.</span>
</span><span id="normalize_identifiers-51"><a href="#normalize_identifiers-51"><span class="linenos">51</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="normalize_identifiers-52"><a href="#normalize_identifiers-52"><span class="linenos">52</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="normalize_identifiers-53"><a href="#normalize_identifiers-53"><span class="linenos">53</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="normalize_identifiers-54"><a href="#normalize_identifiers-54"><span class="linenos">54</span></a>
</span><span id="normalize_identifiers-55"><a href="#normalize_identifiers-55"><span class="linenos">55</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="normalize_identifiers-56"><a href="#normalize_identifiers-56"><span class="linenos">56</span></a>
</span><span id="normalize_identifiers-57"><a href="#normalize_identifiers-57"><span class="linenos">57</span></a> <span class="k">def</span> <span class="nf">_normalize</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">E</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">E</span><span class="p">:</span>
</span><span id="normalize_identifiers-58"><a href="#normalize_identifiers-58"><span class="linenos">58</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">node</span><span class="o">.</span><span class="n">meta</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;case_sensitive&quot;</span><span class="p">):</span>
</span><span id="normalize_identifiers-59"><a href="#normalize_identifiers-59"><span class="linenos">59</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">replace_children</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">_normalize</span><span class="p">)</span>
</span><span id="normalize_identifiers-60"><a href="#normalize_identifiers-60"><span class="linenos">60</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">dialect</span><span class="o">.</span><span class="n">normalize_identifier</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
</span><span id="normalize_identifiers-61"><a href="#normalize_identifiers-61"><span class="linenos">61</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="normalize_identifiers-62"><a href="#normalize_identifiers-62"><span class="linenos">62</span></a>
</span><span id="normalize_identifiers-63"><a href="#normalize_identifiers-63"><span class="linenos">63</span></a> <span class="k">return</span> <span class="n">_normalize</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span></pre></div> </span></pre></div>
<div class="docstring"><p>Normalize all unquoted identifiers to either lower or upper case, depending <div class="docstring"><p>Normalize all unquoted identifiers to either lower or upper case, depending
on the dialect. This essentially makes those identifiers case-insensitive.</p> on the dialect. This essentially makes those identifiers case-insensitive.</p>
<p>It's possible to make this a no-op by adding a special comment next to the
identifier of interest:</p>
<pre><code>SELECT a /* sqlglot.meta case_sensitive */ FROM table
</code></pre>
<p>In this example, the identifier <code>a</code> will not be normalized.</p>
<h6 id="note">Note:</h6> <h6 id="note">Note:</h6>
<blockquote> <blockquote>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -285,235 +285,239 @@
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="p">)</span> </span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="p">)</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> </span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="c1"># we use list here because expression.selects is mutated inside the loop</span> </span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="c1"># we use list here because expression.selects is mutated inside the loop</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span> </span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="o">.</span><span class="n">copy</span><span class="p">():</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">to_replace</span> <span class="o">=</span> <span class="n">select</span> </span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">explode</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> </span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> </span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)):</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> </span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">):</span> </span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">alias</span> </span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="n">select</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">):</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Aliases</span><span class="p">):</span> </span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> </span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> </span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Aliases</span><span class="p">):</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="n">select</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> </span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)):</span> </span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="n">is_posexplode</span> <span class="o">=</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span> </span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="n">explode_arg</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> </span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="n">explode</span> <span class="o">=</span> <span class="n">alias</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="c1"># This ensures that we won&#39;t use [POS]EXPLODE&#39;s argument as a new selection</span> </span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="k">assert</span> <span class="n">explode</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode_arg</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">):</span> </span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="n">taken_select_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">output_name</span><span class="p">)</span> </span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="n">is_posexplode</span> <span class="o">=</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> </span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="n">explode_arg</span> <span class="o">=</span> <span class="n">explode</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="n">unnest_source_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_source_names</span><span class="p">,</span> <span class="s2">&quot;_u&quot;</span><span class="p">)</span> </span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> </span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="c1"># This ensures that we won&#39;t use [POS]EXPLODE&#39;s argument as a new selection</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">explode_alias</span><span class="p">:</span> </span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode_arg</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">):</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;col&quot;</span><span class="p">)</span> </span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="n">taken_select_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">output_name</span><span class="p">)</span>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> </span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span> </span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="n">unnest_source_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_source_names</span><span class="p">,</span> <span class="s2">&quot;_u&quot;</span><span class="p">)</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span> </span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> </span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">explode_alias</span><span class="p">:</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_alias</span><span class="p">:</span> </span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;col&quot;</span><span class="p">)</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span> </span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a> </span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span> </span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span> </span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">),</span> </span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_alias</span><span class="p">:</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">)</span> </span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a> </span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span> </span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="n">alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">))</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span> </span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">index</span> <span class="o">=</span> <span class="n">expressions</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">to_replace</span><span class="p">)</span> </span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> </span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span> </span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">),</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span> </span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a> <span class="p">)</span>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> </span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span> </span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="n">explode</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">column</span><span class="p">)</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span> </span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="p">)</span> </span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">expressions</span><span class="p">)</span> </span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="n">to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">column</span><span class="p">)</span> </span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span>
</span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a> </span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">arrays</span><span class="p">:</span> </span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="k">if</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">):</span> </span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="p">)</span>
</span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">expressions</span><span class="p">)</span>
</span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">arrays</span><span class="p">:</span>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a> </span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a> <span class="k">if</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">):</span>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a> <span class="n">size</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArraySize</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span> </span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-251"><a href="#L-251"><span class="linenos">251</span></a> <span class="n">arrays</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">size</span><span class="p">)</span> </span><span id="L-251"><a href="#L-251"><span class="linenos">251</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-252"><a href="#L-252"><span class="linenos">252</span></a> </span><span id="L-252"><a href="#L-252"><span class="linenos">252</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-253"><a href="#L-253"><span class="linenos">253</span></a> <span class="c1"># trino doesn&#39;t support left join unnest with on conditions</span> </span><span id="L-253"><a href="#L-253"><span class="linenos">253</span></a>
</span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a> <span class="c1"># if it did, this would be much simpler</span> </span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a> <span class="n">size</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArraySize</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> </span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a> <span class="n">arrays</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
</span><span id="L-256"><a href="#L-256"><span class="linenos">256</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span> </span><span id="L-256"><a href="#L-256"><span class="linenos">256</span></a>
</span><span id="L-257"><a href="#L-257"><span class="linenos">257</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span> </span><span id="L-257"><a href="#L-257"><span class="linenos">257</span></a> <span class="c1"># trino doesn&#39;t support left join unnest with on conditions</span>
</span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">()],</span> </span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a> <span class="c1"># if it did, this would be much simpler</span>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a> <span class="n">offset</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a> <span class="p">),</span> </span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span>
</span><span id="L-261"><a href="#L-261"><span class="linenos">261</span></a> <span class="n">unnest_source_alias</span><span class="p">,</span> </span><span id="L-261"><a href="#L-261"><span class="linenos">261</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">explode_alias</span><span class="p">],</span> </span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">()],</span>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="p">),</span> </span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="n">offset</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> </span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a> <span class="p">),</span>
</span><span id="L-265"><a href="#L-265"><span class="linenos">265</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="L-265"><a href="#L-265"><span class="linenos">265</span></a> <span class="n">unnest_source_alias</span><span class="p">,</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="p">)</span> </span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">explode_alias</span><span class="p">],</span>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a> </span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a> <span class="p">),</span>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> </span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a> <span class="n">size</span> <span class="o">=</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span> </span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-270"><a href="#L-270"><span class="linenos">270</span></a> </span><span id="L-270"><a href="#L-270"><span class="linenos">270</span></a> <span class="p">)</span>
</span><span id="L-271"><a href="#L-271"><span class="linenos">271</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span> </span><span id="L-271"><a href="#L-271"><span class="linenos">271</span></a>
</span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> </span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a> <span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">))</span> </span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a> <span class="n">size</span> <span class="o">=</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a> <span class="o">.</span><span class="n">or_</span><span class="p">(</span> </span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a>
</span><span id="L-275"><a href="#L-275"><span class="linenos">275</span></a> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">size</span><span class="p">))</span> </span><span id="L-275"><a href="#L-275"><span class="linenos">275</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a> <span class="p">),</span> </span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a> <span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">))</span>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a> <span class="p">)</span> </span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a> <span class="o">.</span><span class="n">or_</span><span class="p">(</span>
</span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a> </span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
</span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a> <span class="k">if</span> <span class="n">arrays</span><span class="p">:</span> </span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a> <span class="p">),</span>
</span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a> <span class="n">end</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Greatest</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">expressions</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> </span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a> </span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a> <span class="p">)</span>
</span><span id="L-283"><a href="#L-283"><span class="linenos">283</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> </span><span id="L-283"><a href="#L-283"><span class="linenos">283</span></a>
</span><span id="L-284"><a href="#L-284"><span class="linenos">284</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">index_offset</span><span class="p">)</span> </span><span id="L-284"><a href="#L-284"><span class="linenos">284</span></a> <span class="k">if</span> <span class="n">arrays</span><span class="p">:</span>
</span><span id="L-285"><a href="#L-285"><span class="linenos">285</span></a> <span class="n">series</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span> </span><span id="L-285"><a href="#L-285"><span class="linenos">285</span></a> <span class="n">end</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Greatest</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">expressions</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</span><span id="L-286"><a href="#L-286"><span class="linenos">286</span></a> </span><span id="L-286"><a href="#L-286"><span class="linenos">286</span></a>
</span><span id="L-287"><a href="#L-287"><span class="linenos">287</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-287"><a href="#L-287"><span class="linenos">287</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="L-288"><a href="#L-288"><span class="linenos">288</span></a> </span><span id="L-288"><a href="#L-288"><span class="linenos">288</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">index_offset</span><span class="p">)</span>
</span><span id="L-289"><a href="#L-289"><span class="linenos">289</span></a> <span class="k">return</span> <span class="n">_explode_to_unnest</span> </span><span id="L-289"><a href="#L-289"><span class="linenos">289</span></a> <span class="n">series</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span>
</span><span id="L-290"><a href="#L-290"><span class="linenos">290</span></a> </span><span id="L-290"><a href="#L-290"><span class="linenos">290</span></a>
</span><span id="L-291"><a href="#L-291"><span class="linenos">291</span></a> </span><span id="L-291"><a href="#L-291"><span class="linenos">291</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-292"><a href="#L-292"><span class="linenos">292</span></a><span class="n">PERCENTILES</span> <span class="o">=</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">PercentileCont</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">PercentileDisc</span><span class="p">)</span> </span><span id="L-292"><a href="#L-292"><span class="linenos">292</span></a>
</span><span id="L-293"><a href="#L-293"><span class="linenos">293</span></a> </span><span id="L-293"><a href="#L-293"><span class="linenos">293</span></a> <span class="k">return</span> <span class="n">_explode_to_unnest</span>
</span><span id="L-294"><a href="#L-294"><span class="linenos">294</span></a> </span><span id="L-294"><a href="#L-294"><span class="linenos">294</span></a>
</span><span id="L-295"><a href="#L-295"><span class="linenos">295</span></a><span class="k">def</span> <span class="nf">add_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-295"><a href="#L-295"><span class="linenos">295</span></a>
</span><span id="L-296"><a href="#L-296"><span class="linenos">296</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-296"><a href="#L-296"><span class="linenos">296</span></a><span class="n">PERCENTILES</span> <span class="o">=</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">PercentileCont</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">PercentileDisc</span><span class="p">)</span>
</span><span id="L-297"><a href="#L-297"><span class="linenos">297</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span> </span><span id="L-297"><a href="#L-297"><span class="linenos">297</span></a>
</span><span id="L-298"><a href="#L-298"><span class="linenos">298</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span> </span><span id="L-298"><a href="#L-298"><span class="linenos">298</span></a>
</span><span id="L-299"><a href="#L-299"><span class="linenos">299</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> </span><span id="L-299"><a href="#L-299"><span class="linenos">299</span></a><span class="k">def</span> <span class="nf">add_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-300"><a href="#L-300"><span class="linenos">300</span></a> <span class="p">):</span> </span><span id="L-300"><a href="#L-300"><span class="linenos">300</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-301"><a href="#L-301"><span class="linenos">301</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> </span><span id="L-301"><a href="#L-301"><span class="linenos">301</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span>
</span><span id="L-302"><a href="#L-302"><span class="linenos">302</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span> </span><span id="L-302"><a href="#L-302"><span class="linenos">302</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span>
</span><span id="L-303"><a href="#L-303"><span class="linenos">303</span></a> <span class="n">order</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">column</span><span class="p">)])</span> </span><span id="L-303"><a href="#L-303"><span class="linenos">303</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span>
</span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="n">order</span><span class="p">)</span> </span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a> <span class="p">):</span>
</span><span id="L-305"><a href="#L-305"><span class="linenos">305</span></a> </span><span id="L-305"><a href="#L-305"><span class="linenos">305</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-306"><a href="#L-306"><span class="linenos">306</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-306"><a href="#L-306"><span class="linenos">306</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span>
</span><span id="L-307"><a href="#L-307"><span class="linenos">307</span></a> </span><span id="L-307"><a href="#L-307"><span class="linenos">307</span></a> <span class="n">order</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">column</span><span class="p">)])</span>
</span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a> </span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="n">order</span><span class="p">)</span>
</span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a><span class="k">def</span> <span class="nf">remove_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a>
</span><span id="L-310"><a href="#L-310"><span class="linenos">310</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-310"><a href="#L-310"><span class="linenos">310</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-311"><a href="#L-311"><span class="linenos">311</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span> </span><span id="L-311"><a href="#L-311"><span class="linenos">311</span></a>
</span><span id="L-312"><a href="#L-312"><span class="linenos">312</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span> </span><span id="L-312"><a href="#L-312"><span class="linenos">312</span></a>
</span><span id="L-313"><a href="#L-313"><span class="linenos">313</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">)</span> </span><span id="L-313"><a href="#L-313"><span class="linenos">313</span></a><span class="k">def</span> <span class="nf">remove_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-314"><a href="#L-314"><span class="linenos">314</span></a> <span class="p">):</span> </span><span id="L-314"><a href="#L-314"><span class="linenos">314</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-315"><a href="#L-315"><span class="linenos">315</span></a> <span class="n">quantile</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">this</span> </span><span id="L-315"><a href="#L-315"><span class="linenos">315</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span>
</span><span id="L-316"><a href="#L-316"><span class="linenos">316</span></a> <span class="n">input_value</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">))</span><span class="o">.</span><span class="n">this</span> </span><span id="L-316"><a href="#L-316"><span class="linenos">316</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span>
</span><span id="L-317"><a href="#L-317"><span class="linenos">317</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">ApproxQuantile</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">input_value</span><span class="p">,</span> <span class="n">quantile</span><span class="o">=</span><span class="n">quantile</span><span class="p">))</span> </span><span id="L-317"><a href="#L-317"><span class="linenos">317</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">)</span>
</span><span id="L-318"><a href="#L-318"><span class="linenos">318</span></a> </span><span id="L-318"><a href="#L-318"><span class="linenos">318</span></a> <span class="p">):</span>
</span><span id="L-319"><a href="#L-319"><span class="linenos">319</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-319"><a href="#L-319"><span class="linenos">319</span></a> <span class="n">quantile</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a> </span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a> <span class="n">input_value</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">))</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a> </span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">ApproxQuantile</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">input_value</span><span class="p">,</span> <span class="n">quantile</span><span class="o">=</span><span class="n">quantile</span><span class="p">))</span>
</span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a><span class="k">def</span> <span class="nf">add_recursive_cte_column_names</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a>
</span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">recursive</span><span class="p">:</span> </span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a> <span class="n">next_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_c_&quot;</span><span class="p">)</span> </span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a>
</span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a> </span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a>
</span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span> </span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a><span class="k">def</span> <span class="nf">add_recursive_cte_column_names</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">recursive</span><span class="p">:</span>
</span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">this</span> </span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> <span class="n">next_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_c_&quot;</span><span class="p">)</span>
</span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Union</span><span class="p">):</span> </span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a>
</span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">this</span> </span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a> </span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span> </span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span> </span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Union</span><span class="p">):</span>
</span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">or</span> <span class="n">next_name</span><span class="p">())</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">query</span><span class="o">.</span><span class="n">selects</span><span class="p">],</span> </span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a> <span class="p">)</span> </span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a> </span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span>
</span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span>
</span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a> </span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">or</span> <span class="n">next_name</span><span class="p">())</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">query</span><span class="o">.</span><span class="n">selects</span><span class="p">],</span>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a> </span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a> <span class="p">)</span>
</span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a><span class="k">def</span> <span class="nf">epoch_cast_to_ts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a>
</span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TryCast</span><span class="p">))</span> </span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a>
</span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">&quot;epoch&quot;</span> </span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a>
</span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span> </span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a><span class="k">def</span> <span class="nf">epoch_cast_to_ts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a> <span class="p">):</span> </span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">string</span><span class="p">(</span><span class="s2">&quot;1970-01-01 00:00:00&quot;</span><span class="p">))</span> </span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TryCast</span><span class="p">))</span>
</span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a> </span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">&quot;epoch&quot;</span>
</span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span>
</span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a> </span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a> <span class="p">):</span>
</span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a> </span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">string</span><span class="p">(</span><span class="s2">&quot;1970-01-01 00:00:00&quot;</span><span class="p">))</span>
</span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a><span class="k">def</span> <span class="nf">timestamp_to_cast</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a>
</span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span> </span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span> </span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a>
</span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> </span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a>
</span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">,</span> </span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a><span class="k">def</span> <span class="nf">timestamp_to_cast</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a> <span class="p">)</span> </span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span>
</span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a> </span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span>
</span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a> </span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">,</span>
</span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a><span class="k">def</span> <span class="nf">eliminate_semi_and_anti_joins</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> </span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a> <span class="p">)</span>
</span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">):</span> </span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span> </span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a>
</span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span> </span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a>
</span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a> <span class="k">if</span> <span class="n">on</span> <span class="ow">and</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;SEMI&quot;</span><span class="p">,</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">):</span> </span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a><span class="k">def</span> <span class="nf">eliminate_semi_and_anti_joins</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a> <span class="n">subquery</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">this</span><span class="p">)</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">on</span><span class="p">)</span> </span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">):</span>
</span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">subquery</span><span class="p">)</span> </span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a> <span class="k">if</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">:</span> </span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span>
</span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exists</span><span class="o">.</span><span class="n">not_</span><span class="p">(</span><span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a> <span class="k">if</span> <span class="n">on</span> <span class="ow">and</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;SEMI&quot;</span><span class="p">,</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">):</span>
</span><span id="L-369"><a href="#L-369"><span class="linenos">369</span></a> </span><span id="L-369"><a href="#L-369"><span class="linenos">369</span></a> <span class="n">subquery</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">this</span><span class="p">)</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">on</span><span class="p">)</span>
</span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a> <span class="n">join</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> </span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">subquery</span><span class="p">)</span>
</span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">exists</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a> <span class="k">if</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">:</span>
</span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a> </span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exists</span><span class="o">.</span><span class="n">not_</span><span class="p">(</span><span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a>
</span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a> </span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a> <span class="n">join</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a> </span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">exists</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span> </span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a>
</span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a> <span class="n">transforms</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]],</span> </span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">Generator</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="nb">str</span><span class="p">]:</span> </span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a>
</span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a>
</span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span> </span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span>
</span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a><span class="sd"> expression to SQL, using either the &quot;_sql&quot; method corresponding to the resulting expression,</span> </span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a> <span class="n">transforms</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]],</span>
</span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span> </span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">Generator</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="nb">str</span><span class="p">]:</span>
</span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a> </span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a><span class="sd"> Args:</span> </span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span>
</span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</span> </span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a><span class="sd"> expression to SQL, using either the &quot;_sql&quot; method corresponding to the resulting expression,</span>
</span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a> </span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span>
</span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a><span class="sd"> Returns:</span> </span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a>
</span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a><span class="sd"> Function that can be used as a generator transform.</span> </span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a><span class="sd"> Args:</span>
</span><span id="L-389"><a href="#L-389"><span class="linenos">389</span></a><span class="sd"> &quot;&quot;&quot;</span> </span><span id="L-389"><a href="#L-389"><span class="linenos">389</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</span>
</span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a> </span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a>
</span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a> <span class="k">def</span> <span class="nf">_to_sql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span> </span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a><span class="sd"> Returns:</span>
</span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a><span class="sd"> Function that can be used as a generator transform.</span>
</span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a> </span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span> </span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a>
</span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> </span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a> <span class="k">def</span> <span class="nf">_to_sql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a> </span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a>
</span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span> </span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a> <span class="k">return</span> <span class="n">_sql_handler</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-401"><a href="#L-401"><span class="linenos">401</span></a> </span><span id="L-401"><a href="#L-401"><span class="linenos">401</span></a>
</span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a> <span class="n">transforms_handler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TRANSFORMS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span> </span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span> </span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>
</span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a> <span class="k">if</span> <span class="n">expression_type</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span> </span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a> <span class="k">return</span> <span class="n">_sql_handler</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Func</span><span class="p">):</span> </span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a>
</span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">function_fallback_sql</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a> <span class="n">transforms_handler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TRANSFORMS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span>
</span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a> </span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span>
</span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a> <span class="c1"># Ensures we don&#39;t enter an infinite loop. This can happen when the original expression</span> </span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a> <span class="k">if</span> <span class="n">expression_type</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a> <span class="c1"># has the same type as the final expression and there&#39;s no _sql method available for it,</span> </span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Func</span><span class="p">):</span>
</span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span> </span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">function_fallback_sql</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> </span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a>
</span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a> <span class="sa">f</span><span class="s2">&quot;Expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> requires a _sql method in order to be transformed.&quot;</span> </span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a> <span class="c1"># Ensures we don&#39;t enter an infinite loop. This can happen when the original expression</span>
</span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="p">)</span> </span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="c1"># has the same type as the final expression and there&#39;s no _sql method available for it,</span>
</span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> </span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span>
</span><span id="L-415"><a href="#L-415"><span class="linenos">415</span></a> <span class="k">return</span> <span class="n">transforms_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span> </span><span id="L-415"><a href="#L-415"><span class="linenos">415</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="L-416"><a href="#L-416"><span class="linenos">416</span></a> </span><span id="L-416"><a href="#L-416"><span class="linenos">416</span></a> <span class="sa">f</span><span class="s2">&quot;Expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> requires a _sql method in order to be transformed.&quot;</span>
</span><span id="L-417"><a href="#L-417"><span class="linenos">417</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unsupported expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span> </span><span id="L-417"><a href="#L-417"><span class="linenos">417</span></a> <span class="p">)</span>
</span><span id="L-418"><a href="#L-418"><span class="linenos">418</span></a> </span><span id="L-418"><a href="#L-418"><span class="linenos">418</span></a>
</span><span id="L-419"><a href="#L-419"><span class="linenos">419</span></a> <span class="k">return</span> <span class="n">_to_sql</span> </span><span id="L-419"><a href="#L-419"><span class="linenos">419</span></a> <span class="k">return</span> <span class="n">transforms_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
</span><span id="L-420"><a href="#L-420"><span class="linenos">420</span></a>
</span><span id="L-421"><a href="#L-421"><span class="linenos">421</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unsupported expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="L-422"><a href="#L-422"><span class="linenos">422</span></a>
</span><span id="L-423"><a href="#L-423"><span class="linenos">423</span></a> <span class="k">return</span> <span class="n">_to_sql</span>
</span></pre></div> </span></pre></div>
@ -839,105 +843,109 @@ other expressions. This transforms removes the precision from parameterized type
</span><span id="explode_to_unnest-189"><a href="#explode_to_unnest-189"><span class="linenos">189</span></a> <span class="p">)</span> </span><span id="explode_to_unnest-189"><a href="#explode_to_unnest-189"><span class="linenos">189</span></a> <span class="p">)</span>
</span><span id="explode_to_unnest-190"><a href="#explode_to_unnest-190"><span class="linenos">190</span></a> </span><span id="explode_to_unnest-190"><a href="#explode_to_unnest-190"><span class="linenos">190</span></a>
</span><span id="explode_to_unnest-191"><a href="#explode_to_unnest-191"><span class="linenos">191</span></a> <span class="c1"># we use list here because expression.selects is mutated inside the loop</span> </span><span id="explode_to_unnest-191"><a href="#explode_to_unnest-191"><span class="linenos">191</span></a> <span class="c1"># we use list here because expression.selects is mutated inside the loop</span>
</span><span id="explode_to_unnest-192"><a href="#explode_to_unnest-192"><span class="linenos">192</span></a> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span> </span><span id="explode_to_unnest-192"><a href="#explode_to_unnest-192"><span class="linenos">192</span></a> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="o">.</span><span class="n">copy</span><span class="p">():</span>
</span><span id="explode_to_unnest-193"><a href="#explode_to_unnest-193"><span class="linenos">193</span></a> <span class="n">to_replace</span> <span class="o">=</span> <span class="n">select</span> </span><span id="explode_to_unnest-193"><a href="#explode_to_unnest-193"><span class="linenos">193</span></a> <span class="n">explode</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="explode_to_unnest-194"><a href="#explode_to_unnest-194"><span class="linenos">194</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> </span><span id="explode_to_unnest-194"><a href="#explode_to_unnest-194"><span class="linenos">194</span></a>
</span><span id="explode_to_unnest-195"><a href="#explode_to_unnest-195"><span class="linenos">195</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> </span><span id="explode_to_unnest-195"><a href="#explode_to_unnest-195"><span class="linenos">195</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)):</span>
</span><span id="explode_to_unnest-196"><a href="#explode_to_unnest-196"><span class="linenos">196</span></a> </span><span id="explode_to_unnest-196"><a href="#explode_to_unnest-196"><span class="linenos">196</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="explode_to_unnest-197"><a href="#explode_to_unnest-197"><span class="linenos">197</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">):</span> </span><span id="explode_to_unnest-197"><a href="#explode_to_unnest-197"><span class="linenos">197</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="explode_to_unnest-198"><a href="#explode_to_unnest-198"><span class="linenos">198</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">alias</span> </span><span id="explode_to_unnest-198"><a href="#explode_to_unnest-198"><span class="linenos">198</span></a>
</span><span id="explode_to_unnest-199"><a href="#explode_to_unnest-199"><span class="linenos">199</span></a> <span class="n">select</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="explode_to_unnest-199"><a href="#explode_to_unnest-199"><span class="linenos">199</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">):</span>
</span><span id="explode_to_unnest-200"><a href="#explode_to_unnest-200"><span class="linenos">200</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Aliases</span><span class="p">):</span> </span><span id="explode_to_unnest-200"><a href="#explode_to_unnest-200"><span class="linenos">200</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">alias</span>
</span><span id="explode_to_unnest-201"><a href="#explode_to_unnest-201"><span class="linenos">201</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> </span><span id="explode_to_unnest-201"><a href="#explode_to_unnest-201"><span class="linenos">201</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span>
</span><span id="explode_to_unnest-202"><a href="#explode_to_unnest-202"><span class="linenos">202</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">name</span> </span><span id="explode_to_unnest-202"><a href="#explode_to_unnest-202"><span class="linenos">202</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Aliases</span><span class="p">):</span>
</span><span id="explode_to_unnest-203"><a href="#explode_to_unnest-203"><span class="linenos">203</span></a> <span class="n">select</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="explode_to_unnest-203"><a href="#explode_to_unnest-203"><span class="linenos">203</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
</span><span id="explode_to_unnest-204"><a href="#explode_to_unnest-204"><span class="linenos">204</span></a> </span><span id="explode_to_unnest-204"><a href="#explode_to_unnest-204"><span class="linenos">204</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">aliases</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">name</span>
</span><span id="explode_to_unnest-205"><a href="#explode_to_unnest-205"><span class="linenos">205</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)):</span> </span><span id="explode_to_unnest-205"><a href="#explode_to_unnest-205"><span class="linenos">205</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
</span><span id="explode_to_unnest-206"><a href="#explode_to_unnest-206"><span class="linenos">206</span></a> <span class="n">is_posexplode</span> <span class="o">=</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span> </span><span id="explode_to_unnest-206"><a href="#explode_to_unnest-206"><span class="linenos">206</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="explode_to_unnest-207"><a href="#explode_to_unnest-207"><span class="linenos">207</span></a> <span class="n">explode_arg</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">this</span> </span><span id="explode_to_unnest-207"><a href="#explode_to_unnest-207"><span class="linenos">207</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">))</span>
</span><span id="explode_to_unnest-208"><a href="#explode_to_unnest-208"><span class="linenos">208</span></a> </span><span id="explode_to_unnest-208"><a href="#explode_to_unnest-208"><span class="linenos">208</span></a> <span class="n">explode</span> <span class="o">=</span> <span class="n">alias</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="explode_to_unnest-209"><a href="#explode_to_unnest-209"><span class="linenos">209</span></a> <span class="c1"># This ensures that we won&#39;t use [POS]EXPLODE&#39;s argument as a new selection</span> </span><span id="explode_to_unnest-209"><a href="#explode_to_unnest-209"><span class="linenos">209</span></a> <span class="k">assert</span> <span class="n">explode</span>
</span><span id="explode_to_unnest-210"><a href="#explode_to_unnest-210"><span class="linenos">210</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode_arg</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">):</span> </span><span id="explode_to_unnest-210"><a href="#explode_to_unnest-210"><span class="linenos">210</span></a>
</span><span id="explode_to_unnest-211"><a href="#explode_to_unnest-211"><span class="linenos">211</span></a> <span class="n">taken_select_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">output_name</span><span class="p">)</span> </span><span id="explode_to_unnest-211"><a href="#explode_to_unnest-211"><span class="linenos">211</span></a> <span class="n">is_posexplode</span> <span class="o">=</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span><span class="p">)</span>
</span><span id="explode_to_unnest-212"><a href="#explode_to_unnest-212"><span class="linenos">212</span></a> </span><span id="explode_to_unnest-212"><a href="#explode_to_unnest-212"><span class="linenos">212</span></a> <span class="n">explode_arg</span> <span class="o">=</span> <span class="n">explode</span><span class="o">.</span><span class="n">this</span>
</span><span id="explode_to_unnest-213"><a href="#explode_to_unnest-213"><span class="linenos">213</span></a> <span class="n">unnest_source_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_source_names</span><span class="p">,</span> <span class="s2">&quot;_u&quot;</span><span class="p">)</span> </span><span id="explode_to_unnest-213"><a href="#explode_to_unnest-213"><span class="linenos">213</span></a>
</span><span id="explode_to_unnest-214"><a href="#explode_to_unnest-214"><span class="linenos">214</span></a> </span><span id="explode_to_unnest-214"><a href="#explode_to_unnest-214"><span class="linenos">214</span></a> <span class="c1"># This ensures that we won&#39;t use [POS]EXPLODE&#39;s argument as a new selection</span>
</span><span id="explode_to_unnest-215"><a href="#explode_to_unnest-215"><span class="linenos">215</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">explode_alias</span><span class="p">:</span> </span><span id="explode_to_unnest-215"><a href="#explode_to_unnest-215"><span class="linenos">215</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">explode_arg</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">):</span>
</span><span id="explode_to_unnest-216"><a href="#explode_to_unnest-216"><span class="linenos">216</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;col&quot;</span><span class="p">)</span> </span><span id="explode_to_unnest-216"><a href="#explode_to_unnest-216"><span class="linenos">216</span></a> <span class="n">taken_select_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">output_name</span><span class="p">)</span>
</span><span id="explode_to_unnest-217"><a href="#explode_to_unnest-217"><span class="linenos">217</span></a> </span><span id="explode_to_unnest-217"><a href="#explode_to_unnest-217"><span class="linenos">217</span></a>
</span><span id="explode_to_unnest-218"><a href="#explode_to_unnest-218"><span class="linenos">218</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span> </span><span id="explode_to_unnest-218"><a href="#explode_to_unnest-218"><span class="linenos">218</span></a> <span class="n">unnest_source_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_source_names</span><span class="p">,</span> <span class="s2">&quot;_u&quot;</span><span class="p">)</span>
</span><span id="explode_to_unnest-219"><a href="#explode_to_unnest-219"><span class="linenos">219</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span> </span><span id="explode_to_unnest-219"><a href="#explode_to_unnest-219"><span class="linenos">219</span></a>
</span><span id="explode_to_unnest-220"><a href="#explode_to_unnest-220"><span class="linenos">220</span></a> </span><span id="explode_to_unnest-220"><a href="#explode_to_unnest-220"><span class="linenos">220</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">explode_alias</span><span class="p">:</span>
</span><span id="explode_to_unnest-221"><a href="#explode_to_unnest-221"><span class="linenos">221</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_alias</span><span class="p">:</span> </span><span id="explode_to_unnest-221"><a href="#explode_to_unnest-221"><span class="linenos">221</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;col&quot;</span><span class="p">)</span>
</span><span id="explode_to_unnest-222"><a href="#explode_to_unnest-222"><span class="linenos">222</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span> </span><span id="explode_to_unnest-222"><a href="#explode_to_unnest-222"><span class="linenos">222</span></a>
</span><span id="explode_to_unnest-223"><a href="#explode_to_unnest-223"><span class="linenos">223</span></a> </span><span id="explode_to_unnest-223"><a href="#explode_to_unnest-223"><span class="linenos">223</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="explode_to_unnest-224"><a href="#explode_to_unnest-224"><span class="linenos">224</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span> </span><span id="explode_to_unnest-224"><a href="#explode_to_unnest-224"><span class="linenos">224</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span>
</span><span id="explode_to_unnest-225"><a href="#explode_to_unnest-225"><span class="linenos">225</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span> </span><span id="explode_to_unnest-225"><a href="#explode_to_unnest-225"><span class="linenos">225</span></a>
</span><span id="explode_to_unnest-226"><a href="#explode_to_unnest-226"><span class="linenos">226</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">),</span> </span><span id="explode_to_unnest-226"><a href="#explode_to_unnest-226"><span class="linenos">226</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_alias</span><span class="p">:</span>
</span><span id="explode_to_unnest-227"><a href="#explode_to_unnest-227"><span class="linenos">227</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">)</span> </span><span id="explode_to_unnest-227"><a href="#explode_to_unnest-227"><span class="linenos">227</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">new_name</span><span class="p">(</span><span class="n">taken_select_names</span><span class="p">,</span> <span class="s2">&quot;pos&quot;</span><span class="p">)</span>
</span><span id="explode_to_unnest-228"><a href="#explode_to_unnest-228"><span class="linenos">228</span></a> </span><span id="explode_to_unnest-228"><a href="#explode_to_unnest-228"><span class="linenos">228</span></a>
</span><span id="explode_to_unnest-229"><a href="#explode_to_unnest-229"><span class="linenos">229</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span> </span><span id="explode_to_unnest-229"><a href="#explode_to_unnest-229"><span class="linenos">229</span></a> <span class="n">alias</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">))</span>
</span><span id="explode_to_unnest-230"><a href="#explode_to_unnest-230"><span class="linenos">230</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span> </span><span id="explode_to_unnest-230"><a href="#explode_to_unnest-230"><span class="linenos">230</span></a>
</span><span id="explode_to_unnest-231"><a href="#explode_to_unnest-231"><span class="linenos">231</span></a> <span class="n">index</span> <span class="o">=</span> <span class="n">expressions</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">to_replace</span><span class="p">)</span> </span><span id="explode_to_unnest-231"><a href="#explode_to_unnest-231"><span class="linenos">231</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span>
</span><span id="explode_to_unnest-232"><a href="#explode_to_unnest-232"><span class="linenos">232</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> </span><span id="explode_to_unnest-232"><a href="#explode_to_unnest-232"><span class="linenos">232</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span>
</span><span id="explode_to_unnest-233"><a href="#explode_to_unnest-233"><span class="linenos">233</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span> </span><span id="explode_to_unnest-233"><a href="#explode_to_unnest-233"><span class="linenos">233</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">),</span>
</span><span id="explode_to_unnest-234"><a href="#explode_to_unnest-234"><span class="linenos">234</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span> </span><span id="explode_to_unnest-234"><a href="#explode_to_unnest-234"><span class="linenos">234</span></a> <span class="p">)</span>
</span><span id="explode_to_unnest-235"><a href="#explode_to_unnest-235"><span class="linenos">235</span></a> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> </span><span id="explode_to_unnest-235"><a href="#explode_to_unnest-235"><span class="linenos">235</span></a>
</span><span id="explode_to_unnest-236"><a href="#explode_to_unnest-236"><span class="linenos">236</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span> </span><span id="explode_to_unnest-236"><a href="#explode_to_unnest-236"><span class="linenos">236</span></a> <span class="n">explode</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">column</span><span class="p">)</span>
</span><span id="explode_to_unnest-237"><a href="#explode_to_unnest-237"><span class="linenos">237</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span> </span><span id="explode_to_unnest-237"><a href="#explode_to_unnest-237"><span class="linenos">237</span></a>
</span><span id="explode_to_unnest-238"><a href="#explode_to_unnest-238"><span class="linenos">238</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="explode_to_unnest-238"><a href="#explode_to_unnest-238"><span class="linenos">238</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="explode_to_unnest-239"><a href="#explode_to_unnest-239"><span class="linenos">239</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="explode_to_unnest-239"><a href="#explode_to_unnest-239"><span class="linenos">239</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span>
</span><span id="explode_to_unnest-240"><a href="#explode_to_unnest-240"><span class="linenos">240</span></a> <span class="p">)</span> </span><span id="explode_to_unnest-240"><a href="#explode_to_unnest-240"><span class="linenos">240</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span>
</span><span id="explode_to_unnest-241"><a href="#explode_to_unnest-241"><span class="linenos">241</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">expressions</span><span class="p">)</span> </span><span id="explode_to_unnest-241"><a href="#explode_to_unnest-241"><span class="linenos">241</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
</span><span id="explode_to_unnest-242"><a href="#explode_to_unnest-242"><span class="linenos">242</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="explode_to_unnest-242"><a href="#explode_to_unnest-242"><span class="linenos">242</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">If</span><span class="p">(</span>
</span><span id="explode_to_unnest-243"><a href="#explode_to_unnest-243"><span class="linenos">243</span></a> <span class="n">to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">column</span><span class="p">)</span> </span><span id="explode_to_unnest-243"><a href="#explode_to_unnest-243"><span class="linenos">243</span></a> <span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)),</span>
</span><span id="explode_to_unnest-244"><a href="#explode_to_unnest-244"><span class="linenos">244</span></a> </span><span id="explode_to_unnest-244"><a href="#explode_to_unnest-244"><span class="linenos">244</span></a> <span class="n">true</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="explode_to_unnest-245"><a href="#explode_to_unnest-245"><span class="linenos">245</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">arrays</span><span class="p">:</span> </span><span id="explode_to_unnest-245"><a href="#explode_to_unnest-245"><span class="linenos">245</span></a> <span class="p">)</span><span class="o">.</span><span class="n">as_</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="explode_to_unnest-246"><a href="#explode_to_unnest-246"><span class="linenos">246</span></a> <span class="k">if</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">):</span> </span><span id="explode_to_unnest-246"><a href="#explode_to_unnest-246"><span class="linenos">246</span></a> <span class="p">)</span>
</span><span id="explode_to_unnest-247"><a href="#explode_to_unnest-247"><span class="linenos">247</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="explode_to_unnest-247"><a href="#explode_to_unnest-247"><span class="linenos">247</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">expressions</span><span class="p">)</span>
</span><span id="explode_to_unnest-248"><a href="#explode_to_unnest-248"><span class="linenos">248</span></a> <span class="k">else</span><span class="p">:</span> </span><span id="explode_to_unnest-248"><a href="#explode_to_unnest-248"><span class="linenos">248</span></a>
</span><span id="explode_to_unnest-249"><a href="#explode_to_unnest-249"><span class="linenos">249</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="explode_to_unnest-249"><a href="#explode_to_unnest-249"><span class="linenos">249</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">arrays</span><span class="p">:</span>
</span><span id="explode_to_unnest-250"><a href="#explode_to_unnest-250"><span class="linenos">250</span></a> </span><span id="explode_to_unnest-250"><a href="#explode_to_unnest-250"><span class="linenos">250</span></a> <span class="k">if</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">):</span>
</span><span id="explode_to_unnest-251"><a href="#explode_to_unnest-251"><span class="linenos">251</span></a> <span class="n">size</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArraySize</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span> </span><span id="explode_to_unnest-251"><a href="#explode_to_unnest-251"><span class="linenos">251</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="explode_to_unnest-252"><a href="#explode_to_unnest-252"><span class="linenos">252</span></a> <span class="n">arrays</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">size</span><span class="p">)</span> </span><span id="explode_to_unnest-252"><a href="#explode_to_unnest-252"><span class="linenos">252</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="explode_to_unnest-253"><a href="#explode_to_unnest-253"><span class="linenos">253</span></a> </span><span id="explode_to_unnest-253"><a href="#explode_to_unnest-253"><span class="linenos">253</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">series</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="explode_to_unnest-254"><a href="#explode_to_unnest-254"><span class="linenos">254</span></a> <span class="c1"># trino doesn&#39;t support left join unnest with on conditions</span> </span><span id="explode_to_unnest-254"><a href="#explode_to_unnest-254"><span class="linenos">254</span></a>
</span><span id="explode_to_unnest-255"><a href="#explode_to_unnest-255"><span class="linenos">255</span></a> <span class="c1"># if it did, this would be much simpler</span> </span><span id="explode_to_unnest-255"><a href="#explode_to_unnest-255"><span class="linenos">255</span></a> <span class="n">size</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArraySize</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="explode_to_unnest-256"><a href="#explode_to_unnest-256"><span class="linenos">256</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> </span><span id="explode_to_unnest-256"><a href="#explode_to_unnest-256"><span class="linenos">256</span></a> <span class="n">arrays</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
</span><span id="explode_to_unnest-257"><a href="#explode_to_unnest-257"><span class="linenos">257</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span> </span><span id="explode_to_unnest-257"><a href="#explode_to_unnest-257"><span class="linenos">257</span></a>
</span><span id="explode_to_unnest-258"><a href="#explode_to_unnest-258"><span class="linenos">258</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span> </span><span id="explode_to_unnest-258"><a href="#explode_to_unnest-258"><span class="linenos">258</span></a> <span class="c1"># trino doesn&#39;t support left join unnest with on conditions</span>
</span><span id="explode_to_unnest-259"><a href="#explode_to_unnest-259"><span class="linenos">259</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">()],</span> </span><span id="explode_to_unnest-259"><a href="#explode_to_unnest-259"><span class="linenos">259</span></a> <span class="c1"># if it did, this would be much simpler</span>
</span><span id="explode_to_unnest-260"><a href="#explode_to_unnest-260"><span class="linenos">260</span></a> <span class="n">offset</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span> </span><span id="explode_to_unnest-260"><a href="#explode_to_unnest-260"><span class="linenos">260</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="explode_to_unnest-261"><a href="#explode_to_unnest-261"><span class="linenos">261</span></a> <span class="p">),</span> </span><span id="explode_to_unnest-261"><a href="#explode_to_unnest-261"><span class="linenos">261</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span>
</span><span id="explode_to_unnest-262"><a href="#explode_to_unnest-262"><span class="linenos">262</span></a> <span class="n">unnest_source_alias</span><span class="p">,</span> </span><span id="explode_to_unnest-262"><a href="#explode_to_unnest-262"><span class="linenos">262</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span>
</span><span id="explode_to_unnest-263"><a href="#explode_to_unnest-263"><span class="linenos">263</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">explode_alias</span><span class="p">],</span> </span><span id="explode_to_unnest-263"><a href="#explode_to_unnest-263"><span class="linenos">263</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">explode_arg</span><span class="o">.</span><span class="n">copy</span><span class="p">()],</span>
</span><span id="explode_to_unnest-264"><a href="#explode_to_unnest-264"><span class="linenos">264</span></a> <span class="p">),</span> </span><span id="explode_to_unnest-264"><a href="#explode_to_unnest-264"><span class="linenos">264</span></a> <span class="n">offset</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">),</span>
</span><span id="explode_to_unnest-265"><a href="#explode_to_unnest-265"><span class="linenos">265</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> </span><span id="explode_to_unnest-265"><a href="#explode_to_unnest-265"><span class="linenos">265</span></a> <span class="p">),</span>
</span><span id="explode_to_unnest-266"><a href="#explode_to_unnest-266"><span class="linenos">266</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="explode_to_unnest-266"><a href="#explode_to_unnest-266"><span class="linenos">266</span></a> <span class="n">unnest_source_alias</span><span class="p">,</span>
</span><span id="explode_to_unnest-267"><a href="#explode_to_unnest-267"><span class="linenos">267</span></a> <span class="p">)</span> </span><span id="explode_to_unnest-267"><a href="#explode_to_unnest-267"><span class="linenos">267</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">explode_alias</span><span class="p">],</span>
</span><span id="explode_to_unnest-268"><a href="#explode_to_unnest-268"><span class="linenos">268</span></a> </span><span id="explode_to_unnest-268"><a href="#explode_to_unnest-268"><span class="linenos">268</span></a> <span class="p">),</span>
</span><span id="explode_to_unnest-269"><a href="#explode_to_unnest-269"><span class="linenos">269</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> </span><span id="explode_to_unnest-269"><a href="#explode_to_unnest-269"><span class="linenos">269</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span>
</span><span id="explode_to_unnest-270"><a href="#explode_to_unnest-270"><span class="linenos">270</span></a> <span class="n">size</span> <span class="o">=</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span> </span><span id="explode_to_unnest-270"><a href="#explode_to_unnest-270"><span class="linenos">270</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="explode_to_unnest-271"><a href="#explode_to_unnest-271"><span class="linenos">271</span></a> </span><span id="explode_to_unnest-271"><a href="#explode_to_unnest-271"><span class="linenos">271</span></a> <span class="p">)</span>
</span><span id="explode_to_unnest-272"><a href="#explode_to_unnest-272"><span class="linenos">272</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span> </span><span id="explode_to_unnest-272"><a href="#explode_to_unnest-272"><span class="linenos">272</span></a>
</span><span id="explode_to_unnest-273"><a href="#explode_to_unnest-273"><span class="linenos">273</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> </span><span id="explode_to_unnest-273"><a href="#explode_to_unnest-273"><span class="linenos">273</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="explode_to_unnest-274"><a href="#explode_to_unnest-274"><span class="linenos">274</span></a> <span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">))</span> </span><span id="explode_to_unnest-274"><a href="#explode_to_unnest-274"><span class="linenos">274</span></a> <span class="n">size</span> <span class="o">=</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span>
</span><span id="explode_to_unnest-275"><a href="#explode_to_unnest-275"><span class="linenos">275</span></a> <span class="o">.</span><span class="n">or_</span><span class="p">(</span> </span><span id="explode_to_unnest-275"><a href="#explode_to_unnest-275"><span class="linenos">275</span></a>
</span><span id="explode_to_unnest-276"><a href="#explode_to_unnest-276"><span class="linenos">276</span></a> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">size</span><span class="p">))</span> </span><span id="explode_to_unnest-276"><a href="#explode_to_unnest-276"><span class="linenos">276</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span>
</span><span id="explode_to_unnest-277"><a href="#explode_to_unnest-277"><span class="linenos">277</span></a> <span class="p">),</span> </span><span id="explode_to_unnest-277"><a href="#explode_to_unnest-277"><span class="linenos">277</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span>
</span><span id="explode_to_unnest-278"><a href="#explode_to_unnest-278"><span class="linenos">278</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> </span><span id="explode_to_unnest-278"><a href="#explode_to_unnest-278"><span class="linenos">278</span></a> <span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">))</span>
</span><span id="explode_to_unnest-279"><a href="#explode_to_unnest-279"><span class="linenos">279</span></a> <span class="p">)</span> </span><span id="explode_to_unnest-279"><a href="#explode_to_unnest-279"><span class="linenos">279</span></a> <span class="o">.</span><span class="n">or_</span><span class="p">(</span>
</span><span id="explode_to_unnest-280"><a href="#explode_to_unnest-280"><span class="linenos">280</span></a> </span><span id="explode_to_unnest-280"><a href="#explode_to_unnest-280"><span class="linenos">280</span></a> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">series_alias</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">and_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">)</span><span class="o">.</span><span class="n">eq</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>
</span><span id="explode_to_unnest-281"><a href="#explode_to_unnest-281"><span class="linenos">281</span></a> <span class="k">if</span> <span class="n">arrays</span><span class="p">:</span> </span><span id="explode_to_unnest-281"><a href="#explode_to_unnest-281"><span class="linenos">281</span></a> <span class="p">),</span>
</span><span id="explode_to_unnest-282"><a href="#explode_to_unnest-282"><span class="linenos">282</span></a> <span class="n">end</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Greatest</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">expressions</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> </span><span id="explode_to_unnest-282"><a href="#explode_to_unnest-282"><span class="linenos">282</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="explode_to_unnest-283"><a href="#explode_to_unnest-283"><span class="linenos">283</span></a> </span><span id="explode_to_unnest-283"><a href="#explode_to_unnest-283"><span class="linenos">283</span></a> <span class="p">)</span>
</span><span id="explode_to_unnest-284"><a href="#explode_to_unnest-284"><span class="linenos">284</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span> </span><span id="explode_to_unnest-284"><a href="#explode_to_unnest-284"><span class="linenos">284</span></a>
</span><span id="explode_to_unnest-285"><a href="#explode_to_unnest-285"><span class="linenos">285</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">index_offset</span><span class="p">)</span> </span><span id="explode_to_unnest-285"><a href="#explode_to_unnest-285"><span class="linenos">285</span></a> <span class="k">if</span> <span class="n">arrays</span><span class="p">:</span>
</span><span id="explode_to_unnest-286"><a href="#explode_to_unnest-286"><span class="linenos">286</span></a> <span class="n">series</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span> </span><span id="explode_to_unnest-286"><a href="#explode_to_unnest-286"><span class="linenos">286</span></a> <span class="n">end</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Condition</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Greatest</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">expressions</span><span class="o">=</span><span class="n">arrays</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</span><span id="explode_to_unnest-287"><a href="#explode_to_unnest-287"><span class="linenos">287</span></a> </span><span id="explode_to_unnest-287"><a href="#explode_to_unnest-287"><span class="linenos">287</span></a>
</span><span id="explode_to_unnest-288"><a href="#explode_to_unnest-288"><span class="linenos">288</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="explode_to_unnest-288"><a href="#explode_to_unnest-288"><span class="linenos">288</span></a> <span class="k">if</span> <span class="n">index_offset</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="explode_to_unnest-289"><a href="#explode_to_unnest-289"><span class="linenos">289</span></a> </span><span id="explode_to_unnest-289"><a href="#explode_to_unnest-289"><span class="linenos">289</span></a> <span class="n">end</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">index_offset</span><span class="p">)</span>
</span><span id="explode_to_unnest-290"><a href="#explode_to_unnest-290"><span class="linenos">290</span></a> <span class="k">return</span> <span class="n">_explode_to_unnest</span> </span><span id="explode_to_unnest-290"><a href="#explode_to_unnest-290"><span class="linenos">290</span></a> <span class="n">series</span><span class="o">.</span><span class="n">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span>
</span><span id="explode_to_unnest-291"><a href="#explode_to_unnest-291"><span class="linenos">291</span></a>
</span><span id="explode_to_unnest-292"><a href="#explode_to_unnest-292"><span class="linenos">292</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="explode_to_unnest-293"><a href="#explode_to_unnest-293"><span class="linenos">293</span></a>
</span><span id="explode_to_unnest-294"><a href="#explode_to_unnest-294"><span class="linenos">294</span></a> <span class="k">return</span> <span class="n">_explode_to_unnest</span>
</span></pre></div> </span></pre></div>
@ -967,18 +975,18 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#add_within_group_for_percentiles"></a> <a class="headerlink" href="#add_within_group_for_percentiles"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="add_within_group_for_percentiles-296"><a href="#add_within_group_for_percentiles-296"><span class="linenos">296</span></a><span class="k">def</span> <span class="nf">add_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="add_within_group_for_percentiles-300"><a href="#add_within_group_for_percentiles-300"><span class="linenos">300</span></a><span class="k">def</span> <span class="nf">add_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="add_within_group_for_percentiles-297"><a href="#add_within_group_for_percentiles-297"><span class="linenos">297</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="add_within_group_for_percentiles-301"><a href="#add_within_group_for_percentiles-301"><span class="linenos">301</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="add_within_group_for_percentiles-298"><a href="#add_within_group_for_percentiles-298"><span class="linenos">298</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span> </span><span id="add_within_group_for_percentiles-302"><a href="#add_within_group_for_percentiles-302"><span class="linenos">302</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span>
</span><span id="add_within_group_for_percentiles-299"><a href="#add_within_group_for_percentiles-299"><span class="linenos">299</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span> </span><span id="add_within_group_for_percentiles-303"><a href="#add_within_group_for_percentiles-303"><span class="linenos">303</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span>
</span><span id="add_within_group_for_percentiles-300"><a href="#add_within_group_for_percentiles-300"><span class="linenos">300</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> </span><span id="add_within_group_for_percentiles-304"><a href="#add_within_group_for_percentiles-304"><span class="linenos">304</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span>
</span><span id="add_within_group_for_percentiles-301"><a href="#add_within_group_for_percentiles-301"><span class="linenos">301</span></a> <span class="p">):</span> </span><span id="add_within_group_for_percentiles-305"><a href="#add_within_group_for_percentiles-305"><span class="linenos">305</span></a> <span class="p">):</span>
</span><span id="add_within_group_for_percentiles-302"><a href="#add_within_group_for_percentiles-302"><span class="linenos">302</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> </span><span id="add_within_group_for_percentiles-306"><a href="#add_within_group_for_percentiles-306"><span class="linenos">306</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="add_within_group_for_percentiles-303"><a href="#add_within_group_for_percentiles-303"><span class="linenos">303</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span> </span><span id="add_within_group_for_percentiles-307"><a href="#add_within_group_for_percentiles-307"><span class="linenos">307</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span>
</span><span id="add_within_group_for_percentiles-304"><a href="#add_within_group_for_percentiles-304"><span class="linenos">304</span></a> <span class="n">order</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">column</span><span class="p">)])</span> </span><span id="add_within_group_for_percentiles-308"><a href="#add_within_group_for_percentiles-308"><span class="linenos">308</span></a> <span class="n">order</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">column</span><span class="p">)])</span>
</span><span id="add_within_group_for_percentiles-305"><a href="#add_within_group_for_percentiles-305"><span class="linenos">305</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="n">order</span><span class="p">)</span> </span><span id="add_within_group_for_percentiles-309"><a href="#add_within_group_for_percentiles-309"><span class="linenos">309</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="n">order</span><span class="p">)</span>
</span><span id="add_within_group_for_percentiles-306"><a href="#add_within_group_for_percentiles-306"><span class="linenos">306</span></a> </span><span id="add_within_group_for_percentiles-310"><a href="#add_within_group_for_percentiles-310"><span class="linenos">310</span></a>
</span><span id="add_within_group_for_percentiles-307"><a href="#add_within_group_for_percentiles-307"><span class="linenos">307</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="add_within_group_for_percentiles-311"><a href="#add_within_group_for_percentiles-311"><span class="linenos">311</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -996,17 +1004,17 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#remove_within_group_for_percentiles"></a> <a class="headerlink" href="#remove_within_group_for_percentiles"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="remove_within_group_for_percentiles-310"><a href="#remove_within_group_for_percentiles-310"><span class="linenos">310</span></a><span class="k">def</span> <span class="nf">remove_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="remove_within_group_for_percentiles-314"><a href="#remove_within_group_for_percentiles-314"><span class="linenos">314</span></a><span class="k">def</span> <span class="nf">remove_within_group_for_percentiles</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="remove_within_group_for_percentiles-311"><a href="#remove_within_group_for_percentiles-311"><span class="linenos">311</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="remove_within_group_for_percentiles-315"><a href="#remove_within_group_for_percentiles-315"><span class="linenos">315</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="remove_within_group_for_percentiles-312"><a href="#remove_within_group_for_percentiles-312"><span class="linenos">312</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span> </span><span id="remove_within_group_for_percentiles-316"><a href="#remove_within_group_for_percentiles-316"><span class="linenos">316</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">WithinGroup</span><span class="p">)</span>
</span><span id="remove_within_group_for_percentiles-313"><a href="#remove_within_group_for_percentiles-313"><span class="linenos">313</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span> </span><span id="remove_within_group_for_percentiles-317"><a href="#remove_within_group_for_percentiles-317"><span class="linenos">317</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">PERCENTILES</span><span class="p">)</span>
</span><span id="remove_within_group_for_percentiles-314"><a href="#remove_within_group_for_percentiles-314"><span class="linenos">314</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">)</span> </span><span id="remove_within_group_for_percentiles-318"><a href="#remove_within_group_for_percentiles-318"><span class="linenos">318</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</span><span class="p">)</span>
</span><span id="remove_within_group_for_percentiles-315"><a href="#remove_within_group_for_percentiles-315"><span class="linenos">315</span></a> <span class="p">):</span> </span><span id="remove_within_group_for_percentiles-319"><a href="#remove_within_group_for_percentiles-319"><span class="linenos">319</span></a> <span class="p">):</span>
</span><span id="remove_within_group_for_percentiles-316"><a href="#remove_within_group_for_percentiles-316"><span class="linenos">316</span></a> <span class="n">quantile</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">this</span> </span><span id="remove_within_group_for_percentiles-320"><a href="#remove_within_group_for_percentiles-320"><span class="linenos">320</span></a> <span class="n">quantile</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">this</span>
</span><span id="remove_within_group_for_percentiles-317"><a href="#remove_within_group_for_percentiles-317"><span class="linenos">317</span></a> <span class="n">input_value</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">))</span><span class="o">.</span><span class="n">this</span> </span><span id="remove_within_group_for_percentiles-321"><a href="#remove_within_group_for_percentiles-321"><span class="linenos">321</span></a> <span class="n">input_value</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Ordered</span><span class="p">))</span><span class="o">.</span><span class="n">this</span>
</span><span id="remove_within_group_for_percentiles-318"><a href="#remove_within_group_for_percentiles-318"><span class="linenos">318</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">ApproxQuantile</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">input_value</span><span class="p">,</span> <span class="n">quantile</span><span class="o">=</span><span class="n">quantile</span><span class="p">))</span> </span><span id="remove_within_group_for_percentiles-322"><a href="#remove_within_group_for_percentiles-322"><span class="linenos">322</span></a> <span class="k">return</span> <span class="n">expression</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">ApproxQuantile</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">input_value</span><span class="p">,</span> <span class="n">quantile</span><span class="o">=</span><span class="n">quantile</span><span class="p">))</span>
</span><span id="remove_within_group_for_percentiles-319"><a href="#remove_within_group_for_percentiles-319"><span class="linenos">319</span></a> </span><span id="remove_within_group_for_percentiles-323"><a href="#remove_within_group_for_percentiles-323"><span class="linenos">323</span></a>
</span><span id="remove_within_group_for_percentiles-320"><a href="#remove_within_group_for_percentiles-320"><span class="linenos">320</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="remove_within_group_for_percentiles-324"><a href="#remove_within_group_for_percentiles-324"><span class="linenos">324</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -1024,22 +1032,22 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#add_recursive_cte_column_names"></a> <a class="headerlink" href="#add_recursive_cte_column_names"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="add_recursive_cte_column_names-323"><a href="#add_recursive_cte_column_names-323"><span class="linenos">323</span></a><span class="k">def</span> <span class="nf">add_recursive_cte_column_names</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="add_recursive_cte_column_names-327"><a href="#add_recursive_cte_column_names-327"><span class="linenos">327</span></a><span class="k">def</span> <span class="nf">add_recursive_cte_column_names</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="add_recursive_cte_column_names-324"><a href="#add_recursive_cte_column_names-324"><span class="linenos">324</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">recursive</span><span class="p">:</span> </span><span id="add_recursive_cte_column_names-328"><a href="#add_recursive_cte_column_names-328"><span class="linenos">328</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">)</span> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">recursive</span><span class="p">:</span>
</span><span id="add_recursive_cte_column_names-325"><a href="#add_recursive_cte_column_names-325"><span class="linenos">325</span></a> <span class="n">next_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_c_&quot;</span><span class="p">)</span> </span><span id="add_recursive_cte_column_names-329"><a href="#add_recursive_cte_column_names-329"><span class="linenos">329</span></a> <span class="n">next_name</span> <span class="o">=</span> <span class="n">name_sequence</span><span class="p">(</span><span class="s2">&quot;_c_&quot;</span><span class="p">)</span>
</span><span id="add_recursive_cte_column_names-326"><a href="#add_recursive_cte_column_names-326"><span class="linenos">326</span></a> </span><span id="add_recursive_cte_column_names-330"><a href="#add_recursive_cte_column_names-330"><span class="linenos">330</span></a>
</span><span id="add_recursive_cte_column_names-327"><a href="#add_recursive_cte_column_names-327"><span class="linenos">327</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span> </span><span id="add_recursive_cte_column_names-331"><a href="#add_recursive_cte_column_names-331"><span class="linenos">331</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="add_recursive_cte_column_names-328"><a href="#add_recursive_cte_column_names-328"><span class="linenos">328</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span> </span><span id="add_recursive_cte_column_names-332"><a href="#add_recursive_cte_column_names-332"><span class="linenos">332</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="add_recursive_cte_column_names-329"><a href="#add_recursive_cte_column_names-329"><span class="linenos">329</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">this</span> </span><span id="add_recursive_cte_column_names-333"><a href="#add_recursive_cte_column_names-333"><span class="linenos">333</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">this</span>
</span><span id="add_recursive_cte_column_names-330"><a href="#add_recursive_cte_column_names-330"><span class="linenos">330</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Union</span><span class="p">):</span> </span><span id="add_recursive_cte_column_names-334"><a href="#add_recursive_cte_column_names-334"><span class="linenos">334</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Union</span><span class="p">):</span>
</span><span id="add_recursive_cte_column_names-331"><a href="#add_recursive_cte_column_names-331"><span class="linenos">331</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">this</span> </span><span id="add_recursive_cte_column_names-335"><a href="#add_recursive_cte_column_names-335"><span class="linenos">335</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">this</span>
</span><span id="add_recursive_cte_column_names-332"><a href="#add_recursive_cte_column_names-332"><span class="linenos">332</span></a> </span><span id="add_recursive_cte_column_names-336"><a href="#add_recursive_cte_column_names-336"><span class="linenos">336</span></a>
</span><span id="add_recursive_cte_column_names-333"><a href="#add_recursive_cte_column_names-333"><span class="linenos">333</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span> </span><span id="add_recursive_cte_column_names-337"><a href="#add_recursive_cte_column_names-337"><span class="linenos">337</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;alias&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">set</span><span class="p">(</span>
</span><span id="add_recursive_cte_column_names-334"><a href="#add_recursive_cte_column_names-334"><span class="linenos">334</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span> </span><span id="add_recursive_cte_column_names-338"><a href="#add_recursive_cte_column_names-338"><span class="linenos">338</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span>
</span><span id="add_recursive_cte_column_names-335"><a href="#add_recursive_cte_column_names-335"><span class="linenos">335</span></a> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">or</span> <span class="n">next_name</span><span class="p">())</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">query</span><span class="o">.</span><span class="n">selects</span><span class="p">],</span> </span><span id="add_recursive_cte_column_names-339"><a href="#add_recursive_cte_column_names-339"><span class="linenos">339</span></a> <span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">or</span> <span class="n">next_name</span><span class="p">())</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">query</span><span class="o">.</span><span class="n">selects</span><span class="p">],</span>
</span><span id="add_recursive_cte_column_names-336"><a href="#add_recursive_cte_column_names-336"><span class="linenos">336</span></a> <span class="p">)</span> </span><span id="add_recursive_cte_column_names-340"><a href="#add_recursive_cte_column_names-340"><span class="linenos">340</span></a> <span class="p">)</span>
</span><span id="add_recursive_cte_column_names-337"><a href="#add_recursive_cte_column_names-337"><span class="linenos">337</span></a> </span><span id="add_recursive_cte_column_names-341"><a href="#add_recursive_cte_column_names-341"><span class="linenos">341</span></a>
</span><span id="add_recursive_cte_column_names-338"><a href="#add_recursive_cte_column_names-338"><span class="linenos">338</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="add_recursive_cte_column_names-342"><a href="#add_recursive_cte_column_names-342"><span class="linenos">342</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -1057,15 +1065,15 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#epoch_cast_to_ts"></a> <a class="headerlink" href="#epoch_cast_to_ts"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="epoch_cast_to_ts-341"><a href="#epoch_cast_to_ts-341"><span class="linenos">341</span></a><span class="k">def</span> <span class="nf">epoch_cast_to_ts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="epoch_cast_to_ts-345"><a href="#epoch_cast_to_ts-345"><span class="linenos">345</span></a><span class="k">def</span> <span class="nf">epoch_cast_to_ts</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="epoch_cast_to_ts-342"><a href="#epoch_cast_to_ts-342"><span class="linenos">342</span></a> <span class="k">if</span> <span class="p">(</span> </span><span id="epoch_cast_to_ts-346"><a href="#epoch_cast_to_ts-346"><span class="linenos">346</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="epoch_cast_to_ts-343"><a href="#epoch_cast_to_ts-343"><span class="linenos">343</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TryCast</span><span class="p">))</span> </span><span id="epoch_cast_to_ts-347"><a href="#epoch_cast_to_ts-347"><span class="linenos">347</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Cast</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TryCast</span><span class="p">))</span>
</span><span id="epoch_cast_to_ts-344"><a href="#epoch_cast_to_ts-344"><span class="linenos">344</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">&quot;epoch&quot;</span> </span><span id="epoch_cast_to_ts-348"><a href="#epoch_cast_to_ts-348"><span class="linenos">348</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">&quot;epoch&quot;</span>
</span><span id="epoch_cast_to_ts-345"><a href="#epoch_cast_to_ts-345"><span class="linenos">345</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span> </span><span id="epoch_cast_to_ts-349"><a href="#epoch_cast_to_ts-349"><span class="linenos">349</span></a> <span class="ow">and</span> <span class="n">expression</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">TEMPORAL_TYPES</span>
</span><span id="epoch_cast_to_ts-346"><a href="#epoch_cast_to_ts-346"><span class="linenos">346</span></a> <span class="p">):</span> </span><span id="epoch_cast_to_ts-350"><a href="#epoch_cast_to_ts-350"><span class="linenos">350</span></a> <span class="p">):</span>
</span><span id="epoch_cast_to_ts-347"><a href="#epoch_cast_to_ts-347"><span class="linenos">347</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">string</span><span class="p">(</span><span class="s2">&quot;1970-01-01 00:00:00&quot;</span><span class="p">))</span> </span><span id="epoch_cast_to_ts-351"><a href="#epoch_cast_to_ts-351"><span class="linenos">351</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">string</span><span class="p">(</span><span class="s2">&quot;1970-01-01 00:00:00&quot;</span><span class="p">))</span>
</span><span id="epoch_cast_to_ts-348"><a href="#epoch_cast_to_ts-348"><span class="linenos">348</span></a> </span><span id="epoch_cast_to_ts-352"><a href="#epoch_cast_to_ts-352"><span class="linenos">352</span></a>
</span><span id="epoch_cast_to_ts-349"><a href="#epoch_cast_to_ts-349"><span class="linenos">349</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="epoch_cast_to_ts-353"><a href="#epoch_cast_to_ts-353"><span class="linenos">353</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -1083,13 +1091,13 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#timestamp_to_cast"></a> <a class="headerlink" href="#timestamp_to_cast"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="timestamp_to_cast-352"><a href="#timestamp_to_cast-352"><span class="linenos">352</span></a><span class="k">def</span> <span class="nf">timestamp_to_cast</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="timestamp_to_cast-356"><a href="#timestamp_to_cast-356"><span class="linenos">356</span></a><span class="k">def</span> <span class="nf">timestamp_to_cast</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="timestamp_to_cast-353"><a href="#timestamp_to_cast-353"><span class="linenos">353</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span> </span><span id="timestamp_to_cast-357"><a href="#timestamp_to_cast-357"><span class="linenos">357</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Timestamp</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="timestamp_to_cast-354"><a href="#timestamp_to_cast-354"><span class="linenos">354</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span> </span><span id="timestamp_to_cast-358"><a href="#timestamp_to_cast-358"><span class="linenos">358</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span>
</span><span id="timestamp_to_cast-355"><a href="#timestamp_to_cast-355"><span class="linenos">355</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> </span><span id="timestamp_to_cast-359"><a href="#timestamp_to_cast-359"><span class="linenos">359</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">,</span>
</span><span id="timestamp_to_cast-356"><a href="#timestamp_to_cast-356"><span class="linenos">356</span></a> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">,</span> </span><span id="timestamp_to_cast-360"><a href="#timestamp_to_cast-360"><span class="linenos">360</span></a> <span class="n">to</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">DataType</span><span class="o">.</span><span class="n">Type</span><span class="o">.</span><span class="n">TIMESTAMP</span><span class="p">,</span>
</span><span id="timestamp_to_cast-357"><a href="#timestamp_to_cast-357"><span class="linenos">357</span></a> <span class="p">)</span> </span><span id="timestamp_to_cast-361"><a href="#timestamp_to_cast-361"><span class="linenos">361</span></a> <span class="p">)</span>
</span><span id="timestamp_to_cast-358"><a href="#timestamp_to_cast-358"><span class="linenos">358</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="timestamp_to_cast-362"><a href="#timestamp_to_cast-362"><span class="linenos">362</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -1107,20 +1115,20 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#eliminate_semi_and_anti_joins"></a> <a class="headerlink" href="#eliminate_semi_and_anti_joins"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="eliminate_semi_and_anti_joins-361"><a href="#eliminate_semi_and_anti_joins-361"><span class="linenos">361</span></a><span class="k">def</span> <span class="nf">eliminate_semi_and_anti_joins</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span> <div class="pdoc-code codehilite"><pre><span></span><span id="eliminate_semi_and_anti_joins-365"><a href="#eliminate_semi_and_anti_joins-365"><span class="linenos">365</span></a><span class="k">def</span> <span class="nf">eliminate_semi_and_anti_joins</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="eliminate_semi_and_anti_joins-362"><a href="#eliminate_semi_and_anti_joins-362"><span class="linenos">362</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">):</span> </span><span id="eliminate_semi_and_anti_joins-366"><a href="#eliminate_semi_and_anti_joins-366"><span class="linenos">366</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">):</span>
</span><span id="eliminate_semi_and_anti_joins-363"><a href="#eliminate_semi_and_anti_joins-363"><span class="linenos">363</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span> </span><span id="eliminate_semi_and_anti_joins-367"><a href="#eliminate_semi_and_anti_joins-367"><span class="linenos">367</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="eliminate_semi_and_anti_joins-364"><a href="#eliminate_semi_and_anti_joins-364"><span class="linenos">364</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span> </span><span id="eliminate_semi_and_anti_joins-368"><a href="#eliminate_semi_and_anti_joins-368"><span class="linenos">368</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span>
</span><span id="eliminate_semi_and_anti_joins-365"><a href="#eliminate_semi_and_anti_joins-365"><span class="linenos">365</span></a> <span class="k">if</span> <span class="n">on</span> <span class="ow">and</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;SEMI&quot;</span><span class="p">,</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">):</span> </span><span id="eliminate_semi_and_anti_joins-369"><a href="#eliminate_semi_and_anti_joins-369"><span class="linenos">369</span></a> <span class="k">if</span> <span class="n">on</span> <span class="ow">and</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;SEMI&quot;</span><span class="p">,</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">):</span>
</span><span id="eliminate_semi_and_anti_joins-366"><a href="#eliminate_semi_and_anti_joins-366"><span class="linenos">366</span></a> <span class="n">subquery</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">this</span><span class="p">)</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">on</span><span class="p">)</span> </span><span id="eliminate_semi_and_anti_joins-370"><a href="#eliminate_semi_and_anti_joins-370"><span class="linenos">370</span></a> <span class="n">subquery</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;1&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">this</span><span class="p">)</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">on</span><span class="p">)</span>
</span><span id="eliminate_semi_and_anti_joins-367"><a href="#eliminate_semi_and_anti_joins-367"><span class="linenos">367</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">subquery</span><span class="p">)</span> </span><span id="eliminate_semi_and_anti_joins-371"><a href="#eliminate_semi_and_anti_joins-371"><span class="linenos">371</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">subquery</span><span class="p">)</span>
</span><span id="eliminate_semi_and_anti_joins-368"><a href="#eliminate_semi_and_anti_joins-368"><span class="linenos">368</span></a> <span class="k">if</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">:</span> </span><span id="eliminate_semi_and_anti_joins-372"><a href="#eliminate_semi_and_anti_joins-372"><span class="linenos">372</span></a> <span class="k">if</span> <span class="n">join</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;ANTI&quot;</span><span class="p">:</span>
</span><span id="eliminate_semi_and_anti_joins-369"><a href="#eliminate_semi_and_anti_joins-369"><span class="linenos">369</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exists</span><span class="o">.</span><span class="n">not_</span><span class="p">(</span><span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="eliminate_semi_and_anti_joins-373"><a href="#eliminate_semi_and_anti_joins-373"><span class="linenos">373</span></a> <span class="n">exists</span> <span class="o">=</span> <span class="n">exists</span><span class="o">.</span><span class="n">not_</span><span class="p">(</span><span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="eliminate_semi_and_anti_joins-370"><a href="#eliminate_semi_and_anti_joins-370"><span class="linenos">370</span></a> </span><span id="eliminate_semi_and_anti_joins-374"><a href="#eliminate_semi_and_anti_joins-374"><span class="linenos">374</span></a>
</span><span id="eliminate_semi_and_anti_joins-371"><a href="#eliminate_semi_and_anti_joins-371"><span class="linenos">371</span></a> <span class="n">join</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span> </span><span id="eliminate_semi_and_anti_joins-375"><a href="#eliminate_semi_and_anti_joins-375"><span class="linenos">375</span></a> <span class="n">join</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="eliminate_semi_and_anti_joins-372"><a href="#eliminate_semi_and_anti_joins-372"><span class="linenos">372</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">exists</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> </span><span id="eliminate_semi_and_anti_joins-376"><a href="#eliminate_semi_and_anti_joins-376"><span class="linenos">376</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">exists</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="eliminate_semi_and_anti_joins-373"><a href="#eliminate_semi_and_anti_joins-373"><span class="linenos">373</span></a> </span><span id="eliminate_semi_and_anti_joins-377"><a href="#eliminate_semi_and_anti_joins-377"><span class="linenos">377</span></a>
</span><span id="eliminate_semi_and_anti_joins-374"><a href="#eliminate_semi_and_anti_joins-374"><span class="linenos">374</span></a> <span class="k">return</span> <span class="n">expression</span> </span><span id="eliminate_semi_and_anti_joins-378"><a href="#eliminate_semi_and_anti_joins-378"><span class="linenos">378</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div> </span></pre></div>
@ -1138,50 +1146,50 @@ other expressions. This transforms removes the precision from parameterized type
</div> </div>
<a class="headerlink" href="#preprocess"></a> <a class="headerlink" href="#preprocess"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="preprocess-377"><a href="#preprocess-377"><span class="linenos">377</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span> <div class="pdoc-code codehilite"><pre><span></span><span id="preprocess-381"><a href="#preprocess-381"><span class="linenos">381</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span>
</span><span id="preprocess-378"><a href="#preprocess-378"><span class="linenos">378</span></a> <span class="n">transforms</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]],</span> </span><span id="preprocess-382"><a href="#preprocess-382"><span class="linenos">382</span></a> <span class="n">transforms</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">List</span><span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]],</span>
</span><span id="preprocess-379"><a href="#preprocess-379"><span class="linenos">379</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">Generator</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="nb">str</span><span class="p">]:</span> </span><span id="preprocess-383"><a href="#preprocess-383"><span class="linenos">383</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Callable</span><span class="p">[[</span><span class="n">Generator</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">],</span> <span class="nb">str</span><span class="p">]:</span>
</span><span id="preprocess-380"><a href="#preprocess-380"><span class="linenos">380</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span> </span><span id="preprocess-384"><a href="#preprocess-384"><span class="linenos">384</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="preprocess-381"><a href="#preprocess-381"><span class="linenos">381</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span> </span><span id="preprocess-385"><a href="#preprocess-385"><span class="linenos">385</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span>
</span><span id="preprocess-382"><a href="#preprocess-382"><span class="linenos">382</span></a><span class="sd"> expression to SQL, using either the &quot;_sql&quot; method corresponding to the resulting expression,</span> </span><span id="preprocess-386"><a href="#preprocess-386"><span class="linenos">386</span></a><span class="sd"> expression to SQL, using either the &quot;_sql&quot; method corresponding to the resulting expression,</span>
</span><span id="preprocess-383"><a href="#preprocess-383"><span class="linenos">383</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span> </span><span id="preprocess-387"><a href="#preprocess-387"><span class="linenos">387</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span>
</span><span id="preprocess-384"><a href="#preprocess-384"><span class="linenos">384</span></a> </span><span id="preprocess-388"><a href="#preprocess-388"><span class="linenos">388</span></a>
</span><span id="preprocess-385"><a href="#preprocess-385"><span class="linenos">385</span></a><span class="sd"> Args:</span> </span><span id="preprocess-389"><a href="#preprocess-389"><span class="linenos">389</span></a><span class="sd"> Args:</span>
</span><span id="preprocess-386"><a href="#preprocess-386"><span class="linenos">386</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</span> </span><span id="preprocess-390"><a href="#preprocess-390"><span class="linenos">390</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</span>
</span><span id="preprocess-387"><a href="#preprocess-387"><span class="linenos">387</span></a>
</span><span id="preprocess-388"><a href="#preprocess-388"><span class="linenos">388</span></a><span class="sd"> Returns:</span>
</span><span id="preprocess-389"><a href="#preprocess-389"><span class="linenos">389</span></a><span class="sd"> Function that can be used as a generator transform.</span>
</span><span id="preprocess-390"><a href="#preprocess-390"><span class="linenos">390</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="preprocess-391"><a href="#preprocess-391"><span class="linenos">391</span></a> </span><span id="preprocess-391"><a href="#preprocess-391"><span class="linenos">391</span></a>
</span><span id="preprocess-392"><a href="#preprocess-392"><span class="linenos">392</span></a> <span class="k">def</span> <span class="nf">_to_sql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span> </span><span id="preprocess-392"><a href="#preprocess-392"><span class="linenos">392</span></a><span class="sd"> Returns:</span>
</span><span id="preprocess-393"><a href="#preprocess-393"><span class="linenos">393</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-393"><a href="#preprocess-393"><span class="linenos">393</span></a><span class="sd"> Function that can be used as a generator transform.</span>
</span><span id="preprocess-394"><a href="#preprocess-394"><span class="linenos">394</span></a> </span><span id="preprocess-394"><a href="#preprocess-394"><span class="linenos">394</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="preprocess-395"><a href="#preprocess-395"><span class="linenos">395</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span> </span><span id="preprocess-395"><a href="#preprocess-395"><span class="linenos">395</span></a>
</span><span id="preprocess-396"><a href="#preprocess-396"><span class="linenos">396</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span> </span><span id="preprocess-396"><a href="#preprocess-396"><span class="linenos">396</span></a> <span class="k">def</span> <span class="nf">_to_sql</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="preprocess-397"><a href="#preprocess-397"><span class="linenos">397</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-397"><a href="#preprocess-397"><span class="linenos">397</span></a> <span class="n">expression_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-398"><a href="#preprocess-398"><span class="linenos">398</span></a> </span><span id="preprocess-398"><a href="#preprocess-398"><span class="linenos">398</span></a>
</span><span id="preprocess-399"><a href="#preprocess-399"><span class="linenos">399</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> </span><span id="preprocess-399"><a href="#preprocess-399"><span class="linenos">399</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="preprocess-400"><a href="#preprocess-400"><span class="linenos">400</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span> </span><span id="preprocess-400"><a href="#preprocess-400"><span class="linenos">400</span></a> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">transforms</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
</span><span id="preprocess-401"><a href="#preprocess-401"><span class="linenos">401</span></a> <span class="k">return</span> <span class="n">_sql_handler</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-401"><a href="#preprocess-401"><span class="linenos">401</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">t</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-402"><a href="#preprocess-402"><span class="linenos">402</span></a> </span><span id="preprocess-402"><a href="#preprocess-402"><span class="linenos">402</span></a>
</span><span id="preprocess-403"><a href="#preprocess-403"><span class="linenos">403</span></a> <span class="n">transforms_handler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TRANSFORMS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span> </span><span id="preprocess-403"><a href="#preprocess-403"><span class="linenos">403</span></a> <span class="n">_sql_handler</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="o">.</span><span class="n">key</span> <span class="o">+</span> <span class="s2">&quot;_sql&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="preprocess-404"><a href="#preprocess-404"><span class="linenos">404</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span> </span><span id="preprocess-404"><a href="#preprocess-404"><span class="linenos">404</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>
</span><span id="preprocess-405"><a href="#preprocess-405"><span class="linenos">405</span></a> <span class="k">if</span> <span class="n">expression_type</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span> </span><span id="preprocess-405"><a href="#preprocess-405"><span class="linenos">405</span></a> <span class="k">return</span> <span class="n">_sql_handler</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-406"><a href="#preprocess-406"><span class="linenos">406</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Func</span><span class="p">):</span> </span><span id="preprocess-406"><a href="#preprocess-406"><span class="linenos">406</span></a>
</span><span id="preprocess-407"><a href="#preprocess-407"><span class="linenos">407</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">function_fallback_sql</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-407"><a href="#preprocess-407"><span class="linenos">407</span></a> <span class="n">transforms_handler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TRANSFORMS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">))</span>
</span><span id="preprocess-408"><a href="#preprocess-408"><span class="linenos">408</span></a> </span><span id="preprocess-408"><a href="#preprocess-408"><span class="linenos">408</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span>
</span><span id="preprocess-409"><a href="#preprocess-409"><span class="linenos">409</span></a> <span class="c1"># Ensures we don&#39;t enter an infinite loop. This can happen when the original expression</span> </span><span id="preprocess-409"><a href="#preprocess-409"><span class="linenos">409</span></a> <span class="k">if</span> <span class="n">expression_type</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="preprocess-410"><a href="#preprocess-410"><span class="linenos">410</span></a> <span class="c1"># has the same type as the final expression and there&#39;s no _sql method available for it,</span> </span><span id="preprocess-410"><a href="#preprocess-410"><span class="linenos">410</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Func</span><span class="p">):</span>
</span><span id="preprocess-411"><a href="#preprocess-411"><span class="linenos">411</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span> </span><span id="preprocess-411"><a href="#preprocess-411"><span class="linenos">411</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">function_fallback_sql</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-412"><a href="#preprocess-412"><span class="linenos">412</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> </span><span id="preprocess-412"><a href="#preprocess-412"><span class="linenos">412</span></a>
</span><span id="preprocess-413"><a href="#preprocess-413"><span class="linenos">413</span></a> <span class="sa">f</span><span class="s2">&quot;Expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> requires a _sql method in order to be transformed.&quot;</span> </span><span id="preprocess-413"><a href="#preprocess-413"><span class="linenos">413</span></a> <span class="c1"># Ensures we don&#39;t enter an infinite loop. This can happen when the original expression</span>
</span><span id="preprocess-414"><a href="#preprocess-414"><span class="linenos">414</span></a> <span class="p">)</span> </span><span id="preprocess-414"><a href="#preprocess-414"><span class="linenos">414</span></a> <span class="c1"># has the same type as the final expression and there&#39;s no _sql method available for it,</span>
</span><span id="preprocess-415"><a href="#preprocess-415"><span class="linenos">415</span></a> </span><span id="preprocess-415"><a href="#preprocess-415"><span class="linenos">415</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span>
</span><span id="preprocess-416"><a href="#preprocess-416"><span class="linenos">416</span></a> <span class="k">return</span> <span class="n">transforms_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span> </span><span id="preprocess-416"><a href="#preprocess-416"><span class="linenos">416</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="preprocess-417"><a href="#preprocess-417"><span class="linenos">417</span></a> </span><span id="preprocess-417"><a href="#preprocess-417"><span class="linenos">417</span></a> <span class="sa">f</span><span class="s2">&quot;Expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> requires a _sql method in order to be transformed.&quot;</span>
</span><span id="preprocess-418"><a href="#preprocess-418"><span class="linenos">418</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unsupported expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span> </span><span id="preprocess-418"><a href="#preprocess-418"><span class="linenos">418</span></a> <span class="p">)</span>
</span><span id="preprocess-419"><a href="#preprocess-419"><span class="linenos">419</span></a> </span><span id="preprocess-419"><a href="#preprocess-419"><span class="linenos">419</span></a>
</span><span id="preprocess-420"><a href="#preprocess-420"><span class="linenos">420</span></a> <span class="k">return</span> <span class="n">_to_sql</span> </span><span id="preprocess-420"><a href="#preprocess-420"><span class="linenos">420</span></a> <span class="k">return</span> <span class="n">transforms_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
</span><span id="preprocess-421"><a href="#preprocess-421"><span class="linenos">421</span></a>
</span><span id="preprocess-422"><a href="#preprocess-422"><span class="linenos">422</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Unsupported expression type </span><span class="si">{</span><span class="n">expression</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="preprocess-423"><a href="#preprocess-423"><span class="linenos">423</span></a>
</span><span id="preprocess-424"><a href="#preprocess-424"><span class="linenos">424</span></a> <span class="k">return</span> <span class="n">_to_sql</span>
</span></pre></div> </span></pre></div>

View file

@ -16,7 +16,7 @@ setup(
"fallback_version": "0.0.0", "fallback_version": "0.0.0",
"local_scheme": "no-local-version", "local_scheme": "no-local-version",
}, },
setup_requires=["setuptools_scm<8.0.1"], setup_requires=["setuptools_scm"],
python_requires=">=3.7", python_requires=">=3.7",
extras_require={ extras_require={
"dev": [ "dev": [

View file

@ -190,6 +190,16 @@ class BigQuery(Dialect):
"%D": "%m/%d/%y", "%D": "%m/%d/%y",
} }
ESCAPE_SEQUENCES = {
"\\a": "\a",
"\\b": "\b",
"\\f": "\f",
"\\n": "\n",
"\\r": "\r",
"\\t": "\t",
"\\v": "\v",
}
FORMAT_MAPPING = { FORMAT_MAPPING = {
"DD": "%d", "DD": "%d",
"MM": "%m", "MM": "%m",
@ -212,15 +222,14 @@ class BigQuery(Dialect):
@classmethod @classmethod
def normalize_identifier(cls, expression: E) -> E: def normalize_identifier(cls, expression: E) -> E:
# In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least).
# The following check is essentially a heuristic to detect tables based on whether or
# not they're qualified.
if isinstance(expression, exp.Identifier): if isinstance(expression, exp.Identifier):
parent = expression.parent parent = expression.parent
while isinstance(parent, exp.Dot): while isinstance(parent, exp.Dot):
parent = parent.parent parent = parent.parent
# In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least).
# The following check is essentially a heuristic to detect tables based on whether or
# not they're qualified. It also avoids normalizing UDFs, because they're case-sensitive.
if ( if (
not isinstance(parent, exp.UserDefinedFunction) not isinstance(parent, exp.UserDefinedFunction)
and not (isinstance(parent, exp.Table) and parent.db) and not (isinstance(parent, exp.Table) and parent.db)
@ -419,6 +428,7 @@ class BigQuery(Dialect):
RENAME_TABLE_WITH_DB = False RENAME_TABLE_WITH_DB = False
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
UNNEST_WITH_ORDINALITY = False UNNEST_WITH_ORDINALITY = False
COLLATE_IS_FUNC = True
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
@ -520,18 +530,6 @@ class BigQuery(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
} }
UNESCAPED_SEQUENCE_TABLE = str.maketrans( # type: ignore
{
"\a": "\\a",
"\b": "\\b",
"\f": "\\f",
"\n": "\\n",
"\r": "\\r",
"\t": "\\t",
"\v": "\\v",
}
)
# from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords
RESERVED_KEYWORDS = { RESERVED_KEYWORDS = {
*generator.Generator.RESERVED_KEYWORDS, *generator.Generator.RESERVED_KEYWORDS,

View file

@ -2,7 +2,7 @@ from __future__ import annotations
import typing as t import typing as t
from sqlglot import exp, generator, parser, tokens from sqlglot import exp, generator, parser, tokens, transforms
from sqlglot.dialects.dialect import ( from sqlglot.dialects.dialect import (
Dialect, Dialect,
inline_array_sql, inline_array_sql,
@ -21,18 +21,33 @@ def _lower_func(sql: str) -> str:
return sql[:index].lower() + sql[index:] return sql[:index].lower() + sql[index:]
def _quantile_sql(self, e):
quantile = e.args["quantile"]
args = f"({self.sql(e, 'this')})"
if isinstance(quantile, exp.Array):
func = self.func("quantiles", *quantile)
else:
func = self.func("quantile", quantile)
return func + args
class ClickHouse(Dialect): class ClickHouse(Dialect):
NORMALIZE_FUNCTIONS: bool | str = False NORMALIZE_FUNCTIONS: bool | str = False
NULL_ORDERING = "nulls_are_last" NULL_ORDERING = "nulls_are_last"
STRICT_STRING_CONCAT = True STRICT_STRING_CONCAT = True
SUPPORTS_USER_DEFINED_TYPES = False SUPPORTS_USER_DEFINED_TYPES = False
ESCAPE_SEQUENCES = {
"\\0": "\0",
}
class Tokenizer(tokens.Tokenizer): class Tokenizer(tokens.Tokenizer):
COMMENTS = ["--", "#", "#!", ("/*", "*/")] COMMENTS = ["--", "#", "#!", ("/*", "*/")]
IDENTIFIERS = ['"', "`"] IDENTIFIERS = ['"', "`"]
STRING_ESCAPES = ["'", "\\"] STRING_ESCAPES = ["'", "\\"]
BIT_STRINGS = [("0b", "")] BIT_STRINGS = [("0b", "")]
HEX_STRINGS = [("0x", ""), ("0X", "")] HEX_STRINGS = [("0x", ""), ("0X", "")]
HEREDOC_STRINGS = ["$"]
KEYWORDS = { KEYWORDS = {
**tokens.Tokenizer.KEYWORDS, **tokens.Tokenizer.KEYWORDS,
@ -55,6 +70,7 @@ class ClickHouse(Dialect):
"LOWCARDINALITY": TokenType.LOWCARDINALITY, "LOWCARDINALITY": TokenType.LOWCARDINALITY,
"MAP": TokenType.MAP, "MAP": TokenType.MAP,
"NESTED": TokenType.NESTED, "NESTED": TokenType.NESTED,
"SAMPLE": TokenType.TABLE_SAMPLE,
"TUPLE": TokenType.STRUCT, "TUPLE": TokenType.STRUCT,
"UINT128": TokenType.UINT128, "UINT128": TokenType.UINT128,
"UINT16": TokenType.USMALLINT, "UINT16": TokenType.USMALLINT,
@ -64,6 +80,11 @@ class ClickHouse(Dialect):
"UINT8": TokenType.UTINYINT, "UINT8": TokenType.UTINYINT,
} }
SINGLE_TOKENS = {
**tokens.Tokenizer.SINGLE_TOKENS,
"$": TokenType.HEREDOC_STRING,
}
class Parser(parser.Parser): class Parser(parser.Parser):
FUNCTIONS = { FUNCTIONS = {
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
@ -301,6 +322,7 @@ class ClickHouse(Dialect):
QUERY_HINTS = False QUERY_HINTS = False
STRUCT_DELIMITER = ("(", ")") STRUCT_DELIMITER = ("(", ")")
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
TABLESAMPLE_REQUIRES_PARENS = False
STRING_TYPE_MAPPING = { STRING_TYPE_MAPPING = {
exp.DataType.Type.CHAR: "String", exp.DataType.Type.CHAR: "String",
@ -348,6 +370,7 @@ class ClickHouse(Dialect):
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
exp.Select: transforms.preprocess([transforms.eliminate_qualify]),
exp.AnyValue: rename_func("any"), exp.AnyValue: rename_func("any"),
exp.ApproxDistinct: rename_func("uniq"), exp.ApproxDistinct: rename_func("uniq"),
exp.Array: inline_array_sql, exp.Array: inline_array_sql,
@ -359,12 +382,13 @@ class ClickHouse(Dialect):
"DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
), ),
exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL", exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL",
exp.IsNan: rename_func("isNaN"),
exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)), exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)),
exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
exp.Pivot: no_pivot_sql, exp.Pivot: no_pivot_sql,
exp.Quantile: lambda self, e: self.func("quantile", e.args.get("quantile")) exp.Quantile: _quantile_sql,
+ f"({self.sql(e, 'this')})",
exp.RegexpLike: lambda self, e: f"match({self.format_args(e.this, e.expression)})", exp.RegexpLike: lambda self, e: f"match({self.format_args(e.this, e.expression)})",
exp.StartsWith: rename_func("startsWith"),
exp.StrPosition: lambda self, e: f"position({self.format_args(e.this, e.args.get('substr'), e.args.get('position'))})", exp.StrPosition: lambda self, e: f"position({self.format_args(e.this, e.args.get('substr'), e.args.get('position'))})",
exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)), exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)),
exp.Xor: lambda self, e: self.func("xor", e.this, e.expression, *e.expressions), exp.Xor: lambda self, e: self.func("xor", e.this, e.expression, *e.expressions),

View file

@ -51,6 +51,26 @@ class Databricks(Spark):
exp.ToChar: lambda self, e: self.function_fallback_sql(e), exp.ToChar: lambda self, e: self.function_fallback_sql(e),
} }
def columndef_sql(self, expression: exp.ColumnDef, sep: str = " ") -> str:
constraint = expression.find(exp.GeneratedAsIdentityColumnConstraint)
kind = expression.args.get("kind")
if (
constraint
and isinstance(kind, exp.DataType)
and kind.this in exp.DataType.INTEGER_TYPES
):
# only BIGINT generated identity constraints are supported
expression = expression.copy()
expression.set("kind", exp.DataType.build("bigint"))
return super().columndef_sql(expression, sep)
def generatedasidentitycolumnconstraint_sql(
self, expression: exp.GeneratedAsIdentityColumnConstraint
) -> str:
expression = expression.copy()
expression.set("this", True) # trigger ALWAYS in super class
return super().generatedasidentitycolumnconstraint_sql(expression)
class Tokenizer(Spark.Tokenizer): class Tokenizer(Spark.Tokenizer):
HEX_STRINGS = [] HEX_STRINGS = []

View file

@ -81,6 +81,8 @@ class _Dialect(type):
klass.INVERSE_TIME_MAPPING = {v: k for k, v in klass.TIME_MAPPING.items()} klass.INVERSE_TIME_MAPPING = {v: k for k, v in klass.TIME_MAPPING.items()}
klass.INVERSE_TIME_TRIE = new_trie(klass.INVERSE_TIME_MAPPING) klass.INVERSE_TIME_TRIE = new_trie(klass.INVERSE_TIME_MAPPING)
klass.INVERSE_ESCAPE_SEQUENCES = {v: k for k, v in klass.ESCAPE_SEQUENCES.items()}
klass.tokenizer_class = getattr(klass, "Tokenizer", Tokenizer) klass.tokenizer_class = getattr(klass, "Tokenizer", Tokenizer)
klass.parser_class = getattr(klass, "Parser", Parser) klass.parser_class = getattr(klass, "Parser", Parser)
klass.generator_class = getattr(klass, "Generator", Generator) klass.generator_class = getattr(klass, "Generator", Generator)
@ -188,6 +190,9 @@ class Dialect(metaclass=_Dialect):
# special syntax cast(x as date format 'yyyy') defaults to time_mapping # special syntax cast(x as date format 'yyyy') defaults to time_mapping
FORMAT_MAPPING: t.Dict[str, str] = {} FORMAT_MAPPING: t.Dict[str, str] = {}
# Mapping of an unescaped escape sequence to the corresponding character
ESCAPE_SEQUENCES: t.Dict[str, str] = {}
# Columns that are auto-generated by the engine corresponding to this dialect # Columns that are auto-generated by the engine corresponding to this dialect
# Such columns may be excluded from SELECT * queries, for example # Such columns may be excluded from SELECT * queries, for example
PSEUDOCOLUMNS: t.Set[str] = set() PSEUDOCOLUMNS: t.Set[str] = set()
@ -204,6 +209,8 @@ class Dialect(metaclass=_Dialect):
INVERSE_TIME_MAPPING: t.Dict[str, str] = {} INVERSE_TIME_MAPPING: t.Dict[str, str] = {}
INVERSE_TIME_TRIE: t.Dict = {} INVERSE_TIME_TRIE: t.Dict = {}
INVERSE_ESCAPE_SEQUENCES: t.Dict[str, str] = {}
def __eq__(self, other: t.Any) -> bool: def __eq__(self, other: t.Any) -> bool:
return type(self) == other return type(self) == other
@ -245,7 +252,7 @@ class Dialect(metaclass=_Dialect):
""" """
Normalizes an unquoted identifier to either lower or upper case, thus essentially Normalizes an unquoted identifier to either lower or upper case, thus essentially
making it case-insensitive. If a dialect treats all identifiers as case-insensitive, making it case-insensitive. If a dialect treats all identifiers as case-insensitive,
they will be normalized regardless of being quoted or not. they will be normalized to lowercase regardless of being quoted or not.
""" """
if isinstance(expression, exp.Identifier) and ( if isinstance(expression, exp.Identifier) and (
not expression.quoted or cls.RESOLVES_IDENTIFIERS_AS_UPPERCASE is None not expression.quoted or cls.RESOLVES_IDENTIFIERS_AS_UPPERCASE is None

View file

@ -51,6 +51,32 @@ TIME_DIFF_FACTOR = {
DIFF_MONTH_SWITCH = ("YEAR", "QUARTER", "MONTH") DIFF_MONTH_SWITCH = ("YEAR", "QUARTER", "MONTH")
def _create_sql(self, expression: exp.Create) -> str:
expression = expression.copy()
# remove UNIQUE column constraints
for constraint in expression.find_all(exp.UniqueColumnConstraint):
if constraint.parent:
constraint.parent.pop()
properties = expression.args.get("properties")
temporary = any(
isinstance(prop, exp.TemporaryProperty)
for prop in (properties.expressions if properties else [])
)
# CTAS with temp tables map to CREATE TEMPORARY VIEW
kind = expression.args["kind"]
if kind.upper() == "TABLE" and temporary:
if expression.expression:
return f"CREATE TEMPORARY VIEW {self.sql(expression, 'this')} AS {self.sql(expression, 'expression')}"
else:
# CREATE TEMPORARY TABLE may require storage provider
expression = self.temporary_storage_provider(expression)
return create_with_partitions_sql(self, expression)
def _add_date_sql(self: Hive.Generator, expression: exp.DateAdd | exp.DateSub) -> str: def _add_date_sql(self: Hive.Generator, expression: exp.DateAdd | exp.DateSub) -> str:
unit = expression.text("unit").upper() unit = expression.text("unit").upper()
func, multiplier = DATE_DELTA_INTERVAL.get(unit, ("DATE_ADD", 1)) func, multiplier = DATE_DELTA_INTERVAL.get(unit, ("DATE_ADD", 1))
@ -429,7 +455,7 @@ class Hive(Dialect):
if e.args.get("allow_null") if e.args.get("allow_null")
else "NOT NULL", else "NOT NULL",
exp.VarMap: var_map_sql, exp.VarMap: var_map_sql,
exp.Create: create_with_partitions_sql, exp.Create: _create_sql,
exp.Quantile: rename_func("PERCENTILE"), exp.Quantile: rename_func("PERCENTILE"),
exp.ApproxQuantile: rename_func("PERCENTILE_APPROX"), exp.ApproxQuantile: rename_func("PERCENTILE_APPROX"),
exp.RegexpExtract: regexp_extract_sql, exp.RegexpExtract: regexp_extract_sql,
@ -478,8 +504,13 @@ class Hive(Dialect):
exp.FileFormatProperty: exp.Properties.Location.POST_SCHEMA, exp.FileFormatProperty: exp.Properties.Location.POST_SCHEMA,
exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
exp.WithDataProperty: exp.Properties.Location.UNSUPPORTED,
} }
def temporary_storage_provider(self, expression: exp.Create) -> exp.Create:
# Hive has no temporary storage provider (there are hive settings though)
return expression
def parameter_sql(self, expression: exp.Parameter) -> str: def parameter_sql(self, expression: exp.Parameter) -> str:
this = self.sql(expression, "this") this = self.sql(expression, "this")
parent = expression.parent parent = expression.parent

View file

@ -66,7 +66,9 @@ def _str_to_date(args: t.List) -> exp.StrToDate:
return exp.StrToDate(this=seq_get(args, 0), format=date_format) return exp.StrToDate(this=seq_get(args, 0), format=date_format)
def _str_to_date_sql(self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime) -> str: def _str_to_date_sql(
self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate
) -> str:
date_format = self.format_time(expression) date_format = self.format_time(expression)
return f"STR_TO_DATE({self.sql(expression.this)}, {date_format})" return f"STR_TO_DATE({self.sql(expression.this)}, {date_format})"
@ -86,8 +88,10 @@ def _trim_sql(self: MySQL.Generator, expression: exp.Trim) -> str:
return f"TRIM({trim_type}{remove_chars}{from_part}{target})" return f"TRIM({trim_type}{remove_chars}{from_part}{target})"
def _date_add_sql(kind: str) -> t.Callable[[MySQL.Generator, exp.DateAdd | exp.DateSub], str]: def _date_add_sql(
def func(self: MySQL.Generator, expression: exp.DateAdd | exp.DateSub) -> str: kind: str,
) -> t.Callable[[MySQL.Generator, exp.Expression], str]:
def func(self: MySQL.Generator, expression: exp.Expression) -> str:
this = self.sql(expression, "this") this = self.sql(expression, "this")
unit = expression.text("unit").upper() or "DAY" unit = expression.text("unit").upper() or "DAY"
return f"DATE_{kind}({this}, {self.sql(exp.Interval(this=expression.expression.copy(), unit=unit))})" return f"DATE_{kind}({this}, {self.sql(exp.Interval(this=expression.expression.copy(), unit=unit))})"
@ -95,6 +99,30 @@ def _date_add_sql(kind: str) -> t.Callable[[MySQL.Generator, exp.DateAdd | exp.D
return func return func
def _ts_or_ds_to_date_sql(self: MySQL.Generator, expression: exp.TsOrDsToDate) -> str:
time_format = expression.args.get("format")
if time_format:
return _str_to_date_sql(self, expression)
return f"DATE({self.sql(expression, 'this')})"
def _remove_ts_or_ds_to_date(
to_sql: t.Optional[t.Callable[[MySQL.Generator, exp.Expression], str]] = None,
args: t.Tuple[str, ...] = ("this",),
) -> t.Callable[[MySQL.Generator, exp.Func], str]:
def func(self: MySQL.Generator, expression: exp.Func) -> str:
expression = expression.copy()
for arg_key in args:
arg = expression.args.get(arg_key)
if isinstance(arg, exp.TsOrDsToDate) and not arg.args.get("format"):
expression.set(arg_key, arg.this)
return to_sql(self, expression) if to_sql else self.function_fallback_sql(expression)
return func
class MySQL(Dialect): class MySQL(Dialect):
# https://dev.mysql.com/doc/refman/8.0/en/identifiers.html # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
IDENTIFIERS_CAN_START_WITH_DIGIT = True IDENTIFIERS_CAN_START_WITH_DIGIT = True
@ -233,6 +261,7 @@ class MySQL(Dialect):
FUNCTIONS = { FUNCTIONS = {
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
"DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
"DATE_ADD": parse_date_delta_with_interval(exp.DateAdd), "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd),
"DATE_FORMAT": format_time_lambda(exp.TimeToStr, "mysql"), "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "mysql"),
"DATE_SUB": parse_date_delta_with_interval(exp.DateSub), "DATE_SUB": parse_date_delta_with_interval(exp.DateSub),
@ -240,14 +269,33 @@ class MySQL(Dialect):
"ISNULL": isnull_to_is_null, "ISNULL": isnull_to_is_null,
"LOCATE": locate_to_strposition, "LOCATE": locate_to_strposition,
"MONTHNAME": lambda args: exp.TimeToStr( "MONTHNAME": lambda args: exp.TimeToStr(
this=seq_get(args, 0), this=exp.TsOrDsToDate(this=seq_get(args, 0)),
format=exp.Literal.string("%B"), format=exp.Literal.string("%B"),
), ),
"STR_TO_DATE": _str_to_date, "STR_TO_DATE": _str_to_date,
"TO_DAYS": lambda args: exp.paren(
exp.DateDiff(
this=exp.TsOrDsToDate(this=seq_get(args, 0)),
expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
unit=exp.var("DAY"),
)
+ 1
),
"DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"WEEK": lambda args: exp.Week(
this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
),
"WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
"YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
} }
FUNCTION_PARSERS = { FUNCTION_PARSERS = {
**parser.Parser.FUNCTION_PARSERS, **parser.Parser.FUNCTION_PARSERS,
"CHAR": lambda self: self._parse_chr(),
"GROUP_CONCAT": lambda self: self.expression( "GROUP_CONCAT": lambda self: self.expression(
exp.GroupConcat, exp.GroupConcat,
this=self._parse_lambda(), this=self._parse_lambda(),
@ -531,6 +579,18 @@ class MySQL(Dialect):
return super()._parse_type(parse_interval=parse_interval) return super()._parse_type(parse_interval=parse_interval)
def _parse_chr(self) -> t.Optional[exp.Expression]:
expressions = self._parse_csv(self._parse_conjunction)
kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)}
if len(expressions) > 1:
kwargs["expressions"] = expressions[1:]
if self._match(TokenType.USING):
kwargs["charset"] = self._parse_var()
return self.expression(exp.Chr, **kwargs)
class Generator(generator.Generator): class Generator(generator.Generator):
LOCKING_READS_SUPPORTED = True LOCKING_READS_SUPPORTED = True
NULL_ORDERING_SUPPORTED = False NULL_ORDERING_SUPPORTED = False
@ -544,25 +604,33 @@ class MySQL(Dialect):
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
exp.CurrentDate: no_paren_current_date_sql, exp.CurrentDate: no_paren_current_date_sql,
exp.DateDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), exp.DateDiff: _remove_ts_or_ds_to_date(
exp.DateAdd: _date_add_sql("ADD"), lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
),
exp.DateAdd: _remove_ts_or_ds_to_date(_date_add_sql("ADD")),
exp.DateStrToDate: datestrtodate_sql, exp.DateStrToDate: datestrtodate_sql,
exp.DateSub: _date_add_sql("SUB"), exp.DateSub: _remove_ts_or_ds_to_date(_date_add_sql("SUB")),
exp.DateTrunc: _date_trunc_sql, exp.DateTrunc: _date_trunc_sql,
exp.DayOfMonth: rename_func("DAYOFMONTH"), exp.Day: _remove_ts_or_ds_to_date(),
exp.DayOfWeek: rename_func("DAYOFWEEK"), exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
exp.DayOfYear: rename_func("DAYOFYEAR"), exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
exp.GroupConcat: lambda self, e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", exp.GroupConcat: lambda self, e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,
exp.JSONExtractScalar: arrow_json_extract_scalar_sql, exp.JSONExtractScalar: arrow_json_extract_scalar_sql,
exp.JSONKeyValue: json_keyvalue_comma_sql, exp.JSONKeyValue: json_keyvalue_comma_sql,
exp.Max: max_or_greatest, exp.Max: max_or_greatest,
exp.Min: min_or_least, exp.Min: min_or_least,
exp.Month: _remove_ts_or_ds_to_date(),
exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
exp.NullSafeNEQ: lambda self, e: self.not_sql(self.binary(e, "<=>")), exp.NullSafeNEQ: lambda self, e: self.not_sql(self.binary(e, "<=>")),
exp.Pivot: no_pivot_sql, exp.Pivot: no_pivot_sql,
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] [
transforms.eliminate_distinct_on,
transforms.eliminate_semi_and_anti_joins,
transforms.eliminate_qualify,
]
), ),
exp.StrPosition: strposition_to_locate_sql, exp.StrPosition: strposition_to_locate_sql,
exp.StrToDate: _str_to_date_sql, exp.StrToDate: _str_to_date_sql,
@ -573,10 +641,16 @@ class MySQL(Dialect):
exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
exp.TimeStrToTime: lambda self, e: self.sql(exp.cast(e.this, "datetime", copy=True)), exp.TimeStrToTime: lambda self, e: self.sql(exp.cast(e.this, "datetime", copy=True)),
exp.TimeToStr: lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)), exp.TimeToStr: _remove_ts_or_ds_to_date(
lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
),
exp.Trim: _trim_sql, exp.Trim: _trim_sql,
exp.TryCast: no_trycast_sql, exp.TryCast: no_trycast_sql,
exp.WeekOfYear: rename_func("WEEKOFYEAR"), exp.TsOrDsAdd: _date_add_sql("ADD"),
exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
exp.Week: _remove_ts_or_ds_to_date(),
exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
exp.Year: _remove_ts_or_ds_to_date(),
} }
UNSIGNED_TYPE_MAPPING = { UNSIGNED_TYPE_MAPPING = {
@ -585,6 +659,7 @@ class MySQL(Dialect):
exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
exp.DataType.Type.USMALLINT: "SMALLINT", exp.DataType.Type.USMALLINT: "SMALLINT",
exp.DataType.Type.UTINYINT: "TINYINT", exp.DataType.Type.UTINYINT: "TINYINT",
exp.DataType.Type.UDECIMAL: "DECIMAL",
} }
TIMESTAMP_TYPE_MAPPING = { TIMESTAMP_TYPE_MAPPING = {
@ -717,3 +792,9 @@ class MySQL(Dialect):
limit_offset = f"{offset}, {limit}" if offset else limit limit_offset = f"{offset}, {limit}" if offset else limit
return f" LIMIT {limit_offset}" return f" LIMIT {limit_offset}"
return "" return ""
def chr_sql(self, expression: exp.Chr) -> str:
this = self.expressions(sqls=[expression.this] + expression.expressions)
charset = expression.args.get("charset")
using = f" USING {self.sql(charset)}" if charset else ""
return f"CHAR({this}{using})"

View file

@ -153,6 +153,7 @@ class Oracle(Dialect):
JOIN_HINTS = False JOIN_HINTS = False
TABLE_HINTS = False TABLE_HINTS = False
COLUMN_JOIN_MARKS_SUPPORTED = True COLUMN_JOIN_MARKS_SUPPORTED = True
DATA_TYPE_SPECIFIERS_ALLOWED = True
LIMIT_FETCH = "FETCH" LIMIT_FETCH = "FETCH"
@ -179,7 +180,12 @@ class Oracle(Dialect):
), ),
exp.Group: transforms.preprocess([transforms.unalias_group]), exp.Group: transforms.preprocess([transforms.unalias_group]),
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]), exp.Select: transforms.preprocess(
[
transforms.eliminate_distinct_on,
transforms.eliminate_qualify,
]
),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.Subquery: lambda self, e: self.subquery_sql(e, sep=" "), exp.Subquery: lambda self, e: self.subquery_sql(e, sep=" "),
exp.Substring: rename_func("SUBSTR"), exp.Substring: rename_func("SUBSTR"),

View file

@ -22,6 +22,7 @@ from sqlglot.dialects.dialect import (
rename_func, rename_func,
simplify_literal, simplify_literal,
str_position_sql, str_position_sql,
struct_extract_sql,
timestamptrunc_sql, timestamptrunc_sql,
timestrtotime_sql, timestrtotime_sql,
trim_sql, trim_sql,
@ -248,11 +249,10 @@ class Postgres(Dialect):
} }
class Tokenizer(tokens.Tokenizer): class Tokenizer(tokens.Tokenizer):
QUOTES = ["'", "$$"]
BIT_STRINGS = [("b'", "'"), ("B'", "'")] BIT_STRINGS = [("b'", "'"), ("B'", "'")]
HEX_STRINGS = [("x'", "'"), ("X'", "'")] HEX_STRINGS = [("x'", "'"), ("X'", "'")]
BYTE_STRINGS = [("e'", "'"), ("E'", "'")] BYTE_STRINGS = [("e'", "'"), ("E'", "'")]
HEREDOC_STRINGS = ["$"]
KEYWORDS = { KEYWORDS = {
**tokens.Tokenizer.KEYWORDS, **tokens.Tokenizer.KEYWORDS,
@ -296,7 +296,7 @@ class Postgres(Dialect):
SINGLE_TOKENS = { SINGLE_TOKENS = {
**tokens.Tokenizer.SINGLE_TOKENS, **tokens.Tokenizer.SINGLE_TOKENS,
"$": TokenType.PARAMETER, "$": TokenType.HEREDOC_STRING,
} }
VAR_SINGLE_TOKENS = {"$"} VAR_SINGLE_TOKENS = {"$"}
@ -420,9 +420,15 @@ class Postgres(Dialect):
exp.Pow: lambda self, e: self.binary(e, "^"), exp.Pow: lambda self, e: self.binary(e, "^"),
exp.RegexpLike: lambda self, e: self.binary(e, "~"), exp.RegexpLike: lambda self, e: self.binary(e, "~"),
exp.RegexpILike: lambda self, e: self.binary(e, "~*"), exp.RegexpILike: lambda self, e: self.binary(e, "~*"),
exp.Select: transforms.preprocess([transforms.eliminate_semi_and_anti_joins]), exp.Select: transforms.preprocess(
[
transforms.eliminate_semi_and_anti_joins,
transforms.eliminate_qualify,
]
),
exp.StrPosition: str_position_sql, exp.StrPosition: str_position_sql,
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})", exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.StructExtract: struct_extract_sql,
exp.Substring: _substring_sql, exp.Substring: _substring_sql,
exp.TimestampTrunc: timestamptrunc_sql, exp.TimestampTrunc: timestamptrunc_sql,
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,

View file

@ -309,6 +309,9 @@ class Presto(Dialect):
exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'", exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
exp.First: _first_last_sql, exp.First: _first_last_sql,
exp.Group: transforms.preprocess([transforms.unalias_group]), exp.Group: transforms.preprocess([transforms.unalias_group]),
exp.GroupConcat: lambda self, e: self.func(
"ARRAY_JOIN", self.func("ARRAY_AGG", e.this), e.args.get("separator")
),
exp.Hex: rename_func("TO_HEX"), exp.Hex: rename_func("TO_HEX"),
exp.If: if_sql(), exp.If: if_sql(),
exp.ILike: no_ilike_sql, exp.ILike: no_ilike_sql,

View file

@ -83,7 +83,7 @@ class Redshift(Postgres):
class Tokenizer(Postgres.Tokenizer): class Tokenizer(Postgres.Tokenizer):
BIT_STRINGS = [] BIT_STRINGS = []
HEX_STRINGS = [] HEX_STRINGS = []
STRING_ESCAPES = ["\\"] STRING_ESCAPES = ["\\", "'"]
KEYWORDS = { KEYWORDS = {
**Postgres.Tokenizer.KEYWORDS, **Postgres.Tokenizer.KEYWORDS,

View file

@ -239,6 +239,8 @@ class Snowflake(Dialect):
class Parser(parser.Parser): class Parser(parser.Parser):
IDENTIFY_PIVOT_STRINGS = True IDENTIFY_PIVOT_STRINGS = True
TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS | {TokenType.WINDOW}
FUNCTIONS = { FUNCTIONS = {
**parser.Parser.FUNCTIONS, **parser.Parser.FUNCTIONS,
"ARRAYAGG": exp.ArrayAgg.from_arg_list, "ARRAYAGG": exp.ArrayAgg.from_arg_list,
@ -318,6 +320,43 @@ class Snowflake(Dialect):
"TERSE PRIMARY KEYS": _show_parser("PRIMARY KEYS"), "TERSE PRIMARY KEYS": _show_parser("PRIMARY KEYS"),
} }
STAGED_FILE_SINGLE_TOKENS = {
TokenType.DOT,
TokenType.MOD,
TokenType.SLASH,
}
def _parse_table_parts(self, schema: bool = False) -> exp.Table:
# https://docs.snowflake.com/en/user-guide/querying-stage
table: t.Optional[exp.Expression] = None
if self._match_text_seq("@"):
table_name = "@"
while True:
self._advance()
table_name += self._prev.text
if not self._match_set(self.STAGED_FILE_SINGLE_TOKENS, advance=False):
break
while self._match_set(self.STAGED_FILE_SINGLE_TOKENS):
table_name += self._prev.text
table = exp.var(table_name)
elif self._match(TokenType.STRING, advance=False):
table = self._parse_string()
if table:
file_format = None
pattern = None
if self._match_text_seq("(", "FILE_FORMAT", "=>"):
file_format = self._parse_string() or super()._parse_table_parts()
if self._match_text_seq(",", "PATTERN", "=>"):
pattern = self._parse_string()
self._match_r_paren()
return self.expression(exp.Table, this=table, format=file_format, pattern=pattern)
return super()._parse_table_parts(schema=schema)
def _parse_id_var( def _parse_id_var(
self, self,
any_token: bool = True, any_token: bool = True,
@ -394,6 +433,8 @@ class Snowflake(Dialect):
TABLE_HINTS = False TABLE_HINTS = False
QUERY_HINTS = False QUERY_HINTS = False
AGGREGATE_FILTER_SUPPORTED = False AGGREGATE_FILTER_SUPPORTED = False
SUPPORTS_TABLE_COPY = False
COLLATE_IS_FUNC = True
TRANSFORMS = { TRANSFORMS = {
**generator.Generator.TRANSFORMS, **generator.Generator.TRANSFORMS,
@ -423,6 +464,12 @@ class Snowflake(Dialect):
exp.Max: max_or_greatest, exp.Max: max_or_greatest,
exp.Min: min_or_least, exp.Min: min_or_least,
exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
exp.PercentileCont: transforms.preprocess(
[transforms.add_within_group_for_percentiles]
),
exp.PercentileDisc: transforms.preprocess(
[transforms.add_within_group_for_percentiles]
),
exp.RegexpILike: _regexpilike_sql, exp.RegexpILike: _regexpilike_sql,
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[ [

View file

@ -54,6 +54,14 @@ class Spark(Spark2):
FUNCTION_PARSERS = Spark2.Parser.FUNCTION_PARSERS.copy() FUNCTION_PARSERS = Spark2.Parser.FUNCTION_PARSERS.copy()
FUNCTION_PARSERS.pop("ANY_VALUE") FUNCTION_PARSERS.pop("ANY_VALUE")
def _parse_generated_as_identity(
self,
) -> exp.GeneratedAsIdentityColumnConstraint | exp.ComputedColumnConstraint:
this = super()._parse_generated_as_identity()
if this.expression:
return self.expression(exp.ComputedColumnConstraint, this=this.expression)
return this
class Generator(Spark2.Generator): class Generator(Spark2.Generator):
TYPE_MAPPING = { TYPE_MAPPING = {
**Spark2.Generator.TYPE_MAPPING, **Spark2.Generator.TYPE_MAPPING,
@ -73,6 +81,9 @@ class Spark(Spark2):
TRANSFORMS.pop(exp.DateDiff) TRANSFORMS.pop(exp.DateDiff)
TRANSFORMS.pop(exp.Group) TRANSFORMS.pop(exp.Group)
def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
return f"GENERATED ALWAYS AS ({self.sql(expression, 'this')})"
def anyvalue_sql(self, expression: exp.AnyValue) -> str: def anyvalue_sql(self, expression: exp.AnyValue) -> str:
return self.function_fallback_sql(expression) return self.function_fallback_sql(expression)

View file

@ -5,7 +5,6 @@ import typing as t
from sqlglot import exp, transforms from sqlglot import exp, transforms
from sqlglot.dialects.dialect import ( from sqlglot.dialects.dialect import (
binary_from_function, binary_from_function,
create_with_partitions_sql,
format_time_lambda, format_time_lambda,
is_parse_json, is_parse_json,
move_insert_cte_sql, move_insert_cte_sql,
@ -17,22 +16,6 @@ from sqlglot.dialects.hive import Hive
from sqlglot.helper import seq_get from sqlglot.helper import seq_get
def _create_sql(self: Spark2.Generator, e: exp.Create) -> str:
kind = e.args["kind"]
properties = e.args.get("properties")
if (
kind.upper() == "TABLE"
and e.expression
and any(
isinstance(prop, exp.TemporaryProperty)
for prop in (properties.expressions if properties else [])
)
):
return f"CREATE TEMPORARY VIEW {self.sql(e, 'this')} AS {self.sql(e, 'expression')}"
return create_with_partitions_sql(self, e)
def _map_sql(self: Spark2.Generator, expression: exp.Map) -> str: def _map_sql(self: Spark2.Generator, expression: exp.Map) -> str:
keys = expression.args.get("keys") keys = expression.args.get("keys")
values = expression.args.get("values") values = expression.args.get("values")
@ -118,6 +101,8 @@ def _unqualify_pivot_columns(expression: exp.Expression) -> exp.Expression:
class Spark2(Hive): class Spark2(Hive):
class Parser(Hive.Parser): class Parser(Hive.Parser):
TRIM_PATTERN_FIRST = True
FUNCTIONS = { FUNCTIONS = {
**Hive.Parser.FUNCTIONS, **Hive.Parser.FUNCTIONS,
"AGGREGATE": exp.Reduce.from_arg_list, "AGGREGATE": exp.Reduce.from_arg_list,
@ -192,7 +177,6 @@ class Spark2(Hive):
exp.AtTimeZone: lambda self, e: f"FROM_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})", exp.AtTimeZone: lambda self, e: f"FROM_UTC_TIMESTAMP({self.sql(e, 'this')}, {self.sql(e, 'zone')})",
exp.BitwiseLeftShift: rename_func("SHIFTLEFT"), exp.BitwiseLeftShift: rename_func("SHIFTLEFT"),
exp.BitwiseRightShift: rename_func("SHIFTRIGHT"), exp.BitwiseRightShift: rename_func("SHIFTRIGHT"),
exp.Create: _create_sql,
exp.DateFromParts: rename_func("MAKE_DATE"), exp.DateFromParts: rename_func("MAKE_DATE"),
exp.DateTrunc: lambda self, e: self.func("TRUNC", e.this, e.args.get("unit")), exp.DateTrunc: lambda self, e: self.func("TRUNC", e.this, e.args.get("unit")),
exp.DayOfMonth: rename_func("DAYOFMONTH"), exp.DayOfMonth: rename_func("DAYOFMONTH"),
@ -236,6 +220,12 @@ class Spark2(Hive):
WRAP_DERIVED_VALUES = False WRAP_DERIVED_VALUES = False
CREATE_FUNCTION_RETURN_AS = False CREATE_FUNCTION_RETURN_AS = False
def temporary_storage_provider(self, expression: exp.Create) -> exp.Create:
# spark2, spark, Databricks require a storage provider for temporary tables
provider = exp.FileFormatProperty(this=exp.Literal.string("parquet"))
expression.args["properties"].append("expressions", provider)
return expression
def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
if is_parse_json(expression.this): if is_parse_json(expression.this):
schema = f"'{self.sql(expression, 'to')}'" schema = f"'{self.sql(expression, 'to')}'"

View file

@ -14,6 +14,7 @@ from sqlglot.dialects.dialect import (
parse_date_delta, parse_date_delta,
rename_func, rename_func,
timestrtotime_sql, timestrtotime_sql,
ts_or_ds_to_date_sql,
) )
from sqlglot.expressions import DataType from sqlglot.expressions import DataType
from sqlglot.helper import seq_get from sqlglot.helper import seq_get
@ -590,6 +591,7 @@ class TSQL(Dialect):
NVL2_SUPPORTED = False NVL2_SUPPORTED = False
ALTER_TABLE_ADD_COLUMN_KEYWORD = False ALTER_TABLE_ADD_COLUMN_KEYWORD = False
LIMIT_FETCH = "FETCH" LIMIT_FETCH = "FETCH"
COMPUTED_COLUMN_WITH_TYPE = False
TYPE_MAPPING = { TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING, **generator.Generator.TYPE_MAPPING,
@ -619,7 +621,11 @@ class TSQL(Dialect):
exp.Min: min_or_least, exp.Min: min_or_least,
exp.NumberToStr: _format_sql, exp.NumberToStr: _format_sql,
exp.Select: transforms.preprocess( exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins] [
transforms.eliminate_distinct_on,
transforms.eliminate_semi_and_anti_joins,
transforms.eliminate_qualify,
]
), ),
exp.SHA: lambda self, e: self.func("HASHBYTES", exp.Literal.string("SHA1"), e.this), exp.SHA: lambda self, e: self.func("HASHBYTES", exp.Literal.string("SHA1"), e.this),
exp.SHA2: lambda self, e: self.func( exp.SHA2: lambda self, e: self.func(
@ -630,6 +636,7 @@ class TSQL(Dialect):
exp.TemporaryProperty: lambda self, e: "", exp.TemporaryProperty: lambda self, e: "",
exp.TimeStrToTime: timestrtotime_sql, exp.TimeStrToTime: timestrtotime_sql,
exp.TimeToStr: _format_sql, exp.TimeToStr: _format_sql,
exp.TsOrDsToDate: ts_or_ds_to_date_sql("tsql"),
} }
TRANSFORMS.pop(exp.ReturnsProperty) TRANSFORMS.pop(exp.ReturnsProperty)

View file

@ -202,4 +202,5 @@ ENV = {
"CURRENTTIME": datetime.datetime.now, "CURRENTTIME": datetime.datetime.now,
"CURRENTDATE": datetime.date.today, "CURRENTDATE": datetime.date.today,
"STRFTIME": null_if_any(lambda fmt, arg: datetime.datetime.fromisoformat(arg).strftime(fmt)), "STRFTIME": null_if_any(lambda fmt, arg: datetime.datetime.fromisoformat(arg).strftime(fmt)),
"TRIM": null_if_any(lambda this, e=None: this.strip(e)),
} }

View file

@ -52,6 +52,9 @@ class _Expression(type):
return klass return klass
SQLGLOT_META = "sqlglot.meta"
class Expression(metaclass=_Expression): class Expression(metaclass=_Expression):
""" """
The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
@ -266,7 +269,14 @@ class Expression(metaclass=_Expression):
if self.comments is None: if self.comments is None:
self.comments = [] self.comments = []
if comments: if comments:
self.comments.extend(comments) for comment in comments:
_, *meta = comment.split(SQLGLOT_META)
if meta:
for kv in "".join(meta).split(","):
k, *v = kv.split("=")
value = v[0].strip() if v else True
self.meta[k.strip()] = value
self.comments.append(comment)
def append(self, arg_key: str, value: t.Any) -> None: def append(self, arg_key: str, value: t.Any) -> None:
""" """
@ -1036,11 +1046,14 @@ class Create(DDL):
"indexes": False, "indexes": False,
"no_schema_binding": False, "no_schema_binding": False,
"begin": False, "begin": False,
"end": False,
"clone": False, "clone": False,
} }
# https://docs.snowflake.com/en/sql-reference/sql/create-clone # https://docs.snowflake.com/en/sql-reference/sql/create-clone
# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_clone_statement
# https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_copy
class Clone(Expression): class Clone(Expression):
arg_types = { arg_types = {
"this": True, "this": True,
@ -1048,6 +1061,7 @@ class Clone(Expression):
"kind": False, "kind": False,
"shallow": False, "shallow": False,
"expression": False, "expression": False,
"copy": False,
} }
@ -1610,6 +1624,11 @@ class Identifier(Expression):
return self.name return self.name
# https://www.postgresql.org/docs/current/indexes-opclass.html
class Opclass(Expression):
arg_types = {"this": True, "expression": True}
class Index(Expression): class Index(Expression):
arg_types = { arg_types = {
"this": False, "this": False,
@ -2156,6 +2175,10 @@ class QueryTransform(Expression):
} }
class SampleProperty(Property):
arg_types = {"this": True}
class SchemaCommentProperty(Property): class SchemaCommentProperty(Property):
arg_types = {"this": True} arg_types = {"this": True}
@ -2440,6 +2463,8 @@ class Table(Expression):
"hints": False, "hints": False,
"system_time": False, "system_time": False,
"version": False, "version": False,
"format": False,
"pattern": False,
} }
@property @property
@ -2465,17 +2490,17 @@ class Table(Expression):
return [] return []
@property @property
def parts(self) -> t.List[Identifier]: def parts(self) -> t.List[Expression]:
"""Return the parts of a table in order catalog, db, table.""" """Return the parts of a table in order catalog, db, table."""
parts: t.List[Identifier] = [] parts: t.List[Expression] = []
for arg in ("catalog", "db", "this"): for arg in ("catalog", "db", "this"):
part = self.args.get(arg) part = self.args.get(arg)
if isinstance(part, Identifier): if isinstance(part, Dot):
parts.append(part)
elif isinstance(part, Dot):
parts.extend(part.flatten()) parts.extend(part.flatten())
elif isinstance(part, Expression):
parts.append(part)
return parts return parts
@ -2910,6 +2935,7 @@ class Select(Subqueryable):
prefix="OFFSET", prefix="OFFSET",
dialect=dialect, dialect=dialect,
copy=copy, copy=copy,
into_arg="expression",
**opts, **opts,
) )
@ -3572,6 +3598,7 @@ class DataType(Expression):
UINT128 = auto() UINT128 = auto()
UINT256 = auto() UINT256 = auto()
UMEDIUMINT = auto() UMEDIUMINT = auto()
UDECIMAL = auto()
UNIQUEIDENTIFIER = auto() UNIQUEIDENTIFIER = auto()
UNKNOWN = auto() # Sentinel value, useful for type annotation UNKNOWN = auto() # Sentinel value, useful for type annotation
USERDEFINED = "USER-DEFINED" USERDEFINED = "USER-DEFINED"
@ -3693,13 +3720,13 @@ class DataType(Expression):
# https://www.postgresql.org/docs/15/datatype-pseudo.html # https://www.postgresql.org/docs/15/datatype-pseudo.html
class PseudoType(Expression): class PseudoType(DataType):
pass arg_types = {"this": True}
# https://www.postgresql.org/docs/15/datatype-oid.html # https://www.postgresql.org/docs/15/datatype-oid.html
class ObjectIdentifier(Expression): class ObjectIdentifier(DataType):
pass arg_types = {"this": True}
# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...) # WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
@ -4027,10 +4054,20 @@ class TimeUnit(Expression):
return self.args.get("unit") return self.args.get("unit")
class IntervalOp(TimeUnit):
arg_types = {"unit": True, "expression": True}
def interval(self):
return Interval(
this=self.expression.copy(),
unit=self.unit.copy(),
)
# https://www.oracletutorial.com/oracle-basics/oracle-interval/ # https://www.oracletutorial.com/oracle-basics/oracle-interval/
# https://trino.io/docs/current/language/types.html#interval-day-to-second # https://trino.io/docs/current/language/types.html#interval-day-to-second
# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html # https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
class IntervalSpan(Expression): class IntervalSpan(DataType):
arg_types = {"this": True, "expression": True} arg_types = {"this": True, "expression": True}
@ -4269,7 +4306,7 @@ class CastToStrType(Func):
arg_types = {"this": True, "to": True} arg_types = {"this": True, "to": True}
class Collate(Binary): class Collate(Binary, Func):
pass pass
@ -4284,6 +4321,12 @@ class Coalesce(Func):
_sql_names = ["COALESCE", "IFNULL", "NVL"] _sql_names = ["COALESCE", "IFNULL", "NVL"]
class Chr(Func):
arg_types = {"this": True, "charset": False, "expressions": False}
is_var_len_args = True
_sql_names = ["CHR", "CHAR"]
class Concat(Func): class Concat(Func):
arg_types = {"expressions": True} arg_types = {"expressions": True}
is_var_len_args = True is_var_len_args = True
@ -4326,11 +4369,11 @@ class CurrentUser(Func):
arg_types = {"this": False} arg_types = {"this": False}
class DateAdd(Func, TimeUnit): class DateAdd(Func, IntervalOp):
arg_types = {"this": True, "expression": True, "unit": False} arg_types = {"this": True, "expression": True, "unit": False}
class DateSub(Func, TimeUnit): class DateSub(Func, IntervalOp):
arg_types = {"this": True, "expression": True, "unit": False} arg_types = {"this": True, "expression": True, "unit": False}
@ -4347,11 +4390,11 @@ class DateTrunc(Func):
return self.args["unit"] return self.args["unit"]
class DatetimeAdd(Func, TimeUnit): class DatetimeAdd(Func, IntervalOp):
arg_types = {"this": True, "expression": True, "unit": False} arg_types = {"this": True, "expression": True, "unit": False}
class DatetimeSub(Func, TimeUnit): class DatetimeSub(Func, IntervalOp):
arg_types = {"this": True, "expression": True, "unit": False} arg_types = {"this": True, "expression": True, "unit": False}
@ -4375,6 +4418,10 @@ class DayOfYear(Func):
_sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"] _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
class ToDays(Func):
pass
class WeekOfYear(Func): class WeekOfYear(Func):
_sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"] _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
@ -6160,7 +6207,7 @@ def table_name(table: Table | str, dialect: DialectType = None) -> str:
The table name. The table name.
""" """
table = maybe_parse(table, into=Table) table = maybe_parse(table, into=Table, dialect=dialect)
if not table: if not table:
raise ValueError(f"Cannot parse {table}") raise ValueError(f"Cannot parse {table}")

View file

@ -86,6 +86,7 @@ class Generator:
exp.OnUpdateColumnConstraint: lambda self, e: f"ON UPDATE {self.sql(e, 'this')}", exp.OnUpdateColumnConstraint: lambda self, e: f"ON UPDATE {self.sql(e, 'this')}",
exp.PathColumnConstraint: lambda self, e: f"PATH {self.sql(e, 'this')}", exp.PathColumnConstraint: lambda self, e: f"PATH {self.sql(e, 'this')}",
exp.ReturnsProperty: lambda self, e: self.naked_property(e), exp.ReturnsProperty: lambda self, e: self.naked_property(e),
exp.SampleProperty: lambda self, e: f"SAMPLE BY {self.sql(e, 'this')}",
exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET", exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}", exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}",
exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}", exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}",
@ -204,6 +205,21 @@ class Generator:
# Whether or not session variables / parameters are supported, e.g. @x in T-SQL # Whether or not session variables / parameters are supported, e.g. @x in T-SQL
SUPPORTS_PARAMETERS = True SUPPORTS_PARAMETERS = True
# Whether or not to include the type of a computed column in the CREATE DDL
COMPUTED_COLUMN_WITH_TYPE = True
# Whether or not CREATE TABLE .. COPY .. is supported. False means we'll generate CLONE instead of COPY
SUPPORTS_TABLE_COPY = True
# Whether or not parentheses are required around the table sample's expression
TABLESAMPLE_REQUIRES_PARENS = True
# Whether or not COLLATE is a function instead of a binary operator
COLLATE_IS_FUNC = False
# Whether or not data types support additional specifiers like e.g. CHAR or BYTE (oracle)
DATA_TYPE_SPECIFIERS_ALLOWED = False
TYPE_MAPPING = { TYPE_MAPPING = {
exp.DataType.Type.NCHAR: "CHAR", exp.DataType.Type.NCHAR: "CHAR",
exp.DataType.Type.NVARCHAR: "VARCHAR", exp.DataType.Type.NVARCHAR: "VARCHAR",
@ -282,6 +298,7 @@ class Generator:
exp.RowFormatProperty: exp.Properties.Location.POST_SCHEMA, exp.RowFormatProperty: exp.Properties.Location.POST_SCHEMA,
exp.RowFormatDelimitedProperty: exp.Properties.Location.POST_SCHEMA, exp.RowFormatDelimitedProperty: exp.Properties.Location.POST_SCHEMA,
exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA, exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA,
exp.SampleProperty: exp.Properties.Location.POST_SCHEMA,
exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA, exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA,
exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA, exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA,
exp.Set: exp.Properties.Location.POST_SCHEMA, exp.Set: exp.Properties.Location.POST_SCHEMA,
@ -324,13 +341,12 @@ class Generator:
exp.Paren, exp.Paren,
) )
UNESCAPED_SEQUENCE_TABLE = None # type: ignore
SENTINEL_LINE_BREAK = "__SQLGLOT__LB__" SENTINEL_LINE_BREAK = "__SQLGLOT__LB__"
# Autofilled # Autofilled
INVERSE_TIME_MAPPING: t.Dict[str, str] = {} INVERSE_TIME_MAPPING: t.Dict[str, str] = {}
INVERSE_TIME_TRIE: t.Dict = {} INVERSE_TIME_TRIE: t.Dict = {}
INVERSE_ESCAPE_SEQUENCES: t.Dict[str, str] = {}
INDEX_OFFSET = 0 INDEX_OFFSET = 0
UNNEST_COLUMN_ONLY = False UNNEST_COLUMN_ONLY = False
ALIAS_POST_TABLESAMPLE = False ALIAS_POST_TABLESAMPLE = False
@ -480,8 +496,7 @@ class Generator:
if not comments or isinstance(expression, exp.Binary): if not comments or isinstance(expression, exp.Binary):
return sql return sql
sep = "\n" if self.pretty else " " comments_sql = " ".join(
comments_sql = sep.join(
f"/*{self.pad_comment(comment)}*/" for comment in comments if comment f"/*{self.pad_comment(comment)}*/" for comment in comments if comment
) )
@ -649,6 +664,9 @@ class Generator:
position = self.sql(expression, "position") position = self.sql(expression, "position")
position = f" {position}" if position else "" position = f" {position}" if position else ""
if expression.find(exp.ComputedColumnConstraint) and not self.COMPUTED_COLUMN_WITH_TYPE:
kind = ""
return f"{exists}{column}{kind}{constraints}{position}" return f"{exists}{column}{kind}{constraints}{position}"
def columnconstraint_sql(self, expression: exp.ColumnConstraint) -> str: def columnconstraint_sql(self, expression: exp.ColumnConstraint) -> str:
@ -750,9 +768,11 @@ class Generator:
) )
begin = " BEGIN" if expression.args.get("begin") else "" begin = " BEGIN" if expression.args.get("begin") else ""
end = " END" if expression.args.get("end") else ""
expression_sql = self.sql(expression, "expression") expression_sql = self.sql(expression, "expression")
if expression_sql: if expression_sql:
expression_sql = f"{begin}{self.sep()}{expression_sql}" expression_sql = f"{begin}{self.sep()}{expression_sql}{end}"
if self.CREATE_FUNCTION_RETURN_AS or not isinstance(expression.expression, exp.Return): if self.CREATE_FUNCTION_RETURN_AS or not isinstance(expression.expression, exp.Return):
if properties_locs.get(exp.Properties.Location.POST_ALIAS): if properties_locs.get(exp.Properties.Location.POST_ALIAS):
@ -817,7 +837,8 @@ class Generator:
def clone_sql(self, expression: exp.Clone) -> str: def clone_sql(self, expression: exp.Clone) -> str:
this = self.sql(expression, "this") this = self.sql(expression, "this")
shallow = "SHALLOW " if expression.args.get("shallow") else "" shallow = "SHALLOW " if expression.args.get("shallow") else ""
this = f"{shallow}CLONE {this}" keyword = "COPY" if expression.args.get("copy") and self.SUPPORTS_TABLE_COPY else "CLONE"
this = f"{shallow}{keyword} {this}"
when = self.sql(expression, "when") when = self.sql(expression, "when")
if when: if when:
@ -877,7 +898,7 @@ class Generator:
def datatypeparam_sql(self, expression: exp.DataTypeParam) -> str: def datatypeparam_sql(self, expression: exp.DataTypeParam) -> str:
this = self.sql(expression, "this") this = self.sql(expression, "this")
specifier = self.sql(expression, "expression") specifier = self.sql(expression, "expression")
specifier = f" {specifier}" if specifier else "" specifier = f" {specifier}" if specifier and self.DATA_TYPE_SPECIFIERS_ALLOWED else ""
return f"{this}{specifier}" return f"{this}{specifier}"
def datatype_sql(self, expression: exp.DataType) -> str: def datatype_sql(self, expression: exp.DataType) -> str:
@ -1329,8 +1350,13 @@ class Generator:
pivots = f" {pivots}" if pivots else "" pivots = f" {pivots}" if pivots else ""
joins = self.expressions(expression, key="joins", sep="", skip_first=True) joins = self.expressions(expression, key="joins", sep="", skip_first=True)
laterals = self.expressions(expression, key="laterals", sep="") laterals = self.expressions(expression, key="laterals", sep="")
file_format = self.sql(expression, "format")
if file_format:
pattern = self.sql(expression, "pattern")
pattern = f", PATTERN => {pattern}" if pattern else ""
file_format = f" (FILE_FORMAT => {file_format}{pattern})"
return f"{table}{version}{alias}{hints}{pivots}{joins}{laterals}" return f"{table}{version}{file_format}{alias}{hints}{pivots}{joins}{laterals}"
def tablesample_sql( def tablesample_sql(
self, expression: exp.TableSample, seed_prefix: str = "SEED", sep=" AS " self, expression: exp.TableSample, seed_prefix: str = "SEED", sep=" AS "
@ -1343,6 +1369,7 @@ class Generator:
else: else:
this = self.sql(expression, "this") this = self.sql(expression, "this")
alias = "" alias = ""
method = self.sql(expression, "method") method = self.sql(expression, "method")
method = f"{method.upper()} " if method and self.TABLESAMPLE_WITH_METHOD else "" method = f"{method.upper()} " if method and self.TABLESAMPLE_WITH_METHOD else ""
numerator = self.sql(expression, "bucket_numerator") numerator = self.sql(expression, "bucket_numerator")
@ -1354,13 +1381,20 @@ class Generator:
percent = f"{percent} PERCENT" if percent else "" percent = f"{percent} PERCENT" if percent else ""
rows = self.sql(expression, "rows") rows = self.sql(expression, "rows")
rows = f"{rows} ROWS" if rows else "" rows = f"{rows} ROWS" if rows else ""
size = self.sql(expression, "size") size = self.sql(expression, "size")
if size and self.TABLESAMPLE_SIZE_IS_PERCENT: if size and self.TABLESAMPLE_SIZE_IS_PERCENT:
size = f"{size} PERCENT" size = f"{size} PERCENT"
seed = self.sql(expression, "seed") seed = self.sql(expression, "seed")
seed = f" {seed_prefix} ({seed})" if seed else "" seed = f" {seed_prefix} ({seed})" if seed else ""
kind = expression.args.get("kind", "TABLESAMPLE") kind = expression.args.get("kind", "TABLESAMPLE")
return f"{this} {kind} {method}({bucket}{percent}{rows}{size}){seed}{alias}"
expr = f"{bucket}{percent}{rows}{size}"
if self.TABLESAMPLE_REQUIRES_PARENS:
expr = f"({expr})"
return f"{this} {kind} {method}{expr}{seed}{alias}"
def pivot_sql(self, expression: exp.Pivot) -> str: def pivot_sql(self, expression: exp.Pivot) -> str:
expressions = self.expressions(expression, flat=True) expressions = self.expressions(expression, flat=True)
@ -1638,8 +1672,8 @@ class Generator:
def escape_str(self, text: str) -> str: def escape_str(self, text: str) -> str:
text = text.replace(self.QUOTE_END, self._escaped_quote_end) text = text.replace(self.QUOTE_END, self._escaped_quote_end)
if self.UNESCAPED_SEQUENCE_TABLE: if self.INVERSE_ESCAPE_SEQUENCES:
text = text.translate(self.UNESCAPED_SEQUENCE_TABLE) text = "".join(self.INVERSE_ESCAPE_SEQUENCES.get(ch, ch) for ch in text)
elif self.pretty: elif self.pretty:
text = text.replace("\n", self.SENTINEL_LINE_BREAK) text = text.replace("\n", self.SENTINEL_LINE_BREAK)
return text return text
@ -2301,6 +2335,8 @@ class Generator:
return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE" return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE"
def collate_sql(self, expression: exp.Collate) -> str: def collate_sql(self, expression: exp.Collate) -> str:
if self.COLLATE_IS_FUNC:
return self.function_fallback_sql(expression)
return self.binary(expression, "COLLATE") return self.binary(expression, "COLLATE")
def command_sql(self, expression: exp.Command) -> str: def command_sql(self, expression: exp.Command) -> str:
@ -2359,7 +2395,7 @@ class Generator:
collate = f" COLLATE {collate}" if collate else "" collate = f" COLLATE {collate}" if collate else ""
using = self.sql(expression, "using") using = self.sql(expression, "using")
using = f" USING {using}" if using else "" using = f" USING {using}" if using else ""
return f"ALTER COLUMN {this} TYPE {dtype}{collate}{using}" return f"ALTER COLUMN {this} SET DATA TYPE {dtype}{collate}{using}"
default = self.sql(expression, "default") default = self.sql(expression, "default")
if default: if default:
@ -2396,7 +2432,7 @@ class Generator:
elif isinstance(actions[0], exp.Delete): elif isinstance(actions[0], exp.Delete):
actions = self.expressions(expression, key="actions", flat=True) actions = self.expressions(expression, key="actions", flat=True)
else: else:
actions = self.expressions(expression, key="actions") actions = self.expressions(expression, key="actions", flat=True)
exists = " IF EXISTS" if expression.args.get("exists") else "" exists = " IF EXISTS" if expression.args.get("exists") else ""
only = " ONLY" if expression.args.get("only") else "" only = " ONLY" if expression.args.get("only") else ""
@ -2593,7 +2629,7 @@ class Generator:
self, self,
expression: t.Optional[exp.Expression] = None, expression: t.Optional[exp.Expression] = None,
key: t.Optional[str] = None, key: t.Optional[str] = None,
sqls: t.Optional[t.List[str]] = None, sqls: t.Optional[t.Collection[str | exp.Expression]] = None,
flat: bool = False, flat: bool = False,
indent: bool = True, indent: bool = True,
skip_first: bool = False, skip_first: bool = False,
@ -2841,6 +2877,9 @@ class Generator:
def columnprefix_sql(self, expression: exp.ColumnPrefix) -> str: def columnprefix_sql(self, expression: exp.ColumnPrefix) -> str:
return f"{self.sql(expression, 'this')}({self.sql(expression, 'expression')})" return f"{self.sql(expression, 'this')}({self.sql(expression, 'expression')})"
def opclass_sql(self, expression: exp.Opclass) -> str:
return f"{self.sql(expression, 'this')} {self.sql(expression, 'expression')}"
def cached_generator( def cached_generator(
cache: t.Optional[t.Dict[int, str]] = None cache: t.Optional[t.Dict[int, str]] = None

View file

@ -1,5 +1,7 @@
from __future__ import annotations from __future__ import annotations
import datetime
import functools
import typing as t import typing as t
from sqlglot import exp from sqlglot import exp
@ -11,6 +13,16 @@ from sqlglot.schema import Schema, ensure_schema
if t.TYPE_CHECKING: if t.TYPE_CHECKING:
B = t.TypeVar("B", bound=exp.Binary) B = t.TypeVar("B", bound=exp.Binary)
BinaryCoercionFunc = t.Callable[[exp.Expression, exp.Expression], exp.DataType.Type]
BinaryCoercions = t.Dict[
t.Tuple[exp.DataType.Type, exp.DataType.Type],
BinaryCoercionFunc,
]
# Interval units that operate on date components
DATE_UNITS = {"day", "week", "month", "quarter", "year", "year_month"}
def annotate_types( def annotate_types(
expression: E, expression: E,
@ -48,6 +60,59 @@ def _annotate_with_type_lambda(data_type: exp.DataType.Type) -> t.Callable[[Type
return lambda self, e: self._annotate_with_type(e, data_type) return lambda self, e: self._annotate_with_type(e, data_type)
def _is_iso_date(text: str) -> bool:
try:
datetime.date.fromisoformat(text)
return True
except ValueError:
return False
def _is_iso_datetime(text: str) -> bool:
try:
datetime.datetime.fromisoformat(text)
return True
except ValueError:
return False
def _coerce_literal_and_interval(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
date_text = l.name
unit = r.text("unit").lower()
is_iso_date = _is_iso_date(date_text)
if is_iso_date and unit in DATE_UNITS:
l.replace(exp.cast(l.copy(), to=exp.DataType.Type.DATE))
return exp.DataType.Type.DATE
# An ISO date is also an ISO datetime, but not vice versa
if is_iso_date or _is_iso_datetime(date_text):
l.replace(exp.cast(l.copy(), to=exp.DataType.Type.DATETIME))
return exp.DataType.Type.DATETIME
return exp.DataType.Type.UNKNOWN
def _coerce_date_and_interval(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
unit = r.text("unit").lower()
if unit not in DATE_UNITS:
return exp.DataType.Type.DATETIME
return l.type.this if l.type else exp.DataType.Type.UNKNOWN
def swap_args(func: BinaryCoercionFunc) -> BinaryCoercionFunc:
@functools.wraps(func)
def _swapped(l: exp.Expression, r: exp.Expression) -> exp.DataType.Type:
return func(r, l)
return _swapped
def swap_all(coercions: BinaryCoercions) -> BinaryCoercions:
return {**coercions, **{(b, a): swap_args(func) for (a, b), func in coercions.items()}}
class _TypeAnnotator(type): class _TypeAnnotator(type):
def __new__(cls, clsname, bases, attrs): def __new__(cls, clsname, bases, attrs):
klass = super().__new__(cls, clsname, bases, attrs) klass = super().__new__(cls, clsname, bases, attrs)
@ -104,10 +169,8 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
exp.DataType.Type.DATE: { exp.DataType.Type.DATE: {
exp.CurrentDate, exp.CurrentDate,
exp.Date, exp.Date,
exp.DateAdd,
exp.DateFromParts, exp.DateFromParts,
exp.DateStrToDate, exp.DateStrToDate,
exp.DateSub,
exp.DateTrunc, exp.DateTrunc,
exp.DiToDate, exp.DiToDate,
exp.StrToDate, exp.StrToDate,
@ -212,6 +275,8 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"), exp.Case: lambda self, e: self._annotate_by_args(e, "default", "ifs"),
exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"), exp.Coalesce: lambda self, e: self._annotate_by_args(e, "this", "expressions"),
exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()), exp.DataType: lambda self, e: self._annotate_with_type(e, e.copy()),
exp.DateAdd: lambda self, e: self._annotate_dateadd(e),
exp.DateSub: lambda self, e: self._annotate_dateadd(e),
exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"), exp.Distinct: lambda self, e: self._annotate_by_args(e, "expressions"),
exp.Filter: lambda self, e: self._annotate_by_args(e, "this"), exp.Filter: lambda self, e: self._annotate_by_args(e, "this"),
exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"), exp.If: lambda self, e: self._annotate_by_args(e, "true", "false"),
@ -234,21 +299,41 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
# Specifies what types a given type can be coerced into (autofilled) # Specifies what types a given type can be coerced into (autofilled)
COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {} COERCES_TO: t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]] = {}
# Coercion functions for binary operations.
# Map of type pairs to a callable that takes both sides of the binary operation and returns the resulting type.
BINARY_COERCIONS: BinaryCoercions = {
**swap_all(
{
(t, exp.DataType.Type.INTERVAL): _coerce_literal_and_interval
for t in exp.DataType.TEXT_TYPES
}
),
**swap_all(
{
(exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL): _coerce_date_and_interval,
}
),
}
def __init__( def __init__(
self, self,
schema: Schema, schema: Schema,
annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None, annotators: t.Optional[t.Dict[t.Type[E], t.Callable[[TypeAnnotator, E], E]]] = None,
coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None, coerces_to: t.Optional[t.Dict[exp.DataType.Type, t.Set[exp.DataType.Type]]] = None,
binary_coercions: t.Optional[BinaryCoercions] = None,
) -> None: ) -> None:
self.schema = schema self.schema = schema
self.annotators = annotators or self.ANNOTATORS self.annotators = annotators or self.ANNOTATORS
self.coerces_to = coerces_to or self.COERCES_TO self.coerces_to = coerces_to or self.COERCES_TO
self.binary_coercions = binary_coercions or self.BINARY_COERCIONS
# Caches the ids of annotated sub-Expressions, to ensure we only visit them once # Caches the ids of annotated sub-Expressions, to ensure we only visit them once
self._visited: t.Set[int] = set() self._visited: t.Set[int] = set()
def _set_type(self, expression: exp.Expression, target_type: exp.DataType) -> None: def _set_type(
expression.type = target_type self, expression: exp.Expression, target_type: exp.DataType | exp.DataType.Type
) -> None:
expression.type = target_type # type: ignore
self._visited.add(id(expression)) self._visited.add(id(expression))
def annotate(self, expression: E) -> E: def annotate(self, expression: E) -> E:
@ -342,8 +427,8 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
def _annotate_binary(self, expression: B) -> B: def _annotate_binary(self, expression: B) -> B:
self._annotate_args(expression) self._annotate_args(expression)
left_type = expression.left.type.this left, right = expression.left, expression.right
right_type = expression.right.type.this left_type, right_type = left.type.this, right.type.this
if isinstance(expression, exp.Connector): if isinstance(expression, exp.Connector):
if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL: if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL:
@ -357,6 +442,8 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
self._set_type(expression, exp.DataType.Type.BOOLEAN) self._set_type(expression, exp.DataType.Type.BOOLEAN)
elif isinstance(expression, exp.Predicate): elif isinstance(expression, exp.Predicate):
self._set_type(expression, exp.DataType.Type.BOOLEAN) self._set_type(expression, exp.DataType.Type.BOOLEAN)
elif (left_type, right_type) in self.binary_coercions:
self._set_type(expression, self.binary_coercions[(left_type, right_type)](left, right))
else: else:
self._set_type(expression, self._maybe_coerce(left_type, right_type)) self._set_type(expression, self._maybe_coerce(left_type, right_type))
@ -421,3 +508,19 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
) )
return expression return expression
def _annotate_dateadd(self, expression: exp.IntervalOp) -> exp.IntervalOp:
self._annotate_args(expression)
if expression.this.type.this in exp.DataType.TEXT_TYPES:
datatype = _coerce_literal_and_interval(expression.this, expression.interval())
elif (
expression.this.type.is_type(exp.DataType.Type.DATE)
and expression.text("unit").lower() not in DATE_UNITS
):
datatype = exp.DataType.Type.DATETIME
else:
datatype = expression.this.type
self._set_type(expression, datatype)
return expression

View file

@ -45,9 +45,11 @@ def coerce_type(node: exp.Expression) -> exp.Expression:
_coerce_date(node.left, node.right) _coerce_date(node.left, node.right)
elif isinstance(node, exp.Between): elif isinstance(node, exp.Between):
_coerce_date(node.this, node.args["low"]) _coerce_date(node.this, node.args["low"])
elif isinstance(node, exp.Extract): elif isinstance(node, exp.Extract) and not node.expression.type.is_type(
if node.expression.type.this not in exp.DataType.TEMPORAL_TYPES: *exp.DataType.TEMPORAL_TYPES
_replace_cast(node.expression, "datetime") ):
_replace_cast(node.expression, exp.DataType.Type.DATETIME)
return node return node
@ -67,7 +69,7 @@ def ensure_bool_predicates(expression: exp.Expression) -> exp.Expression:
_replace_int_predicate(expression.left) _replace_int_predicate(expression.left)
_replace_int_predicate(expression.right) _replace_int_predicate(expression.right)
elif isinstance(expression, (exp.Where, exp.Having)): elif isinstance(expression, (exp.Where, exp.Having, exp.If)):
_replace_int_predicate(expression.this) _replace_int_predicate(expression.this)
return expression return expression
@ -89,13 +91,16 @@ def _coerce_date(a: exp.Expression, b: exp.Expression) -> None:
and b.type and b.type
and b.type.this not in (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL) and b.type.this not in (exp.DataType.Type.DATE, exp.DataType.Type.INTERVAL)
): ):
_replace_cast(b, "date") _replace_cast(b, exp.DataType.Type.DATE)
def _replace_cast(node: exp.Expression, to: str) -> None: def _replace_cast(node: exp.Expression, to: exp.DataType.Type) -> None:
node.replace(exp.cast(node.copy(), to=to)) node.replace(exp.cast(node.copy(), to=to))
def _replace_int_predicate(expression: exp.Expression) -> None: def _replace_int_predicate(expression: exp.Expression) -> None:
if expression.type and expression.type.this in exp.DataType.INTEGER_TYPES: if isinstance(expression, exp.Coalesce):
for _, child in expression.iter_expressions():
_replace_int_predicate(child)
elif expression.type and expression.type.this in exp.DataType.INTEGER_TYPES:
expression.replace(exp.NEQ(this=expression.copy(), expression=exp.Literal.number(0))) expression.replace(exp.NEQ(this=expression.copy(), expression=exp.Literal.number(0)))

View file

@ -181,7 +181,7 @@ def _mergeable(outer_scope, inner_scope, leave_tables_isolated, from_or_join):
and not any(inner_select.args.get(arg) for arg in UNMERGABLE_ARGS) and not any(inner_select.args.get(arg) for arg in UNMERGABLE_ARGS)
and inner_select.args.get("from") and inner_select.args.get("from")
and not outer_scope.pivots and not outer_scope.pivots
and not any(e.find(exp.AggFunc, exp.Select) for e in inner_select.expressions) and not any(e.find(exp.AggFunc, exp.Select, exp.Explode) for e in inner_select.expressions)
and not (leave_tables_isolated and len(outer_scope.selected_sources) > 1) and not (leave_tables_isolated and len(outer_scope.selected_sources) > 1)
and not ( and not (
isinstance(from_or_join, exp.Join) isinstance(from_or_join, exp.Join)

View file

@ -22,6 +22,13 @@ def normalize_identifiers(expression, dialect=None):
Normalize all unquoted identifiers to either lower or upper case, depending Normalize all unquoted identifiers to either lower or upper case, depending
on the dialect. This essentially makes those identifiers case-insensitive. on the dialect. This essentially makes those identifiers case-insensitive.
It's possible to make this a no-op by adding a special comment next to the
identifier of interest:
SELECT a /* sqlglot.meta case_sensitive */ FROM table
In this example, the identifier `a` will not be normalized.
Note: Note:
Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even Some dialects (e.g. BigQuery) treat identifiers as case-insensitive even
when they're quoted, so in these cases all identifiers are normalized. when they're quoted, so in these cases all identifiers are normalized.
@ -43,4 +50,13 @@ def normalize_identifiers(expression, dialect=None):
""" """
if isinstance(expression, str): if isinstance(expression, str):
expression = exp.to_identifier(expression) expression = exp.to_identifier(expression)
return expression.transform(Dialect.get_or_raise(dialect).normalize_identifier, copy=False)
dialect = Dialect.get_or_raise(dialect)
def _normalize(node: E) -> E:
if not node.meta.get("case_sensitive"):
exp.replace_children(node, _normalize)
node = dialect.normalize_identifier(node)
return node
return _normalize(expression)

View file

@ -387,10 +387,6 @@ def _is_number(expression: exp.Expression) -> bool:
return expression.is_number return expression.is_number
def _is_date(expression: exp.Expression) -> bool:
return isinstance(expression, exp.Cast) and extract_date(expression) is not None
def _is_interval(expression: exp.Expression) -> bool: def _is_interval(expression: exp.Expression) -> bool:
return isinstance(expression, exp.Interval) and extract_interval(expression) is not None return isinstance(expression, exp.Interval) and extract_interval(expression) is not None
@ -422,18 +418,15 @@ def simplify_equality(expression: exp.Expression) -> exp.Expression:
if r.is_number: if r.is_number:
a_predicate = _is_number a_predicate = _is_number
b_predicate = _is_number b_predicate = _is_number
elif _is_date(r): elif _is_date_literal(r):
a_predicate = _is_date a_predicate = _is_date_literal
b_predicate = _is_interval b_predicate = _is_interval
else: else:
return expression return expression
if l.__class__ in INVERSE_DATE_OPS: if l.__class__ in INVERSE_DATE_OPS:
a = l.this a = l.this
b = exp.Interval( b = l.interval()
this=l.expression.copy(),
unit=l.unit.copy(),
)
else: else:
a, b = l.left, l.right a, b = l.left, l.right
@ -509,14 +502,14 @@ def _simplify_binary(expression, a, b):
if boolean: if boolean:
return boolean return boolean
elif isinstance(a, exp.Cast) and isinstance(b, exp.Interval): elif _is_date_literal(a) and isinstance(b, exp.Interval):
a, b = extract_date(a), extract_interval(b) a, b = extract_date(a), extract_interval(b)
if a and b: if a and b:
if isinstance(expression, exp.Add): if isinstance(expression, exp.Add):
return date_literal(a + b) return date_literal(a + b)
if isinstance(expression, exp.Sub): if isinstance(expression, exp.Sub):
return date_literal(a - b) return date_literal(a - b)
elif isinstance(a, exp.Interval) and isinstance(b, exp.Cast): elif isinstance(a, exp.Interval) and _is_date_literal(b):
a, b = extract_interval(a), extract_date(b) a, b = extract_interval(a), extract_date(b)
# you cannot subtract a date from an interval # you cannot subtract a date from an interval
if a and b and isinstance(expression, exp.Add): if a and b and isinstance(expression, exp.Add):
@ -702,11 +695,7 @@ DATETRUNC_COMPARISONS = {exp.In, *DATETRUNC_BINARY_COMPARISONS}
def _is_datetrunc_predicate(left: exp.Expression, right: exp.Expression) -> bool: def _is_datetrunc_predicate(left: exp.Expression, right: exp.Expression) -> bool:
return ( return isinstance(left, (exp.DateTrunc, exp.TimestampTrunc)) and _is_date_literal(right)
isinstance(left, (exp.DateTrunc, exp.TimestampTrunc))
and isinstance(right, exp.Cast)
and right.is_type(*exp.DataType.TEMPORAL_TYPES)
)
@catch(ModuleNotFoundError, UnsupportedUnit) @catch(ModuleNotFoundError, UnsupportedUnit)
@ -731,15 +720,26 @@ def simplify_datetrunc_predicate(expression: exp.Expression) -> exp.Expression:
unit = l.unit.name.lower() unit = l.unit.name.lower()
date = extract_date(r) date = extract_date(r)
if not date:
return expression
return DATETRUNC_BINARY_COMPARISONS[comparison](l.this, date, unit) or expression return DATETRUNC_BINARY_COMPARISONS[comparison](l.this, date, unit) or expression
elif isinstance(expression, exp.In): elif isinstance(expression, exp.In):
l = expression.this l = expression.this
rs = expression.expressions rs = expression.expressions
if all(_is_datetrunc_predicate(l, r) for r in rs): if rs and all(_is_datetrunc_predicate(l, r) for r in rs):
unit = l.unit.name.lower() unit = l.unit.name.lower()
ranges = [r for r in [_datetrunc_range(extract_date(r), unit) for r in rs] if r] ranges = []
for r in rs:
date = extract_date(r)
if not date:
return expression
drange = _datetrunc_range(date, unit)
if drange:
ranges.append(drange)
if not ranges: if not ranges:
return expression return expression
@ -811,18 +811,59 @@ def eval_boolean(expression, a, b):
return None return None
def extract_date(cast): def cast_as_date(value: t.Any) -> t.Optional[datetime.date]:
# The "fromisoformat" conversion could fail if the cast is used on an identifier, if isinstance(value, datetime.datetime):
# so in that case we can't extract the date. return value.date()
if isinstance(value, datetime.date):
return value
try: try:
if cast.args["to"].this == exp.DataType.Type.DATE: return datetime.datetime.fromisoformat(value).date()
return datetime.date.fromisoformat(cast.name)
if cast.args["to"].this == exp.DataType.Type.DATETIME:
return datetime.datetime.fromisoformat(cast.name)
except ValueError: except ValueError:
return None return None
def cast_as_datetime(value: t.Any) -> t.Optional[datetime.datetime]:
if isinstance(value, datetime.datetime):
return value
if isinstance(value, datetime.date):
return datetime.datetime(year=value.year, month=value.month, day=value.day)
try:
return datetime.datetime.fromisoformat(value)
except ValueError:
return None
def cast_value(value: t.Any, to: exp.DataType) -> t.Optional[t.Union[datetime.date, datetime.date]]:
if not value:
return None
if to.is_type(exp.DataType.Type.DATE):
return cast_as_date(value)
if to.is_type(*exp.DataType.TEMPORAL_TYPES):
return cast_as_datetime(value)
return None
def extract_date(cast: exp.Expression) -> t.Optional[t.Union[datetime.date, datetime.date]]:
if isinstance(cast, exp.Cast):
to = cast.to
elif isinstance(cast, exp.TsOrDsToDate):
to = exp.DataType.build(exp.DataType.Type.DATE)
else:
return None
if isinstance(cast.this, exp.Literal):
value: t.Any = cast.this.name
elif isinstance(cast.this, (exp.Cast, exp.TsOrDsToDate)):
value = extract_date(cast.this)
else:
return None
return cast_value(value, to)
def _is_date_literal(expression: exp.Expression) -> bool:
return extract_date(expression) is not None
def extract_interval(expression): def extract_interval(expression):
n = int(expression.name) n = int(expression.name)
unit = expression.text("unit").lower() unit = expression.text("unit").lower()
@ -836,7 +877,9 @@ def extract_interval(expression):
def date_literal(date): def date_literal(date):
return exp.cast( return exp.cast(
exp.Literal.string(date), exp.Literal.string(date),
"DATETIME" if isinstance(date, datetime.datetime) else "DATE", exp.DataType.Type.DATETIME
if isinstance(date, datetime.datetime)
else exp.DataType.Type.DATE,
) )

View file

@ -178,6 +178,7 @@ class Parser(metaclass=_Parser):
TokenType.DATERANGE, TokenType.DATERANGE,
TokenType.DATEMULTIRANGE, TokenType.DATEMULTIRANGE,
TokenType.DECIMAL, TokenType.DECIMAL,
TokenType.UDECIMAL,
TokenType.BIGDECIMAL, TokenType.BIGDECIMAL,
TokenType.UUID, TokenType.UUID,
TokenType.GEOGRAPHY, TokenType.GEOGRAPHY,
@ -215,6 +216,7 @@ class Parser(metaclass=_Parser):
TokenType.MEDIUMINT: TokenType.UMEDIUMINT, TokenType.MEDIUMINT: TokenType.UMEDIUMINT,
TokenType.SMALLINT: TokenType.USMALLINT, TokenType.SMALLINT: TokenType.USMALLINT,
TokenType.TINYINT: TokenType.UTINYINT, TokenType.TINYINT: TokenType.UTINYINT,
TokenType.DECIMAL: TokenType.UDECIMAL,
} }
SUBQUERY_PREDICATES = { SUBQUERY_PREDICATES = {
@ -338,6 +340,7 @@ class Parser(metaclass=_Parser):
TRIM_TYPES = {"LEADING", "TRAILING", "BOTH"} TRIM_TYPES = {"LEADING", "TRAILING", "BOTH"}
FUNC_TOKENS = { FUNC_TOKENS = {
TokenType.COLLATE,
TokenType.COMMAND, TokenType.COMMAND,
TokenType.CURRENT_DATE, TokenType.CURRENT_DATE,
TokenType.CURRENT_DATETIME, TokenType.CURRENT_DATETIME,
@ -590,6 +593,9 @@ class Parser(metaclass=_Parser):
exp.National, this=token.text exp.National, this=token.text
), ),
TokenType.RAW_STRING: lambda self, token: self.expression(exp.RawString, this=token.text), TokenType.RAW_STRING: lambda self, token: self.expression(exp.RawString, this=token.text),
TokenType.HEREDOC_STRING: lambda self, token: self.expression(
exp.RawString, this=token.text
),
TokenType.SESSION_PARAMETER: lambda self, _: self._parse_session_parameter(), TokenType.SESSION_PARAMETER: lambda self, _: self._parse_session_parameter(),
} }
@ -666,6 +672,9 @@ class Parser(metaclass=_Parser):
"RETURNS": lambda self: self._parse_returns(), "RETURNS": lambda self: self._parse_returns(),
"ROW": lambda self: self._parse_row(), "ROW": lambda self: self._parse_row(),
"ROW_FORMAT": lambda self: self._parse_property_assignment(exp.RowFormatProperty), "ROW_FORMAT": lambda self: self._parse_property_assignment(exp.RowFormatProperty),
"SAMPLE": lambda self: self.expression(
exp.SampleProperty, this=self._match_text_seq("BY") and self._parse_bitwise()
),
"SET": lambda self: self.expression(exp.SetProperty, multi=False), "SET": lambda self: self.expression(exp.SetProperty, multi=False),
"SETTINGS": lambda self: self.expression( "SETTINGS": lambda self: self.expression(
exp.SettingsProperty, expressions=self._parse_csv(self._parse_set_item) exp.SettingsProperty, expressions=self._parse_csv(self._parse_set_item)
@ -847,8 +856,11 @@ class Parser(metaclass=_Parser):
INSERT_ALTERNATIVES = {"ABORT", "FAIL", "IGNORE", "REPLACE", "ROLLBACK"} INSERT_ALTERNATIVES = {"ABORT", "FAIL", "IGNORE", "REPLACE", "ROLLBACK"}
CLONE_KEYWORDS = {"CLONE", "COPY"}
CLONE_KINDS = {"TIMESTAMP", "OFFSET", "STATEMENT"} CLONE_KINDS = {"TIMESTAMP", "OFFSET", "STATEMENT"}
OPCLASS_FOLLOW_KEYWORDS = {"ASC", "DESC", "NULLS"}
TABLE_INDEX_HINT_TOKENS = {TokenType.FORCE, TokenType.IGNORE, TokenType.USE} TABLE_INDEX_HINT_TOKENS = {TokenType.FORCE, TokenType.IGNORE, TokenType.USE}
WINDOW_ALIAS_TOKENS = ID_VAR_TOKENS - {TokenType.ROWS} WINDOW_ALIAS_TOKENS = ID_VAR_TOKENS - {TokenType.ROWS}
@ -863,6 +875,8 @@ class Parser(metaclass=_Parser):
NULL_TOKENS = {TokenType.NULL} NULL_TOKENS = {TokenType.NULL}
UNNEST_OFFSET_ALIAS_TOKENS = ID_VAR_TOKENS - SET_OPERATIONS
STRICT_CAST = True STRICT_CAST = True
# A NULL arg in CONCAT yields NULL by default # A NULL arg in CONCAT yields NULL by default
@ -880,9 +894,12 @@ class Parser(metaclass=_Parser):
# Whether or not the table sample clause expects CSV syntax # Whether or not the table sample clause expects CSV syntax
TABLESAMPLE_CSV = False TABLESAMPLE_CSV = False
# Whether or not the SET command needs a delimiter (e.g. "=") for assignments. # Whether or not the SET command needs a delimiter (e.g. "=") for assignments
SET_REQUIRES_ASSIGNMENT_DELIMITER = True SET_REQUIRES_ASSIGNMENT_DELIMITER = True
# Whether the TRIM function expects the characters to trim as its first argument
TRIM_PATTERN_FIRST = False
__slots__ = ( __slots__ = (
"error_level", "error_level",
"error_message_context", "error_message_context",
@ -1268,6 +1285,7 @@ class Parser(metaclass=_Parser):
indexes = None indexes = None
no_schema_binding = None no_schema_binding = None
begin = None begin = None
end = None
clone = None clone = None
def extend_props(temp_props: t.Optional[exp.Properties]) -> None: def extend_props(temp_props: t.Optional[exp.Properties]) -> None:
@ -1299,6 +1317,8 @@ class Parser(metaclass=_Parser):
else: else:
expression = self._parse_statement() expression = self._parse_statement()
end = self._match_text_seq("END")
if return_: if return_:
expression = self.expression(exp.Return, this=expression) expression = self.expression(exp.Return, this=expression)
elif create_token.token_type == TokenType.INDEX: elif create_token.token_type == TokenType.INDEX:
@ -1344,7 +1364,8 @@ class Parser(metaclass=_Parser):
shallow = self._match_text_seq("SHALLOW") shallow = self._match_text_seq("SHALLOW")
if self._match_text_seq("CLONE"): if self._match_texts(self.CLONE_KEYWORDS):
copy = self._prev.text.lower() == "copy"
clone = self._parse_table(schema=True) clone = self._parse_table(schema=True)
when = self._match_texts({"AT", "BEFORE"}) and self._prev.text.upper() when = self._match_texts({"AT", "BEFORE"}) and self._prev.text.upper()
clone_kind = ( clone_kind = (
@ -1361,6 +1382,7 @@ class Parser(metaclass=_Parser):
kind=clone_kind, kind=clone_kind,
shallow=shallow, shallow=shallow,
expression=clone_expression, expression=clone_expression,
copy=copy,
) )
return self.expression( return self.expression(
@ -1376,6 +1398,7 @@ class Parser(metaclass=_Parser):
indexes=indexes, indexes=indexes,
no_schema_binding=no_schema_binding, no_schema_binding=no_schema_binding,
begin=begin, begin=begin,
end=end,
clone=clone, clone=clone,
) )
@ -2445,21 +2468,32 @@ class Parser(metaclass=_Parser):
kwargs["using"] = self._parse_wrapped_id_vars() kwargs["using"] = self._parse_wrapped_id_vars()
elif not (kind and kind.token_type == TokenType.CROSS): elif not (kind and kind.token_type == TokenType.CROSS):
index = self._index index = self._index
joins = self._parse_joins() join = self._parse_join()
if joins and self._match(TokenType.ON): if join and self._match(TokenType.ON):
kwargs["on"] = self._parse_conjunction() kwargs["on"] = self._parse_conjunction()
elif joins and self._match(TokenType.USING): elif join and self._match(TokenType.USING):
kwargs["using"] = self._parse_wrapped_id_vars() kwargs["using"] = self._parse_wrapped_id_vars()
else: else:
joins = None join = None
self._retreat(index) self._retreat(index)
kwargs["this"].set("joins", joins) kwargs["this"].set("joins", [join] if join else None)
comments = [c for token in (method, side, kind) if token for c in token.comments] comments = [c for token in (method, side, kind) if token for c in token.comments]
return self.expression(exp.Join, comments=comments, **kwargs) return self.expression(exp.Join, comments=comments, **kwargs)
def _parse_opclass(self) -> t.Optional[exp.Expression]:
this = self._parse_conjunction()
if self._match_texts(self.OPCLASS_FOLLOW_KEYWORDS, advance=False):
return this
opclass = self._parse_var(any_token=True)
if opclass:
return self.expression(exp.Opclass, this=this, expression=opclass)
return this
def _parse_index( def _parse_index(
self, self,
index: t.Optional[exp.Expression] = None, index: t.Optional[exp.Expression] = None,
@ -2486,7 +2520,7 @@ class Parser(metaclass=_Parser):
using = self._parse_var(any_token=True) if self._match(TokenType.USING) else None using = self._parse_var(any_token=True) if self._match(TokenType.USING) else None
if self._match(TokenType.L_PAREN, advance=False): if self._match(TokenType.L_PAREN, advance=False):
columns = self._parse_wrapped_csv(self._parse_ordered) columns = self._parse_wrapped_csv(lambda: self._parse_ordered(self._parse_opclass))
else: else:
columns = None columns = None
@ -2677,7 +2711,9 @@ class Parser(metaclass=_Parser):
if not offset and self._match_pair(TokenType.WITH, TokenType.OFFSET): if not offset and self._match_pair(TokenType.WITH, TokenType.OFFSET):
self._match(TokenType.ALIAS) self._match(TokenType.ALIAS)
offset = self._parse_id_var() or exp.to_identifier("offset") offset = self._parse_id_var(
any_token=False, tokens=self.UNNEST_OFFSET_ALIAS_TOKENS
) or exp.to_identifier("offset")
return self.expression(exp.Unnest, expressions=expressions, alias=alias, offset=offset) return self.expression(exp.Unnest, expressions=expressions, alias=alias, offset=offset)
@ -2715,14 +2751,18 @@ class Parser(metaclass=_Parser):
) )
method = self._parse_var(tokens=(TokenType.ROW,)) method = self._parse_var(tokens=(TokenType.ROW,))
self._match(TokenType.L_PAREN) matched_l_paren = self._match(TokenType.L_PAREN)
if self.TABLESAMPLE_CSV: if self.TABLESAMPLE_CSV:
num = None num = None
expressions = self._parse_csv(self._parse_primary) expressions = self._parse_csv(self._parse_primary)
else: else:
expressions = None expressions = None
num = self._parse_primary() num = (
self._parse_factor()
if self._match(TokenType.NUMBER, advance=False)
else self._parse_primary()
)
if self._match_text_seq("BUCKET"): if self._match_text_seq("BUCKET"):
bucket_numerator = self._parse_number() bucket_numerator = self._parse_number()
@ -2737,7 +2777,8 @@ class Parser(metaclass=_Parser):
elif num: elif num:
size = num size = num
self._match(TokenType.R_PAREN) if matched_l_paren:
self._match_r_paren()
if self._match(TokenType.L_PAREN): if self._match(TokenType.L_PAREN):
method = self._parse_var() method = self._parse_var()
@ -2965,8 +3006,8 @@ class Parser(metaclass=_Parser):
return None return None
return self.expression(exp_class, expressions=self._parse_csv(self._parse_ordered)) return self.expression(exp_class, expressions=self._parse_csv(self._parse_ordered))
def _parse_ordered(self) -> exp.Ordered: def _parse_ordered(self, parse_method: t.Optional[t.Callable] = None) -> exp.Ordered:
this = self._parse_conjunction() this = parse_method() if parse_method else self._parse_conjunction()
asc = self._match(TokenType.ASC) asc = self._match(TokenType.ASC)
desc = self._match(TokenType.DESC) or (asc and False) desc = self._match(TokenType.DESC) or (asc and False)
@ -3144,7 +3185,7 @@ class Parser(metaclass=_Parser):
if self._match_text_seq("DISTINCT", "FROM"): if self._match_text_seq("DISTINCT", "FROM"):
klass = exp.NullSafeEQ if negate else exp.NullSafeNEQ klass = exp.NullSafeEQ if negate else exp.NullSafeNEQ
return self.expression(klass, this=this, expression=self._parse_expression()) return self.expression(klass, this=this, expression=self._parse_conjunction())
expression = self._parse_null() or self._parse_boolean() expression = self._parse_null() or self._parse_boolean()
if not expression: if not expression:
@ -3760,7 +3801,9 @@ class Parser(metaclass=_Parser):
return self.expression(exp.CompressColumnConstraint, this=self._parse_bitwise()) return self.expression(exp.CompressColumnConstraint, this=self._parse_bitwise())
def _parse_generated_as_identity(self) -> exp.GeneratedAsIdentityColumnConstraint: def _parse_generated_as_identity(
self,
) -> exp.GeneratedAsIdentityColumnConstraint | exp.ComputedColumnConstraint:
if self._match_text_seq("BY", "DEFAULT"): if self._match_text_seq("BY", "DEFAULT"):
on_null = self._match_pair(TokenType.ON, TokenType.NULL) on_null = self._match_pair(TokenType.ON, TokenType.NULL)
this = self.expression( this = self.expression(
@ -4382,16 +4425,18 @@ class Parser(metaclass=_Parser):
position = None position = None
collation = None collation = None
expression = None
if self._match_texts(self.TRIM_TYPES): if self._match_texts(self.TRIM_TYPES):
position = self._prev.text.upper() position = self._prev.text.upper()
expression = self._parse_bitwise()
if self._match_set((TokenType.FROM, TokenType.COMMA)):
this = self._parse_bitwise() this = self._parse_bitwise()
else: if self._match_set((TokenType.FROM, TokenType.COMMA)):
this = expression invert_order = self._prev.token_type == TokenType.FROM or self.TRIM_PATTERN_FIRST
expression = None expression = self._parse_bitwise()
if invert_order:
this, expression = expression, this
if self._match(TokenType.COLLATE): if self._match(TokenType.COLLATE):
collation = self._parse_bitwise() collation = self._parse_bitwise()

View file

@ -77,6 +77,7 @@ class TokenType(AutoName):
BYTE_STRING = auto() BYTE_STRING = auto()
NATIONAL_STRING = auto() NATIONAL_STRING = auto()
RAW_STRING = auto() RAW_STRING = auto()
HEREDOC_STRING = auto()
# types # types
BIT = auto() BIT = auto()
@ -98,6 +99,7 @@ class TokenType(AutoName):
FLOAT = auto() FLOAT = auto()
DOUBLE = auto() DOUBLE = auto()
DECIMAL = auto() DECIMAL = auto()
UDECIMAL = auto()
BIGDECIMAL = auto() BIGDECIMAL = auto()
CHAR = auto() CHAR = auto()
NCHAR = auto() NCHAR = auto()
@ -418,6 +420,7 @@ class _Tokenizer(type):
**_quotes_to_format(TokenType.BYTE_STRING, klass.BYTE_STRINGS), **_quotes_to_format(TokenType.BYTE_STRING, klass.BYTE_STRINGS),
**_quotes_to_format(TokenType.HEX_STRING, klass.HEX_STRINGS), **_quotes_to_format(TokenType.HEX_STRING, klass.HEX_STRINGS),
**_quotes_to_format(TokenType.RAW_STRING, klass.RAW_STRINGS), **_quotes_to_format(TokenType.RAW_STRING, klass.RAW_STRINGS),
**_quotes_to_format(TokenType.HEREDOC_STRING, klass.HEREDOC_STRINGS),
} }
klass._STRING_ESCAPES = set(klass.STRING_ESCAPES) klass._STRING_ESCAPES = set(klass.STRING_ESCAPES)
@ -484,11 +487,13 @@ class Tokenizer(metaclass=_Tokenizer):
BYTE_STRINGS: t.List[str | t.Tuple[str, str]] = [] BYTE_STRINGS: t.List[str | t.Tuple[str, str]] = []
HEX_STRINGS: t.List[str | t.Tuple[str, str]] = [] HEX_STRINGS: t.List[str | t.Tuple[str, str]] = []
RAW_STRINGS: t.List[str | t.Tuple[str, str]] = [] RAW_STRINGS: t.List[str | t.Tuple[str, str]] = []
HEREDOC_STRINGS: t.List[str | t.Tuple[str, str]] = []
IDENTIFIERS: t.List[str | t.Tuple[str, str]] = ['"'] IDENTIFIERS: t.List[str | t.Tuple[str, str]] = ['"']
IDENTIFIER_ESCAPES = ['"'] IDENTIFIER_ESCAPES = ['"']
QUOTES: t.List[t.Tuple[str, str] | str] = ["'"] QUOTES: t.List[t.Tuple[str, str] | str] = ["'"]
STRING_ESCAPES = ["'"] STRING_ESCAPES = ["'"]
VAR_SINGLE_TOKENS: t.Set[str] = set() VAR_SINGLE_TOKENS: t.Set[str] = set()
ESCAPE_SEQUENCES: t.Dict[str, str] = {}
# Autofilled # Autofilled
IDENTIFIERS_CAN_START_WITH_DIGIT: bool = False IDENTIFIERS_CAN_START_WITH_DIGIT: bool = False
@ -997,9 +1002,11 @@ class Tokenizer(metaclass=_Tokenizer):
word = word.upper() word = word.upper()
self._add(self.KEYWORDS[word], text=word) self._add(self.KEYWORDS[word], text=word)
return return
if self._char in self.SINGLE_TOKENS: if self._char in self.SINGLE_TOKENS:
self._add(self.SINGLE_TOKENS[self._char], text=self._char) self._add(self.SINGLE_TOKENS[self._char], text=self._char)
return return
self._scan_var() self._scan_var()
def _scan_comment(self, comment_start: str) -> bool: def _scan_comment(self, comment_start: str) -> bool:
@ -1126,6 +1133,10 @@ class Tokenizer(metaclass=_Tokenizer):
base = 16 base = 16
elif token_type == TokenType.BIT_STRING: elif token_type == TokenType.BIT_STRING:
base = 2 base = 2
elif token_type == TokenType.HEREDOC_STRING:
self._advance()
tag = "" if self._char == end else self._extract_string(end)
end = f"{start}{tag}{end}"
else: else:
return False return False
@ -1193,6 +1204,13 @@ class Tokenizer(metaclass=_Tokenizer):
if self._end: if self._end:
raise TokenError(f"Missing {delimiter} from {self._line}:{self._start}") raise TokenError(f"Missing {delimiter} from {self._line}:{self._start}")
if self.ESCAPE_SEQUENCES and self._peek and self._char in self.STRING_ESCAPES:
escaped_sequence = self.ESCAPE_SEQUENCES.get(self._char + self._peek)
if escaped_sequence:
self._advance(2)
text += escaped_sequence
continue
current = self._current - 1 current = self._current - 1
self._advance(alnum=True) self._advance(alnum=True)
text += self.sql[current : self._current - 1] text += self.sql[current : self._current - 1]

View file

@ -122,6 +122,14 @@ class TestBigQuery(Validator):
"""SELECT JSON '"foo"' AS json_data""", """SELECT JSON '"foo"' AS json_data""",
"""SELECT PARSE_JSON('"foo"') AS json_data""", """SELECT PARSE_JSON('"foo"') AS json_data""",
) )
self.validate_identity(
"CREATE OR REPLACE TABLE `a.b.c` CLONE `a.b.d`",
"CREATE OR REPLACE TABLE a.b.c CLONE a.b.d",
)
self.validate_identity(
"SELECT * FROM UNNEST(x) WITH OFFSET EXCEPT DISTINCT SELECT * FROM UNNEST(y) WITH OFFSET",
"SELECT * FROM UNNEST(x) WITH OFFSET AS offset EXCEPT DISTINCT SELECT * FROM UNNEST(y) WITH OFFSET AS offset",
)
self.validate_all("SELECT SPLIT(foo)", write={"bigquery": "SELECT SPLIT(foo, ',')"}) self.validate_all("SELECT SPLIT(foo)", write={"bigquery": "SELECT SPLIT(foo, ',')"})
self.validate_all("SELECT 1 AS hash", write={"bigquery": "SELECT 1 AS `hash`"}) self.validate_all("SELECT 1 AS hash", write={"bigquery": "SELECT 1 AS `hash`"})
@ -130,6 +138,35 @@ class TestBigQuery(Validator):
self.validate_all('x <> """"""', write={"bigquery": "x <> ''"}) self.validate_all('x <> """"""', write={"bigquery": "x <> ''"})
self.validate_all("x <> ''''''", write={"bigquery": "x <> ''"}) self.validate_all("x <> ''''''", write={"bigquery": "x <> ''"})
self.validate_all("CAST(x AS DATETIME)", read={"": "x::timestamp"}) self.validate_all("CAST(x AS DATETIME)", read={"": "x::timestamp"})
self.validate_all(
"SELECT '\\n'",
read={
"bigquery": "SELECT '''\n'''",
},
write={
"bigquery": "SELECT '\\n'",
"postgres": "SELECT '\n'",
},
)
self.validate_all(
"TRIM(item, '*')",
read={
"snowflake": "TRIM(item, '*')",
"spark": "TRIM('*', item)",
},
write={
"bigquery": "TRIM(item, '*')",
"snowflake": "TRIM(item, '*')",
"spark": "TRIM('*' FROM item)",
},
)
self.validate_all(
"CREATE OR REPLACE TABLE `a.b.c` COPY `a.b.d`",
write={
"bigquery": "CREATE OR REPLACE TABLE a.b.c COPY a.b.d",
"snowflake": "CREATE OR REPLACE TABLE a.b.c CLONE a.b.d",
},
)
self.validate_all( self.validate_all(
"SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)", "SELECT DATETIME_DIFF('2023-01-01T00:00:00', '2023-01-01T05:00:00', MILLISECOND)",
write={ write={
@ -608,6 +645,9 @@ class TestBigQuery(Validator):
"postgres": "CURRENT_DATE AT TIME ZONE 'UTC'", "postgres": "CURRENT_DATE AT TIME ZONE 'UTC'",
}, },
) )
self.validate_identity(
"SELECT * FROM test QUALIFY a IS DISTINCT FROM b WINDOW c AS (PARTITION BY d)"
)
self.validate_all( self.validate_all(
"SELECT a FROM test WHERE a = 1 GROUP BY a HAVING a = 2 QUALIFY z ORDER BY a LIMIT 10", "SELECT a FROM test WHERE a = 1 GROUP BY a HAVING a = 2 QUALIFY z ORDER BY a LIMIT 10",
write={ write={

View file

@ -24,6 +24,9 @@ class TestClickhouse(Validator):
self.assertEqual(expr.sql(dialect="clickhouse"), "COUNT(x)") self.assertEqual(expr.sql(dialect="clickhouse"), "COUNT(x)")
self.assertIsNone(expr._meta) self.assertIsNone(expr._meta)
self.validate_identity("SELECT * FROM (SELECT a FROM b SAMPLE 0.01)")
self.validate_identity("SELECT * FROM (SELECT a FROM b SAMPLE 1 / 10 OFFSET 1 / 2)")
self.validate_identity("SELECT sum(foo * bar) FROM bla SAMPLE 10000000")
self.validate_identity("CAST(x AS Nested(ID UInt32, Serial UInt32, EventTime DATETIME))") self.validate_identity("CAST(x AS Nested(ID UInt32, Serial UInt32, EventTime DATETIME))")
self.validate_identity("CAST(x AS Enum('hello' = 1, 'world' = 2))") self.validate_identity("CAST(x AS Enum('hello' = 1, 'world' = 2))")
self.validate_identity("CAST(x AS Enum('hello', 'world'))") self.validate_identity("CAST(x AS Enum('hello', 'world'))")
@ -82,6 +85,16 @@ class TestClickhouse(Validator):
"CREATE MATERIALIZED VIEW test_view (id UInt8) TO db.table1 AS SELECT * FROM test_data" "CREATE MATERIALIZED VIEW test_view (id UInt8) TO db.table1 AS SELECT * FROM test_data"
) )
self.validate_all(
"SELECT '\\0'",
read={
"mysql": "SELECT '\0'",
},
write={
"clickhouse": "SELECT '\\0'",
"mysql": "SELECT '\0'",
},
)
self.validate_all( self.validate_all(
"DATE_ADD('day', 1, x)", "DATE_ADD('day', 1, x)",
read={ read={
@ -224,6 +237,33 @@ class TestClickhouse(Validator):
self.validate_identity( self.validate_identity(
"SELECT s, arr_external FROM arrays_test ARRAY JOIN [1, 2, 3] AS arr_external" "SELECT s, arr_external FROM arrays_test ARRAY JOIN [1, 2, 3] AS arr_external"
) )
self.validate_all(
"SELECT quantile(0.5)(a)",
read={"duckdb": "SELECT quantile(a, 0.5)"},
write={"clickhouse": "SELECT quantile(0.5)(a)"},
)
self.validate_all(
"SELECT quantiles(0.5, 0.4)(a)",
read={"duckdb": "SELECT quantile(a, [0.5, 0.4])"},
write={"clickhouse": "SELECT quantiles(0.5, 0.4)(a)"},
)
self.validate_all(
"SELECT quantiles(0.5)(a)",
read={"duckdb": "SELECT quantile(a, [0.5])"},
write={"clickhouse": "SELECT quantiles(0.5)(a)"},
)
self.validate_identity("SELECT isNaN(x)")
self.validate_all(
"SELECT IS_NAN(x), ISNAN(x)",
write={"clickhouse": "SELECT isNaN(x), isNaN(x)"},
)
self.validate_identity("SELECT startsWith('a', 'b')")
self.validate_all(
"SELECT STARTS_WITH('a', 'b'), STARTSWITH('a', 'b')",
write={"clickhouse": "SELECT startsWith('a', 'b'), startsWith('a', 'b')"},
)
def test_cte(self): def test_cte(self):
self.validate_identity("WITH 'x' AS foo SELECT foo") self.validate_identity("WITH 'x' AS foo SELECT foo")
@ -304,6 +344,9 @@ class TestClickhouse(Validator):
) )
def test_ddl(self): def test_ddl(self):
self.validate_identity(
'CREATE TABLE data5 ("x" UInt32, "y" UInt32) ENGINE=MergeTree ORDER BY (round(y / 1000000000), cityHash64(x)) SAMPLE BY cityHash64(x)'
)
self.validate_identity( self.validate_identity(
"CREATE TABLE foo (x UInt32) TTL time_column + INTERVAL '1' MONTH DELETE WHERE column = 'value'" "CREATE TABLE foo (x UInt32) TTL time_column + INTERVAL '1' MONTH DELETE WHERE column = 'value'"
) )

View file

@ -32,6 +32,13 @@ class TestDatabricks(Validator):
"CREATE TABLE foo (x INT GENERATED ALWAYS AS (YEAR(y)))", "CREATE TABLE foo (x INT GENERATED ALWAYS AS (YEAR(y)))",
write={ write={
"databricks": "CREATE TABLE foo (x INT GENERATED ALWAYS AS (YEAR(TO_DATE(y))))", "databricks": "CREATE TABLE foo (x INT GENERATED ALWAYS AS (YEAR(TO_DATE(y))))",
"tsql": "CREATE TABLE foo (x AS YEAR(CAST(y AS DATE)))",
},
)
self.validate_all(
"CREATE TABLE t1 AS (SELECT c FROM t2)",
read={
"teradata": "CREATE TABLE t1 AS (SELECT c FROM t2) WITH DATA",
}, },
) )

View file

@ -5,6 +5,7 @@ from sqlglot import (
Dialects, Dialects,
ErrorLevel, ErrorLevel,
ParseError, ParseError,
TokenError,
UnsupportedError, UnsupportedError,
parse_one, parse_one,
) )
@ -308,6 +309,44 @@ class TestDialect(Validator):
read={"postgres": "INET '127.0.0.1/32'"}, read={"postgres": "INET '127.0.0.1/32'"},
) )
def test_heredoc_strings(self):
for dialect in ("clickhouse", "postgres", "redshift"):
# Invalid matching tag
with self.assertRaises(TokenError):
parse_one("SELECT $tag1$invalid heredoc string$tag2$", dialect=dialect)
# Unmatched tag
with self.assertRaises(TokenError):
parse_one("SELECT $tag1$invalid heredoc string", dialect=dialect)
# Without tag
self.validate_all(
"SELECT 'this is a heredoc string'",
read={
dialect: "SELECT $$this is a heredoc string$$",
},
)
self.validate_all(
"SELECT ''",
read={
dialect: "SELECT $$$$",
},
)
# With tag
self.validate_all(
"SELECT 'this is also a heredoc string'",
read={
dialect: "SELECT $foo$this is also a heredoc string$foo$",
},
)
self.validate_all(
"SELECT ''",
read={
dialect: "SELECT $foo$$foo$",
},
)
def test_decode(self): def test_decode(self):
self.validate_identity("DECODE(bin, charset)") self.validate_identity("DECODE(bin, charset)")
@ -568,6 +607,7 @@ class TestDialect(Validator):
"presto": "CAST(CAST(x AS TIMESTAMP) AS DATE)", "presto": "CAST(CAST(x AS TIMESTAMP) AS DATE)",
"snowflake": "CAST(x AS DATE)", "snowflake": "CAST(x AS DATE)",
"doris": "TO_DATE(x)", "doris": "TO_DATE(x)",
"mysql": "DATE(x)",
}, },
) )
self.validate_all( self.validate_all(
@ -648,9 +688,7 @@ class TestDialect(Validator):
self.validate_all( self.validate_all(
"DATE_ADD(x, 1, 'DAY')", "DATE_ADD(x, 1, 'DAY')",
read={ read={
"mysql": "DATE_ADD(x, INTERVAL 1 DAY)",
"snowflake": "DATEADD('DAY', 1, x)", "snowflake": "DATEADD('DAY', 1, x)",
"starrocks": "DATE_ADD(x, INTERVAL 1 DAY)",
}, },
write={ write={
"bigquery": "DATE_ADD(x, INTERVAL 1 DAY)", "bigquery": "DATE_ADD(x, INTERVAL 1 DAY)",
@ -842,6 +880,7 @@ class TestDialect(Validator):
"hive": "DATE_ADD('2021-02-01', 1)", "hive": "DATE_ADD('2021-02-01', 1)",
"presto": "DATE_ADD('DAY', 1, CAST(CAST('2021-02-01' AS TIMESTAMP) AS DATE))", "presto": "DATE_ADD('DAY', 1, CAST(CAST('2021-02-01' AS TIMESTAMP) AS DATE))",
"spark": "DATE_ADD('2021-02-01', 1)", "spark": "DATE_ADD('2021-02-01', 1)",
"mysql": "DATE_ADD('2021-02-01', INTERVAL 1 DAY)",
}, },
) )
self.validate_all( self.validate_all(
@ -897,10 +936,7 @@ class TestDialect(Validator):
"bigquery", "bigquery",
"drill", "drill",
"duckdb", "duckdb",
"mysql",
"presto", "presto",
"starrocks",
"doris",
) )
}, },
write={ write={
@ -913,8 +949,25 @@ class TestDialect(Validator):
"presto", "presto",
"hive", "hive",
"spark", "spark",
"starrocks", )
},
)
self.validate_all(
f"{unit}(TS_OR_DS_TO_DATE(x))",
read={
dialect: f"{unit}(x)"
for dialect in (
"mysql",
"doris", "doris",
"starrocks",
)
},
write={
dialect: f"{unit}(x)"
for dialect in (
"mysql",
"doris",
"starrocks",
) )
}, },
) )
@ -1790,3 +1843,17 @@ SELECT
with self.assertRaises(ParseError): with self.assertRaises(ParseError):
parse_one("CAST(x AS some_udt)", read="bigquery") parse_one("CAST(x AS some_udt)", read="bigquery")
def test_qualify(self):
self.validate_all(
"SELECT * FROM t QUALIFY COUNT(*) OVER () > 1",
write={
"duckdb": "SELECT * FROM t QUALIFY COUNT(*) OVER () > 1",
"snowflake": "SELECT * FROM t QUALIFY COUNT(*) OVER () > 1",
"clickhouse": "SELECT * FROM (SELECT *, COUNT(*) OVER () AS _w FROM t) AS _t WHERE _w > 1",
"mysql": "SELECT * FROM (SELECT *, COUNT(*) OVER () AS _w FROM t) AS _t WHERE _w > 1",
"oracle": "SELECT * FROM (SELECT *, COUNT(*) OVER () AS _w FROM t) _t WHERE _w > 1",
"postgres": "SELECT * FROM (SELECT *, COUNT(*) OVER () AS _w FROM t) AS _t WHERE _w > 1",
"tsql": "SELECT * FROM (SELECT *, COUNT(*) OVER () AS _w FROM t) AS _t WHERE _w > 1",
},
)

View file

@ -10,6 +10,10 @@ class TestDuckDB(Validator):
parse_one("select * from t limit (select 5)").sql(dialect="duckdb"), parse_one("select * from t limit (select 5)").sql(dialect="duckdb"),
exp.select("*").from_("t").limit(exp.select("5").subquery()).sql(dialect="duckdb"), exp.select("*").from_("t").limit(exp.select("5").subquery()).sql(dialect="duckdb"),
) )
self.assertEqual(
parse_one("select * from t offset (select 5)").sql(dialect="duckdb"),
exp.select("*").from_("t").offset(exp.select("5").subquery()).sql(dialect="duckdb"),
)
for struct_value in ("{'a': 1}", "struct_pack(a := 1)"): for struct_value in ("{'a': 1}", "struct_pack(a := 1)"):
self.validate_all(struct_value, write={"presto": UnsupportedError}) self.validate_all(struct_value, write={"presto": UnsupportedError})
@ -287,6 +291,8 @@ class TestDuckDB(Validator):
"duckdb": "STRUCT_EXTRACT(x, 'abc')", "duckdb": "STRUCT_EXTRACT(x, 'abc')",
"presto": "x.abc", "presto": "x.abc",
"hive": "x.abc", "hive": "x.abc",
"postgres": "x.abc",
"redshift": "x.abc",
"spark": "x.abc", "spark": "x.abc",
}, },
) )
@ -446,6 +452,7 @@ class TestDuckDB(Validator):
write={ write={
"duckdb": "SELECT QUANTILE_CONT(x, q) FROM t", "duckdb": "SELECT QUANTILE_CONT(x, q) FROM t",
"postgres": "SELECT PERCENTILE_CONT(q) WITHIN GROUP (ORDER BY x) FROM t", "postgres": "SELECT PERCENTILE_CONT(q) WITHIN GROUP (ORDER BY x) FROM t",
"snowflake": "SELECT PERCENTILE_CONT(q) WITHIN GROUP (ORDER BY x) FROM t",
}, },
) )
self.validate_all( self.validate_all(
@ -453,6 +460,7 @@ class TestDuckDB(Validator):
write={ write={
"duckdb": "SELECT QUANTILE_DISC(x, q) FROM t", "duckdb": "SELECT QUANTILE_DISC(x, q) FROM t",
"postgres": "SELECT PERCENTILE_DISC(q) WITHIN GROUP (ORDER BY x) FROM t", "postgres": "SELECT PERCENTILE_DISC(q) WITHIN GROUP (ORDER BY x) FROM t",
"snowflake": "SELECT PERCENTILE_DISC(q) WITHIN GROUP (ORDER BY x) FROM t",
}, },
) )
self.validate_all( self.validate_all(
@ -460,6 +468,7 @@ class TestDuckDB(Validator):
write={ write={
"duckdb": "SELECT QUANTILE_CONT(x, 0.5) FROM t", "duckdb": "SELECT QUANTILE_CONT(x, 0.5) FROM t",
"postgres": "SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x) FROM t", "postgres": "SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x) FROM t",
"snowflake": "SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x) FROM t",
}, },
) )

View file

@ -12,6 +12,8 @@ class TestMySQL(Validator):
self.validate_identity(f"CREATE TABLE t (id {t} UNSIGNED)") self.validate_identity(f"CREATE TABLE t (id {t} UNSIGNED)")
self.validate_identity(f"CREATE TABLE t (id {t}(10) UNSIGNED)") self.validate_identity(f"CREATE TABLE t (id {t}(10) UNSIGNED)")
self.validate_identity("CREATE TABLE t (id DECIMAL(20, 4) UNSIGNED)")
self.validate_all( self.validate_all(
"CREATE TABLE t (id INT UNSIGNED)", "CREATE TABLE t (id INT UNSIGNED)",
write={ write={
@ -205,6 +207,9 @@ class TestMySQL(Validator):
) )
self.validate_identity("INTERVAL '1' YEAR") self.validate_identity("INTERVAL '1' YEAR")
self.validate_identity("DATE_ADD(x, INTERVAL 1 YEAR)") self.validate_identity("DATE_ADD(x, INTERVAL 1 YEAR)")
self.validate_identity("CHAR(0)")
self.validate_identity("CHAR(77, 121, 83, 81, '76')")
self.validate_identity("CHAR(77, 77.3, '77.3' USING utf8mb4)")
def test_types(self): def test_types(self):
self.validate_identity("CAST(x AS MEDIUMINT) + CAST(y AS YEAR(4))") self.validate_identity("CAST(x AS MEDIUMINT) + CAST(y AS YEAR(4))")
@ -244,6 +249,13 @@ class TestMySQL(Validator):
self.validate_identity( self.validate_identity(
"SELECT WEEK_OF_YEAR('2023-01-01')", "SELECT WEEKOFYEAR('2023-01-01')" "SELECT WEEK_OF_YEAR('2023-01-01')", "SELECT WEEKOFYEAR('2023-01-01')"
) )
self.validate_all(
"CHAR(10)",
write={
"mysql": "CHAR(10)",
"presto": "CHR(10)",
},
)
def test_escape(self): def test_escape(self):
self.validate_identity("""'"abc"'""") self.validate_identity("""'"abc"'""")
@ -496,6 +508,56 @@ class TestMySQL(Validator):
self.validate_identity("FROM_UNIXTIME(a, b)") self.validate_identity("FROM_UNIXTIME(a, b)")
self.validate_identity("FROM_UNIXTIME(a, b, c)") self.validate_identity("FROM_UNIXTIME(a, b, c)")
self.validate_identity("TIME_STR_TO_UNIX(x)", "UNIX_TIMESTAMP(x)") self.validate_identity("TIME_STR_TO_UNIX(x)", "UNIX_TIMESTAMP(x)")
self.validate_all(
"SELECT TO_DAYS(x)",
write={
"mysql": "SELECT (DATEDIFF(x, '0000-01-01') + 1)",
"presto": "SELECT (DATE_DIFF('DAY', CAST(CAST('0000-01-01' AS TIMESTAMP) AS DATE), CAST(CAST(x AS TIMESTAMP) AS DATE)) + 1)",
},
)
self.validate_all(
"SELECT DATEDIFF(x, y)",
write={"mysql": "SELECT DATEDIFF(x, y)", "presto": "SELECT DATE_DIFF('day', y, x)"},
)
self.validate_all(
"DAYOFYEAR(x)",
write={
"mysql": "DAYOFYEAR(x)",
"": "DAY_OF_YEAR(TS_OR_DS_TO_DATE(x))",
},
)
self.validate_all(
"DAYOFMONTH(x)",
write={"mysql": "DAYOFMONTH(x)", "": "DAY_OF_MONTH(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"DAYOFWEEK(x)",
write={"mysql": "DAYOFWEEK(x)", "": "DAY_OF_WEEK(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"WEEKOFYEAR(x)",
write={"mysql": "WEEKOFYEAR(x)", "": "WEEK_OF_YEAR(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"DAY(x)",
write={"mysql": "DAY(x)", "": "DAY(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"WEEK(x)",
write={"mysql": "WEEK(x)", "": "WEEK(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"YEAR(x)",
write={"mysql": "YEAR(x)", "": "YEAR(TS_OR_DS_TO_DATE(x))"},
)
self.validate_all(
"DATE(x)",
read={"": "TS_OR_DS_TO_DATE(x)"},
)
self.validate_all(
"STR_TO_DATE(x, '%M')",
read={"": "TS_OR_DS_TO_DATE(x, '%B')"},
)
def test_mysql(self): def test_mysql(self):
self.validate_all( self.validate_all(
@ -896,7 +958,7 @@ COMMENT='客户账户表'"""
self.validate_all( self.validate_all(
"MONTHNAME(x)", "MONTHNAME(x)",
write={ write={
"": "TIME_TO_STR(x, '%B')", "": "TIME_TO_STR(TS_OR_DS_TO_DATE(x), '%B')",
"mysql": "DATE_FORMAT(x, '%M')", "mysql": "DATE_FORMAT(x, '%M')",
}, },
) )

View file

@ -22,8 +22,6 @@ class TestOracle(Validator):
self.validate_identity("SELECT * FROM t FOR UPDATE OF s.t.c, s.t.v SKIP LOCKED") self.validate_identity("SELECT * FROM t FOR UPDATE OF s.t.c, s.t.v SKIP LOCKED")
self.validate_identity("SELECT STANDARD_HASH('hello')") self.validate_identity("SELECT STANDARD_HASH('hello')")
self.validate_identity("SELECT STANDARD_HASH('hello', 'MD5')") self.validate_identity("SELECT STANDARD_HASH('hello', 'MD5')")
self.validate_identity("SELECT CAST(NULL AS VARCHAR2(2328 CHAR)) AS COL1")
self.validate_identity("SELECT CAST(NULL AS VARCHAR2(2328 BYTE)) AS COL1")
self.validate_identity("SELECT * FROM table_name@dblink_name.database_link_domain") self.validate_identity("SELECT * FROM table_name@dblink_name.database_link_domain")
self.validate_identity("SELECT * FROM table_name SAMPLE (25) s") self.validate_identity("SELECT * FROM table_name SAMPLE (25) s")
self.validate_identity("SELECT * FROM V$SESSION") self.validate_identity("SELECT * FROM V$SESSION")
@ -60,6 +58,20 @@ class TestOracle(Validator):
"SELECT * FROM t SAMPLE (0.25)", "SELECT * FROM t SAMPLE (0.25)",
) )
self.validate_all(
"SELECT CAST(NULL AS VARCHAR2(2328 CHAR)) AS COL1",
write={
"oracle": "SELECT CAST(NULL AS VARCHAR2(2328 CHAR)) AS COL1",
"spark": "SELECT CAST(NULL AS VARCHAR(2328)) AS COL1",
},
)
self.validate_all(
"SELECT CAST(NULL AS VARCHAR2(2328 BYTE)) AS COL1",
write={
"oracle": "SELECT CAST(NULL AS VARCHAR2(2328 BYTE)) AS COL1",
"spark": "SELECT CAST(NULL AS VARCHAR(2328)) AS COL1",
},
)
self.validate_all( self.validate_all(
"NVL(NULL, 1)", "NVL(NULL, 1)",
write={ write={

View file

@ -9,6 +9,9 @@ class TestPostgres(Validator):
dialect = "postgres" dialect = "postgres"
def test_ddl(self): def test_ddl(self):
self.validate_identity(
"CREATE INDEX foo ON bar.baz USING btree(col1 varchar_pattern_ops ASC, col2)"
)
self.validate_identity( self.validate_identity(
"CREATE TABLE test (x TIMESTAMP WITHOUT TIME ZONE[][])", "CREATE TABLE test (x TIMESTAMP WITHOUT TIME ZONE[][])",
"CREATE TABLE test (x TIMESTAMP[][])", "CREATE TABLE test (x TIMESTAMP[][])",
@ -149,15 +152,27 @@ class TestPostgres(Validator):
) )
def test_postgres(self): def test_postgres(self):
expr = parse_one("SELECT * FROM r CROSS JOIN LATERAL UNNEST(ARRAY[1]) AS s(location)") expr = parse_one(
"SELECT * FROM r CROSS JOIN LATERAL UNNEST(ARRAY[1]) AS s(location)", read="postgres"
)
unnest = expr.args["joins"][0].this.this unnest = expr.args["joins"][0].this.this
unnest.assert_is(exp.Unnest) unnest.assert_is(exp.Unnest)
alter_table_only = """ALTER TABLE ONLY "Album" ADD CONSTRAINT "FK_AlbumArtistId" FOREIGN KEY ("ArtistId") REFERENCES "Artist" ("ArtistId") ON DELETE NO ACTION ON UPDATE NO ACTION""" alter_table_only = """ALTER TABLE ONLY "Album" ADD CONSTRAINT "FK_AlbumArtistId" FOREIGN KEY ("ArtistId") REFERENCES "Artist" ("ArtistId") ON DELETE NO ACTION ON UPDATE NO ACTION"""
expr = parse_one(alter_table_only) expr = parse_one(alter_table_only, read="postgres")
# Checks that user-defined types are parsed into DataType instead of Identifier # Checks that user-defined types are parsed into DataType instead of Identifier
parse_one("CREATE TABLE t (a udt)").this.expressions[0].args["kind"].assert_is(exp.DataType) parse_one("CREATE TABLE t (a udt)", read="postgres").this.expressions[0].args[
"kind"
].assert_is(exp.DataType)
# Checks that OID is parsed into a DataType (ObjectIdentifier)
self.assertIsInstance(
parse_one("CREATE TABLE public.propertydata (propertyvalue oid)", read="postgres").find(
exp.DataType
),
exp.ObjectIdentifier,
)
self.assertIsInstance(expr, exp.AlterTable) self.assertIsInstance(expr, exp.AlterTable)
self.assertEqual(expr.sql(dialect="postgres"), alter_table_only) self.assertEqual(expr.sql(dialect="postgres"), alter_table_only)
@ -192,7 +207,6 @@ class TestPostgres(Validator):
self.validate_identity("SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2]") self.validate_identity("SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2]")
self.validate_identity("SELECT ARRAY[1, 2, 3] <@ ARRAY[1, 2]") self.validate_identity("SELECT ARRAY[1, 2, 3] <@ ARRAY[1, 2]")
self.validate_identity("SELECT ARRAY[1, 2, 3] && ARRAY[1, 2]") self.validate_identity("SELECT ARRAY[1, 2, 3] && ARRAY[1, 2]")
self.validate_identity("$x")
self.validate_identity("x$") self.validate_identity("x$")
self.validate_identity("SELECT ARRAY[1, 2, 3]") self.validate_identity("SELECT ARRAY[1, 2, 3]")
self.validate_identity("SELECT ARRAY(SELECT 1)") self.validate_identity("SELECT ARRAY(SELECT 1)")

View file

@ -300,7 +300,6 @@ class TestPresto(Validator):
write={ write={
"presto": "DATE_ADD('DAY', 1 * -1, x)", "presto": "DATE_ADD('DAY', 1 * -1, x)",
}, },
read={"mysql": "DATE_SUB(x, INTERVAL 1 DAY)"},
) )
self.validate_all( self.validate_all(
"NOW()", "NOW()",
@ -503,6 +502,7 @@ class TestPresto(Validator):
@mock.patch("sqlglot.helper.logger") @mock.patch("sqlglot.helper.logger")
def test_presto(self, logger): def test_presto(self, logger):
self.validate_identity("string_agg(x, ',')", "ARRAY_JOIN(ARRAY_AGG(x), ',')")
self.validate_identity( self.validate_identity(
"SELECT * FROM example.testdb.customer_orders FOR VERSION AS OF 8954597067493422955" "SELECT * FROM example.testdb.customer_orders FOR VERSION AS OF 8954597067493422955"
) )

View file

@ -6,6 +6,11 @@ class TestRedshift(Validator):
dialect = "redshift" dialect = "redshift"
def test_redshift(self): def test_redshift(self):
self.validate_identity(
"SELECT 'a''b'",
"SELECT 'a\\'b'",
)
self.validate_all( self.validate_all(
"x ~* 'pat'", "x ~* 'pat'",
write={ write={
@ -226,7 +231,6 @@ class TestRedshift(Validator):
self.validate_identity("SELECT * FROM #x") self.validate_identity("SELECT * FROM #x")
self.validate_identity("SELECT INTERVAL '5 day'") self.validate_identity("SELECT INTERVAL '5 day'")
self.validate_identity("foo$") self.validate_identity("foo$")
self.validate_identity("$foo")
self.validate_identity("CAST('bla' AS SUPER)") self.validate_identity("CAST('bla' AS SUPER)")
self.validate_identity("CREATE TABLE real1 (realcol REAL)") self.validate_identity("CREATE TABLE real1 (realcol REAL)")
self.validate_identity("CAST('foo' AS HLLSKETCH)") self.validate_identity("CAST('foo' AS HLLSKETCH)")

View file

@ -1,6 +1,7 @@
from unittest import mock from unittest import mock
from sqlglot import UnsupportedError, exp, parse_one from sqlglot import UnsupportedError, exp, parse_one
from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
from tests.dialects.test_dialect import Validator from tests.dialects.test_dialect import Validator
@ -8,10 +9,67 @@ class TestSnowflake(Validator):
dialect = "snowflake" dialect = "snowflake"
def test_snowflake(self): def test_snowflake(self):
self.validate_identity("LISTAGG(data['some_field'], ',')")
self.validate_identity("WEEKOFYEAR(tstamp)")
self.validate_identity("SELECT SUM(amount) FROM mytable GROUP BY ALL")
self.validate_identity("WITH x AS (SELECT 1 AS foo) SELECT foo FROM IDENTIFIER('x')")
self.validate_identity("WITH x AS (SELECT 1 AS foo) SELECT IDENTIFIER('foo') FROM x")
self.validate_identity("INITCAP('iqamqinterestedqinqthisqtopic', 'q')")
self.validate_identity("CAST(x AS GEOMETRY)")
self.validate_identity("OBJECT_CONSTRUCT(*)")
self.validate_identity("SELECT TO_DATE('2019-02-28') + INTERVAL '1 day, 1 year'")
self.validate_identity("SELECT CAST('2021-01-01' AS DATE) + INTERVAL '1 DAY'")
self.validate_identity("SELECT HLL(*)")
self.validate_identity("SELECT HLL(a)")
self.validate_identity("SELECT HLL(DISTINCT t.a)")
self.validate_identity("SELECT HLL(a, b, c)")
self.validate_identity("SELECT HLL(DISTINCT a, b, c)")
self.validate_identity("$x") # parameter
self.validate_identity("a$b") # valid snowflake identifier
self.validate_identity("SELECT REGEXP_LIKE(a, b, c)")
self.validate_identity("CREATE TABLE foo (bar FLOAT AUTOINCREMENT START 0 INCREMENT 1)")
self.validate_identity("ALTER TABLE IF EXISTS foo SET TAG a = 'a', b = 'b', c = 'c'")
self.validate_identity("ALTER TABLE foo UNSET TAG a, b, c")
self.validate_identity("ALTER TABLE foo SET COMMENT = 'bar'")
self.validate_identity("ALTER TABLE foo SET CHANGE_TRACKING = FALSE")
self.validate_identity("ALTER TABLE foo UNSET DATA_RETENTION_TIME_IN_DAYS, CHANGE_TRACKING")
self.validate_identity("COMMENT IF EXISTS ON TABLE foo IS 'bar'")
self.validate_identity("SELECT CONVERT_TIMEZONE('UTC', 'America/Los_Angeles', col)")
self.validate_identity("REGEXP_REPLACE('target', 'pattern', '\n')")
self.validate_identity( self.validate_identity(
'DESCRIBE TABLE "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."WEB_SITE" type=stage' 'DESCRIBE TABLE "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."WEB_SITE" type=stage'
) )
self.validate_identity(
"SELECT state, city, SUM(retail_price * quantity) AS gross_revenue FROM sales GROUP BY ALL"
)
self.validate_identity(
"SELECT * FROM foo window",
"SELECT * FROM foo AS window",
)
self.validate_identity(
r"SELECT RLIKE(a, $$regular expression with \ characters: \d{2}-\d{3}-\d{4}$$, 'i') FROM log_source",
r"SELECT REGEXP_LIKE(a, 'regular expression with \\ characters: \\d{2}-\\d{3}-\\d{4}', 'i') FROM log_source",
)
self.validate_identity(
r"SELECT $$a ' \ \t \x21 z $ $$",
r"SELECT 'a \' \\ \\t \\x21 z $ '",
)
self.validate_identity(
"SELECT {'test': 'best'}::VARIANT",
"SELECT CAST(OBJECT_CONSTRUCT('test', 'best') AS VARIANT)",
)
self.validate_all("CAST(x AS BYTEINT)", write={"snowflake": "CAST(x AS INT)"})
self.validate_all("CAST(x AS CHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS CHARACTER VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS NCHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all(
"SELECT COLLATE('B', 'und:ci')",
write={
"bigquery": "SELECT COLLATE('B', 'und:ci')",
"snowflake": "SELECT COLLATE('B', 'und:ci')",
},
)
self.validate_all( self.validate_all(
"SELECT * FROM x START WITH a = b CONNECT BY c = PRIOR d", "SELECT * FROM x START WITH a = b CONNECT BY c = PRIOR d",
read={ read={
@ -35,58 +93,6 @@ class TestSnowflake(Validator):
"tsql": "SELECT STUFF(a, 0, 0, 'b')", "tsql": "SELECT STUFF(a, 0, 0, 'b')",
}, },
) )
self.validate_identity("LISTAGG(data['some_field'], ',')")
self.validate_identity("WEEKOFYEAR(tstamp)")
self.validate_identity("SELECT SUM(amount) FROM mytable GROUP BY ALL")
self.validate_identity("WITH x AS (SELECT 1 AS foo) SELECT foo FROM IDENTIFIER('x')")
self.validate_identity("WITH x AS (SELECT 1 AS foo) SELECT IDENTIFIER('foo') FROM x")
self.validate_identity("INITCAP('iqamqinterestedqinqthisqtopic', 'q')")
self.validate_identity("CAST(x AS GEOMETRY)")
self.validate_identity("OBJECT_CONSTRUCT(*)")
self.validate_identity("SELECT TO_DATE('2019-02-28') + INTERVAL '1 day, 1 year'")
self.validate_identity("SELECT CAST('2021-01-01' AS DATE) + INTERVAL '1 DAY'")
self.validate_identity("SELECT HLL(*)")
self.validate_identity("SELECT HLL(a)")
self.validate_identity("SELECT HLL(DISTINCT t.a)")
self.validate_identity("SELECT HLL(a, b, c)")
self.validate_identity("SELECT HLL(DISTINCT a, b, c)")
self.validate_identity("$x") # parameter
self.validate_identity("a$b") # valid snowflake identifier
self.validate_identity("SELECT REGEXP_LIKE(a, b, c)")
self.validate_identity("PUT file:///dir/tmp.csv @%table")
self.validate_identity("CREATE TABLE foo (bar FLOAT AUTOINCREMENT START 0 INCREMENT 1)")
self.validate_identity("ALTER TABLE IF EXISTS foo SET TAG a = 'a', b = 'b', c = 'c'")
self.validate_identity("ALTER TABLE foo UNSET TAG a, b, c")
self.validate_identity("ALTER TABLE foo SET COMMENT = 'bar'")
self.validate_identity("ALTER TABLE foo SET CHANGE_TRACKING = FALSE")
self.validate_identity("ALTER TABLE foo UNSET DATA_RETENTION_TIME_IN_DAYS, CHANGE_TRACKING")
self.validate_identity("COMMENT IF EXISTS ON TABLE foo IS 'bar'")
self.validate_identity("SELECT CONVERT_TIMEZONE('UTC', 'America/Los_Angeles', col)")
self.validate_identity("REGEXP_REPLACE('target', 'pattern', '\n')")
self.validate_identity(
'COPY INTO NEW_TABLE ("foo", "bar") FROM (SELECT $1, $2, $3, $4 FROM @%old_table)'
)
self.validate_identity(
"SELECT state, city, SUM(retail_price * quantity) AS gross_revenue FROM sales GROUP BY ALL"
)
self.validate_identity(
r"SELECT RLIKE(a, $$regular expression with \ characters: \d{2}-\d{3}-\d{4}$$, 'i') FROM log_source",
r"SELECT REGEXP_LIKE(a, 'regular expression with \\ characters: \\d{2}-\\d{3}-\\d{4}', 'i') FROM log_source",
)
self.validate_identity(
r"SELECT $$a ' \ \t \x21 z $ $$",
r"SELECT 'a \' \\ \\t \\x21 z $ '",
)
self.validate_identity(
"SELECT {'test': 'best'}::VARIANT",
"SELECT CAST(OBJECT_CONSTRUCT('test', 'best') AS VARIANT)",
)
self.validate_all("CAST(x AS BYTEINT)", write={"snowflake": "CAST(x AS INT)"})
self.validate_all("CAST(x AS CHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS CHARACTER VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS NCHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all( self.validate_all(
"ARRAY_GENERATE_RANGE(0, 3)", "ARRAY_GENERATE_RANGE(0, 3)",
write={ write={
@ -513,6 +519,40 @@ class TestSnowflake(Validator):
}, },
) )
def test_staged_files(self):
# Ensure we don't treat staged file paths as identifiers (i.e. they're not normalized)
staged_file = parse_one("SELECT * FROM @foo", read="snowflake")
self.assertEqual(
normalize_identifiers(staged_file, dialect="snowflake").sql(dialect="snowflake"),
staged_file.sql(dialect="snowflake"),
)
self.validate_identity("SELECT * FROM @~")
self.validate_identity("SELECT * FROM @~/some/path/to/file.csv")
self.validate_identity("SELECT * FROM @mystage")
self.validate_identity("SELECT * FROM '@mystage'")
self.validate_identity("SELECT * FROM @namespace.mystage/path/to/file.json.gz")
self.validate_identity("SELECT * FROM @namespace.%table_name/path/to/file.json.gz")
self.validate_identity("SELECT * FROM '@external/location' (FILE_FORMAT => 'path.to.csv')")
self.validate_identity("PUT file:///dir/tmp.csv @%table")
self.validate_identity(
'COPY INTO NEW_TABLE ("foo", "bar") FROM (SELECT $1, $2, $3, $4 FROM @%old_table)'
)
self.validate_identity(
"SELECT * FROM @foo/bar (FILE_FORMAT => ds_sandbox.test.my_csv_format, PATTERN => 'test') AS bla"
)
self.validate_identity(
"SELECT t.$1, t.$2 FROM @mystage1 (FILE_FORMAT => 'myformat', PATTERN => '.*data.*[.]csv.gz') AS t"
)
self.validate_identity(
"SELECT parse_json($1):a.b FROM @mystage2/data1.json.gz",
"SELECT PARSE_JSON($1)['a'].b FROM @mystage2/data1.json.gz",
)
self.validate_identity(
"SELECT * FROM @mystage t (c1)",
"SELECT * FROM @mystage AS t(c1)",
)
def test_sample(self): def test_sample(self):
self.validate_identity("SELECT * FROM testtable TABLESAMPLE BERNOULLI (20.3)") self.validate_identity("SELECT * FROM testtable TABLESAMPLE BERNOULLI (20.3)")
self.validate_identity("SELECT * FROM testtable TABLESAMPLE (100)") self.validate_identity("SELECT * FROM testtable TABLESAMPLE (100)")
@ -660,7 +700,6 @@ class TestSnowflake(Validator):
self.validate_identity("CREATE MATERIALIZED VIEW a COMMENT='...' AS SELECT 1 FROM x") self.validate_identity("CREATE MATERIALIZED VIEW a COMMENT='...' AS SELECT 1 FROM x")
self.validate_identity("CREATE DATABASE mytestdb_clone CLONE mytestdb") self.validate_identity("CREATE DATABASE mytestdb_clone CLONE mytestdb")
self.validate_identity("CREATE SCHEMA mytestschema_clone CLONE testschema") self.validate_identity("CREATE SCHEMA mytestschema_clone CLONE testschema")
self.validate_identity("CREATE TABLE orders_clone CLONE orders")
self.validate_identity("CREATE TABLE IDENTIFIER('foo') (COLUMN1 VARCHAR, COLUMN2 VARCHAR)") self.validate_identity("CREATE TABLE IDENTIFIER('foo') (COLUMN1 VARCHAR, COLUMN2 VARCHAR)")
self.validate_identity("CREATE TABLE IDENTIFIER($foo) (col1 VARCHAR, col2 VARCHAR)") self.validate_identity("CREATE TABLE IDENTIFIER($foo) (col1 VARCHAR, col2 VARCHAR)")
self.validate_identity( self.validate_identity(
@ -679,6 +718,16 @@ class TestSnowflake(Validator):
"CREATE OR REPLACE TABLE EXAMPLE_DB.DEMO.USERS (ID DECIMAL(38, 0) NOT NULL, PRIMARY KEY (ID), FOREIGN KEY (CITY_CODE) REFERENCES EXAMPLE_DB.DEMO.CITIES (CITY_CODE))" "CREATE OR REPLACE TABLE EXAMPLE_DB.DEMO.USERS (ID DECIMAL(38, 0) NOT NULL, PRIMARY KEY (ID), FOREIGN KEY (CITY_CODE) REFERENCES EXAMPLE_DB.DEMO.CITIES (CITY_CODE))"
) )
self.validate_all(
"CREATE TABLE orders_clone CLONE orders",
read={
"bigquery": "CREATE TABLE orders_clone CLONE orders",
},
write={
"bigquery": "CREATE TABLE orders_clone CLONE orders",
"snowflake": "CREATE TABLE orders_clone CLONE orders",
},
)
self.validate_all( self.validate_all(
"CREATE OR REPLACE TRANSIENT TABLE a (id INT)", "CREATE OR REPLACE TRANSIENT TABLE a (id INT)",
read={ read={

View file

@ -8,6 +8,7 @@ class TestSpark(Validator):
dialect = "spark" dialect = "spark"
def test_ddl(self): def test_ddl(self):
self.validate_identity("CREATE TEMPORARY VIEW test AS SELECT 1")
self.validate_identity("CREATE TABLE foo (col VARCHAR(50))") self.validate_identity("CREATE TABLE foo (col VARCHAR(50))")
self.validate_identity("CREATE TABLE foo (col STRUCT<struct_col_a: VARCHAR((50))>)") self.validate_identity("CREATE TABLE foo (col STRUCT<struct_col_a: VARCHAR((50))>)")
self.validate_identity("CREATE TABLE foo (col STRING) CLUSTERED BY (col) INTO 10 BUCKETS") self.validate_identity("CREATE TABLE foo (col STRING) CLUSTERED BY (col) INTO 10 BUCKETS")

View file

@ -6,6 +6,45 @@ class TestTSQL(Validator):
dialect = "tsql" dialect = "tsql"
def test_tsql(self): def test_tsql(self):
self.validate_all(
"CREATE TABLE #mytemptable (a INTEGER)",
read={
"duckdb": "CREATE TEMPORARY TABLE mytemptable (a INT)",
},
write={
"tsql": "CREATE TABLE #mytemptable (a INTEGER)",
"snowflake": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"duckdb": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"oracle": "CREATE TEMPORARY TABLE mytemptable (a NUMBER)",
"hive": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"spark2": "CREATE TEMPORARY TABLE mytemptable (a INT) USING PARQUET",
"spark": "CREATE TEMPORARY TABLE mytemptable (a INT) USING PARQUET",
"databricks": "CREATE TEMPORARY TABLE mytemptable (a INT) USING PARQUET",
},
)
self.validate_all(
"CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))",
write={
"spark": "CREATE TEMPORARY TABLE mytemp (a INT, b CHAR(2), c TIMESTAMP, d FLOAT) USING PARQUET",
"tsql": "CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))",
},
)
self.validate_all(
"""CREATE TABLE [dbo].[mytable](
[email] [varchar](255) NOT NULL,
CONSTRAINT [UN_t_mytable] UNIQUE NONCLUSTERED
(
[email] ASC
)
)""",
write={
"hive": "CREATE TABLE `dbo`.`mytable` (`email` VARCHAR(255) NOT NULL)",
"spark2": "CREATE TABLE `dbo`.`mytable` (`email` VARCHAR(255) NOT NULL)",
"spark": "CREATE TABLE `dbo`.`mytable` (`email` VARCHAR(255) NOT NULL)",
"databricks": "CREATE TABLE `dbo`.`mytable` (`email` VARCHAR(255) NOT NULL)",
},
)
self.validate_all( self.validate_all(
"CREATE TABLE x ( A INTEGER NOT NULL, B INTEGER NULL )", "CREATE TABLE x ( A INTEGER NOT NULL, B INTEGER NULL )",
write={ write={
@ -492,6 +531,10 @@ class TestTSQL(Validator):
) )
def test_ddl(self): def test_ddl(self):
self.validate_identity(
"CREATE PROCEDURE foo AS BEGIN DELETE FROM bla WHERE foo < CURRENT_TIMESTAMP - 7 END",
"CREATE PROCEDURE foo AS BEGIN DELETE FROM bla WHERE foo < GETDATE() - 7 END",
)
self.validate_all( self.validate_all(
"CREATE TABLE tbl (id INTEGER IDENTITY PRIMARY KEY)", "CREATE TABLE tbl (id INTEGER IDENTITY PRIMARY KEY)",
read={ read={
@ -505,6 +548,9 @@ class TestTSQL(Validator):
"postgres": "CREATE TABLE tbl (id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10) PRIMARY KEY)", "postgres": "CREATE TABLE tbl (id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10) PRIMARY KEY)",
"tsql": "CREATE TABLE tbl (id INTEGER NOT NULL IDENTITY(10, 1) PRIMARY KEY)", "tsql": "CREATE TABLE tbl (id INTEGER NOT NULL IDENTITY(10, 1) PRIMARY KEY)",
}, },
write={
"databricks": "CREATE TABLE tbl (id BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 10 INCREMENT BY 1) PRIMARY KEY)",
},
) )
self.validate_all( self.validate_all(
"SELECT * INTO foo.bar.baz FROM (SELECT * FROM a.b.c) AS temp", "SELECT * INTO foo.bar.baz FROM (SELECT * FROM a.b.c) AS temp",
@ -561,22 +607,10 @@ class TestTSQL(Validator):
self.validate_all( self.validate_all(
"CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))", "CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))",
write={ write={
"spark": "CREATE TEMPORARY TABLE mytemp (a INT, b CHAR(2), c TIMESTAMP, d FLOAT)", "spark": "CREATE TEMPORARY TABLE mytemp (a INT, b CHAR(2), c TIMESTAMP, d FLOAT) USING PARQUET",
"tsql": "CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))", "tsql": "CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))",
}, },
) )
self.validate_all(
"CREATE TABLE #mytemptable (a INTEGER)",
read={
"duckdb": "CREATE TEMPORARY TABLE mytemptable (a INT)",
},
write={
"tsql": "CREATE TABLE #mytemptable (a INTEGER)",
"snowflake": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"duckdb": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"oracle": "CREATE TEMPORARY TABLE mytemptable (a NUMBER)",
},
)
def test_insert_cte(self): def test_insert_cte(self):
self.validate_all( self.validate_all(

View file

@ -771,8 +771,8 @@ ALTER TABLE integers DROP COLUMN k
ALTER TABLE integers DROP PRIMARY KEY ALTER TABLE integers DROP PRIMARY KEY
ALTER TABLE integers DROP COLUMN IF EXISTS k ALTER TABLE integers DROP COLUMN IF EXISTS k
ALTER TABLE integers DROP COLUMN k CASCADE ALTER TABLE integers DROP COLUMN k CASCADE
ALTER TABLE integers ALTER COLUMN i TYPE VARCHAR ALTER TABLE integers ALTER COLUMN i SET DATA TYPE VARCHAR
ALTER TABLE integers ALTER COLUMN i TYPE VARCHAR USING CONCAT(i, '_', j) ALTER TABLE integers ALTER COLUMN i SET DATA TYPE VARCHAR USING CONCAT(i, '_', j)
ALTER TABLE integers ALTER COLUMN i SET DEFAULT 10 ALTER TABLE integers ALTER COLUMN i SET DEFAULT 10
ALTER TABLE integers ALTER COLUMN i DROP DEFAULT ALTER TABLE integers ALTER COLUMN i DROP DEFAULT
ALTER TABLE mydataset.mytable DROP COLUMN A, DROP COLUMN IF EXISTS B ALTER TABLE mydataset.mytable DROP COLUMN A, DROP COLUMN IF EXISTS B
@ -864,3 +864,5 @@ SELECT x FROM y ORDER BY x ASC
KILL '123' KILL '123'
KILL CONNECTION 123 KILL CONNECTION 123
KILL QUERY '123' KILL QUERY '123'
CHR(97)
SELECT * FROM UNNEST(x) WITH ORDINALITY UNION ALL SELECT * FROM UNNEST(y) WITH ORDINALITY

View file

@ -29,6 +29,12 @@ SELECT "x"."a" AS "a" FROM "x" AS "x" GROUP BY "x"."a" HAVING SUM("x"."b") <> 0
SELECT a FROM x WHERE 1; SELECT a FROM x WHERE 1;
SELECT "x"."a" AS "a" FROM "x" AS "x" WHERE 1 <> 0; SELECT "x"."a" AS "a" FROM "x" AS "x" WHERE 1 <> 0;
SELECT a FROM x WHERE COALESCE(0, 1);
SELECT "x"."a" AS "a" FROM "x" AS "x" WHERE COALESCE(0 <> 0, 1 <> 0);
SELECT a FROM x WHERE CASE WHEN COALESCE(b, 1) THEN 1 ELSE 0 END;
SELECT "x"."a" AS "a" FROM "x" AS "x" WHERE CASE WHEN COALESCE("x"."b" <> 0, 1 <> 0) THEN 1 ELSE 0 END <> 0;
-------------------------------------- --------------------------------------
-- Replace date functions -- Replace date functions
-------------------------------------- --------------------------------------
@ -40,3 +46,9 @@ CAST('2023-01-01' AS TIMESTAMP);
TIMESTAMP('2023-01-01', '12:00:00'); TIMESTAMP('2023-01-01', '12:00:00');
TIMESTAMP('2023-01-01', '12:00:00'); TIMESTAMP('2023-01-01', '12:00:00');
DATE_ADD(CAST("x" AS DATE), 1, 'YEAR');
DATE_ADD(CAST("x" AS DATE), 1, 'YEAR');
DATE_ADD('2023-01-01', 1, 'YEAR');
DATE_ADD(CAST('2023-01-01' AS DATE), 1, 'YEAR');

View file

@ -62,3 +62,11 @@ SELECT a AS a FROM x UNION SELECT a AS a FROM x;
(SELECT A AS A FROM X); (SELECT A AS A FROM X);
(SELECT a AS a FROM x); (SELECT a AS a FROM x);
# dialect: snowflake
SELECT a /* sqlglot.meta case_sensitive */, b FROM table /* sqlglot.meta case_sensitive */;
SELECT a /* sqlglot.meta case_sensitive */, B FROM table /* sqlglot.meta case_sensitive */;
# dialect: redshift
SELECT COALESCE(json_val.a /* sqlglot.meta case_sensitive */, json_val.A /* sqlglot.meta case_sensitive */) FROM table;
SELECT COALESCE(json_val.a /* sqlglot.meta case_sensitive */, json_val.A /* sqlglot.meta case_sensitive */) FROM table;

View file

@ -1023,3 +1023,25 @@ SELECT
FROM "table1" AS "table1" FROM "table1" AS "table1"
LEFT JOIN "alias3" LEFT JOIN "alias3"
ON "table1"."cid" = "alias3"."cid"; ON "table1"."cid" = "alias3"."cid";
# title: CTE with EXPLODE cannot be merged
# dialect: spark
# execute: false
SELECT Name,
FruitStruct.`$id`,
FruitStruct.value
FROM
(SELECT Name,
explode(Fruits) as FruitStruct
FROM fruits_table);
WITH `_q_0` AS (
SELECT
`fruits_table`.`name` AS `name`,
EXPLODE(`fruits_table`.`fruits`) AS `fruitstruct`
FROM `fruits_table` AS `fruits_table`
)
SELECT
`_q_0`.`name` AS `name`,
`_q_0`.`fruitstruct`.`$id` AS `$id`,
`_q_0`.`fruitstruct`.`value` AS `value`
FROM `_q_0` AS `_q_0`;

View file

@ -444,6 +444,9 @@ CAST('1998-09-02 00:00:00' AS DATETIME);
CAST(x AS DATETIME) + interval '1' week; CAST(x AS DATETIME) + interval '1' week;
CAST(x AS DATETIME) + INTERVAL '1' week; CAST(x AS DATETIME) + INTERVAL '1' week;
TS_OR_DS_TO_DATE('1998-12-01 00:00:01') - interval '90' day;
CAST('1998-09-02' AS DATE);
-------------------------------------- --------------------------------------
-- Comparisons -- Comparisons
-------------------------------------- --------------------------------------
@ -681,6 +684,9 @@ CONCAT('a', x, y, 'bc');
'a' || 'b' || x; 'a' || 'b' || x;
CONCAT('ab', x); CONCAT('ab', x);
CONCAT(a, b) IN (SELECT * FROM foo WHERE cond);
CONCAT(a, b) IN (SELECT * FROM foo WHERE cond);
-------------------------------------- --------------------------------------
-- DATE_TRUNC -- DATE_TRUNC
-------------------------------------- --------------------------------------
@ -740,6 +746,9 @@ x >= CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) > CAST('2021-01-02' AS DATE); DATE_TRUNC('year', x) > CAST('2021-01-02' AS DATE);
x >= CAST('2022-01-01' AS DATE); x >= CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) > TS_OR_DS_TO_DATE(TS_OR_DS_TO_DATE('2021-01-02'));
x >= CAST('2022-01-01' AS DATE);
-- right is not a date -- right is not a date
DATE_TRUNC('year', x) <> '2021-01-02'; DATE_TRUNC('year', x) <> '2021-01-02';
DATE_TRUNC('year', x) <> '2021-01-02'; DATE_TRUNC('year', x) <> '2021-01-02';
@ -758,6 +767,17 @@ x < CAST('2022-01-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
TIMESTAMP_TRUNC(x, YEAR) = CAST('2021-01-01' AS DATETIME); TIMESTAMP_TRUNC(x, YEAR) = CAST('2021-01-01' AS DATETIME);
x < CAST('2022-01-01 00:00:00' AS DATETIME) AND x >= CAST('2021-01-01 00:00:00' AS DATETIME); x < CAST('2022-01-01 00:00:00' AS DATETIME) AND x >= CAST('2021-01-01 00:00:00' AS DATETIME);
-- right side is not a date literal
DATE_TRUNC('day', x) = CAST(y AS DATE);
DATE_TRUNC('day', x) = CAST(y AS DATE);
-- nested cast
DATE_TRUNC('day', x) = CAST(CAST('2021-01-01 01:02:03' AS DATETIME) AS DATE);
x < CAST('2021-01-02' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
TIMESTAMP_TRUNC(x, YEAR) = CAST(CAST('2021-01-01 01:02:03' AS DATE) AS DATETIME);
x < CAST('2022-01-01 00:00:00' AS DATETIME) AND x >= CAST('2021-01-01 00:00:00' AS DATETIME);
-------------------------------------- --------------------------------------
-- EQUALITY -- EQUALITY
-------------------------------------- --------------------------------------
@ -794,6 +814,9 @@ x = 2;
x - INTERVAL 1 DAY = CAST('2021-01-01' AS DATE); x - INTERVAL 1 DAY = CAST('2021-01-01' AS DATE);
x = CAST('2021-01-02' AS DATE); x = CAST('2021-01-02' AS DATE);
x - INTERVAL 1 DAY = TS_OR_DS_TO_DATE('2021-01-01 00:00:01');
x = CAST('2021-01-02' AS DATE);
x - INTERVAL 1 HOUR > CAST('2021-01-01' AS DATETIME); x - INTERVAL 1 HOUR > CAST('2021-01-01' AS DATETIME);
x > CAST('2021-01-01 01:00:00' AS DATETIME); x > CAST('2021-01-01 01:00:00' AS DATETIME);

View file

@ -4793,10 +4793,10 @@ WITH "foo" AS (
"foo"."i_item_sk" AS "i_item_sk", "foo"."i_item_sk" AS "i_item_sk",
"foo"."d_moy" AS "d_moy", "foo"."d_moy" AS "d_moy",
"foo"."mean" AS "mean", "foo"."mean" AS "mean",
CASE "foo"."mean" WHEN 0 THEN NULL ELSE "foo"."stdev" / "foo"."mean" END AS "cov" CASE "foo"."mean" WHEN FALSE THEN NULL ELSE "foo"."stdev" / "foo"."mean" END AS "cov"
FROM "foo" AS "foo" FROM "foo" AS "foo"
WHERE WHERE
CASE "foo"."mean" WHEN 0 THEN 0 ELSE "foo"."stdev" / "foo"."mean" END > 1 CASE "foo"."mean" WHEN FALSE THEN 0 ELSE "foo"."stdev" / "foo"."mean" END > 1
) )
SELECT SELECT
"inv1"."w_warehouse_sk" AS "w_warehouse_sk", "inv1"."w_warehouse_sk" AS "w_warehouse_sk",
@ -9775,7 +9775,7 @@ JOIN "date_dim" AS "d1"
ON "catalog_sales"."cs_sold_date_sk" = "d1"."d_date_sk" ON "catalog_sales"."cs_sold_date_sk" = "d1"."d_date_sk"
AND "d1"."d_week_seq" = "d2"."d_week_seq" AND "d1"."d_week_seq" = "d2"."d_week_seq"
AND "d1"."d_year" = 2002 AND "d1"."d_year" = 2002
AND "d3"."d_date" > CONCAT("d1"."d_date", INTERVAL '5' day) AND "d3"."d_date" > "d1"."d_date" + INTERVAL '5' day
GROUP BY GROUP BY
"item"."i_item_desc", "item"."i_item_desc",
"warehouse"."w_warehouse_name", "warehouse"."w_warehouse_name",

View file

@ -624,6 +624,8 @@ class TestExecutor(unittest.TestCase):
("LEFT('12345', 3)", "123"), ("LEFT('12345', 3)", "123"),
("RIGHT('12345', 3)", "345"), ("RIGHT('12345', 3)", "345"),
("DATEDIFF('2022-01-03'::date, '2022-01-01'::TIMESTAMP::DATE)", 2), ("DATEDIFF('2022-01-03'::date, '2022-01-01'::TIMESTAMP::DATE)", 2),
("TRIM(' foo ')", "foo"),
("TRIM('afoob', 'ab')", "foo"),
]: ]:
with self.subTest(sql): with self.subTest(sql):
result = execute(f"SELECT {sql}") result = execute(f"SELECT {sql}")

View file

@ -182,16 +182,21 @@ class TestExpressions(unittest.TestCase):
self.assertEqual(parse_one("a.b.c").name, "c") self.assertEqual(parse_one("a.b.c").name, "c")
def test_table_name(self): def test_table_name(self):
bq_dashed_table = exp.to_table("a-1.b.c", dialect="bigquery")
self.assertEqual(exp.table_name(bq_dashed_table), '"a-1".b.c')
self.assertEqual(exp.table_name(bq_dashed_table, dialect="bigquery"), "`a-1`.b.c")
self.assertEqual(exp.table_name("a-1.b.c", dialect="bigquery"), "`a-1`.b.c")
self.assertEqual(exp.table_name(parse_one("a", into=exp.Table)), "a") self.assertEqual(exp.table_name(parse_one("a", into=exp.Table)), "a")
self.assertEqual(exp.table_name(parse_one("a.b", into=exp.Table)), "a.b") self.assertEqual(exp.table_name(parse_one("a.b", into=exp.Table)), "a.b")
self.assertEqual(exp.table_name(parse_one("a.b.c", into=exp.Table)), "a.b.c") self.assertEqual(exp.table_name(parse_one("a.b.c", into=exp.Table)), "a.b.c")
self.assertEqual(exp.table_name("a.b.c"), "a.b.c") self.assertEqual(exp.table_name("a.b.c"), "a.b.c")
self.assertEqual(exp.table_name(exp.to_table("a.b.c.d.e", dialect="bigquery")), "a.b.c.d.e")
self.assertEqual(exp.table_name(exp.to_table("'@foo'", dialect="snowflake")), "'@foo'")
self.assertEqual(exp.table_name(exp.to_table("@foo", dialect="snowflake")), "@foo")
self.assertEqual( self.assertEqual(
exp.table_name(parse_one("foo.`{bar,er}`", read="databricks"), dialect="databricks"), exp.table_name(parse_one("foo.`{bar,er}`", read="databricks"), dialect="databricks"),
"foo.`{bar,er}`", "foo.`{bar,er}`",
) )
self.assertEqual(exp.table_name(exp.to_table("a-1.b.c", dialect="bigquery")), '"a-1".b.c')
self.assertEqual(exp.table_name(exp.to_table("a.b.c.d.e", dialect="bigquery")), "a.b.c.d.e")
def test_table(self): def test_table(self):
self.assertEqual(exp.table_("a", alias="b"), parse_one("select * from a b").find(exp.Table)) self.assertEqual(exp.table_("a", alias="b"), parse_one("select * from a b").find(exp.Table))
@ -946,3 +951,8 @@ FROM foo""",
with self.assertRaises(ParseError): with self.assertRaises(ParseError):
exp.DataType.build("foo") exp.DataType.build("foo")
def test_set_meta(self):
query = parse_one("SELECT * FROM foo /* sqlglot.meta x = 1, y = a, z */")
self.assertEqual(query.find(exp.Table).meta, {"x": "1", "y": "a", "z": True})
self.assertEqual(query.sql(), "SELECT * FROM foo /* sqlglot.meta x = 1, y = a, z */")

View file

@ -546,6 +546,53 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
self.assertEqual(expression.right.this.left.type.this, exp.DataType.Type.INT) self.assertEqual(expression.right.this.left.type.this, exp.DataType.Type.INT)
self.assertEqual(expression.right.this.right.type.this, exp.DataType.Type.INT) self.assertEqual(expression.right.this.right.type.this, exp.DataType.Type.INT)
def test_interval_math_annotation(self):
schema = {
"x": {
"a": "DATE",
"b": "DATETIME",
}
}
for sql, expected_type, *expected_sql in [
(
"SELECT '2023-01-01' + INTERVAL '1' DAY",
exp.DataType.Type.DATE,
"SELECT CAST('2023-01-01' AS DATE) + INTERVAL '1' DAY",
),
(
"SELECT '2023-01-01' + INTERVAL '1' HOUR",
exp.DataType.Type.DATETIME,
"SELECT CAST('2023-01-01' AS DATETIME) + INTERVAL '1' HOUR",
),
(
"SELECT '2023-01-01 00:00:01' + INTERVAL '1' HOUR",
exp.DataType.Type.DATETIME,
"SELECT CAST('2023-01-01 00:00:01' AS DATETIME) + INTERVAL '1' HOUR",
),
("SELECT 'nonsense' + INTERVAL '1' DAY", exp.DataType.Type.UNKNOWN),
("SELECT x.a + INTERVAL '1' DAY FROM x AS x", exp.DataType.Type.DATE),
("SELECT x.a + INTERVAL '1' HOUR FROM x AS x", exp.DataType.Type.DATETIME),
("SELECT x.b + INTERVAL '1' DAY FROM x AS x", exp.DataType.Type.DATETIME),
("SELECT x.b + INTERVAL '1' HOUR FROM x AS x", exp.DataType.Type.DATETIME),
(
"SELECT DATE_ADD('2023-01-01', 1, 'DAY')",
exp.DataType.Type.DATE,
"SELECT DATE_ADD(CAST('2023-01-01' AS DATE), 1, 'DAY')",
),
(
"SELECT DATE_ADD('2023-01-01 00:00:00', 1, 'DAY')",
exp.DataType.Type.DATETIME,
"SELECT DATE_ADD(CAST('2023-01-01 00:00:00' AS DATETIME), 1, 'DAY')",
),
("SELECT DATE_ADD(x.a, 1, 'DAY') FROM x AS x", exp.DataType.Type.DATE),
("SELECT DATE_ADD(x.a, 1, 'HOUR') FROM x AS x", exp.DataType.Type.DATETIME),
("SELECT DATE_ADD(x.b, 1, 'DAY') FROM x AS x", exp.DataType.Type.DATETIME),
]:
with self.subTest(sql):
expression = annotate_types(parse_one(sql), schema=schema)
self.assertEqual(expected_type, expression.expressions[0].type.this)
self.assertEqual(expected_sql[0] if expected_sql else sql, expression.sql())
def test_lateral_annotation(self): def test_lateral_annotation(self):
expression = optimizer.optimize( expression = optimizer.optimize(
parse_one("SELECT c FROM (select 1 a) as x LATERAL VIEW EXPLODE (a) AS c") parse_one("SELECT c FROM (select 1 a) as x LATERAL VIEW EXPLODE (a) AS c")

View file

@ -690,6 +690,31 @@ class TestParser(unittest.TestCase):
LEFT JOIN b ON a.id = b.id LEFT JOIN b ON a.id = b.id
""" """
) )
self.assertIsNotNone(query)
query = parse_one(
"""
SELECT *
FROM a
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
LEFT JOIN UNNEST(ARRAY[])
"""
)
self.assertIsNotNone(query) self.assertIsNotNone(query)
self.assertLessEqual(time.time() - now, 0.2) self.assertLessEqual(time.time() - now, 0.2)

View file

@ -156,9 +156,7 @@ SELECT * FROM foo
-- comment 2 -- comment 2
-- comment 3 -- comment 3
SELECT * FROM foo""", SELECT * FROM foo""",
"""/* comment 1 */ """/* comment 1 */ /* comment 2 */ /* comment 3 */
/* comment 2 */
/* comment 3 */
SELECT SELECT
* *
FROM foo""", FROM foo""",
@ -182,8 +180,7 @@ line3*/ /*another comment*/ where 1=1 -- comment at the end""",
* *
FROM tbl /* line1 FROM tbl /* line1
line2 line2
line3 */ line3 */ /* another comment */
/* another comment */
WHERE WHERE
1 = 1 /* comment at the end */""", 1 = 1 /* comment at the end */""",
pretty=True, pretty=True,
@ -310,9 +307,7 @@ FROM v""",
-- comment3 -- comment3
DROP TABLE IF EXISTS db.tba DROP TABLE IF EXISTS db.tba
""", """,
"""/* comment1 */ """/* comment1 */ /* comment2 */ /* comment3 */
/* comment2 */
/* comment3 */
DROP TABLE IF EXISTS db.tba""", DROP TABLE IF EXISTS db.tba""",
pretty=True, pretty=True,
) )
@ -337,9 +332,7 @@ SELECT
c c
FROM tb_01 FROM tb_01
WHERE WHERE
a /* comment5 */ = 1 AND b = 2 /* comment6 */ a /* comment5 */ = 1 AND b = 2 /* comment6 */ /* and c = 1 */ /* comment7 */""",
/* and c = 1 */
/* comment7 */""",
pretty=True, pretty=True,
) )
self.validate( self.validate(
@ -375,11 +368,17 @@ INNER JOIN b""",
"""SELECT """SELECT
* *
FROM a FROM a
/* comment 1 */ /* comment 1 */ /* comment 2 */
/* comment 2 */
LEFT OUTER JOIN b""", LEFT OUTER JOIN b""",
pretty=True, pretty=True,
) )
self.validate(
"SELECT\n a /* sqlglot.meta case_sensitive */ -- noqa\nFROM tbl",
"""SELECT
a /* sqlglot.meta case_sensitive */ /* noqa */
FROM tbl""",
pretty=True,
)
def test_types(self): def test_types(self):
self.validate("INT 1", "CAST(1 AS INT)") self.validate("INT 1", "CAST(1 AS INT)")
@ -468,12 +467,12 @@ LEFT OUTER JOIN b""",
"ALTER TABLE integers ADD COLUMN k INT", "ALTER TABLE integers ADD COLUMN k INT",
) )
self.validate( self.validate(
"ALTER TABLE integers ALTER i SET DATA TYPE VARCHAR", "ALTER TABLE integers ALTER i TYPE VARCHAR",
"ALTER TABLE integers ALTER COLUMN i TYPE VARCHAR", "ALTER TABLE integers ALTER COLUMN i SET DATA TYPE VARCHAR",
) )
self.validate( self.validate(
"ALTER TABLE integers ALTER i TYPE VARCHAR COLLATE foo USING bar", "ALTER TABLE integers ALTER i TYPE VARCHAR COLLATE foo USING bar",
"ALTER TABLE integers ALTER COLUMN i TYPE VARCHAR COLLATE foo USING bar", "ALTER TABLE integers ALTER COLUMN i SET DATA TYPE VARCHAR COLLATE foo USING bar",
) )
def test_time(self): def test_time(self):
@ -604,7 +603,7 @@ LEFT OUTER JOIN b""",
self.validate( self.validate(
"CREATE TEMPORARY TABLE test AS SELECT 1", "CREATE TEMPORARY TABLE test AS SELECT 1",
"CREATE TEMPORARY VIEW test AS SELECT 1", "CREATE TEMPORARY VIEW test AS SELECT 1",
write="spark", write="spark2",
) )
@mock.patch("sqlglot.helper.logger") @mock.patch("sqlglot.helper.logger")