1
0
Fork 0

Adding upstream version 18.7.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:03:05 +01:00
parent c4fc25c23b
commit be16920347
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
96 changed files with 59037 additions and 52828 deletions

View file

@ -1,6 +1,100 @@
Changelog
=========
## [v18.6.0] - 2023-09-21
### :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))*:
explode to unnest with multiple explosions (#2235)
- due to [`ff19f4c`](https://github.com/tobymao/sqlglot/commit/ff19f4c4e1d735710bb945ced6d6c15af186c058) - don't parse SEMI, ANTI as table aliases, fix join side issue *(PR [#2247](https://github.com/tobymao/sqlglot/pull/2247) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
don't parse SEMI, ANTI as table aliases, fix join side issue (#2247)
- due to [`8ebbfe2`](https://github.com/tobymao/sqlglot/commit/8ebbfe214dbdff967bd0923b215dcd73ddca6bb1) - store expressions in Limit.expression when using builder *(PR [#2249](https://github.com/tobymao/sqlglot/pull/2249) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
store expressions in Limit.expression when using builder (#2249)
- due to [`4badd91`](https://github.com/tobymao/sqlglot/commit/4badd91549e172890653fdd54f96a7e878bf23c9) - preserve ascending order of sorting when present *(PR [#2256](https://github.com/tobymao/sqlglot/pull/2256) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
preserve ascending order of sorting when present (#2256)
- due to [`e90312a`](https://github.com/tobymao/sqlglot/commit/e90312a81f929dfd6af1fb6799cd77e0bf58ea47) - improve transpilation of T-SQL's SET assignment command *(PR [#2275](https://github.com/tobymao/sqlglot/pull/2275) by [@GeorgeSittas](https://github.com/GeorgeSittas))*:
improve transpilation of T-SQL's SET assignment command (#2275)
### :sparkles: New Features
- [`f63a06b`](https://github.com/tobymao/sqlglot/commit/f63a06b5b743db58ea62769e3ba605e44ab7f60a) - eliminate semi/anti joins transformation *(PR [#2242](https://github.com/tobymao/sqlglot/pull/2242) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2240](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`d1cfa01`](https://github.com/tobymao/sqlglot/commit/d1cfa01e999e494faea948c8959471deae6e4a2a) - **optimizer**: simplify date_trunc *(PR [#2271](https://github.com/tobymao/sqlglot/pull/2271) by [@barakalon](https://github.com/barakalon))*
- [`e90312a`](https://github.com/tobymao/sqlglot/commit/e90312a81f929dfd6af1fb6799cd77e0bf58ea47) - improve transpilation of T-SQL's SET assignment command *(PR [#2275](https://github.com/tobymao/sqlglot/pull/2275) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`69a2c67`](https://github.com/tobymao/sqlglot/commit/69a2c67f7713586a831cf1db236b555abe54b12f) - **optimizer**: simplify_equality *(PR [#2281](https://github.com/tobymao/sqlglot/pull/2281) by [@barakalon](https://github.com/barakalon))*
- [`ef062d1`](https://github.com/tobymao/sqlglot/commit/ef062d10c2f42d17ede45927bebc643c90f3eb79) - kill *(PR [#2285](https://github.com/tobymao/sqlglot/pull/2285) by [@barakalon](https://github.com/barakalon))*
### :bug: Bug Fixes
- [`66aadfc`](https://github.com/tobymao/sqlglot/commit/66aadfc60b9bffe914b89043b293a3e7357d5dde) - unescape escape sequences *(PR [#2230](https://github.com/tobymao/sqlglot/pull/2230) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2225](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`cd30eb7`](https://github.com/tobymao/sqlglot/commit/cd30eb765a4b733c1b12148609eb3bafa4983eab) - **tsql**: include catalog and db in create if not exists *(PR [#2231](https://github.com/tobymao/sqlglot/pull/2231) by [@treysp](https://github.com/treysp))*
- [`c2238a5`](https://github.com/tobymao/sqlglot/commit/c2238a5d551b8054f183a310b41cf1908bad1323) - **snowflake**: transpile SELECT UNNEST(x) to TABLE(FLATTEN(..)) *(PR [#2232](https://github.com/tobymao/sqlglot/pull/2232) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2228](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`8509d52`](https://github.com/tobymao/sqlglot/commit/8509d52a763169c4ff9529b58ed0ed04499984b5) - don't unnest subqueries when the parent select doesn't have a from since the subquery can't be joined *(PR [#2233](https://github.com/tobymao/sqlglot/pull/2233) by [@ginter](https://github.com/ginter))*
- [`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))*
- :arrow_lower_right: *fixes issue [#2227](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`1992ab9`](https://github.com/tobymao/sqlglot/commit/1992ab98347a1b3e9fdfbbe2657e6c7a29467685) - transpile bool xor closes [#2238](https://github.com/tobymao/sqlglot/pull/2238) *(commit by [@tobymao](https://github.com/tobymao))*
- [`12de208`](https://github.com/tobymao/sqlglot/commit/12de208ff99671df7f2cd18b8d9952fb3072336d) - **snowflake**: use IF instead of FILTER(WHERE cond) for conditional aggregation *(PR [#2241](https://github.com/tobymao/sqlglot/pull/2241) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2239](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`94d56be`](https://github.com/tobymao/sqlglot/commit/94d56bee6532a5713c89a147eb428837c1efe024) - **bigquery**: regex with raw strings compile closes [#2236](https://github.com/tobymao/sqlglot/pull/2236) *(commit by [@tobymao](https://github.com/tobymao))*
- [`ff19f4c`](https://github.com/tobymao/sqlglot/commit/ff19f4c4e1d735710bb945ced6d6c15af186c058) - don't parse SEMI, ANTI as table aliases, fix join side issue *(PR [#2247](https://github.com/tobymao/sqlglot/pull/2247) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2244](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`8ebbfe2`](https://github.com/tobymao/sqlglot/commit/8ebbfe214dbdff967bd0923b215dcd73ddca6bb1) - store expressions in Limit.expression when using builder *(PR [#2249](https://github.com/tobymao/sqlglot/pull/2249) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2248](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`829415c`](https://github.com/tobymao/sqlglot/commit/829415c3a9295cf281aad255c614b3b344cab8eb) - **snowflake**: rename GenerateSeries, include offset in unnest_sql *(PR [#2243](https://github.com/tobymao/sqlglot/pull/2243) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`ba013d6`](https://github.com/tobymao/sqlglot/commit/ba013d6ad795bf7455b523d765cf573e670aa2e6) - **presto**: treat struct with key-value definition as unsupported *(PR [#2245](https://github.com/tobymao/sqlglot/pull/2245) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2229](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`ab7effe`](https://github.com/tobymao/sqlglot/commit/ab7effe6186a756991cbd3f95e1a87b088978a39) - **parser**: check for column operators after having parsed brackets *(PR [#2251](https://github.com/tobymao/sqlglot/pull/2251) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2250](undefined) opened by [@wezham](https://github.com/wezham)*
- [`3b654f2`](https://github.com/tobymao/sqlglot/commit/3b654f24f91f47b424e14f48a45286b514dec30c) - **dataframe**: ensure Column.alias preserves quotes *(PR [#2254](https://github.com/tobymao/sqlglot/pull/2254) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`f76ebb2`](https://github.com/tobymao/sqlglot/commit/f76ebb257bd1938326a5c6c845fb93388179b423) - **tsql**: generate SELECT INTO from CTAS *(PR [#2237](https://github.com/tobymao/sqlglot/pull/2237) by [@treysp](https://github.com/treysp))*
- [`4badd91`](https://github.com/tobymao/sqlglot/commit/4badd91549e172890653fdd54f96a7e878bf23c9) - preserve ascending order of sorting when present *(PR [#2256](https://github.com/tobymao/sqlglot/pull/2256) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2253](undefined) opened by [@cpcloud](https://github.com/cpcloud)*
- [`86538ba`](https://github.com/tobymao/sqlglot/commit/86538bae5304c6c78254e36f6226734d42ab190b) - **bigquery**: reduce the scope where UNKNOWN is treated as NULL *(PR [#2260](https://github.com/tobymao/sqlglot/pull/2260) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2258](undefined) opened by [@middagj](https://github.com/middagj)*
- [`12c83b6`](https://github.com/tobymao/sqlglot/commit/12c83b69828af32ade4cb546042b0ea1b267d154) - **hive**: get rid of any ASC in a ClusteredColumnConstraint *(PR [#2261](https://github.com/tobymao/sqlglot/pull/2261) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`35927a2`](https://github.com/tobymao/sqlglot/commit/35927a2c8df0a9644556e47d3173b3629e8f0c08) - **tsql**: correctly escape single quotes in EXEC *(PR [#2263](https://github.com/tobymao/sqlglot/pull/2263) by [@treysp](https://github.com/treysp))*
- [`61f85a4`](https://github.com/tobymao/sqlglot/commit/61f85a4862240fdcdd4faf4847c14a755151091d) - **postgres**: parse RESTRICT constraint action *(PR [#2267](https://github.com/tobymao/sqlglot/pull/2267) by [@Nitrino](https://github.com/Nitrino))*
- [`d5b229a`](https://github.com/tobymao/sqlglot/commit/d5b229a65030c5b75ba30e795f63f8615a473be6) - **snowflake**: implement correct semantics of EXCEPT, RENAME *(PR [#2268](https://github.com/tobymao/sqlglot/pull/2268) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2265](undefined) opened by [@diogo-fernan](https://github.com/diogo-fernan)*
- [`ccff88c`](https://github.com/tobymao/sqlglot/commit/ccff88c5eea32d9a940dcfe79a721d331bd8c697) - **postgres**: add support for WHERE clause in CREATE INDEX *(PR [#2269](https://github.com/tobymao/sqlglot/pull/2269) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2266](undefined) opened by [@Nitrino](https://github.com/Nitrino)*
- [`ed8714f`](https://github.com/tobymao/sqlglot/commit/ed8714f1e2f2ab1052a9cbf3fe34b4ab3e937ee5) - **bigquery**: allow overlaps to be used as an identifier *(PR [#2273](https://github.com/tobymao/sqlglot/pull/2273) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *fixes issue [#2272](undefined) opened by [@turntable-justin](https://github.com/turntable-justin)*
- [`76b7077`](https://github.com/tobymao/sqlglot/commit/76b707727f374c8d94395674fcf0b50acdb2e5cf) - ensure Expression is not an iterable to avoid inf. loops *(PR [#2280](https://github.com/tobymao/sqlglot/pull/2280) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`6475b84`](https://github.com/tobymao/sqlglot/commit/6475b84d084783912ea00c8d634f3c5bc456c4c4) - remove copy *(PR [#2282](https://github.com/tobymao/sqlglot/pull/2282) by [@barakalon](https://github.com/barakalon))*
- [`310d691`](https://github.com/tobymao/sqlglot/commit/310d691d836637c48d4a7fb281a5eddab5926c2c) - improve performance of VALUES -> UNION ALL transpilation *(PR [#2283](https://github.com/tobymao/sqlglot/pull/2283) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
### :wrench: Chores
- [`0e996f5`](https://github.com/tobymao/sqlglot/commit/0e996f55591be016eb21ae8838be7d6543d698eb) - cleanup *(commit by [@tobymao](https://github.com/tobymao))*
- [`bca7570`](https://github.com/tobymao/sqlglot/commit/bca757031e801d94c90a3c7c45b4a0b9e644bba0) - cleanup pop *(commit by [@tobymao](https://github.com/tobymao))*
## [v18.5.1] - 2023-09-15
### :sparkles: New Features
- [`0378325`](https://github.com/tobymao/sqlglot/commit/03783258d5229f338568cd838d8a454e698274c5) - improve support for percentiles in duckdb, postgres *(PR [#2219](https://github.com/tobymao/sqlglot/pull/2219) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`b59ef0f`](https://github.com/tobymao/sqlglot/commit/b59ef0f6abbe90310b56a4cea72f0850c22e1086) - add support for scoped user-defined types *(PR [#2226](https://github.com/tobymao/sqlglot/pull/2226) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- :arrow_lower_right: *addresses issue [#2217](undefined) opened by [@sashindeitidata](https://github.com/sashindeitidata)*
### :bug: Bug Fixes
- [`b3c97de`](https://github.com/tobymao/sqlglot/commit/b3c97decb98ca237e3ccac87e053e2a25419522c) - **mysql**: timestamp add/sub closes [#2214](https://github.com/tobymao/sqlglot/pull/2214) *(commit by [@tobymao](https://github.com/tobymao))*
- [`4634220`](https://github.com/tobymao/sqlglot/commit/46342204037afb91f3c865b367d70fe4f8116584) - use parse primary in the sample parser to handle nums like .25 *(commit by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`fd1ed25`](https://github.com/tobymao/sqlglot/commit/fd1ed25210340bce4292a1ff698b26198ff8bf57) - **oracle**: add support for locking reads fixes [#2216](https://github.com/tobymao/sqlglot/pull/2216) *(commit by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`5ec8e1f`](https://github.com/tobymao/sqlglot/commit/5ec8e1f58b3e5fa62682529d0b0bf5a507659878) - normalize before qualifying tables *(commit by [@tobymao](https://github.com/tobymao))*
- [`da398f4`](https://github.com/tobymao/sqlglot/commit/da398f49b276eb0598d85e8cec5f17aca2a41361) - parse and generate JSON <literal> correctly *(PR [#2220](https://github.com/tobymao/sqlglot/pull/2220) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
- [`6bc8e13`](https://github.com/tobymao/sqlglot/commit/6bc8e132b2f067577702c26299eafae5fa45f2f9) - **mysql**: transpile ISNULL to IS NULL *(PR [#2221](https://github.com/tobymao/sqlglot/pull/2221) by [@barakalon](https://github.com/barakalon))*
- [`2fa4043`](https://github.com/tobymao/sqlglot/commit/2fa40435d0d87ed02ee9556575909ea28e550868) - **mysql**: transpile MONTHNAME *(PR [#2222](https://github.com/tobymao/sqlglot/pull/2222) by [@barakalon](https://github.com/barakalon))*
- [`857e380`](https://github.com/tobymao/sqlglot/commit/857e38075945ee0057fdfb4140d9636c0400c587) - **mysql**: TIMESTAMP -> CAST *(PR [#2223](https://github.com/tobymao/sqlglot/pull/2223) by [@barakalon](https://github.com/barakalon))*
## [v18.5.0] - 2023-09-13
### :sparkles: New Features
- [`72e939e`](https://github.com/tobymao/sqlglot/commit/72e939e901eb0b2adde6f66ebe31bb8c498f70c6) - **parser**: allow functions in FETCH clause *(PR [#2207](https://github.com/tobymao/sqlglot/pull/2207) by [@GeorgeSittas](https://github.com/GeorgeSittas))*
@ -1402,3 +1496,5 @@ Changelog
[v18.4.0]: https://github.com/tobymao/sqlglot/compare/v18.3.0...v18.4.0
[v18.4.1]: https://github.com/tobymao/sqlglot/compare/v18.4.0...v18.4.1
[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.6.0]: https://github.com/tobymao/sqlglot/compare/v18.5.1...v18.6.0

File diff suppressed because one or more lines are too long

View file

@ -53,14 +53,19 @@
<label class="view-source-button" for="mod-_typing-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="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos">2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos">3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos">4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos">5</span></a><span class="kn">import</span> <span class="nn">sqlglot</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos">6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos">7</span></a><span class="n">E</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;E&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">&quot;sqlglot.exp.Expression&quot;</span><span class="p">)</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos">8</span></a><span class="n">T</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;T&quot;</span><span class="p">)</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="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">import</span> <span class="nn">sqlglot</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="c1"># A little hack for backwards compatibility with Python 3.7.</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="c1"># For example, we might want a TypeVar for objects that support comparison e.g. SupportsRichComparisonT from typeshed.</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="c1"># But Python 3.7 doesn&#39;t support Protocols, so we&#39;d also need typing_extensions, which we don&#39;t want as a dependency.</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a><span class="n">A</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;A&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">E</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;E&quot;</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">&quot;sqlglot.exp.Expression&quot;</span><span class="p">)</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">T</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">TypeVar</span><span class="p">(</span><span class="s2">&quot;T&quot;</span><span class="p">)</span>
</span></pre></div>

View file

@ -51,8 +51,8 @@
<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-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.5.0&#39;</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">5</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</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-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></pre></div>

View file

@ -777,7 +777,7 @@
<div class="attr function">
<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;139837312855216&#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;139837312855216&#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;139837314723616&#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;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>
<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">
<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;139837317713728&#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;139837317947568&#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;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>
<label class="view-source-button" for="DataFrame.__init__-view-source"><span>View Source</span></label>
@ -2018,7 +2018,7 @@
<div class="attr function">
<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;139837313594752&#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;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>
<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>
<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;139837311755664&#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;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>
<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>
<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;139837311922624&#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;139837311922624&#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;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>
<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>
<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;139837312058512&#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;139837312187264&#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;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>
<label class="view-source-button" for="DataFrame.repartition-view-source"><span>View Source</span></label>
@ -3630,124 +3630,132 @@ and check if it matches the type of the value provided. If not then make it null
</span><span id="Column-213"><a href="#Column-213"><span class="linenos">213</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">sql</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s2">&quot;dialect&quot;</span><span class="p">:</span> <span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">})</span>
</span><span id="Column-214"><a href="#Column-214"><span class="linenos">214</span></a>
</span><span id="Column-215"><a href="#Column-215"><span class="linenos">215</span></a> <span class="k">def</span> <span class="nf">alias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-216"><a href="#Column-216"><span class="linenos">216</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="Column-217"><a href="#Column-217"><span class="linenos">217</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-218"><a href="#Column-218"><span class="linenos">218</span></a>
</span><span id="Column-219"><a href="#Column-219"><span class="linenos">219</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-220"><a href="#Column-220"><span class="linenos">220</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column-221"><a href="#Column-221"><span class="linenos">221</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-222"><a href="#Column-222"><span class="linenos">222</span></a>
</span><span id="Column-223"><a href="#Column-223"><span class="linenos">223</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-224"><a href="#Column-224"><span class="linenos">224</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column-216"><a href="#Column-216"><span class="linenos">216</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column-217"><a href="#Column-217"><span class="linenos">217</span></a>
</span><span id="Column-218"><a href="#Column-218"><span class="linenos">218</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span>
</span><span id="Column-219"><a href="#Column-219"><span class="linenos">219</span></a> <span class="n">alias</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span> <span class="o">=</span> <span class="n">sqlglot</span><span class="o">.</span><span class="n">maybe_parse</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Column-220"><a href="#Column-220"><span class="linenos">220</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span>
</span><span id="Column-221"><a href="#Column-221"><span class="linenos">221</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column-222"><a href="#Column-222"><span class="linenos">222</span></a> <span class="n">alias</span><span class="o">.</span><span class="n">this</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">alias</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="k">else</span> <span class="n">name</span><span class="p">,</span>
</span><span id="Column-223"><a href="#Column-223"><span class="linenos">223</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="Column-224"><a href="#Column-224"><span class="linenos">224</span></a> <span class="p">)</span>
</span><span id="Column-225"><a href="#Column-225"><span class="linenos">225</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-226"><a href="#Column-226"><span class="linenos">226</span></a>
</span><span id="Column-227"><a href="#Column-227"><span class="linenos">227</span></a> <span class="n">asc_nulls_first</span> <span class="o">=</span> <span class="n">asc</span>
</span><span id="Column-228"><a href="#Column-228"><span class="linenos">228</span></a>
</span><span id="Column-229"><a href="#Column-229"><span class="linenos">229</span></a> <span class="k">def</span> <span class="nf">asc_nulls_last</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-230"><a href="#Column-230"><span class="linenos">230</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column-231"><a href="#Column-231"><span class="linenos">231</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-232"><a href="#Column-232"><span class="linenos">232</span></a>
</span><span id="Column-233"><a href="#Column-233"><span class="linenos">233</span></a> <span class="k">def</span> <span class="nf">desc_nulls_first</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-234"><a href="#Column-234"><span class="linenos">234</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column-235"><a href="#Column-235"><span class="linenos">235</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-227"><a href="#Column-227"><span class="linenos">227</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-228"><a href="#Column-228"><span class="linenos">228</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column-229"><a href="#Column-229"><span class="linenos">229</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-230"><a href="#Column-230"><span class="linenos">230</span></a>
</span><span id="Column-231"><a href="#Column-231"><span class="linenos">231</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-232"><a href="#Column-232"><span class="linenos">232</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column-233"><a href="#Column-233"><span class="linenos">233</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-234"><a href="#Column-234"><span class="linenos">234</span></a>
</span><span id="Column-235"><a href="#Column-235"><span class="linenos">235</span></a> <span class="n">asc_nulls_first</span> <span class="o">=</span> <span class="n">asc</span>
</span><span id="Column-236"><a href="#Column-236"><span class="linenos">236</span></a>
</span><span id="Column-237"><a href="#Column-237"><span class="linenos">237</span></a> <span class="n">desc_nulls_last</span> <span class="o">=</span> <span class="n">desc</span>
</span><span id="Column-238"><a href="#Column-238"><span class="linenos">238</span></a>
</span><span id="Column-239"><a href="#Column-239"><span class="linenos">239</span></a> <span class="k">def</span> <span class="nf">when</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">condition</span><span class="p">:</span> <span class="n">Column</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-240"><a href="#Column-240"><span class="linenos">240</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">when</span>
</span><span id="Column-241"><a href="#Column-241"><span class="linenos">241</span></a>
</span><span id="Column-242"><a href="#Column-242"><span class="linenos">242</span></a> <span class="n">column_with_if</span> <span class="o">=</span> <span class="n">when</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-243"><a href="#Column-243"><span class="linenos">243</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</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">Case</span><span class="p">):</span>
</span><span id="Column-244"><a href="#Column-244"><span class="linenos">244</span></a> <span class="k">return</span> <span class="n">column_with_if</span>
</span><span id="Column-245"><a href="#Column-245"><span class="linenos">245</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column-246"><a href="#Column-246"><span class="linenos">246</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">column_with_if</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">])</span>
</span><span id="Column-247"><a href="#Column-247"><span class="linenos">247</span></a> <span class="k">return</span> <span class="n">new_column</span>
</span><span id="Column-248"><a href="#Column-248"><span class="linenos">248</span></a>
</span><span id="Column-249"><a href="#Column-249"><span class="linenos">249</span></a> <span class="k">def</span> <span class="nf">otherwise</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-250"><a href="#Column-250"><span class="linenos">250</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">lit</span>
</span><span id="Column-251"><a href="#Column-251"><span class="linenos">251</span></a>
</span><span id="Column-252"><a href="#Column-252"><span class="linenos">252</span></a> <span class="n">true_value</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="Column-237"><a href="#Column-237"><span class="linenos">237</span></a> <span class="k">def</span> <span class="nf">asc_nulls_last</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-238"><a href="#Column-238"><span class="linenos">238</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column-239"><a href="#Column-239"><span class="linenos">239</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-240"><a href="#Column-240"><span class="linenos">240</span></a>
</span><span id="Column-241"><a href="#Column-241"><span class="linenos">241</span></a> <span class="k">def</span> <span class="nf">desc_nulls_first</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-242"><a href="#Column-242"><span class="linenos">242</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column-243"><a href="#Column-243"><span class="linenos">243</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-244"><a href="#Column-244"><span class="linenos">244</span></a>
</span><span id="Column-245"><a href="#Column-245"><span class="linenos">245</span></a> <span class="n">desc_nulls_last</span> <span class="o">=</span> <span class="n">desc</span>
</span><span id="Column-246"><a href="#Column-246"><span class="linenos">246</span></a>
</span><span id="Column-247"><a href="#Column-247"><span class="linenos">247</span></a> <span class="k">def</span> <span class="nf">when</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">condition</span><span class="p">:</span> <span class="n">Column</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-248"><a href="#Column-248"><span class="linenos">248</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">when</span>
</span><span id="Column-249"><a href="#Column-249"><span class="linenos">249</span></a>
</span><span id="Column-250"><a href="#Column-250"><span class="linenos">250</span></a> <span class="n">column_with_if</span> <span class="o">=</span> <span class="n">when</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-251"><a href="#Column-251"><span class="linenos">251</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</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">Case</span><span class="p">):</span>
</span><span id="Column-252"><a href="#Column-252"><span class="linenos">252</span></a> <span class="k">return</span> <span class="n">column_with_if</span>
</span><span id="Column-253"><a href="#Column-253"><span class="linenos">253</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column-254"><a href="#Column-254"><span class="linenos">254</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">,</span> <span class="n">true_value</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column-254"><a href="#Column-254"><span class="linenos">254</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">column_with_if</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">])</span>
</span><span id="Column-255"><a href="#Column-255"><span class="linenos">255</span></a> <span class="k">return</span> <span class="n">new_column</span>
</span><span id="Column-256"><a href="#Column-256"><span class="linenos">256</span></a>
</span><span id="Column-257"><a href="#Column-257"><span class="linenos">257</span></a> <span class="k">def</span> <span class="nf">isNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-258"><a href="#Column-258"><span class="linenos">258</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">())</span>
</span><span id="Column-259"><a href="#Column-259"><span class="linenos">259</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-260"><a href="#Column-260"><span class="linenos">260</span></a>
</span><span id="Column-261"><a href="#Column-261"><span class="linenos">261</span></a> <span class="k">def</span> <span class="nf">isNotNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-262"><a href="#Column-262"><span class="linenos">262</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Not</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">()))</span>
</span><span id="Column-263"><a href="#Column-263"><span class="linenos">263</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-257"><a href="#Column-257"><span class="linenos">257</span></a> <span class="k">def</span> <span class="nf">otherwise</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-258"><a href="#Column-258"><span class="linenos">258</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">lit</span>
</span><span id="Column-259"><a href="#Column-259"><span class="linenos">259</span></a>
</span><span id="Column-260"><a href="#Column-260"><span class="linenos">260</span></a> <span class="n">true_value</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="Column-261"><a href="#Column-261"><span class="linenos">261</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column-262"><a href="#Column-262"><span class="linenos">262</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">,</span> <span class="n">true_value</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column-263"><a href="#Column-263"><span class="linenos">263</span></a> <span class="k">return</span> <span class="n">new_column</span>
</span><span id="Column-264"><a href="#Column-264"><span class="linenos">264</span></a>
</span><span id="Column-265"><a href="#Column-265"><span class="linenos">265</span></a> <span class="k">def</span> <span class="nf">cast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataType</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">DataType</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-266"><a href="#Column-266"><span class="linenos">266</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="Column-267"><a href="#Column-267"><span class="linenos">267</span></a><span class="sd"> Functionality Difference: PySpark cast accepts a datatype instance of the datatype class</span>
</span><span id="Column-268"><a href="#Column-268"><span class="linenos">268</span></a><span class="sd"> Sqlglot doesn&#39;t currently replicate this class so it only accepts a string</span>
</span><span id="Column-269"><a href="#Column-269"><span class="linenos">269</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="Column-270"><a href="#Column-270"><span class="linenos">270</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column-271"><a href="#Column-271"><span class="linenos">271</span></a>
</span><span id="Column-272"><a href="#Column-272"><span class="linenos">272</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dataType</span><span class="p">,</span> <span class="n">DataType</span><span class="p">):</span>
</span><span id="Column-273"><a href="#Column-273"><span class="linenos">273</span></a> <span class="n">dataType</span> <span class="o">=</span> <span class="n">dataType</span><span class="o">.</span><span class="n">simpleString</span><span class="p">()</span>
</span><span id="Column-274"><a href="#Column-274"><span class="linenos">274</span></a> <span class="k">return</span> <span class="n">Column</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">dataType</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span><span class="p">))</span>
</span><span id="Column-275"><a href="#Column-275"><span class="linenos">275</span></a>
</span><span id="Column-276"><a href="#Column-276"><span class="linenos">276</span></a> <span class="k">def</span> <span class="nf">startswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-277"><a href="#Column-277"><span class="linenos">277</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column-278"><a href="#Column-278"><span class="linenos">278</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;STARTSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-265"><a href="#Column-265"><span class="linenos">265</span></a> <span class="k">def</span> <span class="nf">isNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-266"><a href="#Column-266"><span class="linenos">266</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">())</span>
</span><span id="Column-267"><a href="#Column-267"><span class="linenos">267</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-268"><a href="#Column-268"><span class="linenos">268</span></a>
</span><span id="Column-269"><a href="#Column-269"><span class="linenos">269</span></a> <span class="k">def</span> <span class="nf">isNotNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-270"><a href="#Column-270"><span class="linenos">270</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Not</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">()))</span>
</span><span id="Column-271"><a href="#Column-271"><span class="linenos">271</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column-272"><a href="#Column-272"><span class="linenos">272</span></a>
</span><span id="Column-273"><a href="#Column-273"><span class="linenos">273</span></a> <span class="k">def</span> <span class="nf">cast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataType</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">DataType</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-274"><a href="#Column-274"><span class="linenos">274</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="Column-275"><a href="#Column-275"><span class="linenos">275</span></a><span class="sd"> Functionality Difference: PySpark cast accepts a datatype instance of the datatype class</span>
</span><span id="Column-276"><a href="#Column-276"><span class="linenos">276</span></a><span class="sd"> Sqlglot doesn&#39;t currently replicate this class so it only accepts a string</span>
</span><span id="Column-277"><a href="#Column-277"><span class="linenos">277</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="Column-278"><a href="#Column-278"><span class="linenos">278</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column-279"><a href="#Column-279"><span class="linenos">279</span></a>
</span><span id="Column-280"><a href="#Column-280"><span class="linenos">280</span></a> <span class="k">def</span> <span class="nf">endswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-281"><a href="#Column-281"><span class="linenos">281</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column-282"><a href="#Column-282"><span class="linenos">282</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;ENDSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-280"><a href="#Column-280"><span class="linenos">280</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dataType</span><span class="p">,</span> <span class="n">DataType</span><span class="p">):</span>
</span><span id="Column-281"><a href="#Column-281"><span class="linenos">281</span></a> <span class="n">dataType</span> <span class="o">=</span> <span class="n">dataType</span><span class="o">.</span><span class="n">simpleString</span><span class="p">()</span>
</span><span id="Column-282"><a href="#Column-282"><span class="linenos">282</span></a> <span class="k">return</span> <span class="n">Column</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">dataType</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span><span class="p">))</span>
</span><span id="Column-283"><a href="#Column-283"><span class="linenos">283</span></a>
</span><span id="Column-284"><a href="#Column-284"><span class="linenos">284</span></a> <span class="k">def</span> <span class="nf">rlike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regexp</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-285"><a href="#Column-285"><span class="linenos">285</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-286"><a href="#Column-286"><span class="linenos">286</span></a> <span class="n">column</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">callable_expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">RegexpLike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">regexp</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-287"><a href="#Column-287"><span class="linenos">287</span></a> <span class="p">)</span>
</span><span id="Column-288"><a href="#Column-288"><span class="linenos">288</span></a>
</span><span id="Column-289"><a href="#Column-289"><span class="linenos">289</span></a> <span class="k">def</span> <span class="nf">like</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column-290"><a href="#Column-290"><span class="linenos">290</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-291"><a href="#Column-291"><span class="linenos">291</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Like</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-292"><a href="#Column-292"><span class="linenos">292</span></a> <span class="p">)</span>
</span><span id="Column-293"><a href="#Column-293"><span class="linenos">293</span></a>
</span><span id="Column-294"><a href="#Column-294"><span class="linenos">294</span></a> <span class="k">def</span> <span class="nf">ilike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column-295"><a href="#Column-295"><span class="linenos">295</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-296"><a href="#Column-296"><span class="linenos">296</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ILike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-297"><a href="#Column-297"><span class="linenos">297</span></a> <span class="p">)</span>
</span><span id="Column-298"><a href="#Column-298"><span class="linenos">298</span></a>
</span><span id="Column-299"><a href="#Column-299"><span class="linenos">299</span></a> <span class="k">def</span> <span class="nf">substr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">startPos</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">],</span> <span class="n">length</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-300"><a href="#Column-300"><span class="linenos">300</span></a> <span class="n">startPos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">startPos</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">startPos</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">startPos</span>
</span><span id="Column-301"><a href="#Column-301"><span class="linenos">301</span></a> <span class="n">length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">length</span>
</span><span id="Column-302"><a href="#Column-302"><span class="linenos">302</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-303"><a href="#Column-303"><span class="linenos">303</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Substring</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">startPos</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="n">length</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-304"><a href="#Column-304"><span class="linenos">304</span></a> <span class="p">)</span>
</span><span id="Column-305"><a href="#Column-305"><span class="linenos">305</span></a>
</span><span id="Column-306"><a href="#Column-306"><span class="linenos">306</span></a> <span class="k">def</span> <span class="nf">isin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">]]):</span>
</span><span id="Column-307"><a href="#Column-307"><span class="linenos">307</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">cols</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cols</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">set</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="k">else</span> <span class="n">cols</span> <span class="c1"># type: ignore</span>
</span><span id="Column-308"><a href="#Column-308"><span class="linenos">308</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">]</span>
</span><span id="Column-309"><a href="#Column-309"><span class="linenos">309</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span> <span class="c1"># type: ignore</span>
</span><span id="Column-310"><a href="#Column-310"><span class="linenos">310</span></a>
</span><span id="Column-311"><a href="#Column-311"><span class="linenos">311</span></a> <span class="k">def</span> <span class="nf">between</span><span class="p">(</span>
</span><span id="Column-312"><a href="#Column-312"><span class="linenos">312</span></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="Column-313"><a href="#Column-313"><span class="linenos">313</span></a> <span class="n">lowerBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column-314"><a href="#Column-314"><span class="linenos">314</span></a> <span class="n">upperBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column-315"><a href="#Column-315"><span class="linenos">315</span></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-316"><a href="#Column-316"><span class="linenos">316</span></a> <span class="n">lower_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column-317"><a href="#Column-317"><span class="linenos">317</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lowerBound</span>
</span><span id="Column-318"><a href="#Column-318"><span class="linenos">318</span></a> <span class="p">)</span>
</span><span id="Column-319"><a href="#Column-319"><span class="linenos">319</span></a> <span class="n">upper_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column-320"><a href="#Column-320"><span class="linenos">320</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">upperBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">upperBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">upperBound</span>
</span><span id="Column-321"><a href="#Column-321"><span class="linenos">321</span></a> <span class="p">)</span>
</span><span id="Column-322"><a href="#Column-322"><span class="linenos">322</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span>
</span><span id="Column-323"><a href="#Column-323"><span class="linenos">323</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">(</span>
</span><span id="Column-324"><a href="#Column-324"><span class="linenos">324</span></a> <span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column-325"><a href="#Column-325"><span class="linenos">325</span></a> <span class="n">low</span><span class="o">=</span><span class="n">lower_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column-326"><a href="#Column-326"><span class="linenos">326</span></a> <span class="n">high</span><span class="o">=</span><span class="n">upper_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column-327"><a href="#Column-327"><span class="linenos">327</span></a> <span class="p">)</span>
</span><span id="Column-328"><a href="#Column-328"><span class="linenos">328</span></a> <span class="p">)</span>
</span><span id="Column-329"><a href="#Column-329"><span class="linenos">329</span></a>
</span><span id="Column-330"><a href="#Column-330"><span class="linenos">330</span></a> <span class="k">def</span> <span class="nf">over</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="p">:</span> <span class="n">WindowSpec</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-331"><a href="#Column-331"><span class="linenos">331</span></a> <span class="n">window_expression</span> <span class="o">=</span> <span class="n">window</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column-332"><a href="#Column-332"><span class="linenos">332</span></a> <span class="n">window_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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column-333"><a href="#Column-333"><span class="linenos">333</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">window_expression</span><span class="p">)</span>
</span><span id="Column-284"><a href="#Column-284"><span class="linenos">284</span></a> <span class="k">def</span> <span class="nf">startswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-285"><a href="#Column-285"><span class="linenos">285</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column-286"><a href="#Column-286"><span class="linenos">286</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;STARTSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-287"><a href="#Column-287"><span class="linenos">287</span></a>
</span><span id="Column-288"><a href="#Column-288"><span class="linenos">288</span></a> <span class="k">def</span> <span class="nf">endswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-289"><a href="#Column-289"><span class="linenos">289</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column-290"><a href="#Column-290"><span class="linenos">290</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;ENDSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column-291"><a href="#Column-291"><span class="linenos">291</span></a>
</span><span id="Column-292"><a href="#Column-292"><span class="linenos">292</span></a> <span class="k">def</span> <span class="nf">rlike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regexp</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-293"><a href="#Column-293"><span class="linenos">293</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-294"><a href="#Column-294"><span class="linenos">294</span></a> <span class="n">column</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">callable_expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">RegexpLike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">regexp</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-295"><a href="#Column-295"><span class="linenos">295</span></a> <span class="p">)</span>
</span><span id="Column-296"><a href="#Column-296"><span class="linenos">296</span></a>
</span><span id="Column-297"><a href="#Column-297"><span class="linenos">297</span></a> <span class="k">def</span> <span class="nf">like</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column-298"><a href="#Column-298"><span class="linenos">298</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-299"><a href="#Column-299"><span class="linenos">299</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Like</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-300"><a href="#Column-300"><span class="linenos">300</span></a> <span class="p">)</span>
</span><span id="Column-301"><a href="#Column-301"><span class="linenos">301</span></a>
</span><span id="Column-302"><a href="#Column-302"><span class="linenos">302</span></a> <span class="k">def</span> <span class="nf">ilike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column-303"><a href="#Column-303"><span class="linenos">303</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-304"><a href="#Column-304"><span class="linenos">304</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ILike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-305"><a href="#Column-305"><span class="linenos">305</span></a> <span class="p">)</span>
</span><span id="Column-306"><a href="#Column-306"><span class="linenos">306</span></a>
</span><span id="Column-307"><a href="#Column-307"><span class="linenos">307</span></a> <span class="k">def</span> <span class="nf">substr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">startPos</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">],</span> <span class="n">length</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-308"><a href="#Column-308"><span class="linenos">308</span></a> <span class="n">startPos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">startPos</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">startPos</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">startPos</span>
</span><span id="Column-309"><a href="#Column-309"><span class="linenos">309</span></a> <span class="n">length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">length</span>
</span><span id="Column-310"><a href="#Column-310"><span class="linenos">310</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column-311"><a href="#Column-311"><span class="linenos">311</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Substring</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">startPos</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="n">length</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column-312"><a href="#Column-312"><span class="linenos">312</span></a> <span class="p">)</span>
</span><span id="Column-313"><a href="#Column-313"><span class="linenos">313</span></a>
</span><span id="Column-314"><a href="#Column-314"><span class="linenos">314</span></a> <span class="k">def</span> <span class="nf">isin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">]]):</span>
</span><span id="Column-315"><a href="#Column-315"><span class="linenos">315</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">cols</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cols</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">set</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="k">else</span> <span class="n">cols</span> <span class="c1"># type: ignore</span>
</span><span id="Column-316"><a href="#Column-316"><span class="linenos">316</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">]</span>
</span><span id="Column-317"><a href="#Column-317"><span class="linenos">317</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span> <span class="c1"># type: ignore</span>
</span><span id="Column-318"><a href="#Column-318"><span class="linenos">318</span></a>
</span><span id="Column-319"><a href="#Column-319"><span class="linenos">319</span></a> <span class="k">def</span> <span class="nf">between</span><span class="p">(</span>
</span><span id="Column-320"><a href="#Column-320"><span class="linenos">320</span></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="Column-321"><a href="#Column-321"><span class="linenos">321</span></a> <span class="n">lowerBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column-322"><a href="#Column-322"><span class="linenos">322</span></a> <span class="n">upperBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column-323"><a href="#Column-323"><span class="linenos">323</span></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-324"><a href="#Column-324"><span class="linenos">324</span></a> <span class="n">lower_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column-325"><a href="#Column-325"><span class="linenos">325</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lowerBound</span>
</span><span id="Column-326"><a href="#Column-326"><span class="linenos">326</span></a> <span class="p">)</span>
</span><span id="Column-327"><a href="#Column-327"><span class="linenos">327</span></a> <span class="n">upper_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column-328"><a href="#Column-328"><span class="linenos">328</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">upperBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">upperBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">upperBound</span>
</span><span id="Column-329"><a href="#Column-329"><span class="linenos">329</span></a> <span class="p">)</span>
</span><span id="Column-330"><a href="#Column-330"><span class="linenos">330</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span>
</span><span id="Column-331"><a href="#Column-331"><span class="linenos">331</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">(</span>
</span><span id="Column-332"><a href="#Column-332"><span class="linenos">332</span></a> <span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column-333"><a href="#Column-333"><span class="linenos">333</span></a> <span class="n">low</span><span class="o">=</span><span class="n">lower_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column-334"><a href="#Column-334"><span class="linenos">334</span></a> <span class="n">high</span><span class="o">=</span><span class="n">upper_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column-335"><a href="#Column-335"><span class="linenos">335</span></a> <span class="p">)</span>
</span><span id="Column-336"><a href="#Column-336"><span class="linenos">336</span></a> <span class="p">)</span>
</span><span id="Column-337"><a href="#Column-337"><span class="linenos">337</span></a>
</span><span id="Column-338"><a href="#Column-338"><span class="linenos">338</span></a> <span class="k">def</span> <span class="nf">over</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="p">:</span> <span class="n">WindowSpec</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column-339"><a href="#Column-339"><span class="linenos">339</span></a> <span class="n">window_expression</span> <span class="o">=</span> <span class="n">window</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column-340"><a href="#Column-340"><span class="linenos">340</span></a> <span class="n">window_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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column-341"><a href="#Column-341"><span class="linenos">341</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">window_expression</span><span class="p">)</span>
</span></pre></div>
@ -3757,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">
<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;139837313928208&#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;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>
<label class="view-source-button" for="Column.__init__-view-source"><span>View Source</span></label>
@ -3801,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>
<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;139837312269808&#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;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>
<label class="view-source-button" for="Column.ensure_col-view-source"><span>View Source</span></label>
@ -3822,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>
<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;139837312553392&#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;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>
<label class="view-source-button" for="Column.ensure_cols-view-source"><span>View Source</span></label>
@ -3843,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>
<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;139837311833936&#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;139837312381856&#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;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>
<label class="view-source-button" for="Column.invoke_anonymous_function-view-source"><span>View Source</span></label>
@ -3870,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>
<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;139837312308880&#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;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>
<label class="view-source-button" for="Column.invoke_expression_over_column-view-source"><span>View Source</span></label>
@ -3907,7 +3915,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="attr function">
<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;139837312651840&#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;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>
<label class="view-source-button" for="Column.binary_op-view-source"><span>View Source</span></label>
@ -3928,7 +3936,7 @@ and check if it matches the type of the value provided. If not then make it null
<div class="attr function">
<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;139837312652944&#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;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>
<label class="view-source-button" for="Column.inverse_binary_op-view-source"><span>View Source</span></label>
@ -4107,8 +4115,16 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.alias"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.alias-215"><a href="#Column.alias-215"><span class="linenos">215</span></a> <span class="k">def</span> <span class="nf">alias</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.alias-216"><a href="#Column.alias-216"><span class="linenos">216</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="Column.alias-217"><a href="#Column.alias-217"><span class="linenos">217</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span><span id="Column.alias-216"><a href="#Column.alias-216"><span class="linenos">216</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column.alias-217"><a href="#Column.alias-217"><span class="linenos">217</span></a>
</span><span id="Column.alias-218"><a href="#Column.alias-218"><span class="linenos">218</span></a> <span class="n">dialect</span> <span class="o">=</span> <span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span>
</span><span id="Column.alias-219"><a href="#Column.alias-219"><span class="linenos">219</span></a> <span class="n">alias</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span> <span class="o">=</span> <span class="n">sqlglot</span><span class="o">.</span><span class="n">maybe_parse</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="Column.alias-220"><a href="#Column.alias-220"><span class="linenos">220</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span>
</span><span id="Column.alias-221"><a href="#Column.alias-221"><span class="linenos">221</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column.alias-222"><a href="#Column.alias-222"><span class="linenos">222</span></a> <span class="n">alias</span><span class="o">.</span><span class="n">this</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">alias</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="k">else</span> <span class="n">name</span><span class="p">,</span>
</span><span id="Column.alias-223"><a href="#Column.alias-223"><span class="linenos">223</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="Column.alias-224"><a href="#Column.alias-224"><span class="linenos">224</span></a> <span class="p">)</span>
</span><span id="Column.alias-225"><a href="#Column.alias-225"><span class="linenos">225</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4126,9 +4142,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.asc"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc-219"><a href="#Column.asc-219"><span class="linenos">219</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc-220"><a href="#Column.asc-220"><span class="linenos">220</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.asc-221"><a href="#Column.asc-221"><span class="linenos">221</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc-227"><a href="#Column.asc-227"><span class="linenos">227</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc-228"><a href="#Column.asc-228"><span class="linenos">228</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.asc-229"><a href="#Column.asc-229"><span class="linenos">229</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4146,9 +4162,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.desc"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc-223"><a href="#Column.desc-223"><span class="linenos">223</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc-224"><a href="#Column.desc-224"><span class="linenos">224</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.desc-225"><a href="#Column.desc-225"><span class="linenos">225</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc-231"><a href="#Column.desc-231"><span class="linenos">231</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc-232"><a href="#Column.desc-232"><span class="linenos">232</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.desc-233"><a href="#Column.desc-233"><span class="linenos">233</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4166,9 +4182,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.asc_nulls_first"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc_nulls_first-219"><a href="#Column.asc_nulls_first-219"><span class="linenos">219</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc_nulls_first-220"><a href="#Column.asc_nulls_first-220"><span class="linenos">220</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.asc_nulls_first-221"><a href="#Column.asc_nulls_first-221"><span class="linenos">221</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc_nulls_first-227"><a href="#Column.asc_nulls_first-227"><span class="linenos">227</span></a> <span class="k">def</span> <span class="nf">asc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc_nulls_first-228"><a href="#Column.asc_nulls_first-228"><span class="linenos">228</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.asc_nulls_first-229"><a href="#Column.asc_nulls_first-229"><span class="linenos">229</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4186,9 +4202,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.asc_nulls_last"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc_nulls_last-229"><a href="#Column.asc_nulls_last-229"><span class="linenos">229</span></a> <span class="k">def</span> <span class="nf">asc_nulls_last</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc_nulls_last-230"><a href="#Column.asc_nulls_last-230"><span class="linenos">230</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.asc_nulls_last-231"><a href="#Column.asc_nulls_last-231"><span class="linenos">231</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.asc_nulls_last-237"><a href="#Column.asc_nulls_last-237"><span class="linenos">237</span></a> <span class="k">def</span> <span class="nf">asc_nulls_last</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.asc_nulls_last-238"><a href="#Column.asc_nulls_last-238"><span class="linenos">238</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.asc_nulls_last-239"><a href="#Column.asc_nulls_last-239"><span class="linenos">239</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4206,9 +4222,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.desc_nulls_first"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc_nulls_first-233"><a href="#Column.desc_nulls_first-233"><span class="linenos">233</span></a> <span class="k">def</span> <span class="nf">desc_nulls_first</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc_nulls_first-234"><a href="#Column.desc_nulls_first-234"><span class="linenos">234</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.desc_nulls_first-235"><a href="#Column.desc_nulls_first-235"><span class="linenos">235</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc_nulls_first-241"><a href="#Column.desc_nulls_first-241"><span class="linenos">241</span></a> <span class="k">def</span> <span class="nf">desc_nulls_first</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc_nulls_first-242"><a href="#Column.desc_nulls_first-242"><span class="linenos">242</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span><span id="Column.desc_nulls_first-243"><a href="#Column.desc_nulls_first-243"><span class="linenos">243</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4226,9 +4242,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.desc_nulls_last"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc_nulls_last-223"><a href="#Column.desc_nulls_last-223"><span class="linenos">223</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc_nulls_last-224"><a href="#Column.desc_nulls_last-224"><span class="linenos">224</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.desc_nulls_last-225"><a href="#Column.desc_nulls_last-225"><span class="linenos">225</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.desc_nulls_last-231"><a href="#Column.desc_nulls_last-231"><span class="linenos">231</span></a> <span class="k">def</span> <span class="nf">desc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.desc_nulls_last-232"><a href="#Column.desc_nulls_last-232"><span class="linenos">232</span></a> <span class="n">new_expression</span> <span class="o">=</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">desc</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">nulls_first</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="Column.desc_nulls_last-233"><a href="#Column.desc_nulls_last-233"><span class="linenos">233</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4246,15 +4262,15 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.when"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.when-239"><a href="#Column.when-239"><span class="linenos">239</span></a> <span class="k">def</span> <span class="nf">when</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">condition</span><span class="p">:</span> <span class="n">Column</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.when-240"><a href="#Column.when-240"><span class="linenos">240</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">when</span>
</span><span id="Column.when-241"><a href="#Column.when-241"><span class="linenos">241</span></a>
</span><span id="Column.when-242"><a href="#Column.when-242"><span class="linenos">242</span></a> <span class="n">column_with_if</span> <span class="o">=</span> <span class="n">when</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column.when-243"><a href="#Column.when-243"><span class="linenos">243</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</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">Case</span><span class="p">):</span>
</span><span id="Column.when-244"><a href="#Column.when-244"><span class="linenos">244</span></a> <span class="k">return</span> <span class="n">column_with_if</span>
</span><span id="Column.when-245"><a href="#Column.when-245"><span class="linenos">245</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.when-246"><a href="#Column.when-246"><span class="linenos">246</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">column_with_if</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">])</span>
</span><span id="Column.when-247"><a href="#Column.when-247"><span class="linenos">247</span></a> <span class="k">return</span> <span class="n">new_column</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.when-247"><a href="#Column.when-247"><span class="linenos">247</span></a> <span class="k">def</span> <span class="nf">when</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">condition</span><span class="p">:</span> <span class="n">Column</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.when-248"><a href="#Column.when-248"><span class="linenos">248</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">when</span>
</span><span id="Column.when-249"><a href="#Column.when-249"><span class="linenos">249</span></a>
</span><span id="Column.when-250"><a href="#Column.when-250"><span class="linenos">250</span></a> <span class="n">column_with_if</span> <span class="o">=</span> <span class="n">when</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span id="Column.when-251"><a href="#Column.when-251"><span class="linenos">251</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</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">Case</span><span class="p">):</span>
</span><span id="Column.when-252"><a href="#Column.when-252"><span class="linenos">252</span></a> <span class="k">return</span> <span class="n">column_with_if</span>
</span><span id="Column.when-253"><a href="#Column.when-253"><span class="linenos">253</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.when-254"><a href="#Column.when-254"><span class="linenos">254</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">column_with_if</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;ifs&quot;</span><span class="p">])</span>
</span><span id="Column.when-255"><a href="#Column.when-255"><span class="linenos">255</span></a> <span class="k">return</span> <span class="n">new_column</span>
</span></pre></div>
@ -4272,13 +4288,13 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.otherwise"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.otherwise-249"><a href="#Column.otherwise-249"><span class="linenos">249</span></a> <span class="k">def</span> <span class="nf">otherwise</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.otherwise-250"><a href="#Column.otherwise-250"><span class="linenos">250</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">lit</span>
</span><span id="Column.otherwise-251"><a href="#Column.otherwise-251"><span class="linenos">251</span></a>
</span><span id="Column.otherwise-252"><a href="#Column.otherwise-252"><span class="linenos">252</span></a> <span class="n">true_value</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="Column.otherwise-253"><a href="#Column.otherwise-253"><span class="linenos">253</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.otherwise-254"><a href="#Column.otherwise-254"><span class="linenos">254</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">,</span> <span class="n">true_value</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column.otherwise-255"><a href="#Column.otherwise-255"><span class="linenos">255</span></a> <span class="k">return</span> <span class="n">new_column</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.otherwise-257"><a href="#Column.otherwise-257"><span class="linenos">257</span></a> <span class="k">def</span> <span class="nf">otherwise</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.otherwise-258"><a href="#Column.otherwise-258"><span class="linenos">258</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.functions</span> <span class="kn">import</span> <span class="n">lit</span>
</span><span id="Column.otherwise-259"><a href="#Column.otherwise-259"><span class="linenos">259</span></a>
</span><span id="Column.otherwise-260"><a href="#Column.otherwise-260"><span class="linenos">260</span></a> <span class="n">true_value</span> <span class="o">=</span> <span class="n">value</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
</span><span id="Column.otherwise-261"><a href="#Column.otherwise-261"><span class="linenos">261</span></a> <span class="n">new_column</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.otherwise-262"><a href="#Column.otherwise-262"><span class="linenos">262</span></a> <span class="n">new_column</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">,</span> <span class="n">true_value</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column.otherwise-263"><a href="#Column.otherwise-263"><span class="linenos">263</span></a> <span class="k">return</span> <span class="n">new_column</span>
</span></pre></div>
@ -4296,9 +4312,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.isNull"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isNull-257"><a href="#Column.isNull-257"><span class="linenos">257</span></a> <span class="k">def</span> <span class="nf">isNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.isNull-258"><a href="#Column.isNull-258"><span class="linenos">258</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">())</span>
</span><span id="Column.isNull-259"><a href="#Column.isNull-259"><span class="linenos">259</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isNull-265"><a href="#Column.isNull-265"><span class="linenos">265</span></a> <span class="k">def</span> <span class="nf">isNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.isNull-266"><a href="#Column.isNull-266"><span class="linenos">266</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">())</span>
</span><span id="Column.isNull-267"><a href="#Column.isNull-267"><span class="linenos">267</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4316,9 +4332,9 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.isNotNull"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isNotNull-261"><a href="#Column.isNotNull-261"><span class="linenos">261</span></a> <span class="k">def</span> <span class="nf">isNotNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.isNotNull-262"><a href="#Column.isNotNull-262"><span class="linenos">262</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Not</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">()))</span>
</span><span id="Column.isNotNull-263"><a href="#Column.isNotNull-263"><span class="linenos">263</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isNotNull-269"><a href="#Column.isNotNull-269"><span class="linenos">269</span></a> <span class="k">def</span> <span class="nf">isNotNull</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.isNotNull-270"><a href="#Column.isNotNull-270"><span class="linenos">270</span></a> <span class="n">new_expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Not</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Is</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</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">Null</span><span class="p">()))</span>
</span><span id="Column.isNotNull-271"><a href="#Column.isNotNull-271"><span class="linenos">271</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">new_expression</span><span class="p">)</span>
</span></pre></div>
@ -4336,16 +4352,16 @@ and check if it matches the type of the value provided. If not then make it null
</div>
<a class="headerlink" href="#Column.cast"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.cast-265"><a href="#Column.cast-265"><span class="linenos">265</span></a> <span class="k">def</span> <span class="nf">cast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataType</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">DataType</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.cast-266"><a href="#Column.cast-266"><span class="linenos">266</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="Column.cast-267"><a href="#Column.cast-267"><span class="linenos">267</span></a><span class="sd"> Functionality Difference: PySpark cast accepts a datatype instance of the datatype class</span>
</span><span id="Column.cast-268"><a href="#Column.cast-268"><span class="linenos">268</span></a><span class="sd"> Sqlglot doesn&#39;t currently replicate this class so it only accepts a string</span>
</span><span id="Column.cast-269"><a href="#Column.cast-269"><span class="linenos">269</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="Column.cast-270"><a href="#Column.cast-270"><span class="linenos">270</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column.cast-271"><a href="#Column.cast-271"><span class="linenos">271</span></a>
</span><span id="Column.cast-272"><a href="#Column.cast-272"><span class="linenos">272</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dataType</span><span class="p">,</span> <span class="n">DataType</span><span class="p">):</span>
</span><span id="Column.cast-273"><a href="#Column.cast-273"><span class="linenos">273</span></a> <span class="n">dataType</span> <span class="o">=</span> <span class="n">dataType</span><span class="o">.</span><span class="n">simpleString</span><span class="p">()</span>
</span><span id="Column.cast-274"><a href="#Column.cast-274"><span class="linenos">274</span></a> <span class="k">return</span> <span class="n">Column</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">dataType</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span><span class="p">))</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.cast-273"><a href="#Column.cast-273"><span class="linenos">273</span></a> <span class="k">def</span> <span class="nf">cast</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dataType</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">DataType</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.cast-274"><a href="#Column.cast-274"><span class="linenos">274</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="Column.cast-275"><a href="#Column.cast-275"><span class="linenos">275</span></a><span class="sd"> Functionality Difference: PySpark cast accepts a datatype instance of the datatype class</span>
</span><span id="Column.cast-276"><a href="#Column.cast-276"><span class="linenos">276</span></a><span class="sd"> Sqlglot doesn&#39;t currently replicate this class so it only accepts a string</span>
</span><span id="Column.cast-277"><a href="#Column.cast-277"><span class="linenos">277</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="Column.cast-278"><a href="#Column.cast-278"><span class="linenos">278</span></a> <span class="kn">from</span> <span class="nn">sqlglot.dataframe.sql.session</span> <span class="kn">import</span> <span class="n">SparkSession</span>
</span><span id="Column.cast-279"><a href="#Column.cast-279"><span class="linenos">279</span></a>
</span><span id="Column.cast-280"><a href="#Column.cast-280"><span class="linenos">280</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dataType</span><span class="p">,</span> <span class="n">DataType</span><span class="p">):</span>
</span><span id="Column.cast-281"><a href="#Column.cast-281"><span class="linenos">281</span></a> <span class="n">dataType</span> <span class="o">=</span> <span class="n">dataType</span><span class="o">.</span><span class="n">simpleString</span><span class="p">()</span>
</span><span id="Column.cast-282"><a href="#Column.cast-282"><span class="linenos">282</span></a> <span class="k">return</span> <span class="n">Column</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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span> <span class="n">dataType</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">SparkSession</span><span class="p">()</span><span class="o">.</span><span class="n">dialect</span><span class="p">))</span>
</span></pre></div>
@ -4366,9 +4382,9 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.startswith"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.startswith-276"><a href="#Column.startswith-276"><span class="linenos">276</span></a> <span class="k">def</span> <span class="nf">startswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.startswith-277"><a href="#Column.startswith-277"><span class="linenos">277</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column.startswith-278"><a href="#Column.startswith-278"><span class="linenos">278</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;STARTSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.startswith-284"><a href="#Column.startswith-284"><span class="linenos">284</span></a> <span class="k">def</span> <span class="nf">startswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.startswith-285"><a href="#Column.startswith-285"><span class="linenos">285</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column.startswith-286"><a href="#Column.startswith-286"><span class="linenos">286</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;STARTSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span></pre></div>
@ -4386,9 +4402,9 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.endswith"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.endswith-280"><a href="#Column.endswith-280"><span class="linenos">280</span></a> <span class="k">def</span> <span class="nf">endswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.endswith-281"><a href="#Column.endswith-281"><span class="linenos">281</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column.endswith-282"><a href="#Column.endswith-282"><span class="linenos">282</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;ENDSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.endswith-288"><a href="#Column.endswith-288"><span class="linenos">288</span></a> <span class="k">def</span> <span class="nf">endswith</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.endswith-289"><a href="#Column.endswith-289"><span class="linenos">289</span></a> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">value</span>
</span><span id="Column.endswith-290"><a href="#Column.endswith-290"><span class="linenos">290</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_anonymous_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;ENDSWITH&quot;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span></pre></div>
@ -4406,10 +4422,10 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.rlike"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.rlike-284"><a href="#Column.rlike-284"><span class="linenos">284</span></a> <span class="k">def</span> <span class="nf">rlike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regexp</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.rlike-285"><a href="#Column.rlike-285"><span class="linenos">285</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.rlike-286"><a href="#Column.rlike-286"><span class="linenos">286</span></a> <span class="n">column</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">callable_expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">RegexpLike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">regexp</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.rlike-287"><a href="#Column.rlike-287"><span class="linenos">287</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.rlike-292"><a href="#Column.rlike-292"><span class="linenos">292</span></a> <span class="k">def</span> <span class="nf">rlike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regexp</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.rlike-293"><a href="#Column.rlike-293"><span class="linenos">293</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.rlike-294"><a href="#Column.rlike-294"><span class="linenos">294</span></a> <span class="n">column</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">callable_expression</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">RegexpLike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">regexp</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.rlike-295"><a href="#Column.rlike-295"><span class="linenos">295</span></a> <span class="p">)</span>
</span></pre></div>
@ -4427,10 +4443,10 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.like"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.like-289"><a href="#Column.like-289"><span class="linenos">289</span></a> <span class="k">def</span> <span class="nf">like</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column.like-290"><a href="#Column.like-290"><span class="linenos">290</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.like-291"><a href="#Column.like-291"><span class="linenos">291</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Like</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.like-292"><a href="#Column.like-292"><span class="linenos">292</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.like-297"><a href="#Column.like-297"><span class="linenos">297</span></a> <span class="k">def</span> <span class="nf">like</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column.like-298"><a href="#Column.like-298"><span class="linenos">298</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.like-299"><a href="#Column.like-299"><span class="linenos">299</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Like</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.like-300"><a href="#Column.like-300"><span class="linenos">300</span></a> <span class="p">)</span>
</span></pre></div>
@ -4448,10 +4464,10 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.ilike"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.ilike-294"><a href="#Column.ilike-294"><span class="linenos">294</span></a> <span class="k">def</span> <span class="nf">ilike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column.ilike-295"><a href="#Column.ilike-295"><span class="linenos">295</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.ilike-296"><a href="#Column.ilike-296"><span class="linenos">296</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ILike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.ilike-297"><a href="#Column.ilike-297"><span class="linenos">297</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.ilike-302"><a href="#Column.ilike-302"><span class="linenos">302</span></a> <span class="k">def</span> <span class="nf">ilike</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span><span id="Column.ilike-303"><a href="#Column.ilike-303"><span class="linenos">303</span></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.ilike-304"><a href="#Column.ilike-304"><span class="linenos">304</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">ILike</span><span class="p">,</span> <span class="n">expression</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.ilike-305"><a href="#Column.ilike-305"><span class="linenos">305</span></a> <span class="p">)</span>
</span></pre></div>
@ -4469,12 +4485,12 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
</div>
<a class="headerlink" href="#Column.substr"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.substr-299"><a href="#Column.substr-299"><span class="linenos">299</span></a> <span class="k">def</span> <span class="nf">substr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">startPos</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">],</span> <span class="n">length</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.substr-300"><a href="#Column.substr-300"><span class="linenos">300</span></a> <span class="n">startPos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">startPos</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">startPos</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">startPos</span>
</span><span id="Column.substr-301"><a href="#Column.substr-301"><span class="linenos">301</span></a> <span class="n">length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">length</span>
</span><span id="Column.substr-302"><a href="#Column.substr-302"><span class="linenos">302</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.substr-303"><a href="#Column.substr-303"><span class="linenos">303</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Substring</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">startPos</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="n">length</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.substr-304"><a href="#Column.substr-304"><span class="linenos">304</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.substr-307"><a href="#Column.substr-307"><span class="linenos">307</span></a> <span class="k">def</span> <span class="nf">substr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">startPos</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">],</span> <span class="n">length</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Column</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.substr-308"><a href="#Column.substr-308"><span class="linenos">308</span></a> <span class="n">startPos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">startPos</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">startPos</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">startPos</span>
</span><span id="Column.substr-309"><a href="#Column.substr-309"><span class="linenos">309</span></a> <span class="n">length</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">length</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">length</span>
</span><span id="Column.substr-310"><a href="#Column.substr-310"><span class="linenos">310</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span>
</span><span id="Column.substr-311"><a href="#Column.substr-311"><span class="linenos">311</span></a> <span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Substring</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="n">startPos</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="n">length</span><span class="o">.</span><span class="n">expression</span>
</span><span id="Column.substr-312"><a href="#Column.substr-312"><span class="linenos">312</span></a> <span class="p">)</span>
</span></pre></div>
@ -4486,16 +4502,16 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function">
<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;139837310748032&#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;139837310748032&#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;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>
<label class="view-source-button" for="Column.isin-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#Column.isin"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isin-306"><a href="#Column.isin-306"><span class="linenos">306</span></a> <span class="k">def</span> <span class="nf">isin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">]]):</span>
</span><span id="Column.isin-307"><a href="#Column.isin-307"><span class="linenos">307</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">cols</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cols</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">set</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="k">else</span> <span class="n">cols</span> <span class="c1"># type: ignore</span>
</span><span id="Column.isin-308"><a href="#Column.isin-308"><span class="linenos">308</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">]</span>
</span><span id="Column.isin-309"><a href="#Column.isin-309"><span class="linenos">309</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span> <span class="c1"># type: ignore</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.isin-314"><a href="#Column.isin-314"><span class="linenos">314</span></a> <span class="k">def</span> <span class="nf">isin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">cols</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Iterable</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">]]):</span>
</span><span id="Column.isin-315"><a href="#Column.isin-315"><span class="linenos">315</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">cols</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cols</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">set</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">))</span> <span class="k">else</span> <span class="n">cols</span> <span class="c1"># type: ignore</span>
</span><span id="Column.isin-316"><a href="#Column.isin-316"><span class="linenos">316</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">expression</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">]</span>
</span><span id="Column.isin-317"><a href="#Column.isin-317"><span class="linenos">317</span></a> <span class="k">return</span> <span class="n">Column</span><span class="o">.</span><span class="n">invoke_expression_over_column</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">expressions</span><span class="o">=</span><span class="n">expressions</span><span class="p">)</span> <span class="c1"># type: ignore</span>
</span></pre></div>
@ -4507,30 +4523,30 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function">
<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;139837310853392&#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;139837310907872&#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;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>
<label class="view-source-button" for="Column.between-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#Column.between"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.between-311"><a href="#Column.between-311"><span class="linenos">311</span></a> <span class="k">def</span> <span class="nf">between</span><span class="p">(</span>
</span><span id="Column.between-312"><a href="#Column.between-312"><span class="linenos">312</span></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="Column.between-313"><a href="#Column.between-313"><span class="linenos">313</span></a> <span class="n">lowerBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column.between-314"><a href="#Column.between-314"><span class="linenos">314</span></a> <span class="n">upperBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column.between-315"><a href="#Column.between-315"><span class="linenos">315</span></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.between-316"><a href="#Column.between-316"><span class="linenos">316</span></a> <span class="n">lower_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column.between-317"><a href="#Column.between-317"><span class="linenos">317</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lowerBound</span>
</span><span id="Column.between-318"><a href="#Column.between-318"><span class="linenos">318</span></a> <span class="p">)</span>
</span><span id="Column.between-319"><a href="#Column.between-319"><span class="linenos">319</span></a> <span class="n">upper_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column.between-320"><a href="#Column.between-320"><span class="linenos">320</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">upperBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">upperBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">upperBound</span>
</span><span id="Column.between-321"><a href="#Column.between-321"><span class="linenos">321</span></a> <span class="p">)</span>
</span><span id="Column.between-322"><a href="#Column.between-322"><span class="linenos">322</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span>
</span><span id="Column.between-323"><a href="#Column.between-323"><span class="linenos">323</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">(</span>
</span><span id="Column.between-324"><a href="#Column.between-324"><span class="linenos">324</span></a> <span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column.between-325"><a href="#Column.between-325"><span class="linenos">325</span></a> <span class="n">low</span><span class="o">=</span><span class="n">lower_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column.between-326"><a href="#Column.between-326"><span class="linenos">326</span></a> <span class="n">high</span><span class="o">=</span><span class="n">upper_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column.between-327"><a href="#Column.between-327"><span class="linenos">327</span></a> <span class="p">)</span>
</span><span id="Column.between-328"><a href="#Column.between-328"><span class="linenos">328</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.between-319"><a href="#Column.between-319"><span class="linenos">319</span></a> <span class="k">def</span> <span class="nf">between</span><span class="p">(</span>
</span><span id="Column.between-320"><a href="#Column.between-320"><span class="linenos">320</span></a> <span class="bp">self</span><span class="p">,</span>
</span><span id="Column.between-321"><a href="#Column.between-321"><span class="linenos">321</span></a> <span class="n">lowerBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column.between-322"><a href="#Column.between-322"><span class="linenos">322</span></a> <span class="n">upperBound</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">ColumnOrLiteral</span><span class="p">],</span>
</span><span id="Column.between-323"><a href="#Column.between-323"><span class="linenos">323</span></a> <span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.between-324"><a href="#Column.between-324"><span class="linenos">324</span></a> <span class="n">lower_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column.between-325"><a href="#Column.between-325"><span class="linenos">325</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">lowerBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">lowerBound</span>
</span><span id="Column.between-326"><a href="#Column.between-326"><span class="linenos">326</span></a> <span class="p">)</span>
</span><span id="Column.between-327"><a href="#Column.between-327"><span class="linenos">327</span></a> <span class="n">upper_bound_exp</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="Column.between-328"><a href="#Column.between-328"><span class="linenos">328</span></a> <span class="bp">self</span><span class="o">.</span><span class="n">_lit</span><span class="p">(</span><span class="n">upperBound</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">upperBound</span><span class="p">,</span> <span class="n">Column</span><span class="p">)</span> <span class="k">else</span> <span class="n">upperBound</span>
</span><span id="Column.between-329"><a href="#Column.between-329"><span class="linenos">329</span></a> <span class="p">)</span>
</span><span id="Column.between-330"><a href="#Column.between-330"><span class="linenos">330</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span>
</span><span id="Column.between-331"><a href="#Column.between-331"><span class="linenos">331</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Between</span><span class="p">(</span>
</span><span id="Column.between-332"><a href="#Column.between-332"><span class="linenos">332</span></a> <span class="n">this</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">,</span>
</span><span id="Column.between-333"><a href="#Column.between-333"><span class="linenos">333</span></a> <span class="n">low</span><span class="o">=</span><span class="n">lower_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column.between-334"><a href="#Column.between-334"><span class="linenos">334</span></a> <span class="n">high</span><span class="o">=</span><span class="n">upper_bound_exp</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="Column.between-335"><a href="#Column.between-335"><span class="linenos">335</span></a> <span class="p">)</span>
</span><span id="Column.between-336"><a href="#Column.between-336"><span class="linenos">336</span></a> <span class="p">)</span>
</span></pre></div>
@ -4542,16 +4558,16 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function">
<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;139837310981968&#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;139723639702768&#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>
</div>
<a class="headerlink" href="#Column.over"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.over-330"><a href="#Column.over-330"><span class="linenos">330</span></a> <span class="k">def</span> <span class="nf">over</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="p">:</span> <span class="n">WindowSpec</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.over-331"><a href="#Column.over-331"><span class="linenos">331</span></a> <span class="n">window_expression</span> <span class="o">=</span> <span class="n">window</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.over-332"><a href="#Column.over-332"><span class="linenos">332</span></a> <span class="n">window_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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column.over-333"><a href="#Column.over-333"><span class="linenos">333</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">window_expression</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="Column.over-338"><a href="#Column.over-338"><span class="linenos">338</span></a> <span class="k">def</span> <span class="nf">over</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="p">:</span> <span class="n">WindowSpec</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Column</span><span class="p">:</span>
</span><span id="Column.over-339"><a href="#Column.over-339"><span class="linenos">339</span></a> <span class="n">window_expression</span> <span class="o">=</span> <span class="n">window</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span><span id="Column.over-340"><a href="#Column.over-340"><span class="linenos">340</span></a> <span class="n">window_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="bp">self</span><span class="o">.</span><span class="n">column_expression</span><span class="p">)</span>
</span><span id="Column.over-341"><a href="#Column.over-341"><span class="linenos">341</span></a> <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">window_expression</span><span class="p">)</span>
</span></pre></div>
@ -4787,7 +4803,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="decorator">@classmethod</div>
<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;139837311435968&#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;139837311435968&#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;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>
<label class="view-source-button" for="Window.partitionBy-view-source"><span>View Source</span></label>
@ -4808,7 +4824,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="decorator">@classmethod</div>
<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;139837311484592&#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;139837311484592&#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;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>
<label class="view-source-button" for="Window.orderBy-view-source"><span>View Source</span></label>
@ -5048,7 +5064,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function">
<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;139837311307536&#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;139837311307536&#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;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>
<label class="view-source-button" for="WindowSpec.partitionBy-view-source"><span>View Source</span></label>
@ -5075,7 +5091,7 @@ Sqlglot doesn't currently replicate this class so it only accepts a string</p>
<div class="attr function">
<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;139837311073200&#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;139837311073200&#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;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>
<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

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 it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -45,6 +45,9 @@
<li>
<a class="function" href="#ensure_bool_predicates">ensure_bool_predicates</a>
</li>
<li>
<a class="function" href="#remove_ascending_order">remove_ascending_order</a>
</li>
</ul>
@ -90,70 +93,79 @@
</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-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-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-23"><a href="#L-23"><span class="linenos">23</span></a>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</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-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-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="k">return</span> <span class="n">expression</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</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 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="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">return</span> <span class="n">node</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</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-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-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-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-32"><a href="#L-32"><span class="linenos">32</span></a>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</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 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="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">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="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">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">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="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 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-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-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-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-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-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-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-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-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-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-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">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="k">if</span> <span class="p">(</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos">46</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="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="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="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="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 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><span id="L-44"><a href="#L-44"><span class="linenos">44</span></a>
</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-46"><a href="#L-46"><span class="linenos">46</span></a> <span class="k">if</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-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-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-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-51"><a href="#L-51"><span class="linenos">51</span></a> <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-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-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 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">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="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="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><span id="L-60"><a href="#L-60"><span class="linenos">60</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="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><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><span id="L-64"><a href="#L-64"><span class="linenos">64</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-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-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-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-60"><a href="#L-60"><span class="linenos">60</span></a>
</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-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-63"><a href="#L-63"><span class="linenos">63</span></a>
</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-66"><a href="#L-66"><span class="linenos">66</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-67"><a href="#L-67"><span class="linenos">67</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-68"><a href="#L-68"><span class="linenos">68</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos">69</span></a> <span class="n">a</span><span class="o">.</span><span class="n">type</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos">70</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-71"><a href="#L-71"><span class="linenos">71</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-72"><a href="#L-72"><span class="linenos">72</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-73"><a href="#L-73"><span class="linenos">73</span></a> <span class="p">):</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos">74</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-75"><a href="#L-75"><span class="linenos">75</span></a>
</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">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-78"><a href="#L-78"><span class="linenos">78</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-79"><a href="#L-79"><span class="linenos">79</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-80"><a href="#L-80"><span class="linenos">80</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-81"><a href="#L-81"><span class="linenos">81</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-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><span id="L-84"><a href="#L-84"><span class="linenos">84</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-85"><a href="#L-85"><span class="linenos">85</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-86"><a href="#L-86"><span class="linenos">86</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-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-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-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-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-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-73"><a href="#L-73"><span class="linenos">73</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-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-77"><a href="#L-77"><span class="linenos">77</span></a> <span class="k">if</span> <span class="p">(</span>
</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-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-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-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-82"><a href="#L-82"><span class="linenos">82</span></a> <span class="p">):</span>
</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-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-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-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-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-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-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-91"><a href="#L-91"><span class="linenos">91</span></a>
</span><span id="L-92"><a href="#L-92"><span class="linenos">92</span></a>
</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-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-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></pre></div>
@ -184,8 +196,9 @@
</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-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-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-24"><a href="#canonicalize-24"><span class="linenos">24</span></a>
</span><span id="canonicalize-25"><a href="#canonicalize-25"><span class="linenos">25</span></a> <span class="k">return</span> <span class="n">expression</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-25"><a href="#canonicalize-25"><span class="linenos">25</span></a>
</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></pre></div>
@ -214,10 +227,10 @@ conversions rely on type inference.</p>
</div>
<a class="headerlink" href="#add_text_to_concat"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="add_text_to_concat-28"><a href="#add_text_to_concat-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="add_text_to_concat-29"><a href="#add_text_to_concat-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="add_text_to_concat-30"><a href="#add_text_to_concat-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="add_text_to_concat-31"><a href="#add_text_to_concat-31"><span class="linenos">31</span></a> <span class="k">return</span> <span class="n">node</span>
<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>
</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="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></pre></div>
@ -235,15 +248,15 @@ conversions rely on type inference.</p>
</div>
<a class="headerlink" href="#coerce_type"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="coerce_type-34"><a href="#coerce_type-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="coerce_type-35"><a href="#coerce_type-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="coerce_type-36"><a href="#coerce_type-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="coerce_type-37"><a href="#coerce_type-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="coerce_type-38"><a href="#coerce_type-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="coerce_type-39"><a href="#coerce_type-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="coerce_type-40"><a href="#coerce_type-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="coerce_type-41"><a href="#coerce_type-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="coerce_type-42"><a href="#coerce_type-42"><span class="linenos">42</span></a> <span class="k">return</span> <span class="n">node</span>
<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>
</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-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-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-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-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-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-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-43"><a href="#coerce_type-43"><span class="linenos">43</span></a> <span class="k">return</span> <span class="n">node</span>
</span></pre></div>
@ -261,15 +274,15 @@ conversions rely on type inference.</p>
</div>
<a class="headerlink" href="#remove_redundant_casts"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="remove_redundant_casts-45"><a href="#remove_redundant_casts-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="remove_redundant_casts-46"><a href="#remove_redundant_casts-46"><span class="linenos">46</span></a> <span class="k">if</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="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-48"><a href="#remove_redundant_casts-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="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">this</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">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-51"><a href="#remove_redundant_casts-51"><span class="linenos">51</span></a> <span class="p">):</span>
</span><span id="remove_redundant_casts-52"><a href="#remove_redundant_casts-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="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>
<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>
</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-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-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-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-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-52"><a href="#remove_redundant_casts-52"><span class="linenos">52</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-54"><a href="#remove_redundant_casts-54"><span class="linenos">54</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div>
@ -287,15 +300,38 @@ conversions rely on type inference.</p>
</div>
<a class="headerlink" href="#ensure_bool_predicates"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="ensure_bool_predicates-56"><a href="#ensure_bool_predicates-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="ensure_bool_predicates-57"><a href="#ensure_bool_predicates-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="ensure_bool_predicates-58"><a href="#ensure_bool_predicates-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="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">right</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><span id="ensure_bool_predicates-61"><a href="#ensure_bool_predicates-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="ensure_bool_predicates-62"><a href="#ensure_bool_predicates-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="ensure_bool_predicates-63"><a href="#ensure_bool_predicates-63"><span class="linenos">63</span></a>
</span><span id="ensure_bool_predicates-64"><a href="#ensure_bool_predicates-64"><span class="linenos">64</span></a> <span class="k">return</span> <span class="n">expression</span>
<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>
</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-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-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-61"><a href="#ensure_bool_predicates-61"><span class="linenos">61</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-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-64"><a href="#ensure_bool_predicates-64"><span class="linenos">64</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></pre></div>
</section>
<section id="remove_ascending_order">
<input id="remove_ascending_order-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">remove_ascending_order</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</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="remove_ascending_order-view-source"><span>View Source</span></label>
</div>
<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>
</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-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-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-72"><a href="#remove_ascending_order-72"><span class="linenos">72</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></pre></div>

View file

@ -568,7 +568,7 @@ queries if it would result in multiple table selects in a single query:</p>
<div class="attr variable">
<span class="name">UNMERGABLE_ARGS</span> =
<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;group&#39;, &#39;locks&#39;, &#39;cluster&#39;, &#39;windows&#39;, &#39;sort&#39;, &#39;limit&#39;, &#39;sample&#39;, &#39;kind&#39;, &#39;having&#39;, &#39;settings&#39;, &#39;with&#39;, &#39;distribute&#39;, &#39;laterals&#39;, &#39;match&#39;, &#39;qualify&#39;, &#39;format&#39;, &#39;connect&#39;, &#39;offset&#39;, &#39;distinct&#39;, &#39;pivots&#39;, &#39;into&#39;}</span>
<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>
</div>

File diff suppressed because one or more lines are too long

View file

@ -118,8 +118,8 @@
</span><span id="L-60"><a href="#L-60"><span class="linenos">60</span></a><span class="sd"> The qualified expression.</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos">61</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos">62</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos">63</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos">64</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</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 class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos">67</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
@ -196,8 +196,8 @@
</span><span id="qualify-61"><a href="#qualify-61"><span class="linenos">61</span></a><span class="sd"> The qualified expression.</span>
</span><span id="qualify-62"><a href="#qualify-62"><span class="linenos">62</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="qualify-63"><a href="#qualify-63"><span class="linenos">63</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-64"><a href="#qualify-64"><span class="linenos">64</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="qualify-65"><a href="#qualify-65"><span class="linenos">65</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-64"><a href="#qualify-64"><span class="linenos">64</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-65"><a href="#qualify-65"><span class="linenos">65</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="qualify-66"><a href="#qualify-66"><span class="linenos">66</span></a>
</span><span id="qualify-67"><a href="#qualify-67"><span class="linenos">67</span></a> <span class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="qualify-68"><a href="#qualify-68"><span class="linenos">68</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>

File diff suppressed because it is too large Load diff

View file

@ -107,229 +107,233 @@
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Condition</span><span class="p">)</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="k">return</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="c1"># This subquery returns a scalar and can just be converted to a cross join</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">)):</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="n">column</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">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">alias</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-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="ow">not</span> <span class="n">predicate</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="ow">or</span> <span class="ow">not</span> <span class="n">parent_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-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="k">return</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="n">clause</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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">Where</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-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">clause_parent_select</span> <span class="o">=</span> <span class="n">clause</span><span class="o">.</span><span class="n">parent_select</span> <span class="k">if</span> <span class="n">clause</span> <span class="k">else</span> <span class="kc">None</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">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">clause</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="ow">and</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="n">parent_select</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="p">(</span><span class="ow">not</span> <span class="n">clause</span> <span class="ow">or</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">parent_select</span><span class="p">)</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="ow">and</span> <span class="p">(</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="n">parent_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;group&quot;</span><span class="p">)</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">projection</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="k">for</span> <span class="n">projection</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <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 class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</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-64"><a href="#L-64"><span class="linenos"> 64</span></a>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</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-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="k">return</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="c1"># This subquery returns a scalar and can just be converted to a cross join</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">)):</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="n">column</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">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="n">clause</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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">Where</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-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="n">clause_parent_select</span> <span class="o">=</span> <span class="n">clause</span><span class="o">.</span><span class="n">parent_select</span> <span class="k">if</span> <span class="n">clause</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">clause</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="ow">and</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="n">parent_select</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="p">(</span><span class="ow">not</span> <span class="n">clause</span> <span class="ow">or</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">parent_select</span><span class="p">)</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="ow">and</span> <span class="p">(</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="n">parent_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;group&quot;</span><span class="p">)</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">projection</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="k">for</span> <span class="n">projection</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="p">)</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="p">):</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</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-68"><a href="#L-68"><span class="linenos"> 68</span></a>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="k">if</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="k">return</span>
</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">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span>
</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">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="k">return</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">column</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">predicate</span><span class="p">)</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">condition</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s1"> = &quot;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;.&quot;</span><span class="si">{</span><span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">on</span><span class="o">.</span><span class="n">right</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">this</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-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="n">on</span><span class="o">=</span><span class="n">on</span><span class="p">,</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="p">)</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a><span class="k">def</span> <span class="nf">decorrelate</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">parent_select</span><span class="p">,</span> <span class="n">external_columns</span><span class="p">,</span> <span class="n">next_alias_name</span><span class="p">):</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">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;where&quot;</span><span class="p">)</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</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-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="k">return</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="k">if</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="k">return</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">return</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">predicate</span><span class="p">)</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</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 class="n">on</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">condition</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s1"> = &quot;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;.&quot;</span><span class="si">{</span><span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">on</span><span class="o">.</span><span class="n">right</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">this</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-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">on</span><span class="o">=</span><span class="n">on</span><span class="p">,</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <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 class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="n">where</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">Or</span><span class="p">)</span> <span class="ow">or</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="k">return</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="c1"># for all external columns in the where statement, find the relevant predicate</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="c1"># keys to convert it into a join</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">external_columns</span><span class="p">:</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="k">return</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="k">return</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</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-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="n">key</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="n">predicate</span><span class="o">.</span><span class="n">right</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">node</span> <span class="ow">is</span> <span class="n">column</span> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">walk</span><span class="p">())</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="k">else</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="p">)</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="k">return</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span><span class="p">))</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">):</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="k">return</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="n">is_subquery_projection</span> <span class="o">=</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="n">node</span> <span class="ow">is</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span> <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">Subquery</span><span class="p">)</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="p">)</span>
</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">decorrelate</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">parent_select</span><span class="p">,</span> <span class="n">external_columns</span><span class="p">,</span> <span class="n">next_alias_name</span><span class="p">):</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">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;where&quot;</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 class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="n">where</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">Or</span><span class="p">)</span> <span class="ow">or</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="k">return</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="c1"># for all external columns in the where statement, find the relevant predicate</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="c1"># keys to convert it into a join</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">external_columns</span><span class="p">:</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">return</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="k">return</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</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-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="n">key</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">predicate</span><span class="o">.</span><span class="n">right</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">node</span> <span class="ow">is</span> <span class="n">column</span> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">walk</span><span class="p">())</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="k">else</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="p">)</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">return</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span><span class="p">))</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">):</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">return</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">key_aliases</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="n">group_by</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">is_subquery_projection</span> <span class="o">=</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">node</span> <span class="ow">is</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span> <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">Subquery</span><span class="p">)</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="p">)</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="c1"># if we filter on the value of the subquery, it needs to be unique</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="p">:</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="c1"># all predicates that are equalities must also be in the unique</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="c1"># so that we don&#39;t do a many to many join</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="c1"># if the value of the subquery is not an agg or a key, we need to collect it into an array</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="c1"># so that it can be grouped. For subquery projections, we use a MAX aggregation instead.</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">agg_func</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span> <span class="k">if</span> <span class="n">is_subquery_projection</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArrayAgg</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">value</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="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">),</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</span><span class="p">),</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="p">)</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="c1"># exists queries should not have any selects as it only checks if there are any rows</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="c1"># all selects will be added by the optimizer and only used for join keys</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="n">select</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;expressions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="c1"># add all keys to the projections of the subquery</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="c1"># so that we can use it as a join key</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">)</span> <span class="ow">or</span> <span class="n">key</span> <span class="o">!=</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> AS </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&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-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">select</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">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">key</span><span class="o">.</span><span class="n">copy</span><span class="p">()),</span> <span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</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-173"><a href="#L-173"><span class="linenos">173</span></a>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="n">alias</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">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="n">other</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">)</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="n">alias</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="nb">list</span><span class="p">(</span><span class="n">key_aliases</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">):</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ALL(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="p">)</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">):</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">,</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="p">)</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">)</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="c1"># COUNT always returns 0 on empty datasets, so we need take that into consideration here</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="c1"># by transforming all counts into 0 and using that as the coalesced value</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="k">if</span> <span class="n">value</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">Count</span><span class="p">):</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="n">key_aliases</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="n">group_by</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="c1"># if we filter on the value of the subquery, it needs to be unique</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="p">:</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="c1"># all predicates that are equalities must also be in the unique</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="c1"># so that we don&#39;t do a many to many join</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="c1"># if the value of the subquery is not an agg or a key, we need to collect it into an array</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="c1"># so that it can be grouped. For subquery projections, we use a MAX aggregation instead.</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a> <span class="n">agg_func</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span> <span class="k">if</span> <span class="n">is_subquery_projection</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArrayAgg</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">value</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="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">),</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</span><span class="p">),</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="p">)</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="c1"># exists queries should not have any selects as it only checks if there are any rows</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="c1"># all selects will be added by the optimizer and only used for join keys</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="n">select</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;expressions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="c1"># add all keys to the projections of the subquery</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="c1"># so that we can use it as a join key</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">)</span> <span class="ow">or</span> <span class="n">key</span> <span class="o">!=</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> AS </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&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-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="n">select</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">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">key</span><span class="o">.</span><span class="n">copy</span><span class="p">()),</span> <span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</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-177"><a href="#L-177"><span class="linenos">177</span></a>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="n">alias</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">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="n">other</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">)</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="n">alias</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="nb">list</span><span class="p">(</span><span class="n">key_aliases</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">):</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ALL(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="p">)</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">):</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">,</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="p">)</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">)</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="k">def</span> <span class="nf">remove_aggs</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</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">Count</span><span class="p">):</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="k">return</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-208"><a href="#L-208"><span class="linenos">208</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">AggFunc</span><span class="p">):</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">null</span><span class="p">()</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Coalesce</span><span class="p">(</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="n">this</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">remove_aggs</span><span class="p">)],</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="p">)</span>
</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="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">alias</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 class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="n">predicate</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">true</span><span class="p">())</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="n">nested</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">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="c1"># COUNT always returns 0 on empty datasets, so we need take that into consideration here</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="c1"># by transforming all counts into 0 and using that as the coalesced value</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="k">if</span> <span class="n">value</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">Count</span><span class="p">):</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="k">def</span> <span class="nf">remove_aggs</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</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">Count</span><span class="p">):</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="k">return</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-212"><a href="#L-212"><span class="linenos">212</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">AggFunc</span><span class="p">):</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">null</span><span class="p">()</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Coalesce</span><span class="p">(</span>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="n">this</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">remove_aggs</span><span class="p">)],</span>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> <span class="p">)</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a> <span class="k">continue</span>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a> <span class="n">predicate</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">true</span><span class="p">())</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a> <span class="n">nested</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">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">):</span>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s2"> AND ARRAY_CONTAINS(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s2">))&quot;</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="k">else</span><span class="p">:</span>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="n">key</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">to_identifier</span><span class="p">(</span><span class="s2">&quot;_x&quot;</span><span class="p">))</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="sa">f</span><span class="s1">&#39;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s1"> AND ARRAY_ANY(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s1">, &quot;_x&quot; -&gt; </span><span class="si">{</span><span class="n">predicate</span><span class="si">}</span><span class="s1">))&#39;</span><span class="p">,</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="p">)</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="o">*</span><span class="n">group_by</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-243"><a href="#L-243"><span class="linenos">243</span></a> <span class="n">on</span><span class="o">=</span><span class="p">[</span><span class="n">predicate</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)],</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">table_alias</span><span class="p">,</span>
</span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a> <span class="p">)</span>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a><span class="k">def</span> <span class="nf">_replace</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">condition</span><span class="p">):</span>
</span><span id="L-251"><a href="#L-251"><span class="linenos">251</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">condition</span><span class="p">(</span><span class="n">condition</span><span class="p">))</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="k">continue</span>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">):</span>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s2"> AND ARRAY_CONTAINS(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s2">))&quot;</span><span class="p">,</span>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="p">)</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="n">key</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">to_identifier</span><span class="p">(</span><span class="s2">&quot;_x&quot;</span><span class="p">))</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="sa">f</span><span class="s1">&#39;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s1"> AND ARRAY_ANY(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s1">, &quot;_x&quot; -&gt; </span><span class="si">{</span><span class="n">predicate</span><span class="si">}</span><span class="s1">))&#39;</span><span class="p">,</span>
</span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a> <span class="p">)</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a>
</span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="o">*</span><span class="n">group_by</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-247"><a href="#L-247"><span class="linenos">247</span></a> <span class="n">on</span><span class="o">=</span><span class="p">[</span><span class="n">predicate</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)],</span>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">table_alias</span><span class="p">,</span>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a> <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="p">)</span>
</span><span id="L-252"><a href="#L-252"><span class="linenos">252</span></a>
</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="k">def</span> <span class="nf">_other_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</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">In</span><span class="p">):</span>
</span><span id="L-256"><a href="#L-256"><span class="linenos">256</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-254"><a href="#L-254"><span class="linenos">254</span></a><span class="k">def</span> <span class="nf">_replace</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">condition</span><span class="p">):</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</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">condition</span><span class="p">(</span><span class="n">condition</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><span id="L-258"><a href="#L-258"><span class="linenos">258</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="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">)):</span>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a> <span class="k">return</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a>
</span><span id="L-261"><a href="#L-261"><span class="linenos">261</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">Binary</span><span class="p">):</span>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a> <span class="k">return</span> <span class="p">(</span>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">right</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">))</span>
</span><span id="L-265"><a href="#L-265"><span class="linenos">265</span></a> <span class="k">else</span> <span class="n">expression</span><span class="o">.</span><span class="n">left</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="p">)</span>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a><span class="k">def</span> <span class="nf">_other_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</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">In</span><span class="p">):</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</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-261"><a href="#L-261"><span class="linenos">261</span></a>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</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="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">)):</span>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="k">return</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a>
</span><span id="L-265"><a href="#L-265"><span class="linenos">265</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">Binary</span><span class="p">):</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="k">return</span> <span class="p">(</span>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">right</span>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">))</span>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a> <span class="k">else</span> <span class="n">expression</span><span class="o">.</span><span class="n">left</span>
</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><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a> <span class="k">return</span> <span class="kc">None</span>
</span></pre></div>
@ -429,51 +433,55 @@ Convert correlated or vectorized subqueries into a group by so it is not a many
</span><span id="unnest-44"><a href="#unnest-44"><span class="linenos">44</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Condition</span><span class="p">)</span>
</span><span id="unnest-45"><a href="#unnest-45"><span class="linenos">45</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="unnest-46"><a href="#unnest-46"><span class="linenos">46</span></a>
</span><span id="unnest-47"><a href="#unnest-47"><span class="linenos">47</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="unnest-48"><a href="#unnest-48"><span class="linenos">48</span></a> <span class="k">return</span>
</span><span id="unnest-49"><a href="#unnest-49"><span class="linenos">49</span></a>
</span><span id="unnest-50"><a href="#unnest-50"><span class="linenos">50</span></a> <span class="c1"># This subquery returns a scalar and can just be converted to a cross join</span>
</span><span id="unnest-51"><a href="#unnest-51"><span class="linenos">51</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">)):</span>
</span><span id="unnest-52"><a href="#unnest-52"><span class="linenos">52</span></a> <span class="n">column</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">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
</span><span id="unnest-47"><a href="#unnest-47"><span class="linenos">47</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="unnest-48"><a href="#unnest-48"><span class="linenos">48</span></a> <span class="ow">not</span> <span class="n">predicate</span>
</span><span id="unnest-49"><a href="#unnest-49"><span class="linenos">49</span></a> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span>
</span><span id="unnest-50"><a href="#unnest-50"><span class="linenos">50</span></a> <span class="ow">or</span> <span class="ow">not</span> <span class="n">parent_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="unnest-51"><a href="#unnest-51"><span class="linenos">51</span></a> <span class="p">):</span>
</span><span id="unnest-52"><a href="#unnest-52"><span class="linenos">52</span></a> <span class="k">return</span>
</span><span id="unnest-53"><a href="#unnest-53"><span class="linenos">53</span></a>
</span><span id="unnest-54"><a href="#unnest-54"><span class="linenos">54</span></a> <span class="n">clause</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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">Where</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="unnest-55"><a href="#unnest-55"><span class="linenos">55</span></a> <span class="n">clause_parent_select</span> <span class="o">=</span> <span class="n">clause</span><span class="o">.</span><span class="n">parent_select</span> <span class="k">if</span> <span class="n">clause</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="unnest-56"><a href="#unnest-56"><span class="linenos">56</span></a>
</span><span id="unnest-57"><a href="#unnest-57"><span class="linenos">57</span></a> <span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">clause</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="ow">and</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="n">parent_select</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span>
</span><span id="unnest-58"><a href="#unnest-58"><span class="linenos">58</span></a> <span class="p">(</span><span class="ow">not</span> <span class="n">clause</span> <span class="ow">or</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">parent_select</span><span class="p">)</span>
</span><span id="unnest-59"><a href="#unnest-59"><span class="linenos">59</span></a> <span class="ow">and</span> <span class="p">(</span>
</span><span id="unnest-60"><a href="#unnest-60"><span class="linenos">60</span></a> <span class="n">parent_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;group&quot;</span><span class="p">)</span>
</span><span id="unnest-61"><a href="#unnest-61"><span class="linenos">61</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">projection</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="k">for</span> <span class="n">projection</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="unnest-62"><a href="#unnest-62"><span class="linenos">62</span></a> <span class="p">)</span>
</span><span id="unnest-63"><a href="#unnest-63"><span class="linenos">63</span></a> <span class="p">):</span>
</span><span id="unnest-64"><a href="#unnest-64"><span class="linenos">64</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</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="unnest-65"><a href="#unnest-65"><span class="linenos">65</span></a>
</span><span id="unnest-66"><a href="#unnest-66"><span class="linenos">66</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>
</span><span id="unnest-67"><a href="#unnest-67"><span class="linenos">67</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</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="unnest-68"><a href="#unnest-68"><span class="linenos">68</span></a> <span class="k">return</span>
</span><span id="unnest-54"><a href="#unnest-54"><span class="linenos">54</span></a> <span class="c1"># This subquery returns a scalar and can just be converted to a cross join</span>
</span><span id="unnest-55"><a href="#unnest-55"><span class="linenos">55</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">)):</span>
</span><span id="unnest-56"><a href="#unnest-56"><span class="linenos">56</span></a> <span class="n">column</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">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">alias</span><span class="p">)</span>
</span><span id="unnest-57"><a href="#unnest-57"><span class="linenos">57</span></a>
</span><span id="unnest-58"><a href="#unnest-58"><span class="linenos">58</span></a> <span class="n">clause</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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">Where</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="unnest-59"><a href="#unnest-59"><span class="linenos">59</span></a> <span class="n">clause_parent_select</span> <span class="o">=</span> <span class="n">clause</span><span class="o">.</span><span class="n">parent_select</span> <span class="k">if</span> <span class="n">clause</span> <span class="k">else</span> <span class="kc">None</span>
</span><span id="unnest-60"><a href="#unnest-60"><span class="linenos">60</span></a>
</span><span id="unnest-61"><a href="#unnest-61"><span class="linenos">61</span></a> <span class="k">if</span> <span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">clause</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="ow">and</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="n">parent_select</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span>
</span><span id="unnest-62"><a href="#unnest-62"><span class="linenos">62</span></a> <span class="p">(</span><span class="ow">not</span> <span class="n">clause</span> <span class="ow">or</span> <span class="n">clause_parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">parent_select</span><span class="p">)</span>
</span><span id="unnest-63"><a href="#unnest-63"><span class="linenos">63</span></a> <span class="ow">and</span> <span class="p">(</span>
</span><span id="unnest-64"><a href="#unnest-64"><span class="linenos">64</span></a> <span class="n">parent_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;group&quot;</span><span class="p">)</span>
</span><span id="unnest-65"><a href="#unnest-65"><span class="linenos">65</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">projection</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="k">for</span> <span class="n">projection</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="unnest-66"><a href="#unnest-66"><span class="linenos">66</span></a> <span class="p">)</span>
</span><span id="unnest-67"><a href="#unnest-67"><span class="linenos">67</span></a> <span class="p">):</span>
</span><span id="unnest-68"><a href="#unnest-68"><span class="linenos">68</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</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="unnest-69"><a href="#unnest-69"><span class="linenos">69</span></a>
</span><span id="unnest-70"><a href="#unnest-70"><span class="linenos">70</span></a> <span class="k">if</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="unnest-71"><a href="#unnest-71"><span class="linenos">71</span></a> <span class="k">return</span>
</span><span id="unnest-72"><a href="#unnest-72"><span class="linenos">72</span></a>
</span><span id="unnest-73"><a href="#unnest-73"><span class="linenos">73</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="unnest-74"><a href="#unnest-74"><span class="linenos">74</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span>
</span><span id="unnest-75"><a href="#unnest-75"><span class="linenos">75</span></a>
</span><span id="unnest-76"><a href="#unnest-76"><span class="linenos">76</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="unnest-77"><a href="#unnest-77"><span class="linenos">77</span></a> <span class="k">return</span>
</span><span id="unnest-78"><a href="#unnest-78"><span class="linenos">78</span></a>
</span><span id="unnest-79"><a href="#unnest-79"><span class="linenos">79</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">predicate</span><span class="p">)</span>
</span><span id="unnest-80"><a href="#unnest-80"><span class="linenos">80</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="unnest-81"><a href="#unnest-81"><span class="linenos">81</span></a>
</span><span id="unnest-82"><a href="#unnest-82"><span class="linenos">82</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">condition</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s1"> = &quot;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;.&quot;</span><span class="si">{</span><span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="unnest-83"><a href="#unnest-83"><span class="linenos">83</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">on</span><span class="o">.</span><span class="n">right</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="unnest-84"><a href="#unnest-84"><span class="linenos">84</span></a>
</span><span id="unnest-85"><a href="#unnest-85"><span class="linenos">85</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="unnest-86"><a href="#unnest-86"><span class="linenos">86</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">this</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="unnest-87"><a href="#unnest-87"><span class="linenos">87</span></a> <span class="n">on</span><span class="o">=</span><span class="n">on</span><span class="p">,</span>
</span><span id="unnest-88"><a href="#unnest-88"><span class="linenos">88</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="unnest-89"><a href="#unnest-89"><span class="linenos">89</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="unnest-90"><a href="#unnest-90"><span class="linenos">90</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="unnest-91"><a href="#unnest-91"><span class="linenos">91</span></a> <span class="p">)</span>
</span><span id="unnest-70"><a href="#unnest-70"><span class="linenos">70</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>
</span><span id="unnest-71"><a href="#unnest-71"><span class="linenos">71</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&quot;</span><span class="p">,</span> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</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="unnest-72"><a href="#unnest-72"><span class="linenos">72</span></a> <span class="k">return</span>
</span><span id="unnest-73"><a href="#unnest-73"><span class="linenos">73</span></a>
</span><span id="unnest-74"><a href="#unnest-74"><span class="linenos">74</span></a> <span class="k">if</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="unnest-75"><a href="#unnest-75"><span class="linenos">75</span></a> <span class="k">return</span>
</span><span id="unnest-76"><a href="#unnest-76"><span class="linenos">76</span></a>
</span><span id="unnest-77"><a href="#unnest-77"><span class="linenos">77</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="unnest-78"><a href="#unnest-78"><span class="linenos">78</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span>
</span><span id="unnest-79"><a href="#unnest-79"><span class="linenos">79</span></a>
</span><span id="unnest-80"><a href="#unnest-80"><span class="linenos">80</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">parent_select</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">predicate</span><span class="o">.</span><span class="n">parent_select</span><span class="p">:</span>
</span><span id="unnest-81"><a href="#unnest-81"><span class="linenos">81</span></a> <span class="k">return</span>
</span><span id="unnest-82"><a href="#unnest-82"><span class="linenos">82</span></a>
</span><span id="unnest-83"><a href="#unnest-83"><span class="linenos">83</span></a> <span class="n">column</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">predicate</span><span class="p">)</span>
</span><span id="unnest-84"><a href="#unnest-84"><span class="linenos">84</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="unnest-85"><a href="#unnest-85"><span class="linenos">85</span></a>
</span><span id="unnest-86"><a href="#unnest-86"><span class="linenos">86</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">condition</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s1"> = &quot;</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;.&quot;</span><span class="si">{</span><span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="si">}</span><span class="s1">&quot;&#39;</span><span class="p">)</span>
</span><span id="unnest-87"><a href="#unnest-87"><span class="linenos">87</span></a> <span class="n">_replace</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">on</span><span class="o">.</span><span class="n">right</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="unnest-88"><a href="#unnest-88"><span class="linenos">88</span></a>
</span><span id="unnest-89"><a href="#unnest-89"><span class="linenos">89</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="unnest-90"><a href="#unnest-90"><span class="linenos">90</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">this</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="unnest-91"><a href="#unnest-91"><span class="linenos">91</span></a> <span class="n">on</span><span class="o">=</span><span class="n">on</span><span class="p">,</span>
</span><span id="unnest-92"><a href="#unnest-92"><span class="linenos">92</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="unnest-93"><a href="#unnest-93"><span class="linenos">93</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="unnest-94"><a href="#unnest-94"><span class="linenos">94</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="unnest-95"><a href="#unnest-95"><span class="linenos">95</span></a> <span class="p">)</span>
</span></pre></div>
@ -491,161 +499,161 @@ Convert correlated or vectorized subqueries into a group by so it is not a many
</div>
<a class="headerlink" href="#decorrelate"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="decorrelate-94"><a href="#decorrelate-94"><span class="linenos"> 94</span></a><span class="k">def</span> <span class="nf">decorrelate</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">parent_select</span><span class="p">,</span> <span class="n">external_columns</span><span class="p">,</span> <span class="n">next_alias_name</span><span class="p">):</span>
</span><span id="decorrelate-95"><a href="#decorrelate-95"><span class="linenos"> 95</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">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;where&quot;</span><span class="p">)</span>
</span><span id="decorrelate-96"><a href="#decorrelate-96"><span class="linenos"> 96</span></a>
</span><span id="decorrelate-97"><a href="#decorrelate-97"><span class="linenos"> 97</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="n">where</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">Or</span><span class="p">)</span> <span class="ow">or</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="decorrelate-98"><a href="#decorrelate-98"><span class="linenos"> 98</span></a> <span class="k">return</span>
</span><span id="decorrelate-99"><a href="#decorrelate-99"><span class="linenos"> 99</span></a>
</span><span id="decorrelate-100"><a href="#decorrelate-100"><span class="linenos">100</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="decorrelate-101"><a href="#decorrelate-101"><span class="linenos">101</span></a> <span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-102"><a href="#decorrelate-102"><span class="linenos">102</span></a>
</span><span id="decorrelate-103"><a href="#decorrelate-103"><span class="linenos">103</span></a> <span class="c1"># for all external columns in the where statement, find the relevant predicate</span>
</span><span id="decorrelate-104"><a href="#decorrelate-104"><span class="linenos">104</span></a> <span class="c1"># keys to convert it into a join</span>
</span><span id="decorrelate-105"><a href="#decorrelate-105"><span class="linenos">105</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">external_columns</span><span class="p">:</span>
</span><span id="decorrelate-106"><a href="#decorrelate-106"><span class="linenos">106</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="decorrelate-107"><a href="#decorrelate-107"><span class="linenos">107</span></a> <span class="k">return</span>
</span><span id="decorrelate-108"><a href="#decorrelate-108"><span class="linenos">108</span></a>
</span><span id="decorrelate-109"><a href="#decorrelate-109"><span class="linenos">109</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="decorrelate-110"><a href="#decorrelate-110"><span class="linenos">110</span></a>
</span><span id="decorrelate-111"><a href="#decorrelate-111"><span class="linenos">111</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="decorrelate-112"><a href="#decorrelate-112"><span class="linenos">112</span></a> <span class="k">return</span>
</span><span id="decorrelate-113"><a href="#decorrelate-113"><span class="linenos">113</span></a>
</span><span id="decorrelate-114"><a href="#decorrelate-114"><span class="linenos">114</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</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="decorrelate-115"><a href="#decorrelate-115"><span class="linenos">115</span></a> <span class="n">key</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="decorrelate-116"><a href="#decorrelate-116"><span class="linenos">116</span></a> <span class="n">predicate</span><span class="o">.</span><span class="n">right</span>
</span><span id="decorrelate-117"><a href="#decorrelate-117"><span class="linenos">117</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">node</span> <span class="ow">is</span> <span class="n">column</span> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">walk</span><span class="p">())</span>
</span><span id="decorrelate-118"><a href="#decorrelate-118"><span class="linenos">118</span></a> <span class="k">else</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span>
</span><span id="decorrelate-119"><a href="#decorrelate-119"><span class="linenos">119</span></a> <span class="p">)</span>
</span><span id="decorrelate-120"><a href="#decorrelate-120"><span class="linenos">120</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-121"><a href="#decorrelate-121"><span class="linenos">121</span></a> <span class="k">return</span>
</span><span id="decorrelate-122"><a href="#decorrelate-122"><span class="linenos">122</span></a>
</span><span id="decorrelate-123"><a href="#decorrelate-123"><span class="linenos">123</span></a> <span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span><span class="p">))</span>
</span><span id="decorrelate-124"><a href="#decorrelate-124"><span class="linenos">124</span></a>
</span><span id="decorrelate-125"><a href="#decorrelate-125"><span class="linenos">125</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">):</span>
</span><span id="decorrelate-126"><a href="#decorrelate-126"><span class="linenos">126</span></a> <span class="k">return</span>
</span><span id="decorrelate-127"><a href="#decorrelate-127"><span class="linenos">127</span></a>
</span><span id="decorrelate-128"><a href="#decorrelate-128"><span class="linenos">128</span></a> <span class="n">is_subquery_projection</span> <span class="o">=</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="decorrelate-129"><a href="#decorrelate-129"><span class="linenos">129</span></a> <span class="n">node</span> <span class="ow">is</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span> <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">Subquery</span><span class="p">)</span>
</span><span id="decorrelate-130"><a href="#decorrelate-130"><span class="linenos">130</span></a> <span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="decorrelate-98"><a href="#decorrelate-98"><span class="linenos"> 98</span></a><span class="k">def</span> <span class="nf">decorrelate</span><span class="p">(</span><span class="n">select</span><span class="p">,</span> <span class="n">parent_select</span><span class="p">,</span> <span class="n">external_columns</span><span class="p">,</span> <span class="n">next_alias_name</span><span class="p">):</span>
</span><span id="decorrelate-99"><a href="#decorrelate-99"><span class="linenos"> 99</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">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;where&quot;</span><span class="p">)</span>
</span><span id="decorrelate-100"><a href="#decorrelate-100"><span class="linenos">100</span></a>
</span><span id="decorrelate-101"><a href="#decorrelate-101"><span class="linenos">101</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="n">where</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">Or</span><span class="p">)</span> <span class="ow">or</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">Limit</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Offset</span><span class="p">):</span>
</span><span id="decorrelate-102"><a href="#decorrelate-102"><span class="linenos">102</span></a> <span class="k">return</span>
</span><span id="decorrelate-103"><a href="#decorrelate-103"><span class="linenos">103</span></a>
</span><span id="decorrelate-104"><a href="#decorrelate-104"><span class="linenos">104</span></a> <span class="n">table_alias</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="decorrelate-105"><a href="#decorrelate-105"><span class="linenos">105</span></a> <span class="n">keys</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-106"><a href="#decorrelate-106"><span class="linenos">106</span></a>
</span><span id="decorrelate-107"><a href="#decorrelate-107"><span class="linenos">107</span></a> <span class="c1"># for all external columns in the where statement, find the relevant predicate</span>
</span><span id="decorrelate-108"><a href="#decorrelate-108"><span class="linenos">108</span></a> <span class="c1"># keys to convert it into a join</span>
</span><span id="decorrelate-109"><a href="#decorrelate-109"><span class="linenos">109</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">external_columns</span><span class="p">:</span>
</span><span id="decorrelate-110"><a href="#decorrelate-110"><span class="linenos">110</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="decorrelate-111"><a href="#decorrelate-111"><span class="linenos">111</span></a> <span class="k">return</span>
</span><span id="decorrelate-112"><a href="#decorrelate-112"><span class="linenos">112</span></a>
</span><span id="decorrelate-113"><a href="#decorrelate-113"><span class="linenos">113</span></a> <span class="n">predicate</span> <span class="o">=</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="decorrelate-114"><a href="#decorrelate-114"><span class="linenos">114</span></a>
</span><span id="decorrelate-115"><a href="#decorrelate-115"><span class="linenos">115</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">predicate</span> <span class="ow">or</span> <span class="n">predicate</span><span class="o">.</span><span class="n">find_ancestor</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="ow">is</span> <span class="ow">not</span> <span class="n">where</span><span class="p">:</span>
</span><span id="decorrelate-116"><a href="#decorrelate-116"><span class="linenos">116</span></a> <span class="k">return</span>
</span><span id="decorrelate-117"><a href="#decorrelate-117"><span class="linenos">117</span></a>
</span><span id="decorrelate-118"><a href="#decorrelate-118"><span class="linenos">118</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</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="decorrelate-119"><a href="#decorrelate-119"><span class="linenos">119</span></a> <span class="n">key</span> <span class="o">=</span> <span class="p">(</span>
</span><span id="decorrelate-120"><a href="#decorrelate-120"><span class="linenos">120</span></a> <span class="n">predicate</span><span class="o">.</span><span class="n">right</span>
</span><span id="decorrelate-121"><a href="#decorrelate-121"><span class="linenos">121</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">node</span> <span class="ow">is</span> <span class="n">column</span> <span class="k">for</span> <span class="n">node</span><span class="p">,</span> <span class="o">*</span><span class="n">_</span> <span class="ow">in</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">walk</span><span class="p">())</span>
</span><span id="decorrelate-122"><a href="#decorrelate-122"><span class="linenos">122</span></a> <span class="k">else</span> <span class="n">predicate</span><span class="o">.</span><span class="n">left</span>
</span><span id="decorrelate-123"><a href="#decorrelate-123"><span class="linenos">123</span></a> <span class="p">)</span>
</span><span id="decorrelate-124"><a href="#decorrelate-124"><span class="linenos">124</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-125"><a href="#decorrelate-125"><span class="linenos">125</span></a> <span class="k">return</span>
</span><span id="decorrelate-126"><a href="#decorrelate-126"><span class="linenos">126</span></a>
</span><span id="decorrelate-127"><a href="#decorrelate-127"><span class="linenos">127</span></a> <span class="n">keys</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span><span class="p">))</span>
</span><span id="decorrelate-128"><a href="#decorrelate-128"><span class="linenos">128</span></a>
</span><span id="decorrelate-129"><a href="#decorrelate-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">):</span>
</span><span id="decorrelate-130"><a href="#decorrelate-130"><span class="linenos">130</span></a> <span class="k">return</span>
</span><span id="decorrelate-131"><a href="#decorrelate-131"><span class="linenos">131</span></a>
</span><span id="decorrelate-132"><a href="#decorrelate-132"><span class="linenos">132</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="decorrelate-133"><a href="#decorrelate-133"><span class="linenos">133</span></a> <span class="n">key_aliases</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="decorrelate-134"><a href="#decorrelate-134"><span class="linenos">134</span></a> <span class="n">group_by</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-132"><a href="#decorrelate-132"><span class="linenos">132</span></a> <span class="n">is_subquery_projection</span> <span class="o">=</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="decorrelate-133"><a href="#decorrelate-133"><span class="linenos">133</span></a> <span class="n">node</span> <span class="ow">is</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">parent_select</span><span class="o">.</span><span class="n">selects</span> <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">Subquery</span><span class="p">)</span>
</span><span id="decorrelate-134"><a href="#decorrelate-134"><span class="linenos">134</span></a> <span class="p">)</span>
</span><span id="decorrelate-135"><a href="#decorrelate-135"><span class="linenos">135</span></a>
</span><span id="decorrelate-136"><a href="#decorrelate-136"><span class="linenos">136</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="decorrelate-137"><a href="#decorrelate-137"><span class="linenos">137</span></a> <span class="c1"># if we filter on the value of the subquery, it needs to be unique</span>
</span><span id="decorrelate-138"><a href="#decorrelate-138"><span class="linenos">138</span></a> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="decorrelate-139"><a href="#decorrelate-139"><span class="linenos">139</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span>
</span><span id="decorrelate-140"><a href="#decorrelate-140"><span class="linenos">140</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="decorrelate-141"><a href="#decorrelate-141"><span class="linenos">141</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-142"><a href="#decorrelate-142"><span class="linenos">142</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="p">:</span>
</span><span id="decorrelate-143"><a href="#decorrelate-143"><span class="linenos">143</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="decorrelate-144"><a href="#decorrelate-144"><span class="linenos">144</span></a> <span class="c1"># all predicates that are equalities must also be in the unique</span>
</span><span id="decorrelate-145"><a href="#decorrelate-145"><span class="linenos">145</span></a> <span class="c1"># so that we don&#39;t do a many to many join</span>
</span><span id="decorrelate-146"><a href="#decorrelate-146"><span class="linenos">146</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-147"><a href="#decorrelate-147"><span class="linenos">147</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="decorrelate-148"><a href="#decorrelate-148"><span class="linenos">148</span></a>
</span><span id="decorrelate-149"><a href="#decorrelate-149"><span class="linenos">149</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="decorrelate-150"><a href="#decorrelate-150"><span class="linenos">150</span></a>
</span><span id="decorrelate-151"><a href="#decorrelate-151"><span class="linenos">151</span></a> <span class="c1"># if the value of the subquery is not an agg or a key, we need to collect it into an array</span>
</span><span id="decorrelate-152"><a href="#decorrelate-152"><span class="linenos">152</span></a> <span class="c1"># so that it can be grouped. For subquery projections, we use a MAX aggregation instead.</span>
</span><span id="decorrelate-153"><a href="#decorrelate-153"><span class="linenos">153</span></a> <span class="n">agg_func</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span> <span class="k">if</span> <span class="n">is_subquery_projection</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArrayAgg</span>
</span><span id="decorrelate-154"><a href="#decorrelate-154"><span class="linenos">154</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">value</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="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-155"><a href="#decorrelate-155"><span class="linenos">155</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span>
</span><span id="decorrelate-156"><a href="#decorrelate-156"><span class="linenos">156</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">),</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</span><span class="p">),</span>
</span><span id="decorrelate-157"><a href="#decorrelate-157"><span class="linenos">157</span></a> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-158"><a href="#decorrelate-158"><span class="linenos">158</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-159"><a href="#decorrelate-159"><span class="linenos">159</span></a> <span class="p">)</span>
</span><span id="decorrelate-160"><a href="#decorrelate-160"><span class="linenos">160</span></a>
</span><span id="decorrelate-161"><a href="#decorrelate-161"><span class="linenos">161</span></a> <span class="c1"># exists queries should not have any selects as it only checks if there are any rows</span>
</span><span id="decorrelate-162"><a href="#decorrelate-162"><span class="linenos">162</span></a> <span class="c1"># all selects will be added by the optimizer and only used for join keys</span>
</span><span id="decorrelate-163"><a href="#decorrelate-163"><span class="linenos">163</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="decorrelate-164"><a href="#decorrelate-164"><span class="linenos">164</span></a> <span class="n">select</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;expressions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-165"><a href="#decorrelate-165"><span class="linenos">165</span></a>
</span><span id="decorrelate-166"><a href="#decorrelate-166"><span class="linenos">166</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="decorrelate-167"><a href="#decorrelate-167"><span class="linenos">167</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-168"><a href="#decorrelate-168"><span class="linenos">168</span></a> <span class="c1"># add all keys to the projections of the subquery</span>
</span><span id="decorrelate-169"><a href="#decorrelate-169"><span class="linenos">169</span></a> <span class="c1"># so that we can use it as a join key</span>
</span><span id="decorrelate-170"><a href="#decorrelate-170"><span class="linenos">170</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">)</span> <span class="ow">or</span> <span class="n">key</span> <span class="o">!=</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="decorrelate-171"><a href="#decorrelate-171"><span class="linenos">171</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> AS </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&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="decorrelate-172"><a href="#decorrelate-172"><span class="linenos">172</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-173"><a href="#decorrelate-173"><span class="linenos">173</span></a> <span class="n">select</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">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">key</span><span class="o">.</span><span class="n">copy</span><span class="p">()),</span> <span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</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="decorrelate-174"><a href="#decorrelate-174"><span class="linenos">174</span></a>
</span><span id="decorrelate-175"><a href="#decorrelate-175"><span class="linenos">175</span></a> <span class="n">alias</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">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-176"><a href="#decorrelate-176"><span class="linenos">176</span></a> <span class="n">other</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">)</span>
</span><span id="decorrelate-177"><a href="#decorrelate-177"><span class="linenos">177</span></a>
</span><span id="decorrelate-178"><a href="#decorrelate-178"><span class="linenos">178</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="decorrelate-179"><a href="#decorrelate-179"><span class="linenos">179</span></a> <span class="n">alias</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="nb">list</span><span class="p">(</span><span class="n">key_aliases</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-180"><a href="#decorrelate-180"><span class="linenos">180</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="decorrelate-181"><a href="#decorrelate-181"><span class="linenos">181</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">):</span>
</span><span id="decorrelate-182"><a href="#decorrelate-182"><span class="linenos">182</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-183"><a href="#decorrelate-183"><span class="linenos">183</span></a> <span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ALL(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span>
</span><span id="decorrelate-184"><a href="#decorrelate-184"><span class="linenos">184</span></a> <span class="p">)</span>
</span><span id="decorrelate-185"><a href="#decorrelate-185"><span class="linenos">185</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="decorrelate-186"><a href="#decorrelate-186"><span class="linenos">186</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-187"><a href="#decorrelate-187"><span class="linenos">187</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="decorrelate-188"><a href="#decorrelate-188"><span class="linenos">188</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-189"><a href="#decorrelate-189"><span class="linenos">189</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</span><span id="decorrelate-190"><a href="#decorrelate-190"><span class="linenos">190</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">):</span>
</span><span id="decorrelate-191"><a href="#decorrelate-191"><span class="linenos">191</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-192"><a href="#decorrelate-192"><span class="linenos">192</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="decorrelate-193"><a href="#decorrelate-193"><span class="linenos">193</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-194"><a href="#decorrelate-194"><span class="linenos">194</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-195"><a href="#decorrelate-195"><span class="linenos">195</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-196"><a href="#decorrelate-196"><span class="linenos">196</span></a> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">,</span>
</span><span id="decorrelate-197"><a href="#decorrelate-197"><span class="linenos">197</span></a> <span class="p">)</span>
</span><span id="decorrelate-198"><a href="#decorrelate-198"><span class="linenos">198</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-199"><a href="#decorrelate-199"><span class="linenos">199</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="decorrelate-200"><a href="#decorrelate-200"><span class="linenos">200</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">)</span>
</span><span id="decorrelate-201"><a href="#decorrelate-201"><span class="linenos">201</span></a>
</span><span id="decorrelate-202"><a href="#decorrelate-202"><span class="linenos">202</span></a> <span class="c1"># COUNT always returns 0 on empty datasets, so we need take that into consideration here</span>
</span><span id="decorrelate-203"><a href="#decorrelate-203"><span class="linenos">203</span></a> <span class="c1"># by transforming all counts into 0 and using that as the coalesced value</span>
</span><span id="decorrelate-204"><a href="#decorrelate-204"><span class="linenos">204</span></a> <span class="k">if</span> <span class="n">value</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">Count</span><span class="p">):</span>
</span><span id="decorrelate-136"><a href="#decorrelate-136"><span class="linenos">136</span></a> <span class="n">value</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span id="decorrelate-137"><a href="#decorrelate-137"><span class="linenos">137</span></a> <span class="n">key_aliases</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="decorrelate-138"><a href="#decorrelate-138"><span class="linenos">138</span></a> <span class="n">group_by</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-139"><a href="#decorrelate-139"><span class="linenos">139</span></a>
</span><span id="decorrelate-140"><a href="#decorrelate-140"><span class="linenos">140</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="decorrelate-141"><a href="#decorrelate-141"><span class="linenos">141</span></a> <span class="c1"># if we filter on the value of the subquery, it needs to be unique</span>
</span><span id="decorrelate-142"><a href="#decorrelate-142"><span class="linenos">142</span></a> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="decorrelate-143"><a href="#decorrelate-143"><span class="linenos">143</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span>
</span><span id="decorrelate-144"><a href="#decorrelate-144"><span class="linenos">144</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="decorrelate-145"><a href="#decorrelate-145"><span class="linenos">145</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-146"><a href="#decorrelate-146"><span class="linenos">146</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="p">:</span>
</span><span id="decorrelate-147"><a href="#decorrelate-147"><span class="linenos">147</span></a> <span class="n">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">next_alias_name</span><span class="p">()</span>
</span><span id="decorrelate-148"><a href="#decorrelate-148"><span class="linenos">148</span></a> <span class="c1"># all predicates that are equalities must also be in the unique</span>
</span><span id="decorrelate-149"><a href="#decorrelate-149"><span class="linenos">149</span></a> <span class="c1"># so that we don&#39;t do a many to many join</span>
</span><span id="decorrelate-150"><a href="#decorrelate-150"><span class="linenos">150</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-151"><a href="#decorrelate-151"><span class="linenos">151</span></a> <span class="n">group_by</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span id="decorrelate-152"><a href="#decorrelate-152"><span class="linenos">152</span></a>
</span><span id="decorrelate-153"><a href="#decorrelate-153"><span class="linenos">153</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Predicate</span><span class="p">)</span>
</span><span id="decorrelate-154"><a href="#decorrelate-154"><span class="linenos">154</span></a>
</span><span id="decorrelate-155"><a href="#decorrelate-155"><span class="linenos">155</span></a> <span class="c1"># if the value of the subquery is not an agg or a key, we need to collect it into an array</span>
</span><span id="decorrelate-156"><a href="#decorrelate-156"><span class="linenos">156</span></a> <span class="c1"># so that it can be grouped. For subquery projections, we use a MAX aggregation instead.</span>
</span><span id="decorrelate-157"><a href="#decorrelate-157"><span class="linenos">157</span></a> <span class="n">agg_func</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Max</span> <span class="k">if</span> <span class="n">is_subquery_projection</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">ArrayAgg</span>
</span><span id="decorrelate-158"><a href="#decorrelate-158"><span class="linenos">158</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">value</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="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-159"><a href="#decorrelate-159"><span class="linenos">159</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span>
</span><span id="decorrelate-160"><a href="#decorrelate-160"><span class="linenos">160</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">),</span> <span class="n">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</span><span class="p">),</span>
</span><span id="decorrelate-161"><a href="#decorrelate-161"><span class="linenos">161</span></a> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-162"><a href="#decorrelate-162"><span class="linenos">162</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-163"><a href="#decorrelate-163"><span class="linenos">163</span></a> <span class="p">)</span>
</span><span id="decorrelate-164"><a href="#decorrelate-164"><span class="linenos">164</span></a>
</span><span id="decorrelate-165"><a href="#decorrelate-165"><span class="linenos">165</span></a> <span class="c1"># exists queries should not have any selects as it only checks if there are any rows</span>
</span><span id="decorrelate-166"><a href="#decorrelate-166"><span class="linenos">166</span></a> <span class="c1"># all selects will be added by the optimizer and only used for join keys</span>
</span><span id="decorrelate-167"><a href="#decorrelate-167"><span class="linenos">167</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="decorrelate-168"><a href="#decorrelate-168"><span class="linenos">168</span></a> <span class="n">select</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;expressions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="decorrelate-169"><a href="#decorrelate-169"><span class="linenos">169</span></a>
</span><span id="decorrelate-170"><a href="#decorrelate-170"><span class="linenos">170</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">key_aliases</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="decorrelate-171"><a href="#decorrelate-171"><span class="linenos">171</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-172"><a href="#decorrelate-172"><span class="linenos">172</span></a> <span class="c1"># add all keys to the projections of the subquery</span>
</span><span id="decorrelate-173"><a href="#decorrelate-173"><span class="linenos">173</span></a> <span class="c1"># so that we can use it as a join key</span>
</span><span id="decorrelate-174"><a href="#decorrelate-174"><span class="linenos">174</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">)</span> <span class="ow">or</span> <span class="n">key</span> <span class="o">!=</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="decorrelate-175"><a href="#decorrelate-175"><span class="linenos">175</span></a> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2"> AS </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&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="decorrelate-176"><a href="#decorrelate-176"><span class="linenos">176</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-177"><a href="#decorrelate-177"><span class="linenos">177</span></a> <span class="n">select</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">alias_</span><span class="p">(</span><span class="n">agg_func</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">key</span><span class="o">.</span><span class="n">copy</span><span class="p">()),</span> <span class="n">alias</span><span class="p">,</span> <span class="n">quoted</span><span class="o">=</span><span class="kc">False</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="decorrelate-178"><a href="#decorrelate-178"><span class="linenos">178</span></a>
</span><span id="decorrelate-179"><a href="#decorrelate-179"><span class="linenos">179</span></a> <span class="n">alias</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">value</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-180"><a href="#decorrelate-180"><span class="linenos">180</span></a> <span class="n">other</span> <span class="o">=</span> <span class="n">_other_operand</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">)</span>
</span><span id="decorrelate-181"><a href="#decorrelate-181"><span class="linenos">181</span></a>
</span><span id="decorrelate-182"><a href="#decorrelate-182"><span class="linenos">182</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Exists</span><span class="p">):</span>
</span><span id="decorrelate-183"><a href="#decorrelate-183"><span class="linenos">183</span></a> <span class="n">alias</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="nb">list</span><span class="p">(</span><span class="n">key_aliases</span><span class="o">.</span><span class="n">values</span><span class="p">())[</span><span class="mi">0</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-184"><a href="#decorrelate-184"><span class="linenos">184</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;NOT </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2"> IS NULL&quot;</span><span class="p">)</span>
</span><span id="decorrelate-185"><a href="#decorrelate-185"><span class="linenos">185</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">All</span><span class="p">):</span>
</span><span id="decorrelate-186"><a href="#decorrelate-186"><span class="linenos">186</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-187"><a href="#decorrelate-187"><span class="linenos">187</span></a> <span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ALL(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span>
</span><span id="decorrelate-188"><a href="#decorrelate-188"><span class="linenos">188</span></a> <span class="p">)</span>
</span><span id="decorrelate-189"><a href="#decorrelate-189"><span class="linenos">189</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Any</span><span class="p">):</span>
</span><span id="decorrelate-190"><a href="#decorrelate-190"><span class="linenos">190</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-191"><a href="#decorrelate-191"><span class="linenos">191</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="decorrelate-192"><a href="#decorrelate-192"><span class="linenos">192</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-193"><a href="#decorrelate-193"><span class="linenos">193</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</span><span id="decorrelate-194"><a href="#decorrelate-194"><span class="linenos">194</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">In</span><span class="p">):</span>
</span><span id="decorrelate-195"><a href="#decorrelate-195"><span class="linenos">195</span></a> <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">this</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-196"><a href="#decorrelate-196"><span class="linenos">196</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span><span class="n">parent_predicate</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">other</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span id="decorrelate-197"><a href="#decorrelate-197"><span class="linenos">197</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-198"><a href="#decorrelate-198"><span class="linenos">198</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-199"><a href="#decorrelate-199"><span class="linenos">199</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-200"><a href="#decorrelate-200"><span class="linenos">200</span></a> <span class="sa">f</span><span class="s2">&quot;ARRAY_ANY(</span><span class="si">{</span><span class="n">alias</span><span class="si">}</span><span class="s2">, _x -&gt; _x = </span><span class="si">{</span><span class="n">parent_predicate</span><span class="o">.</span><span class="n">this</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">,</span>
</span><span id="decorrelate-201"><a href="#decorrelate-201"><span class="linenos">201</span></a> <span class="p">)</span>
</span><span id="decorrelate-202"><a href="#decorrelate-202"><span class="linenos">202</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-203"><a href="#decorrelate-203"><span class="linenos">203</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="decorrelate-204"><a href="#decorrelate-204"><span class="linenos">204</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">)</span>
</span><span id="decorrelate-205"><a href="#decorrelate-205"><span class="linenos">205</span></a>
</span><span id="decorrelate-206"><a href="#decorrelate-206"><span class="linenos">206</span></a> <span class="k">def</span> <span class="nf">remove_aggs</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
</span><span id="decorrelate-207"><a href="#decorrelate-207"><span class="linenos">207</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">Count</span><span class="p">):</span>
</span><span id="decorrelate-208"><a href="#decorrelate-208"><span class="linenos">208</span></a> <span class="k">return</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="decorrelate-209"><a href="#decorrelate-209"><span class="linenos">209</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">AggFunc</span><span class="p">):</span>
</span><span id="decorrelate-210"><a href="#decorrelate-210"><span class="linenos">210</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">null</span><span class="p">()</span>
</span><span id="decorrelate-211"><a href="#decorrelate-211"><span class="linenos">211</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="decorrelate-212"><a href="#decorrelate-212"><span class="linenos">212</span></a>
</span><span id="decorrelate-213"><a href="#decorrelate-213"><span class="linenos">213</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Coalesce</span><span class="p">(</span>
</span><span id="decorrelate-214"><a href="#decorrelate-214"><span class="linenos">214</span></a> <span class="n">this</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="decorrelate-215"><a href="#decorrelate-215"><span class="linenos">215</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">remove_aggs</span><span class="p">)],</span>
</span><span id="decorrelate-216"><a href="#decorrelate-216"><span class="linenos">216</span></a> <span class="p">)</span>
</span><span id="decorrelate-217"><a href="#decorrelate-217"><span class="linenos">217</span></a>
</span><span id="decorrelate-218"><a href="#decorrelate-218"><span class="linenos">218</span></a> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
</span><span id="decorrelate-219"><a href="#decorrelate-219"><span class="linenos">219</span></a>
</span><span id="decorrelate-220"><a href="#decorrelate-220"><span class="linenos">220</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="decorrelate-221"><a href="#decorrelate-221"><span class="linenos">221</span></a> <span class="n">predicate</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">true</span><span class="p">())</span>
</span><span id="decorrelate-222"><a href="#decorrelate-222"><span class="linenos">222</span></a> <span class="n">nested</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">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-206"><a href="#decorrelate-206"><span class="linenos">206</span></a> <span class="c1"># COUNT always returns 0 on empty datasets, so we need take that into consideration here</span>
</span><span id="decorrelate-207"><a href="#decorrelate-207"><span class="linenos">207</span></a> <span class="c1"># by transforming all counts into 0 and using that as the coalesced value</span>
</span><span id="decorrelate-208"><a href="#decorrelate-208"><span class="linenos">208</span></a> <span class="k">if</span> <span class="n">value</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">Count</span><span class="p">):</span>
</span><span id="decorrelate-209"><a href="#decorrelate-209"><span class="linenos">209</span></a>
</span><span id="decorrelate-210"><a href="#decorrelate-210"><span class="linenos">210</span></a> <span class="k">def</span> <span class="nf">remove_aggs</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
</span><span id="decorrelate-211"><a href="#decorrelate-211"><span class="linenos">211</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">Count</span><span class="p">):</span>
</span><span id="decorrelate-212"><a href="#decorrelate-212"><span class="linenos">212</span></a> <span class="k">return</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="decorrelate-213"><a href="#decorrelate-213"><span class="linenos">213</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">AggFunc</span><span class="p">):</span>
</span><span id="decorrelate-214"><a href="#decorrelate-214"><span class="linenos">214</span></a> <span class="k">return</span> <span class="n">exp</span><span class="o">.</span><span class="n">null</span><span class="p">()</span>
</span><span id="decorrelate-215"><a href="#decorrelate-215"><span class="linenos">215</span></a> <span class="k">return</span> <span class="n">node</span>
</span><span id="decorrelate-216"><a href="#decorrelate-216"><span class="linenos">216</span></a>
</span><span id="decorrelate-217"><a href="#decorrelate-217"><span class="linenos">217</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Coalesce</span><span class="p">(</span>
</span><span id="decorrelate-218"><a href="#decorrelate-218"><span class="linenos">218</span></a> <span class="n">this</span><span class="o">=</span><span class="n">alias</span><span class="p">,</span>
</span><span id="decorrelate-219"><a href="#decorrelate-219"><span class="linenos">219</span></a> <span class="n">expressions</span><span class="o">=</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">remove_aggs</span><span class="p">)],</span>
</span><span id="decorrelate-220"><a href="#decorrelate-220"><span class="linenos">220</span></a> <span class="p">)</span>
</span><span id="decorrelate-221"><a href="#decorrelate-221"><span class="linenos">221</span></a>
</span><span id="decorrelate-222"><a href="#decorrelate-222"><span class="linenos">222</span></a> <span class="n">select</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
</span><span id="decorrelate-223"><a href="#decorrelate-223"><span class="linenos">223</span></a>
</span><span id="decorrelate-224"><a href="#decorrelate-224"><span class="linenos">224</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="decorrelate-225"><a href="#decorrelate-225"><span class="linenos">225</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="decorrelate-226"><a href="#decorrelate-226"><span class="linenos">226</span></a> <span class="k">continue</span>
</span><span id="decorrelate-224"><a href="#decorrelate-224"><span class="linenos">224</span></a> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span><span class="p">:</span>
</span><span id="decorrelate-225"><a href="#decorrelate-225"><span class="linenos">225</span></a> <span class="n">predicate</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">true</span><span class="p">())</span>
</span><span id="decorrelate-226"><a href="#decorrelate-226"><span class="linenos">226</span></a> <span class="n">nested</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">key_aliases</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">table_alias</span><span class="p">)</span>
</span><span id="decorrelate-227"><a href="#decorrelate-227"><span class="linenos">227</span></a>
</span><span id="decorrelate-228"><a href="#decorrelate-228"><span class="linenos">228</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-228"><a href="#decorrelate-228"><span class="linenos">228</span></a> <span class="k">if</span> <span class="n">is_subquery_projection</span><span class="p">:</span>
</span><span id="decorrelate-229"><a href="#decorrelate-229"><span class="linenos">229</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="decorrelate-230"><a href="#decorrelate-230"><span class="linenos">230</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">):</span>
</span><span id="decorrelate-231"><a href="#decorrelate-231"><span class="linenos">231</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-232"><a href="#decorrelate-232"><span class="linenos">232</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-233"><a href="#decorrelate-233"><span class="linenos">233</span></a> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s2"> AND ARRAY_CONTAINS(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s2">))&quot;</span><span class="p">,</span>
</span><span id="decorrelate-234"><a href="#decorrelate-234"><span class="linenos">234</span></a> <span class="p">)</span>
</span><span id="decorrelate-235"><a href="#decorrelate-235"><span class="linenos">235</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-236"><a href="#decorrelate-236"><span class="linenos">236</span></a> <span class="n">key</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">to_identifier</span><span class="p">(</span><span class="s2">&quot;_x&quot;</span><span class="p">))</span>
</span><span id="decorrelate-237"><a href="#decorrelate-237"><span class="linenos">237</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-238"><a href="#decorrelate-238"><span class="linenos">238</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-239"><a href="#decorrelate-239"><span class="linenos">239</span></a> <span class="sa">f</span><span class="s1">&#39;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s1"> AND ARRAY_ANY(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s1">, &quot;_x&quot; -&gt; </span><span class="si">{</span><span class="n">predicate</span><span class="si">}</span><span class="s1">))&#39;</span><span class="p">,</span>
</span><span id="decorrelate-240"><a href="#decorrelate-240"><span class="linenos">240</span></a> <span class="p">)</span>
</span><span id="decorrelate-241"><a href="#decorrelate-241"><span class="linenos">241</span></a>
</span><span id="decorrelate-242"><a href="#decorrelate-242"><span class="linenos">242</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="decorrelate-243"><a href="#decorrelate-243"><span class="linenos">243</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="o">*</span><span class="n">group_by</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="decorrelate-244"><a href="#decorrelate-244"><span class="linenos">244</span></a> <span class="n">on</span><span class="o">=</span><span class="p">[</span><span class="n">predicate</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)],</span>
</span><span id="decorrelate-245"><a href="#decorrelate-245"><span class="linenos">245</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="decorrelate-246"><a href="#decorrelate-246"><span class="linenos">246</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">table_alias</span><span class="p">,</span>
</span><span id="decorrelate-247"><a href="#decorrelate-247"><span class="linenos">247</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-248"><a href="#decorrelate-248"><span class="linenos">248</span></a> <span class="p">)</span>
</span><span id="decorrelate-230"><a href="#decorrelate-230"><span class="linenos">230</span></a> <span class="k">continue</span>
</span><span id="decorrelate-231"><a href="#decorrelate-231"><span class="linenos">231</span></a>
</span><span id="decorrelate-232"><a href="#decorrelate-232"><span class="linenos">232</span></a> <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">group_by</span><span class="p">:</span>
</span><span id="decorrelate-233"><a href="#decorrelate-233"><span class="linenos">233</span></a> <span class="n">key</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">nested</span><span class="p">)</span>
</span><span id="decorrelate-234"><a href="#decorrelate-234"><span class="linenos">234</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">):</span>
</span><span id="decorrelate-235"><a href="#decorrelate-235"><span class="linenos">235</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-236"><a href="#decorrelate-236"><span class="linenos">236</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-237"><a href="#decorrelate-237"><span class="linenos">237</span></a> <span class="sa">f</span><span class="s2">&quot;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s2"> AND ARRAY_CONTAINS(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">column</span><span class="si">}</span><span class="s2">))&quot;</span><span class="p">,</span>
</span><span id="decorrelate-238"><a href="#decorrelate-238"><span class="linenos">238</span></a> <span class="p">)</span>
</span><span id="decorrelate-239"><a href="#decorrelate-239"><span class="linenos">239</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="decorrelate-240"><a href="#decorrelate-240"><span class="linenos">240</span></a> <span class="n">key</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">to_identifier</span><span class="p">(</span><span class="s2">&quot;_x&quot;</span><span class="p">))</span>
</span><span id="decorrelate-241"><a href="#decorrelate-241"><span class="linenos">241</span></a> <span class="n">parent_predicate</span> <span class="o">=</span> <span class="n">_replace</span><span class="p">(</span>
</span><span id="decorrelate-242"><a href="#decorrelate-242"><span class="linenos">242</span></a> <span class="n">parent_predicate</span><span class="p">,</span>
</span><span id="decorrelate-243"><a href="#decorrelate-243"><span class="linenos">243</span></a> <span class="sa">f</span><span class="s1">&#39;(</span><span class="si">{</span><span class="n">parent_predicate</span><span class="si">}</span><span class="s1"> AND ARRAY_ANY(</span><span class="si">{</span><span class="n">nested</span><span class="si">}</span><span class="s1">, &quot;_x&quot; -&gt; </span><span class="si">{</span><span class="n">predicate</span><span class="si">}</span><span class="s1">))&#39;</span><span class="p">,</span>
</span><span id="decorrelate-244"><a href="#decorrelate-244"><span class="linenos">244</span></a> <span class="p">)</span>
</span><span id="decorrelate-245"><a href="#decorrelate-245"><span class="linenos">245</span></a>
</span><span id="decorrelate-246"><a href="#decorrelate-246"><span class="linenos">246</span></a> <span class="n">parent_select</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span><span id="decorrelate-247"><a href="#decorrelate-247"><span class="linenos">247</span></a> <span class="n">select</span><span class="o">.</span><span class="n">group_by</span><span class="p">(</span><span class="o">*</span><span class="n">group_by</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="decorrelate-248"><a href="#decorrelate-248"><span class="linenos">248</span></a> <span class="n">on</span><span class="o">=</span><span class="p">[</span><span class="n">predicate</span> <span class="k">for</span> <span class="o">*</span><span class="n">_</span><span class="p">,</span> <span class="n">predicate</span> <span class="ow">in</span> <span class="n">keys</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">predicate</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">EQ</span><span class="p">)],</span>
</span><span id="decorrelate-249"><a href="#decorrelate-249"><span class="linenos">249</span></a> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;LEFT&quot;</span><span class="p">,</span>
</span><span id="decorrelate-250"><a href="#decorrelate-250"><span class="linenos">250</span></a> <span class="n">join_alias</span><span class="o">=</span><span class="n">table_alias</span><span class="p">,</span>
</span><span id="decorrelate-251"><a href="#decorrelate-251"><span class="linenos">251</span></a> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
</span><span id="decorrelate-252"><a href="#decorrelate-252"><span class="linenos">252</span></a> <span class="p">)</span>
</span></pre></div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -48,6 +48,12 @@
<li>
<a class="function" href="#explode_to_unnest">explode_to_unnest</a>
</li>
<li>
<a class="variable" href="#PERCENTILES">PERCENTILES</a>
</li>
<li>
<a class="function" href="#add_within_group_for_percentiles">add_within_group_for_percentiles</a>
</li>
<li>
<a class="function" href="#remove_within_group_for_percentiles">remove_within_group_for_percentiles</a>
</li>
@ -57,6 +63,12 @@
<li>
<a class="function" href="#epoch_cast_to_ts">epoch_cast_to_ts</a>
</li>
<li>
<a class="function" href="#timestamp_to_cast">timestamp_to_cast</a>
</li>
<li>
<a class="function" href="#eliminate_semi_and_anti_joins">eliminate_semi_and_anti_joins</a>
</li>
<li>
<a class="function" href="#preprocess">preprocess</a>
</li>
@ -231,7 +243,7 @@
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">):</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">unnest</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;alias&quot;</span><span class="p">)</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span> <span class="k">if</span> <span class="n">unnest</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;ordinality&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span> <span class="k">if</span> <span class="n">unnest</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;offset&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;joins&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">join</span><span class="p">)</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a>
@ -248,150 +260,260 @@
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a><span class="k">def</span> <span class="nf">explode_to_unnest</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-167"><a href="#L-167"><span class="linenos">167</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Convert explode/posexplode into unnest (used in hive -&gt; presto).&quot;&quot;&quot;</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</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-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="n">taken_select_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">named_selects</span><span class="p">)</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">taken_source_names</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">Scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">references</span><span class="p">}</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</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="p">:</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="n">to_replace</span> <span class="o">=</span> <span class="n">select</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a><span class="k">def</span> <span class="nf">explode_to_unnest</span><span class="p">(</span><span class="n">index_offset</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><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">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-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="k">def</span> <span class="nf">_explode_to_unnest</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-168"><a href="#L-168"><span class="linenos">168</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Convert explode/posexplode into unnest (used in hive -&gt; presto).&quot;&quot;&quot;</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</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-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">taken_select_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">named_selects</span><span class="p">)</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="n">taken_source_names</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">Scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">references</span><span class="p">}</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="k">def</span> <span class="nf">new_name</span><span class="p">(</span><span class="n">names</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Set</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="n">names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="k">return</span> <span class="n">name</span>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</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-181"><a href="#L-181"><span class="linenos">181</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-182"><a href="#L-182"><span class="linenos">182</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-183"><a href="#L-183"><span class="linenos">183</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-184"><a href="#L-184"><span class="linenos">184</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-185"><a href="#L-185"><span class="linenos">185</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-186"><a href="#L-186"><span class="linenos">186</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-187"><a href="#L-187"><span class="linenos">187</span></a>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</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-189"><a href="#L-189"><span class="linenos">189</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-190"><a href="#L-190"><span class="linenos">190</span></a>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</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-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">unnest</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span><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 class="n">ordinality</span><span class="o">=</span><span class="n">is_posexplode</span><span class="p">)</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="c1"># This ensures that we won&#39;t use [POS]EXPLODE&#39;s argument as a new selection</span>
</span><span id="L-195"><a href="#L-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_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-196"><a href="#L-196"><span class="linenos">196</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-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">unnest_source_alias</span> <span class="o">=</span> <span class="n">find_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-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="n">taken_source_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">unnest_source_alias</span><span class="p">)</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</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-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">find_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-203"><a href="#L-203"><span class="linenos">203</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_alias</span><span class="p">)</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="n">find_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-207"><a href="#L-207"><span class="linenos">207</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">pos_alias</span><span class="p">)</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="k">if</span> <span class="n">is_posexplode</span><span class="p">:</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="n">column_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">explode_alias</span><span class="p">,</span> <span class="n">pos_alias</span><span class="p">]</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="n">to_replace</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">,</span> <span class="n">explode_alias</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-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="n">column_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">explode_alias</span><span class="p">]</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="n">to_replace</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">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">))</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="n">arrays</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">exp</span><span class="o">.</span><span class="n">Condition</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="n">series_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-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="n">series</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <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">GenerateSeries</span><span class="p">(</span><span class="n">start</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="n">index_offset</span><span class="p">))]</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="p">),</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <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-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">series_alias</span><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-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-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-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-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-195"><a href="#L-195"><span class="linenos">195</span></a>
</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-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-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-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-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-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-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-203"><a href="#L-203"><span class="linenos">203</span></a>
</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-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-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-207"><a href="#L-207"><span class="linenos">207</span></a>
</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-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-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-211"><a href="#L-211"><span class="linenos">211</span></a>
</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-213"><a href="#L-213"><span class="linenos">213</span></a>
</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-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-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="n">unnest</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">unnest_source_alias</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="n">column_names</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 class="k">if</span> <span class="ow">not</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-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnest</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-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&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-223"><a href="#L-223"><span class="linenos">223</span></a>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</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-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</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-230"><a href="#L-230"><span class="linenos">230</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="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-231"><a href="#L-231"><span class="linenos">231</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-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="p">):</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</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-234"><a href="#L-234"><span class="linenos">234</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-235"><a href="#L-235"><span class="linenos">235</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-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="k">return</span> <span class="n">expression</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</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-241"><a href="#L-241"><span class="linenos">241</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-242"><a href="#L-242"><span class="linenos">242</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-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-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-219"><a href="#L-219"><span class="linenos">219</span></a>
</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-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-222"><a href="#L-222"><span class="linenos">222</span></a>
</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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-239"><a href="#L-239"><span class="linenos">239</span></a> <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-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="k">else</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-243"><a href="#L-243"><span class="linenos">243</span></a>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</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-245"><a href="#L-245"><span class="linenos">245</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-246"><a href="#L-246"><span class="linenos">246</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-247"><a href="#L-247"><span class="linenos">247</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-248"><a href="#L-248"><span class="linenos">248</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-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-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-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-247"><a href="#L-247"><span class="linenos">247</span></a> <span class="k">else</span><span class="p">:</span>
</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-249"><a href="#L-249"><span class="linenos">249</span></a>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</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-251"><a href="#L-251"><span class="linenos">251</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span>
</span><span id="L-252"><a href="#L-252"><span class="linenos">252</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-253"><a href="#L-253"><span class="linenos">253</span></a> <span class="p">)</span>
</span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a> <span class="k">return</span> <span class="n">expression</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><span id="L-258"><a href="#L-258"><span class="linenos">258</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-259"><a href="#L-259"><span class="linenos">259</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</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-261"><a href="#L-261"><span class="linenos">261</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-262"><a href="#L-262"><span class="linenos">262</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-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="p">):</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</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-265"><a href="#L-265"><span class="linenos">265</span></a>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="k">return</span> <span class="n">expression</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-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-252"><a href="#L-252"><span class="linenos">252</span></a>
</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-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-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-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-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-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-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-260"><a href="#L-260"><span class="linenos">260</span></a> <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-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-263"><a href="#L-263"><span class="linenos">263</span></a> <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-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-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="p">)</span>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span>
</span><span id="L-270"><a href="#L-270"><span class="linenos">270</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-271"><a href="#L-271"><span class="linenos">271</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-272"><a href="#L-272"><span class="linenos">272</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</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-275"><a href="#L-275"><span class="linenos">275</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a><span class="sd"> Args:</span>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</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-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-270"><a href="#L-270"><span class="linenos">270</span></a>
</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-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-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-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-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-276"><a href="#L-276"><span class="linenos">276</span></a> <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-278"><a href="#L-278"><span class="linenos">278</span></a> <span class="p">)</span>
</span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a>
</span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a><span class="sd"> Returns:</span>
</span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a><span class="sd"> Function that can be used as a generator transform.</span>
</span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a><span class="sd"> &quot;&quot;&quot;</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="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-285"><a href="#L-285"><span class="linenos">285</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-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-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-282"><a href="#L-282"><span class="linenos">282</span></a>
</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-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-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-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="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-288"><a href="#L-288"><span class="linenos">288</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-289"><a href="#L-289"><span class="linenos">289</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-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-288"><a href="#L-288"><span class="linenos">288</span></a>
</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-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 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-292"><a href="#L-292"><span class="linenos">292</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>
</span><span id="L-293"><a href="#L-293"><span class="linenos">293</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-291"><a href="#L-291"><span class="linenos">291</span></a>
</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-293"><a href="#L-293"><span class="linenos">293</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="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-296"><a href="#L-296"><span class="linenos">296</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span>
</span><span id="L-297"><a href="#L-297"><span class="linenos">297</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-298"><a href="#L-298"><span class="linenos">298</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-299"><a href="#L-299"><span class="linenos">299</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span>
</span><span id="L-300"><a href="#L-300"><span class="linenos">300</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-301"><a href="#L-301"><span class="linenos">301</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="L-302"><a href="#L-302"><span class="linenos">302</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-303"><a href="#L-303"><span class="linenos">303</span></a> <span class="p">)</span>
</span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a>
</span><span id="L-305"><a href="#L-305"><span class="linenos">305</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-306"><a href="#L-306"><span class="linenos">306</span></a>
</span><span id="L-307"><a href="#L-307"><span class="linenos">307</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-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-296"><a href="#L-296"><span class="linenos">296</span></a> <span class="k">if</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-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-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-300"><a href="#L-300"><span class="linenos">300</span></a> <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-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-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-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-305"><a href="#L-305"><span class="linenos">305</span></a>
</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-307"><a href="#L-307"><span class="linenos">307</span></a>
</span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a>
</span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a> <span class="k">return</span> <span class="n">_to_sql</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-310"><a href="#L-310"><span class="linenos">310</span></a> <span class="k">if</span> <span class="p">(</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-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-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-314"><a href="#L-314"><span class="linenos">314</span></a> <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-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-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-318"><a href="#L-318"><span class="linenos">318</span></a>
</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-320"><a href="#L-320"><span class="linenos">320</span></a>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a>
</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-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-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-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-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-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-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-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-331"><a href="#L-331"><span class="linenos">331</span></a>
</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-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-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-335"><a href="#L-335"><span class="linenos">335</span></a> <span class="p">)</span>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a>
</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-338"><a href="#L-338"><span class="linenos">338</span></a>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a>
</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-341"><a href="#L-341"><span class="linenos">341</span></a> <span class="k">if</span> <span class="p">(</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-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-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-345"><a href="#L-345"><span class="linenos">345</span></a> <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-347"><a href="#L-347"><span class="linenos">347</span></a>
</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-349"><a href="#L-349"><span class="linenos">349</span></a>
</span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a>
</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-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-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-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-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-356"><a href="#L-356"><span class="linenos">356</span></a> <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-358"><a href="#L-358"><span class="linenos">358</span></a>
</span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a>
</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-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-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-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-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-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-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-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-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-369"><a href="#L-369"><span class="linenos">369</span></a>
</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-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-372"><a href="#L-372"><span class="linenos">372</span></a>
</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-374"><a href="#L-374"><span class="linenos">374</span></a>
</span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a>
</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-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-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-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-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-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-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-383"><a href="#L-383"><span class="linenos">383</span></a>
</span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a><span class="sd"> Args:</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-386"><a href="#L-386"><span class="linenos">386</span></a>
</span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a><span class="sd"> Returns:</span>
</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-389"><a href="#L-389"><span class="linenos">389</span></a><span class="sd"> &quot;&quot;&quot;</span>
</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-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-393"><a href="#L-393"><span class="linenos">393</span></a>
</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-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-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-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-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-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-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-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-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-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-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-407"><a href="#L-407"><span class="linenos">407</span></a>
</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-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-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-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-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-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="p">)</span>
</span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a>
</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-416"><a href="#L-416"><span class="linenos">416</span></a>
</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-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></pre></div>
@ -658,7 +780,7 @@ other expressions. This transforms removes the precision from parameterized type
</span><span id="unnest_to_explode-147"><a href="#unnest_to_explode-147"><span class="linenos">147</span></a>
</span><span id="unnest_to_explode-148"><a href="#unnest_to_explode-148"><span class="linenos">148</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">):</span>
</span><span id="unnest_to_explode-149"><a href="#unnest_to_explode-149"><span class="linenos">149</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">unnest</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;alias&quot;</span><span class="p">)</span>
</span><span id="unnest_to_explode-150"><a href="#unnest_to_explode-150"><span class="linenos">150</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span> <span class="k">if</span> <span class="n">unnest</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;ordinality&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span>
</span><span id="unnest_to_explode-150"><a href="#unnest_to_explode-150"><span class="linenos">150</span></a> <span class="n">udtf</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Posexplode</span> <span class="k">if</span> <span class="n">unnest</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;offset&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span>
</span><span id="unnest_to_explode-151"><a href="#unnest_to_explode-151"><span class="linenos">151</span></a>
</span><span id="unnest_to_explode-152"><a href="#unnest_to_explode-152"><span class="linenos">152</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;joins&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">join</span><span class="p">)</span>
</span><span id="unnest_to_explode-153"><a href="#unnest_to_explode-153"><span class="linenos">153</span></a>
@ -686,76 +808,180 @@ other expressions. This transforms removes the precision from parameterized type
<div class="attr function">
<span class="def">def</span>
<span class="name">explode_to_unnest</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</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>
<span class="name">explode_to_unnest</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">index_offset</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span></span><span class="return-annotation">) -> <span class="n">Callable</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"><a href="expressions.html#Expression">sqlglot.expressions.Expression</a></span><span class="p">]</span>:</span></span>
<label class="view-source-button" for="explode_to_unnest-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#explode_to_unnest"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="explode_to_unnest-167"><a href="#explode_to_unnest-167"><span class="linenos">167</span></a><span class="k">def</span> <span class="nf">explode_to_unnest</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="explode_to_unnest-168"><a href="#explode_to_unnest-168"><span class="linenos">168</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Convert explode/posexplode into unnest (used in hive -&gt; presto).&quot;&quot;&quot;</span>
</span><span id="explode_to_unnest-169"><a href="#explode_to_unnest-169"><span class="linenos">169</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="explode_to_unnest-170"><a href="#explode_to_unnest-170"><span class="linenos">170</span></a> <span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span>
</span><span id="explode_to_unnest-171"><a href="#explode_to_unnest-171"><span class="linenos">171</span></a>
</span><span id="explode_to_unnest-172"><a href="#explode_to_unnest-172"><span class="linenos">172</span></a> <span class="n">taken_select_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">named_selects</span><span class="p">)</span>
</span><span id="explode_to_unnest-173"><a href="#explode_to_unnest-173"><span class="linenos">173</span></a> <span class="n">taken_source_names</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">Scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">references</span><span class="p">}</span>
</span><span id="explode_to_unnest-174"><a href="#explode_to_unnest-174"><span class="linenos">174</span></a>
</span><span id="explode_to_unnest-175"><a href="#explode_to_unnest-175"><span class="linenos">175</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="p">:</span>
</span><span id="explode_to_unnest-176"><a href="#explode_to_unnest-176"><span class="linenos">176</span></a> <span class="n">to_replace</span> <span class="o">=</span> <span class="n">select</span>
</span><span id="explode_to_unnest-177"><a href="#explode_to_unnest-177"><span class="linenos">177</span></a>
</span><span id="explode_to_unnest-178"><a href="#explode_to_unnest-178"><span class="linenos">178</span></a> <span class="n">pos_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
</span><span id="explode_to_unnest-179"><a href="#explode_to_unnest-179"><span class="linenos">179</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="explode_to_unnest-167"><a href="#explode_to_unnest-167"><span class="linenos">167</span></a><span class="k">def</span> <span class="nf">explode_to_unnest</span><span class="p">(</span><span class="n">index_offset</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><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">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="explode_to_unnest-168"><a href="#explode_to_unnest-168"><span class="linenos">168</span></a> <span class="k">def</span> <span class="nf">_explode_to_unnest</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="explode_to_unnest-169"><a href="#explode_to_unnest-169"><span class="linenos">169</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Convert explode/posexplode into unnest (used in hive -&gt; presto).&quot;&quot;&quot;</span>
</span><span id="explode_to_unnest-170"><a href="#explode_to_unnest-170"><span class="linenos">170</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="explode_to_unnest-171"><a href="#explode_to_unnest-171"><span class="linenos">171</span></a> <span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span>
</span><span id="explode_to_unnest-172"><a href="#explode_to_unnest-172"><span class="linenos">172</span></a>
</span><span id="explode_to_unnest-173"><a href="#explode_to_unnest-173"><span class="linenos">173</span></a> <span class="n">taken_select_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">named_selects</span><span class="p">)</span>
</span><span id="explode_to_unnest-174"><a href="#explode_to_unnest-174"><span class="linenos">174</span></a> <span class="n">taken_source_names</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">Scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span><span class="o">.</span><span class="n">references</span><span class="p">}</span>
</span><span id="explode_to_unnest-175"><a href="#explode_to_unnest-175"><span class="linenos">175</span></a>
</span><span id="explode_to_unnest-176"><a href="#explode_to_unnest-176"><span class="linenos">176</span></a> <span class="k">def</span> <span class="nf">new_name</span><span class="p">(</span><span class="n">names</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Set</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span><span id="explode_to_unnest-177"><a href="#explode_to_unnest-177"><span class="linenos">177</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
</span><span id="explode_to_unnest-178"><a href="#explode_to_unnest-178"><span class="linenos">178</span></a> <span class="n">names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
</span><span id="explode_to_unnest-179"><a href="#explode_to_unnest-179"><span class="linenos">179</span></a> <span class="k">return</span> <span class="n">name</span>
</span><span id="explode_to_unnest-180"><a href="#explode_to_unnest-180"><span class="linenos">180</span></a>
</span><span id="explode_to_unnest-181"><a href="#explode_to_unnest-181"><span class="linenos">181</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-182"><a href="#explode_to_unnest-182"><span class="linenos">182</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-183"><a href="#explode_to_unnest-183"><span class="linenos">183</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-184"><a href="#explode_to_unnest-184"><span class="linenos">184</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-185"><a href="#explode_to_unnest-185"><span class="linenos">185</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-186"><a href="#explode_to_unnest-186"><span class="linenos">186</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-187"><a href="#explode_to_unnest-187"><span class="linenos">187</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-188"><a href="#explode_to_unnest-188"><span class="linenos">188</span></a>
</span><span id="explode_to_unnest-189"><a href="#explode_to_unnest-189"><span class="linenos">189</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-190"><a href="#explode_to_unnest-190"><span class="linenos">190</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-191"><a href="#explode_to_unnest-191"><span class="linenos">191</span></a>
</span><span id="explode_to_unnest-192"><a href="#explode_to_unnest-192"><span class="linenos">192</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-193"><a href="#explode_to_unnest-193"><span class="linenos">193</span></a> <span class="n">unnest</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">Unnest</span><span class="p">(</span><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 class="n">ordinality</span><span class="o">=</span><span class="n">is_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><span id="explode_to_unnest-195"><a href="#explode_to_unnest-195"><span class="linenos">195</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-196"><a href="#explode_to_unnest-196"><span class="linenos">196</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-197"><a href="#explode_to_unnest-197"><span class="linenos">197</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-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">unnest_source_alias</span> <span class="o">=</span> <span class="n">find_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-200"><a href="#explode_to_unnest-200"><span class="linenos">200</span></a> <span class="n">taken_source_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">unnest_source_alias</span><span class="p">)</span>
</span><span id="explode_to_unnest-201"><a href="#explode_to_unnest-201"><span class="linenos">201</span></a>
</span><span id="explode_to_unnest-202"><a href="#explode_to_unnest-202"><span class="linenos">202</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-203"><a href="#explode_to_unnest-203"><span class="linenos">203</span></a> <span class="n">explode_alias</span> <span class="o">=</span> <span class="n">find_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-204"><a href="#explode_to_unnest-204"><span class="linenos">204</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_alias</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><span id="explode_to_unnest-206"><a href="#explode_to_unnest-206"><span class="linenos">206</span></a> <span class="k">if</span> <span class="n">is_posexplode</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">pos_alias</span> <span class="o">=</span> <span class="n">find_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-208"><a href="#explode_to_unnest-208"><span class="linenos">208</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">pos_alias</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><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="n">is_posexplode</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">column_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">explode_alias</span><span class="p">,</span> <span class="n">pos_alias</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 class="n">to_replace</span><span class="o">.</span><span class="n">pop</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 class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">pos_alias</span><span class="p">,</span> <span class="n">explode_alias</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-214"><a href="#explode_to_unnest-214"><span class="linenos">214</span></a> <span class="k">else</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="n">column_names</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-216"><a href="#explode_to_unnest-216"><span class="linenos">216</span></a> <span class="n">to_replace</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">column</span><span class="p">(</span><span class="n">explode_alias</span><span class="p">))</span>
</span><span id="explode_to_unnest-181"><a href="#explode_to_unnest-181"><span class="linenos">181</span></a> <span class="n">arrays</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">exp</span><span class="o">.</span><span class="n">Condition</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="explode_to_unnest-182"><a href="#explode_to_unnest-182"><span class="linenos">182</span></a> <span class="n">series_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-183"><a href="#explode_to_unnest-183"><span class="linenos">183</span></a> <span class="n">series</span> <span class="o">=</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-184"><a href="#explode_to_unnest-184"><span class="linenos">184</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-185"><a href="#explode_to_unnest-185"><span class="linenos">185</span></a> <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">GenerateSeries</span><span class="p">(</span><span class="n">start</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="n">index_offset</span><span class="p">))]</span>
</span><span id="explode_to_unnest-186"><a href="#explode_to_unnest-186"><span class="linenos">186</span></a> <span class="p">),</span>
</span><span id="explode_to_unnest-187"><a href="#explode_to_unnest-187"><span class="linenos">187</span></a> <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-188"><a href="#explode_to_unnest-188"><span class="linenos">188</span></a> <span class="n">table</span><span class="o">=</span><span class="p">[</span><span class="n">series_alias</span><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-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-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-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-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-196"><a href="#explode_to_unnest-196"><span class="linenos">196</span></a>
</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-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-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-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-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-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-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-204"><a href="#explode_to_unnest-204"><span class="linenos">204</span></a>
</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-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-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-208"><a href="#explode_to_unnest-208"><span class="linenos">208</span></a>
</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-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-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-212"><a href="#explode_to_unnest-212"><span class="linenos">212</span></a>
</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-214"><a href="#explode_to_unnest-214"><span class="linenos">214</span></a>
</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-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-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="n">unnest</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">unnest_source_alias</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="n">column_names</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 class="k">if</span> <span class="ow">not</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-221"><a href="#explode_to_unnest-221"><span class="linenos">221</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">from_</span><span class="p">(</span><span class="n">unnest</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-222"><a href="#explode_to_unnest-222"><span class="linenos">222</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="explode_to_unnest-223"><a href="#explode_to_unnest-223"><span class="linenos">223</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">unnest</span><span class="p">,</span> <span class="n">join_type</span><span class="o">=</span><span class="s2">&quot;CROSS&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-224"><a href="#explode_to_unnest-224"><span class="linenos">224</span></a>
</span><span id="explode_to_unnest-225"><a href="#explode_to_unnest-225"><span class="linenos">225</span></a> <span class="k">return</span> <span class="n">expression</span>
</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-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-220"><a href="#explode_to_unnest-220"><span class="linenos">220</span></a>
</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-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-223"><a href="#explode_to_unnest-223"><span class="linenos">223</span></a>
</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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-240"><a href="#explode_to_unnest-240"><span class="linenos">240</span></a> <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-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-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-244"><a href="#explode_to_unnest-244"><span class="linenos">244</span></a>
</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-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-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-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-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-250"><a href="#explode_to_unnest-250"><span class="linenos">250</span></a>
</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-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-253"><a href="#explode_to_unnest-253"><span class="linenos">253</span></a>
</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-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-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-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-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-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-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-261"><a href="#explode_to_unnest-261"><span class="linenos">261</span></a> <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-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-264"><a href="#explode_to_unnest-264"><span class="linenos">264</span></a> <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-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-267"><a href="#explode_to_unnest-267"><span class="linenos">267</span></a> <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-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-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-271"><a href="#explode_to_unnest-271"><span class="linenos">271</span></a>
</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-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-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-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-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-277"><a href="#explode_to_unnest-277"><span class="linenos">277</span></a> <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-279"><a href="#explode_to_unnest-279"><span class="linenos">279</span></a> <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-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-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-283"><a href="#explode_to_unnest-283"><span class="linenos">283</span></a>
</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-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-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-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-289"><a href="#explode_to_unnest-289"><span class="linenos">289</span></a>
</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></pre></div>
</section>
<section id="PERCENTILES">
<div class="attr variable">
<span class="name">PERCENTILES</span> =
<span class="default_value">(&lt;class &#39;<a href="expressions.html#PercentileCont">sqlglot.expressions.PercentileCont</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#PercentileDisc">sqlglot.expressions.PercentileDisc</a>&#39;&gt;)</span>
</div>
<a class="headerlink" href="#PERCENTILES"></a>
</section>
<section id="add_within_group_for_percentiles">
<input id="add_within_group_for_percentiles-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">add_within_group_for_percentiles</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</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="add_within_group_for_percentiles-view-source"><span>View Source</span></label>
</div>
<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>
</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-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-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-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-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-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-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-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-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-306"><a href="#add_within_group_for_percentiles-306"><span class="linenos">306</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></pre></div>
<div class="docstring"><p>Convert explode/posexplode into unnest (used in hive -> presto).</p>
</div>
</section>
@ -770,17 +996,17 @@ other expressions. This transforms removes the precision from parameterized type
</div>
<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-228"><a href="#remove_within_group_for_percentiles-228"><span class="linenos">228</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-229"><a href="#remove_within_group_for_percentiles-229"><span class="linenos">229</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="remove_within_group_for_percentiles-230"><a href="#remove_within_group_for_percentiles-230"><span class="linenos">230</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-231"><a href="#remove_within_group_for_percentiles-231"><span class="linenos">231</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="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="remove_within_group_for_percentiles-232"><a href="#remove_within_group_for_percentiles-232"><span class="linenos">232</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-233"><a href="#remove_within_group_for_percentiles-233"><span class="linenos">233</span></a> <span class="p">):</span>
</span><span id="remove_within_group_for_percentiles-234"><a href="#remove_within_group_for_percentiles-234"><span class="linenos">234</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-235"><a href="#remove_within_group_for_percentiles-235"><span class="linenos">235</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-236"><a href="#remove_within_group_for_percentiles-236"><span class="linenos">236</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-237"><a href="#remove_within_group_for_percentiles-237"><span class="linenos">237</span></a>
</span><span id="remove_within_group_for_percentiles-238"><a href="#remove_within_group_for_percentiles-238"><span class="linenos">238</span></a> <span class="k">return</span> <span class="n">expression</span>
<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>
</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-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-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-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-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-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-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-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-319"><a href="#remove_within_group_for_percentiles-319"><span class="linenos">319</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></pre></div>
@ -798,22 +1024,22 @@ other expressions. This transforms removes the precision from parameterized type
</div>
<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-241"><a href="#add_recursive_cte_column_names-241"><span class="linenos">241</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-242"><a href="#add_recursive_cte_column_names-242"><span class="linenos">242</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-243"><a href="#add_recursive_cte_column_names-243"><span class="linenos">243</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-244"><a href="#add_recursive_cte_column_names-244"><span class="linenos">244</span></a>
</span><span id="add_recursive_cte_column_names-245"><a href="#add_recursive_cte_column_names-245"><span class="linenos">245</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-246"><a href="#add_recursive_cte_column_names-246"><span class="linenos">246</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-247"><a href="#add_recursive_cte_column_names-247"><span class="linenos">247</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-248"><a href="#add_recursive_cte_column_names-248"><span class="linenos">248</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-249"><a href="#add_recursive_cte_column_names-249"><span class="linenos">249</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-250"><a href="#add_recursive_cte_column_names-250"><span class="linenos">250</span></a>
</span><span id="add_recursive_cte_column_names-251"><a href="#add_recursive_cte_column_names-251"><span class="linenos">251</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-252"><a href="#add_recursive_cte_column_names-252"><span class="linenos">252</span></a> <span class="s2">&quot;columns&quot;</span><span class="p">,</span>
</span><span id="add_recursive_cte_column_names-253"><a href="#add_recursive_cte_column_names-253"><span class="linenos">253</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-254"><a href="#add_recursive_cte_column_names-254"><span class="linenos">254</span></a> <span class="p">)</span>
</span><span id="add_recursive_cte_column_names-255"><a href="#add_recursive_cte_column_names-255"><span class="linenos">255</span></a>
</span><span id="add_recursive_cte_column_names-256"><a href="#add_recursive_cte_column_names-256"><span class="linenos">256</span></a> <span class="k">return</span> <span class="n">expression</span>
<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>
</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-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-326"><a href="#add_recursive_cte_column_names-326"><span class="linenos">326</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-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-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-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-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-332"><a href="#add_recursive_cte_column_names-332"><span class="linenos">332</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-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-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-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-337"><a href="#add_recursive_cte_column_names-337"><span class="linenos">337</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></pre></div>
@ -831,15 +1057,70 @@ other expressions. This transforms removes the precision from parameterized type
</div>
<a class="headerlink" href="#epoch_cast_to_ts"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="epoch_cast_to_ts-259"><a href="#epoch_cast_to_ts-259"><span class="linenos">259</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-260"><a href="#epoch_cast_to_ts-260"><span class="linenos">260</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="epoch_cast_to_ts-261"><a href="#epoch_cast_to_ts-261"><span class="linenos">261</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-262"><a href="#epoch_cast_to_ts-262"><span class="linenos">262</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-263"><a href="#epoch_cast_to_ts-263"><span class="linenos">263</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-264"><a href="#epoch_cast_to_ts-264"><span class="linenos">264</span></a> <span class="p">):</span>
</span><span id="epoch_cast_to_ts-265"><a href="#epoch_cast_to_ts-265"><span class="linenos">265</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-266"><a href="#epoch_cast_to_ts-266"><span class="linenos">266</span></a>
</span><span id="epoch_cast_to_ts-267"><a href="#epoch_cast_to_ts-267"><span class="linenos">267</span></a> <span class="k">return</span> <span class="n">expression</span>
<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>
</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-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-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-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-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-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-348"><a href="#epoch_cast_to_ts-348"><span class="linenos">348</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></pre></div>
</section>
<section id="timestamp_to_cast">
<input id="timestamp_to_cast-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">timestamp_to_cast</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</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="timestamp_to_cast-view-source"><span>View Source</span></label>
</div>
<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>
</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-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-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-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-357"><a href="#timestamp_to_cast-357"><span class="linenos">357</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></pre></div>
</section>
<section id="eliminate_semi_and_anti_joins">
<input id="eliminate_semi_and_anti_joins-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">eliminate_semi_and_anti_joins</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</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="eliminate_semi_and_anti_joins-view-source"><span>View Source</span></label>
</div>
<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>
</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-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-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-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-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-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-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-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-370"><a href="#eliminate_semi_and_anti_joins-370"><span class="linenos">370</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-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-373"><a href="#eliminate_semi_and_anti_joins-373"><span class="linenos">373</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></pre></div>
@ -857,47 +1138,50 @@ other expressions. This transforms removes the precision from parameterized type
</div>
<a class="headerlink" href="#preprocess"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="preprocess-270"><a href="#preprocess-270"><span class="linenos">270</span></a><span class="k">def</span> <span class="nf">preprocess</span><span class="p">(</span>
</span><span id="preprocess-271"><a href="#preprocess-271"><span class="linenos">271</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-272"><a href="#preprocess-272"><span class="linenos">272</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-273"><a href="#preprocess-273"><span class="linenos">273</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="preprocess-274"><a href="#preprocess-274"><span class="linenos">274</span></a><span class="sd"> Creates a new transform by chaining a sequence of transformations and converts the resulting</span>
</span><span id="preprocess-275"><a href="#preprocess-275"><span class="linenos">275</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-276"><a href="#preprocess-276"><span class="linenos">276</span></a><span class="sd"> or the appropriate `Generator.TRANSFORMS` function (when applicable -- see below).</span>
</span><span id="preprocess-277"><a href="#preprocess-277"><span class="linenos">277</span></a>
</span><span id="preprocess-278"><a href="#preprocess-278"><span class="linenos">278</span></a><span class="sd"> Args:</span>
</span><span id="preprocess-279"><a href="#preprocess-279"><span class="linenos">279</span></a><span class="sd"> transforms: sequence of transform functions. These will be called in order.</span>
</span><span id="preprocess-280"><a href="#preprocess-280"><span class="linenos">280</span></a>
</span><span id="preprocess-281"><a href="#preprocess-281"><span class="linenos">281</span></a><span class="sd"> Returns:</span>
</span><span id="preprocess-282"><a href="#preprocess-282"><span class="linenos">282</span></a><span class="sd"> Function that can be used as a generator transform.</span>
</span><span id="preprocess-283"><a href="#preprocess-283"><span class="linenos">283</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="preprocess-284"><a href="#preprocess-284"><span class="linenos">284</span></a>
</span><span id="preprocess-285"><a href="#preprocess-285"><span class="linenos">285</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-286"><a href="#preprocess-286"><span class="linenos">286</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-287"><a href="#preprocess-287"><span class="linenos">287</span></a>
</span><span id="preprocess-288"><a href="#preprocess-288"><span class="linenos">288</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-289"><a href="#preprocess-289"><span class="linenos">289</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-290"><a href="#preprocess-290"><span class="linenos">290</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-291"><a href="#preprocess-291"><span class="linenos">291</span></a>
</span><span id="preprocess-292"><a href="#preprocess-292"><span class="linenos">292</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-293"><a href="#preprocess-293"><span class="linenos">293</span></a> <span class="k">if</span> <span class="n">_sql_handler</span><span class="p">:</span>
</span><span id="preprocess-294"><a href="#preprocess-294"><span class="linenos">294</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-295"><a href="#preprocess-295"><span class="linenos">295</span></a>
</span><span id="preprocess-296"><a href="#preprocess-296"><span class="linenos">296</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-297"><a href="#preprocess-297"><span class="linenos">297</span></a> <span class="k">if</span> <span class="n">transforms_handler</span><span class="p">:</span>
</span><span id="preprocess-298"><a href="#preprocess-298"><span class="linenos">298</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-299"><a href="#preprocess-299"><span class="linenos">299</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-300"><a href="#preprocess-300"><span class="linenos">300</span></a> <span class="c1"># because then it&#39;d re-enter _to_sql.</span>
</span><span id="preprocess-301"><a href="#preprocess-301"><span class="linenos">301</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-302"><a href="#preprocess-302"><span class="linenos">302</span></a> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
</span><span id="preprocess-303"><a href="#preprocess-303"><span class="linenos">303</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-304"><a href="#preprocess-304"><span class="linenos">304</span></a> <span class="p">)</span>
</span><span id="preprocess-305"><a href="#preprocess-305"><span class="linenos">305</span></a>
</span><span id="preprocess-306"><a href="#preprocess-306"><span class="linenos">306</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-307"><a href="#preprocess-307"><span class="linenos">307</span></a>
</span><span id="preprocess-308"><a href="#preprocess-308"><span class="linenos">308</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-309"><a href="#preprocess-309"><span class="linenos">309</span></a>
</span><span id="preprocess-310"><a href="#preprocess-310"><span class="linenos">310</span></a> <span class="k">return</span> <span class="n">_to_sql</span>
<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>
</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-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-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-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-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-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-384"><a href="#preprocess-384"><span class="linenos">384</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-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-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-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-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-394"><a href="#preprocess-394"><span class="linenos">394</span></a>
</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-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-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-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-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-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-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-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-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-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-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-408"><a href="#preprocess-408"><span class="linenos">408</span></a>
</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-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-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-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-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-414"><a href="#preprocess-414"><span class="linenos">414</span></a> <span class="p">)</span>
</span><span id="preprocess-415"><a href="#preprocess-415"><span class="linenos">415</span></a>
</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-417"><a href="#preprocess-417"><span class="linenos">417</span></a>
</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-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></pre></div>

View file

@ -16,7 +16,7 @@ setup(
"fallback_version": "0.0.0",
"local_scheme": "no-local-version",
},
setup_requires=["setuptools_scm"],
setup_requires=["setuptools_scm<8.0.1"],
python_requires=">=3.7",
extras_require={
"dev": [
@ -30,6 +30,7 @@ setup(
"python-dateutil",
"pdoc",
"pre-commit",
"types-python-dateutil",
],
},
classifiers=[

View file

@ -4,5 +4,10 @@ import typing as t
import sqlglot
# A little hack for backwards compatibility with Python 3.7.
# For example, we might want a TypeVar for objects that support comparison e.g. SupportsRichComparisonT from typeshed.
# But Python 3.7 doesn't support Protocols, so we'd also need typing_extensions, which we don't want as a dependency.
A = t.TypeVar("A", bound=t.Any)
E = t.TypeVar("E", bound="sqlglot.exp.Expression")
T = t.TypeVar("T")

View file

@ -212,7 +212,15 @@ class Column:
return self.expression.sql(**{"dialect": SparkSession().dialect, **kwargs})
def alias(self, name: str) -> Column:
new_expression = exp.alias_(self.column_expression, name)
from sqlglot.dataframe.sql.session import SparkSession
dialect = SparkSession().dialect
alias: exp.Expression = sqlglot.maybe_parse(name, dialect=dialect)
new_expression = exp.alias_(
self.column_expression,
alias.this if isinstance(alias, exp.Column) else name,
dialect=dialect,
)
return Column(new_expression)
def asc(self) -> Column:

View file

@ -12,6 +12,7 @@ from sqlglot.dialects.dialect import (
date_add_interval_sql,
datestrtodate_sql,
format_time_lambda,
if_sql,
inline_array_sql,
json_keyvalue_comma_sql,
max_or_greatest,
@ -176,6 +177,8 @@ def _parse_to_hex(args: t.List) -> exp.Hex | exp.MD5:
class BigQuery(Dialect):
UNNEST_COLUMN_ONLY = True
SUPPORTS_USER_DEFINED_TYPES = False
SUPPORTS_SEMI_ANTI_JOIN = False
LOG_BASE_FIRST = False
# https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity
RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
@ -256,7 +259,6 @@ class BigQuery(Dialect):
"RECORD": TokenType.STRUCT,
"TIMESTAMP": TokenType.TIMESTAMPTZ,
"NOT DETERMINISTIC": TokenType.VOLATILE,
"UNKNOWN": TokenType.NULL,
"FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
}
KEYWORDS.pop("DIV")
@ -264,7 +266,6 @@ class BigQuery(Dialect):
class Parser(parser.Parser):
PREFIXED_PIVOT_COLUMNS = True
LOG_BASE_FIRST = False
LOG_DEFAULTS_TO_LN = True
FUNCTIONS = {
@ -292,9 +293,7 @@ class BigQuery(Dialect):
expression=seq_get(args, 1),
position=seq_get(args, 2),
occurrence=seq_get(args, 3),
group=exp.Literal.number(1)
if re.compile(str(seq_get(args, 1))).groups == 1
else None,
group=exp.Literal.number(1) if re.compile(args[1].name).groups == 1 else None,
),
"SHA256": lambda args: exp.SHA2(this=seq_get(args, 0), length=exp.Literal.number(256)),
"SHA512": lambda args: exp.SHA2(this=seq_get(args, 0), length=exp.Literal.number(512)),
@ -344,6 +343,11 @@ class BigQuery(Dialect):
"OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()),
}
RANGE_PARSERS = parser.Parser.RANGE_PARSERS.copy()
RANGE_PARSERS.pop(TokenType.OVERLAPS, None)
NULL_TOKENS = {TokenType.NULL, TokenType.UNKNOWN}
def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
this = super()._parse_table_part(schema=schema) or self._parse_number()
@ -413,8 +417,8 @@ class BigQuery(Dialect):
TABLE_HINTS = False
LIMIT_FETCH = "LIMIT"
RENAME_TABLE_WITH_DB = False
ESCAPE_LINE_BREAK = True
NVL2_SUPPORTED = False
UNNEST_WITH_ORDINALITY = False
TRANSFORMS = {
**generator.Generator.TRANSFORMS,
@ -434,6 +438,7 @@ class BigQuery(Dialect):
exp.GenerateSeries: rename_func("GENERATE_ARRAY"),
exp.GroupConcat: rename_func("STRING_AGG"),
exp.Hex: rename_func("TO_HEX"),
exp.If: if_sql(false_value="NULL"),
exp.ILike: no_ilike_sql,
exp.IntDiv: rename_func("DIV"),
exp.JSONFormat: rename_func("TO_JSON_STRING"),
@ -455,10 +460,11 @@ class BigQuery(Dialect):
exp.ReturnsProperty: _returnsproperty_sql,
exp.Select: transforms.preprocess(
[
transforms.explode_to_unnest,
transforms.explode_to_unnest(),
_unqualify_unnest,
transforms.eliminate_distinct_on,
_alias_ordered_group,
transforms.eliminate_semi_and_anti_joins,
]
),
exp.SHA2: lambda self, e: self.func(
@ -514,6 +520,18 @@ class BigQuery(Dialect):
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
RESERVED_KEYWORDS = {
*generator.Generator.RESERVED_KEYWORDS,

View file

@ -113,15 +113,11 @@ class ClickHouse(Dialect):
*parser.Parser.JOIN_KINDS,
TokenType.ANY,
TokenType.ASOF,
TokenType.ANTI,
TokenType.SEMI,
TokenType.ARRAY,
}
TABLE_ALIAS_TOKENS = {*parser.Parser.TABLE_ALIAS_TOKENS} - {
TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS - {
TokenType.ANY,
TokenType.SEMI,
TokenType.ANTI,
TokenType.SETTINGS,
TokenType.FORMAT,
TokenType.ARRAY,

View file

@ -51,8 +51,6 @@ class Databricks(Spark):
exp.ToChar: lambda self, e: self.function_fallback_sql(e),
}
PARAMETER_TOKEN = "$"
class Tokenizer(Spark.Tokenizer):
HEX_STRINGS = []

View file

@ -125,6 +125,12 @@ class _Dialect(type):
if not klass.STRICT_STRING_CONCAT and klass.DPIPE_IS_STRING_CONCAT:
klass.parser_class.BITWISE[TokenType.DPIPE] = exp.SafeDPipe
if not klass.SUPPORTS_SEMI_ANTI_JOIN:
klass.parser_class.TABLE_ALIAS_TOKENS = klass.parser_class.TABLE_ALIAS_TOKENS | {
TokenType.ANTI,
TokenType.SEMI,
}
klass.generator_class.can_identify = klass.can_identify
return klass
@ -156,9 +162,15 @@ class Dialect(metaclass=_Dialect):
# Determines whether or not user-defined data types are supported
SUPPORTS_USER_DEFINED_TYPES = True
# Determines whether or not SEMI/ANTI JOINs are supported
SUPPORTS_SEMI_ANTI_JOIN = True
# Determines how function names are going to be normalized
NORMALIZE_FUNCTIONS: bool | str = "upper"
# Determines whether the base comes first in the LOG function
LOG_BASE_FIRST = True
# Indicates the default null ordering method to use if not explicitly set
# Options are: "nulls_are_small", "nulls_are_large", "nulls_are_last"
NULL_ORDERING = "nulls_are_small"
@ -331,11 +343,19 @@ def approx_count_distinct_sql(self: Generator, expression: exp.ApproxDistinct) -
return self.func("APPROX_COUNT_DISTINCT", expression.this)
def if_sql(self: Generator, expression: exp.If) -> str:
def if_sql(
name: str = "IF", false_value: t.Optional[exp.Expression | str] = None
) -> t.Callable[[Generator, exp.If], str]:
def _if_sql(self: Generator, expression: exp.If) -> str:
return self.func(
"IF", expression.this, expression.args.get("true"), expression.args.get("false")
name,
expression.this,
expression.args.get("true"),
expression.args.get("false") or false_value,
)
return _if_sql
def arrow_json_extract_sql(self: Generator, expression: exp.JSONExtract | exp.JSONBExtract) -> str:
return self.binary(expression, "->")
@ -751,6 +771,12 @@ def any_value_to_max_sql(self: Generator, expression: exp.AnyValue) -> str:
return self.func("MAX", expression.this)
def bool_xor_sql(self: Generator, expression: exp.Xor) -> str:
a = self.sql(expression.left)
b = self.sql(expression.right)
return f"({a} AND (NOT {b})) OR ((NOT {a}) AND {b})"
# Used to generate JSON_OBJECT with a comma in BigQuery and MySQL instead of colon
def json_keyvalue_comma_sql(self: Generator, expression: exp.JSONKeyValue) -> str:
return f"{self.sql(expression, 'this')}, {self.sql(expression, 'expression')}"
@ -764,3 +790,10 @@ def is_parse_json(expression: exp.Expression) -> bool:
def isnull_to_is_null(args: t.List) -> exp.Expression:
return exp.Paren(this=exp.Is(this=seq_get(args, 0), expression=exp.null()))
def move_insert_cte_sql(self: Generator, expression: exp.Insert) -> str:
if expression.expression.args.get("with"):
expression = expression.copy()
expression.set("with", expression.expression.args["with"].pop())
return self.insert_sql(expression)

View file

@ -40,6 +40,7 @@ class Drill(Dialect):
DATEINT_FORMAT = "'yyyyMMdd'"
TIME_FORMAT = "'yyyy-MM-dd HH:mm:ss'"
SUPPORTS_USER_DEFINED_TYPES = False
SUPPORTS_SEMI_ANTI_JOIN = False
TIME_MAPPING = {
"y": "%Y",
@ -135,7 +136,9 @@ class Drill(Dialect):
exp.StrPosition: str_position_sql,
exp.StrToDate: _str_to_date,
exp.Pow: rename_func("POW"),
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
),
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.TimeStrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE)",
exp.TimeStrToTime: timestrtotime_sql,

View file

@ -9,6 +9,7 @@ from sqlglot.dialects.dialect import (
arrow_json_extract_scalar_sql,
arrow_json_extract_sql,
binary_from_function,
bool_xor_sql,
date_trunc_to_time,
datestrtodate_sql,
encode_decode_sql,
@ -190,6 +191,11 @@ class DuckDB(Dialect):
),
}
TABLE_ALIAS_TOKENS = parser.Parser.TABLE_ALIAS_TOKENS - {
TokenType.SEMI,
TokenType.ANTI,
}
def _parse_types(
self, check_func: bool = False, schema: bool = False, allow_identifiers: bool = True
) -> t.Optional[exp.Expression]:
@ -224,6 +230,7 @@ class DuckDB(Dialect):
STRUCT_DELIMITER = ("(", ")")
RENAME_TABLE_WITH_DB = False
NVL2_SUPPORTED = False
SEMI_ANTI_JOIN_WITH_SIDE = False
TRANSFORMS = {
**generator.Generator.TRANSFORMS,
@ -234,7 +241,7 @@ class DuckDB(Dialect):
exp.ArraySize: rename_func("ARRAY_LENGTH"),
exp.ArraySort: _array_sort_sql,
exp.ArraySum: rename_func("LIST_SUM"),
exp.BitwiseXor: lambda self, e: self.func("XOR", e.this, e.expression),
exp.BitwiseXor: rename_func("XOR"),
exp.CommentColumnConstraint: no_comment_column_constraint_sql,
exp.CurrentDate: lambda self, e: "CURRENT_DATE",
exp.CurrentTime: lambda self, e: "CURRENT_TIME",
@ -301,6 +308,7 @@ class DuckDB(Dialect):
exp.UnixToTimeStr: lambda self, e: f"CAST(TO_TIMESTAMP({self.sql(e, 'this')}) AS TEXT)",
exp.VariancePop: rename_func("VAR_POP"),
exp.WeekOfYear: rename_func("WEEKOFYEAR"),
exp.Xor: bool_xor_sql,
}
TYPE_MAPPING = {

View file

@ -111,7 +111,7 @@ def _array_sort_sql(self: Hive.Generator, expression: exp.ArraySort) -> str:
def _property_sql(self: Hive.Generator, expression: exp.Property) -> str:
return f"'{expression.name}'={self.sql(expression, 'value')}"
return f"{self.property_name(expression, string_key=True)}={self.sql(expression, 'value')}"
def _str_to_unix_sql(self: Hive.Generator, expression: exp.StrToUnix) -> str:
@ -413,7 +413,7 @@ class Hive(Dialect):
exp.DiToDate: lambda self, e: f"TO_DATE(CAST({self.sql(e, 'this')} AS STRING), {Hive.DATEINT_FORMAT})",
exp.FileFormatProperty: lambda self, e: f"STORED AS {self.sql(e, 'this') if isinstance(e.this, exp.InputOutputFormat) else e.name.upper()}",
exp.FromBase64: rename_func("UNBASE64"),
exp.If: if_sql,
exp.If: if_sql(),
exp.ILike: no_ilike_sql,
exp.IsNan: rename_func("ISNAN"),
exp.JSONExtract: rename_func("GET_JSON_OBJECT"),
@ -466,6 +466,11 @@ class Hive(Dialect):
exp.NumberToStr: rename_func("FORMAT_NUMBER"),
exp.LastDateOfMonth: rename_func("LAST_DAY"),
exp.National: lambda self, e: self.national_sql(e, prefix=""),
exp.ClusteredColumnConstraint: lambda self, e: f"({self.expressions(e, 'this', indent=False)})",
exp.NonClusteredColumnConstraint: lambda self, e: f"({self.expressions(e, 'this', indent=False)})",
exp.NotForReplicationColumnConstraint: lambda self, e: "",
exp.OnProperty: lambda self, e: "",
exp.PrimaryKeyColumnConstraint: lambda self, e: "PRIMARY KEY",
}
PROPERTIES_LOCATION = {
@ -475,6 +480,35 @@ class Hive(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
}
def parameter_sql(self, expression: exp.Parameter) -> str:
this = self.sql(expression, "this")
parent = expression.parent
if isinstance(parent, exp.EQ) and isinstance(parent.parent, exp.SetItem):
# We need to produce SET key = value instead of SET ${key} = value
return this
return f"${{{this}}}"
def schema_sql(self, expression: exp.Schema) -> str:
expression = expression.copy()
for ordered in expression.find_all(exp.Ordered):
if ordered.args.get("desc") is False:
ordered.set("desc", None)
return super().schema_sql(expression)
def constraint_sql(self, expression: exp.Constraint) -> str:
expression = expression.copy()
for prop in list(expression.find_all(exp.Properties)):
prop.pop()
this = self.sql(expression, "this")
expressions = self.expressions(expression, sep=" ", flat=True)
return f"CONSTRAINT {this} {expressions}"
def rowformatserdeproperty_sql(self, expression: exp.RowFormatSerdeProperty) -> str:
serde_props = self.sql(expression, "serde_properties")
serde_props = f" {serde_props}" if serde_props else ""

View file

@ -102,6 +102,7 @@ class MySQL(Dialect):
TIME_FORMAT = "'%Y-%m-%d %T'"
DPIPE_IS_STRING_CONCAT = False
SUPPORTS_USER_DEFINED_TYPES = False
SUPPORTS_SEMI_ANTI_JOIN = False
# https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions
TIME_MAPPING = {
@ -519,7 +520,7 @@ class MySQL(Dialect):
return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
def _parse_type(self) -> t.Optional[exp.Expression]:
def _parse_type(self, parse_interval: bool = True) -> t.Optional[exp.Expression]:
# mysql binary is special and can work anywhere, even in order by operations
# it operates like a no paren func
if self._match(TokenType.BINARY, advance=False):
@ -528,7 +529,7 @@ class MySQL(Dialect):
if isinstance(data_type, exp.DataType):
return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
return super()._parse_type()
return super()._parse_type(parse_interval=parse_interval)
class Generator(generator.Generator):
LOCKING_READS_SUPPORTED = True
@ -560,7 +561,9 @@ class MySQL(Dialect):
exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
exp.NullSafeNEQ: lambda self, e: self.not_sql(self.binary(e, "<=>")),
exp.Pivot: no_pivot_sql,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
),
exp.StrPosition: strposition_to_locate_sql,
exp.StrToDate: _str_to_date_sql,
exp.StrToTime: _str_to_date_sql,

View file

@ -8,6 +8,7 @@ from sqlglot.dialects.dialect import (
any_value_to_max_sql,
arrow_json_extract_scalar_sql,
arrow_json_extract_sql,
bool_xor_sql,
datestrtodate_sql,
format_time_lambda,
max_or_greatest,
@ -110,7 +111,7 @@ def _string_agg_sql(self: Postgres.Generator, expression: exp.GroupConcat) -> st
def _datatype_sql(self: Postgres.Generator, expression: exp.DataType) -> str:
if expression.is_type("array"):
return f"{self.expressions(expression, flat=True)}[]"
return f"{self.expressions(expression, flat=True)}[]" if expression.expressions else "ARRAY"
return self.datatype_sql(expression)
@ -380,25 +381,29 @@ class Postgres(Dialect):
TRANSFORMS = {
**generator.Generator.TRANSFORMS,
exp.AnyValue: any_value_to_max_sql,
exp.Array: lambda self, e: f"{self.normalize_func('ARRAY')}({self.sql(e.expressions[0])})"
if isinstance(seq_get(e.expressions, 0), exp.Select)
else f"{self.normalize_func('ARRAY')}[{self.expressions(e, flat=True)}]",
exp.ArrayConcat: rename_func("ARRAY_CAT"),
exp.ArrayContained: lambda self, e: self.binary(e, "<@"),
exp.ArrayContains: lambda self, e: self.binary(e, "@>"),
exp.ArrayOverlaps: lambda self, e: self.binary(e, "&&"),
exp.BitwiseXor: lambda self, e: self.binary(e, "#"),
exp.ColumnDef: transforms.preprocess([_auto_increment_to_serial, _serial_to_generated]),
exp.CurrentDate: no_paren_current_date_sql,
exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
exp.DateAdd: _date_add_sql("+"),
exp.DateDiff: _date_diff_sql,
exp.DateStrToDate: datestrtodate_sql,
exp.DataType: _datatype_sql,
exp.DateSub: _date_add_sql("-"),
exp.Explode: rename_func("UNNEST"),
exp.GroupConcat: _string_agg_sql,
exp.JSONExtract: arrow_json_extract_sql,
exp.JSONExtractScalar: arrow_json_extract_scalar_sql,
exp.JSONBExtract: lambda self, e: self.binary(e, "#>"),
exp.JSONBExtractScalar: lambda self, e: self.binary(e, "#>>"),
exp.JSONBContains: lambda self, e: self.binary(e, "?"),
exp.Pow: lambda self, e: self.binary(e, "^"),
exp.CurrentDate: no_paren_current_date_sql,
exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
exp.DateAdd: _date_add_sql("+"),
exp.DateStrToDate: datestrtodate_sql,
exp.DateSub: _date_add_sql("-"),
exp.DateDiff: _date_diff_sql,
exp.LogicalOr: rename_func("BOOL_OR"),
exp.LogicalAnd: rename_func("BOOL_AND"),
exp.Max: max_or_greatest,
@ -412,8 +417,10 @@ class Postgres(Dialect):
[transforms.add_within_group_for_percentiles]
),
exp.Pivot: no_pivot_sql,
exp.Pow: lambda self, e: self.binary(e, "^"),
exp.RegexpLike: 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.StrPosition: str_position_sql,
exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
exp.Substring: _substring_sql,
@ -426,11 +433,7 @@ class Postgres(Dialect):
exp.TryCast: no_trycast_sql,
exp.TsOrDsToDate: ts_or_ds_to_date_sql("postgres"),
exp.UnixToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')})",
exp.DataType: _datatype_sql,
exp.GroupConcat: _string_agg_sql,
exp.Array: lambda self, e: f"{self.normalize_func('ARRAY')}({self.sql(e.expressions[0])})"
if isinstance(seq_get(e.expressions, 0), exp.Select)
else f"{self.normalize_func('ARRAY')}[{self.expressions(e, flat=True)}]",
exp.Xor: bool_xor_sql,
}
PROPERTIES_LOCATION = {

View file

@ -6,6 +6,7 @@ from sqlglot import exp, generator, parser, tokens, transforms
from sqlglot.dialects.dialect import (
Dialect,
binary_from_function,
bool_xor_sql,
date_trunc_to_time,
encode_decode_sql,
format_time_lambda,
@ -40,7 +41,7 @@ def _explode_to_unnest_sql(self: Presto.Generator, expression: exp.Lateral) -> s
this=exp.Unnest(
expressions=[expression.this.this],
alias=expression.args.get("alias"),
ordinality=isinstance(expression.this, exp.Posexplode),
offset=isinstance(expression.this, exp.Posexplode),
),
kind="cross",
)
@ -173,6 +174,7 @@ class Presto(Dialect):
TIME_FORMAT = MySQL.TIME_FORMAT
TIME_MAPPING = MySQL.TIME_MAPPING
STRICT_STRING_CONCAT = True
SUPPORTS_SEMI_ANTI_JOIN = False
# https://github.com/trinodb/trino/issues/17
# https://github.com/trinodb/trino/issues/12289
@ -308,7 +310,7 @@ class Presto(Dialect):
exp.First: _first_last_sql,
exp.Group: transforms.preprocess([transforms.unalias_group]),
exp.Hex: rename_func("TO_HEX"),
exp.If: if_sql,
exp.If: if_sql(),
exp.ILike: no_ilike_sql,
exp.Initcap: _initcap_sql,
exp.ParseJSON: rename_func("JSON_PARSE"),
@ -331,7 +333,8 @@ class Presto(Dialect):
[
transforms.eliminate_qualify,
transforms.eliminate_distinct_on,
transforms.explode_to_unnest,
transforms.explode_to_unnest(1),
transforms.eliminate_semi_and_anti_joins,
]
),
exp.SortArray: _no_sort_array,
@ -340,7 +343,6 @@ class Presto(Dialect):
exp.StrToMap: rename_func("SPLIT_TO_MAP"),
exp.StrToTime: _str_to_time_sql,
exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
exp.Struct: rename_func("ROW"),
exp.StructExtract: struct_extract_sql,
exp.Table: transforms.preprocess([_unnest_sequence]),
exp.TimestampTrunc: timestamptrunc_sql,
@ -363,8 +365,16 @@ class Presto(Dialect):
[transforms.remove_within_group_for_percentiles]
),
exp.Timestamp: transforms.preprocess([transforms.timestamp_to_cast]),
exp.Xor: bool_xor_sql,
}
def struct_sql(self, expression: exp.Struct) -> str:
if any(isinstance(arg, (exp.EQ, exp.Slice)) for arg in expression.expressions):
self.unsupported("Struct with key-value definitions is unsupported.")
return self.function_fallback_sql(expression)
return rename_func("ROW")(self, expression)
def interval_sql(self, expression: exp.Interval) -> str:
unit = self.sql(expression, "unit")
if expression.this and unit.lower().startswith("week"):

View file

@ -138,7 +138,9 @@ class Redshift(Postgres):
exp.JSONExtract: _json_sql,
exp.JSONExtractScalar: _json_sql,
exp.SafeConcat: concat_to_dpipe_sql,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
),
exp.SortKeyProperty: lambda self, e: f"{'COMPOUND ' if e.args['compound'] else ''}SORTKEY({self.format_args(*e.this)})",
exp.TsOrDsToDate: ts_or_ds_to_date_sql("redshift"),
}

View file

@ -5,9 +5,11 @@ import typing as t
from sqlglot import exp, generator, parser, tokens, transforms
from sqlglot.dialects.dialect import (
Dialect,
binary_from_function,
date_trunc_to_time,
datestrtodate_sql,
format_time_lambda,
if_sql,
inline_array_sql,
max_or_greatest,
min_or_least,
@ -203,6 +205,7 @@ class Snowflake(Dialect):
NULL_ORDERING = "nulls_are_large"
TIME_FORMAT = "'YYYY-MM-DD HH24:MI:SS'"
SUPPORTS_USER_DEFINED_TYPES = False
SUPPORTS_SEMI_ANTI_JOIN = False
TIME_MAPPING = {
"YYYY": "%Y",
@ -240,7 +243,16 @@ class Snowflake(Dialect):
**parser.Parser.FUNCTIONS,
"ARRAYAGG": exp.ArrayAgg.from_arg_list,
"ARRAY_CONSTRUCT": exp.Array.from_arg_list,
"ARRAY_GENERATE_RANGE": lambda args: exp.GenerateSeries(
# ARRAY_GENERATE_RANGE has an exlusive end; we normalize it to be inclusive
start=seq_get(args, 0),
end=exp.Sub(this=seq_get(args, 1), expression=exp.Literal.number(1)),
step=seq_get(args, 2),
),
"ARRAY_TO_STRING": exp.ArrayJoin.from_arg_list,
"BITXOR": binary_from_function(exp.BitwiseXor),
"BIT_XOR": binary_from_function(exp.BitwiseXor),
"BOOLXOR": binary_from_function(exp.Xor),
"CONVERT_TIMEZONE": _parse_convert_timezone,
"DATE_TRUNC": date_trunc_to_time,
"DATEADD": lambda args: exp.DateAdd(
@ -277,7 +289,7 @@ class Snowflake(Dialect):
),
}
TIMESTAMPS = parser.Parser.TIMESTAMPS.copy() - {TokenType.TIME}
TIMESTAMPS = parser.Parser.TIMESTAMPS - {TokenType.TIME}
RANGE_PARSERS = {
**parser.Parser.RANGE_PARSERS,
@ -381,6 +393,7 @@ class Snowflake(Dialect):
JOIN_HINTS = False
TABLE_HINTS = False
QUERY_HINTS = False
AGGREGATE_FILTER_SUPPORTED = False
TRANSFORMS = {
**generator.Generator.TRANSFORMS,
@ -390,6 +403,7 @@ class Snowflake(Dialect):
exp.AtTimeZone: lambda self, e: self.func(
"CONVERT_TIMEZONE", e.args.get("zone"), e.this
),
exp.BitwiseXor: rename_func("BITXOR"),
exp.DateAdd: lambda self, e: self.func("DATEADD", e.text("unit"), e.expression, e.this),
exp.DateDiff: lambda self, e: self.func(
"DATEDIFF", e.text("unit"), e.expression, e.this
@ -398,8 +412,11 @@ class Snowflake(Dialect):
exp.DataType: _datatype_sql,
exp.DayOfWeek: rename_func("DAYOFWEEK"),
exp.Extract: rename_func("DATE_PART"),
exp.GenerateSeries: lambda self, e: self.func(
"ARRAY_GENERATE_RANGE", e.args["start"], e.args["end"] + 1, e.args.get("step")
),
exp.GroupConcat: rename_func("LISTAGG"),
exp.If: rename_func("IFF"),
exp.If: if_sql(name="IFF", false_value="NULL"),
exp.LogicalAnd: rename_func("BOOLAND_AGG"),
exp.LogicalOr: rename_func("BOOLOR_AGG"),
exp.Map: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),
@ -407,7 +424,13 @@ class Snowflake(Dialect):
exp.Min: min_or_least,
exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
exp.RegexpILike: _regexpilike_sql,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[
transforms.eliminate_distinct_on,
transforms.explode_to_unnest(0),
transforms.eliminate_semi_and_anti_joins,
]
),
exp.StarMap: rename_func("OBJECT_CONSTRUCT"),
exp.StartsWith: rename_func("STARTSWITH"),
exp.StrPosition: lambda self, e: self.func(
@ -431,6 +454,7 @@ class Snowflake(Dialect):
exp.UnixToTime: _unix_to_time_sql,
exp.VarMap: lambda self, e: var_map_sql(self, e, "OBJECT_CONSTRUCT"),
exp.WeekOfYear: rename_func("WEEKOFYEAR"),
exp.Xor: rename_func("BOOLXOR"),
}
TYPE_MAPPING = {
@ -449,6 +473,27 @@ class Snowflake(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
}
def unnest_sql(self, expression: exp.Unnest) -> str:
selects = ["value"]
unnest_alias = expression.args.get("alias")
offset = expression.args.get("offset")
if offset:
if unnest_alias:
expression = expression.copy()
unnest_alias.append("columns", offset.pop())
selects.append("index")
subquery = exp.Subquery(
this=exp.select(*selects).from_(
f"TABLE(FLATTEN(INPUT => {self.sql(expression.expressions[0])}))"
),
)
alias = self.sql(unnest_alias)
alias = f" AS {alias}" if alias else ""
return f"{self.sql(subquery)}{alias}"
def show_sql(self, expression: exp.Show) -> str:
scope = self.sql(expression, "scope")
scope = f" {scope}" if scope else ""

View file

@ -8,6 +8,7 @@ from sqlglot.dialects.dialect import (
create_with_partitions_sql,
format_time_lambda,
is_parse_json,
move_insert_cte_sql,
pivot_column_names,
rename_func,
trim_sql,
@ -115,13 +116,6 @@ def _unqualify_pivot_columns(expression: exp.Expression) -> exp.Expression:
return expression
def _insert_sql(self: Spark2.Generator, expression: exp.Insert) -> str:
if expression.expression.args.get("with"):
expression = expression.copy()
expression.set("with", expression.expression.args.pop("with"))
return self.insert_sql(expression)
class Spark2(Hive):
class Parser(Hive.Parser):
FUNCTIONS = {
@ -206,7 +200,7 @@ class Spark2(Hive):
exp.DayOfYear: rename_func("DAYOFYEAR"),
exp.FileFormatProperty: lambda self, e: f"USING {e.name.upper()}",
exp.From: transforms.preprocess([_unalias_pivot]),
exp.Insert: _insert_sql,
exp.Insert: move_insert_cte_sql,
exp.LogicalAnd: rename_func("BOOL_AND"),
exp.LogicalOr: rename_func("BOOL_OR"),
exp.Map: _map_sql,

View file

@ -64,6 +64,7 @@ def _transform_create(expression: exp.Expression) -> exp.Expression:
class SQLite(Dialect):
# https://sqlite.org/forum/forumpost/5e575586ac5c711b?raw
RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
SUPPORTS_SEMI_ANTI_JOIN = False
class Tokenizer(tokens.Tokenizer):
IDENTIFIERS = ['"', ("[", "]"), "`"]
@ -125,7 +126,11 @@ class SQLite(Dialect):
exp.Pivot: no_pivot_sql,
exp.SafeConcat: concat_to_dpipe_sql,
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_qualify]
[
transforms.eliminate_distinct_on,
transforms.eliminate_qualify,
transforms.eliminate_semi_and_anti_joins,
]
),
exp.TableSample: no_tablesample_sql,
exp.TimeStrToTime: lambda self, e: self.sql(e, "this"),

View file

@ -8,6 +8,8 @@ from sqlglot.tokens import TokenType
class Teradata(Dialect):
SUPPORTS_SEMI_ANTI_JOIN = False
TIME_MAPPING = {
"Y": "%Y",
"YYYY": "%Y",
@ -168,7 +170,9 @@ class Teradata(Dialect):
**generator.Generator.TRANSFORMS,
exp.Max: max_or_greatest,
exp.Min: min_or_least,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
),
exp.StrToDate: lambda self, e: f"CAST({self.sql(e, 'this')} AS DATE FORMAT {self.format_time(e)})",
exp.ToChar: lambda self, e: self.function_fallback_sql(e),
exp.Use: lambda self, e: f"DATABASE {self.sql(e, 'this')}",

View file

@ -10,6 +10,7 @@ from sqlglot.dialects.dialect import (
any_value_to_max_sql,
max_or_greatest,
min_or_least,
move_insert_cte_sql,
parse_date_delta,
rename_func,
timestrtotime_sql,
@ -206,6 +207,8 @@ class TSQL(Dialect):
RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
NULL_ORDERING = "nulls_are_small"
TIME_FORMAT = "'yyyy-mm-dd hh:mm:ss'"
SUPPORTS_SEMI_ANTI_JOIN = False
LOG_BASE_FIRST = False
TIME_MAPPING = {
"year": "%Y",
@ -345,6 +348,8 @@ class TSQL(Dialect):
}
class Parser(parser.Parser):
SET_REQUIRES_ASSIGNMENT_DELIMITER = False
FUNCTIONS = {
**parser.Parser.FUNCTIONS,
"CHARINDEX": lambda args: exp.StrPosition(
@ -396,7 +401,6 @@ class TSQL(Dialect):
TokenType.END: lambda self: self._parse_command(),
}
LOG_BASE_FIRST = False
LOG_DEFAULTS_TO_LN = True
CONCAT_NULL_OUTPUTS_STRING = True
@ -609,11 +613,14 @@ class TSQL(Dialect):
exp.Extract: rename_func("DATEPART"),
exp.GroupConcat: _string_agg_sql,
exp.If: rename_func("IIF"),
exp.Insert: move_insert_cte_sql,
exp.Max: max_or_greatest,
exp.MD5: lambda self, e: self.func("HASHBYTES", exp.Literal.string("MD5"), e.this),
exp.Min: min_or_least,
exp.NumberToStr: _format_sql,
exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
exp.Select: transforms.preprocess(
[transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
),
exp.SHA: lambda self, e: self.func("HASHBYTES", exp.Literal.string("SHA1"), e.this),
exp.SHA2: lambda self, e: self.func(
"HASHBYTES",
@ -632,6 +639,14 @@ class TSQL(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
}
def setitem_sql(self, expression: exp.SetItem) -> str:
this = expression.this
if isinstance(this, exp.EQ) and not isinstance(this.left, exp.Parameter):
# T-SQL does not use '=' in SET command, except when the LHS is a variable.
return f"{self.sql(this.left)} {self.sql(this.right)}"
return super().setitem_sql(expression)
def boolean_sql(self, expression: exp.Boolean) -> str:
if type(expression.parent) in BIT_TYPES:
return "1" if expression.this else "0"
@ -661,16 +676,27 @@ class TSQL(Dialect):
exists = expression.args.pop("exists", None)
sql = super().create_sql(expression)
if exists:
table = expression.find(exp.Table)
if kind == "TABLE" and expression.expression:
sql = f"SELECT * INTO {self.sql(table)} FROM ({self.sql(expression.expression)}) AS temp"
if exists:
identifier = self.sql(exp.Literal.string(exp.table_name(table) if table else ""))
sql = self.sql(exp.Literal.string(sql))
if kind == "SCHEMA":
sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = {identifier}) EXEC('{sql}')"""
sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = {identifier}) EXEC({sql})"""
elif kind == "TABLE":
sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = {identifier}) EXEC('{sql}')"""
assert table
where = exp.and_(
exp.column("table_name").eq(table.name),
exp.column("table_schema").eq(table.db) if table.db else None,
exp.column("table_catalog").eq(table.catalog) if table.catalog else None,
)
sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE {where}) EXEC({sql})"""
elif kind == "INDEX":
index = self.sql(exp.Literal.string(expression.this.text("this")))
sql = f"""IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id({identifier}) AND name = {index}) EXEC('{sql}')"""
sql = f"""IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id({identifier}) AND name = {index}) EXEC({sql})"""
elif expression.args.get("replace"):
sql = sql.replace("CREATE OR REPLACE ", "CREATE OR ALTER ", 1)

View file

@ -664,16 +664,6 @@ class Expression(metaclass=_Expression):
return load(obj)
IntoType = t.Union[
str,
t.Type[Expression],
t.Collection[t.Union[str, t.Type[Expression]]],
]
ExpOrStr = t.Union[str, Expression]
class Condition(Expression):
def and_(
self,
*expressions: t.Optional[ExpOrStr],
@ -762,11 +752,19 @@ class Condition(Expression):
return klass(this=other, expression=this)
return klass(this=this, expression=other)
def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]):
def __getitem__(self, other: ExpOrStr | t.Tuple[ExpOrStr]) -> Bracket:
return Bracket(
this=self.copy(), expressions=[convert(e, copy=True) for e in ensure_list(other)]
)
def __iter__(self) -> t.Iterator:
if "expressions" in self.arg_types:
return iter(self.args.get("expressions") or [])
# We define this because __getitem__ converts Expression into an iterable, which is
# problematic because one can hit infinite loops if they do "for x in some_expr: ..."
# See: https://peps.python.org/pep-0234/
raise TypeError(f"'{self.__class__.__name__}' object is not iterable")
def isin(
self,
*expressions: t.Any,
@ -886,6 +884,18 @@ class Condition(Expression):
return not_(self.copy())
IntoType = t.Union[
str,
t.Type[Expression],
t.Collection[t.Union[str, t.Type[Expression]]],
]
ExpOrStr = t.Union[str, Expression]
class Condition(Expression):
"""Logical conditions like x AND y, or simply x"""
class Predicate(Condition):
"""Relationships like x = y, x > 1, x >= y."""
@ -1045,6 +1055,10 @@ class Describe(Expression):
arg_types = {"this": True, "kind": False, "expressions": False}
class Kill(Expression):
arg_types = {"this": True, "kind": False}
class Pragma(Expression):
pass
@ -1161,7 +1175,7 @@ class Column(Condition):
if self.args.get(part)
]
def to_dot(self) -> Dot:
def to_dot(self) -> Dot | Identifier:
"""Converts the column into a dot expression."""
parts = self.parts
parent = self.parent
@ -1171,7 +1185,7 @@ class Column(Condition):
parts.append(parent.expression)
parent = parent.parent
return Dot.build(deepcopy(parts))
return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
class ColumnPosition(Expression):
@ -1607,6 +1621,7 @@ class Index(Expression):
"primary": False,
"amp": False, # teradata
"partition_by": False, # teradata
"where": False, # postgres partial indexes
}
@ -1917,7 +1932,7 @@ class Sort(Order):
class Ordered(Expression):
arg_types = {"this": True, "desc": True, "nulls_first": True}
arg_types = {"this": True, "desc": False, "nulls_first": True}
class Property(Expression):
@ -2569,7 +2584,6 @@ class Intersect(Union):
class Unnest(UDTF):
arg_types = {
"expressions": True,
"ordinality": False,
"alias": False,
"offset": False,
}
@ -2862,6 +2876,7 @@ class Select(Subqueryable):
prefix="LIMIT",
dialect=dialect,
copy=copy,
into_arg="expression",
**opts,
)
@ -4007,6 +4022,10 @@ class TimeUnit(Expression):
super().__init__(**args)
@property
def unit(self) -> t.Optional[Var]:
return self.args.get("unit")
# https://www.oracletutorial.com/oracle-basics/oracle-interval/
# https://trino.io/docs/current/language/types.html#interval-day-to-second
@ -4018,10 +4037,6 @@ class IntervalSpan(Expression):
class Interval(TimeUnit):
arg_types = {"this": False, "unit": False}
@property
def unit(self) -> t.Optional[Var]:
return self.args.get("unit")
class IgnoreNulls(Expression):
pass
@ -4327,6 +4342,10 @@ class DateDiff(Func, TimeUnit):
class DateTrunc(Func):
arg_types = {"unit": True, "this": True, "zone": False}
@property
def unit(self) -> Expression:
return self.args["unit"]
class DatetimeAdd(Func, TimeUnit):
arg_types = {"this": True, "expression": True, "unit": False}
@ -4427,7 +4446,8 @@ class DateToDi(Func):
# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
class Date(Func):
arg_types = {"this": True, "zone": False}
arg_types = {"this": False, "zone": False, "expressions": False}
is_var_len_args = True
class Day(Func):
@ -5131,10 +5151,11 @@ def _apply_builder(
prefix=None,
into=None,
dialect=None,
into_arg="this",
**opts,
):
if _is_wrong_expression(expression, into):
expression = into(this=expression)
expression = into(**{into_arg: expression})
instance = maybe_copy(instance, copy)
expression = maybe_parse(
sql_or_expression=expression,
@ -5926,7 +5947,10 @@ def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Ca
The new Cast instance.
"""
expression = maybe_parse(expression, **opts)
return Cast(this=expression, to=DataType.build(to, **opts))
data_type = DataType.build(to, **opts)
expression = Cast(this=expression, to=data_type)
expression.type = data_type
return expression
def table_(

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import logging
import typing as t
from collections import defaultdict
from functools import reduce
from sqlglot import exp
from sqlglot.errors import ErrorLevel, UnsupportedError, concat_messages
@ -99,6 +100,9 @@ class Generator:
exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}",
}
# Whether the base comes first
LOG_BASE_FIRST = True
# Whether or not null ordering is supported in order by
NULL_ORDERING_SUPPORTED = True
@ -188,6 +192,18 @@ class Generator:
# Whether or not the word COLUMN is included when adding a column with ALTER TABLE
ALTER_TABLE_ADD_COLUMN_KEYWORD = True
# UNNEST WITH ORDINALITY (presto) instead of UNNEST WITH OFFSET (bigquery)
UNNEST_WITH_ORDINALITY = True
# Whether or not FILTER (WHERE cond) can be used for conditional aggregation
AGGREGATE_FILTER_SUPPORTED = True
# Whether or not JOIN sides (LEFT, RIGHT) are supported in conjunction with SEMI/ANTI join kinds
SEMI_ANTI_JOIN_WITH_SIDE = True
# Whether or not session variables / parameters are supported, e.g. @x in T-SQL
SUPPORTS_PARAMETERS = True
TYPE_MAPPING = {
exp.DataType.Type.NCHAR: "CHAR",
exp.DataType.Type.NVARCHAR: "VARCHAR",
@ -308,6 +324,8 @@ class Generator:
exp.Paren,
)
UNESCAPED_SEQUENCE_TABLE = None # type: ignore
SENTINEL_LINE_BREAK = "__SQLGLOT__LB__"
# Autofilled
@ -320,7 +338,6 @@ class Generator:
STRICT_STRING_CONCAT = False
NORMALIZE_FUNCTIONS: bool | str = "upper"
NULL_ORDERING = "nulls_are_small"
ESCAPE_LINE_BREAK = False
can_identify: t.Callable[[str, str | bool], bool]
@ -955,10 +972,17 @@ class Generator:
return f"{self.seg('FETCH')}{direction}{count} ROWS {with_ties_or_only}"
def filter_sql(self, expression: exp.Filter) -> str:
if self.AGGREGATE_FILTER_SUPPORTED:
this = self.sql(expression, "this")
where = self.sql(expression, "expression").strip()
return f"{this} FILTER({where})"
agg = expression.this.copy()
agg_arg = agg.this
cond = expression.expression.this
agg_arg.replace(exp.If(this=cond.copy(), true=agg_arg.copy()))
return self.sql(agg)
def hint_sql(self, expression: exp.Hint) -> str:
if not self.QUERY_HINTS:
self.unsupported("Hints are not supported")
@ -975,13 +999,14 @@ class Generator:
table = self.sql(expression, "table")
table = f"{self.INDEX_ON} {table}" if table else ""
using = self.sql(expression, "using")
using = f" USING {using} " if using else ""
using = f" USING {using}" if using else ""
index = "INDEX " if not table else ""
columns = self.expressions(expression, key="columns", flat=True)
columns = f"({columns})" if columns else ""
partition_by = self.expressions(expression, key="partition_by", flat=True)
partition_by = f" PARTITION BY {partition_by}" if partition_by else ""
return f"{unique}{primary}{amp}{index}{name}{table}{using}{columns}{partition_by}"
where = self.sql(expression, "where")
return f"{unique}{primary}{amp}{index}{name}{table}{using}{columns}{partition_by}{where}"
def identifier_sql(self, expression: exp.Identifier) -> str:
text = expression.name
@ -1060,10 +1085,15 @@ class Generator:
return properties_locs
def property_name(self, expression: exp.Property, string_key: bool = False) -> str:
if isinstance(expression.this, exp.Dot):
return self.sql(expression, "this")
return f"'{expression.name}'" if string_key else expression.name
def property_sql(self, expression: exp.Property) -> str:
property_cls = expression.__class__
if property_cls == exp.Property:
return f"{expression.name}={self.sql(expression, 'value')}"
return f"{self.property_name(expression)}={self.sql(expression, 'value')}"
property_name = exp.Properties.PROPERTY_TO_NAME.get(property_cls)
if not property_name:
@ -1224,6 +1254,13 @@ class Generator:
def introducer_sql(self, expression: exp.Introducer) -> str:
return f"{self.sql(expression, 'this')} {self.sql(expression, 'expression')}"
def kill_sql(self, expression: exp.Kill) -> str:
kind = self.sql(expression, "kind")
kind = f" {kind}" if kind else ""
this = self.sql(expression, "this")
this = f" {this}" if this else ""
return f"KILL{kind}{this}"
def pseudotype_sql(self, expression: exp.PseudoType) -> str:
return expression.name.upper()
@ -1386,13 +1423,11 @@ class Generator:
return f"{values} AS {alias}" if alias else values
# Converts `VALUES...` expression into a series of select unions.
# Note: If you have a lot of unions then this will result in a large number of recursive statements to
# evaluate the expression. You may need to increase `sys.setrecursionlimit` to run and it can also be
# very slow.
expression = expression.copy()
column_names = expression.alias and expression.args["alias"].columns
alias_node = expression.args.get("alias")
column_names = alias_node and alias_node.columns
selects = []
selects: t.List[exp.Subqueryable] = []
for i, tup in enumerate(expression.expressions):
row = tup.expressions
@ -1404,14 +1439,18 @@ class Generator:
selects.append(exp.Select(expressions=row))
subquery_expression: exp.Select | exp.Union = selects[0]
if len(selects) > 1:
for select in selects[1:]:
subquery_expression = exp.union(
subquery_expression, select, distinct=False, copy=False
if self.pretty:
# This may result in poor performance for large-cardinality `VALUES` tables, due to
# the deep nesting of the resulting exp.Unions. If this is a problem, either increase
# `sys.setrecursionlimit` to avoid RecursionErrors, or don't set `pretty`.
subqueryable = reduce(lambda x, y: exp.union(x, y, distinct=False, copy=False), selects)
return self.subquery_sql(
subqueryable.subquery(alias_node and alias_node.this, copy=False)
)
return self.subquery_sql(subquery_expression.subquery(expression.alias, copy=False))
alias = f" AS {self.sql(alias_node, 'this')}" if alias_node else ""
unions = " UNION ALL ".join(self.sql(select) for select in selects)
return f"({unions}){alias}"
def var_sql(self, expression: exp.Var) -> str:
return self.sql(expression, "this")
@ -1477,12 +1516,17 @@ class Generator:
return f"PRIOR {self.sql(expression, 'this')}"
def join_sql(self, expression: exp.Join) -> str:
if not self.SEMI_ANTI_JOIN_WITH_SIDE and expression.kind in ("SEMI", "ANTI"):
side = None
else:
side = expression.side
op_sql = " ".join(
op
for op in (
expression.method,
"GLOBAL" if expression.args.get("global") else None,
expression.side,
side,
expression.kind,
expression.hint if self.JOIN_HINTS else None,
)
@ -1594,8 +1638,8 @@ class Generator:
def escape_str(self, text: str) -> str:
text = text.replace(self.QUOTE_END, self._escaped_quote_end)
if self.ESCAPE_LINE_BREAK:
text = text.replace("\n", "\\n")
if self.UNESCAPED_SEQUENCE_TABLE:
text = text.translate(self.UNESCAPED_SEQUENCE_TABLE)
elif self.pretty:
text = text.replace("\n", self.SENTINEL_LINE_BREAK)
return text
@ -1643,7 +1687,7 @@ class Generator:
nulls_are_small = self.NULL_ORDERING == "nulls_are_small"
nulls_are_last = self.NULL_ORDERING == "nulls_are_last"
sort_order = " DESC" if desc else ""
sort_order = " DESC" if desc else (" ASC" if desc is False else "")
nulls_sort_change = ""
if nulls_first and (
(asc and nulls_are_large) or (desc and nulls_are_small) or nulls_are_last
@ -1817,8 +1861,7 @@ class Generator:
def parameter_sql(self, expression: exp.Parameter) -> str:
this = self.sql(expression, "this")
this = f"{{{this}}}" if expression.args.get("wrapped") else f"{this}"
return f"{self.PARAMETER_TOKEN}{this}"
return f"{self.PARAMETER_TOKEN}{this}" if self.SUPPORTS_PARAMETERS else this
def sessionparameter_sql(self, expression: exp.SessionParameter) -> str:
this = self.sql(expression, "this")
@ -1858,17 +1901,33 @@ class Generator:
def unnest_sql(self, expression: exp.Unnest) -> str:
args = self.expressions(expression, flat=True)
alias = expression.args.get("alias")
offset = expression.args.get("offset")
if self.UNNEST_WITH_ORDINALITY:
if alias and isinstance(offset, exp.Expression):
alias = alias.copy()
alias.append("columns", offset.copy())
if alias and self.UNNEST_COLUMN_ONLY:
columns = alias.columns
alias = self.sql(columns[0]) if columns else ""
else:
alias = self.sql(expression, "alias")
alias = self.sql(alias)
alias = f" AS {alias}" if alias else alias
ordinality = " WITH ORDINALITY" if expression.args.get("ordinality") else ""
offset = expression.args.get("offset")
offset = f" WITH OFFSET AS {self.sql(offset)}" if offset else ""
return f"UNNEST({args}){ordinality}{alias}{offset}"
if self.UNNEST_WITH_ORDINALITY:
suffix = f" WITH ORDINALITY{alias}" if offset else alias
else:
if isinstance(offset, exp.Expression):
suffix = f"{alias} WITH OFFSET AS {self.sql(offset)}"
elif offset:
suffix = f"{alias} WITH OFFSET"
else:
suffix = alias
return f"UNNEST({args}){suffix}"
def where_sql(self, expression: exp.Where) -> str:
this = self.indent(self.sql(expression, "this"))
@ -2471,6 +2530,12 @@ class Generator:
def trycast_sql(self, expression: exp.TryCast) -> str:
return self.cast_sql(expression, safe_prefix="TRY_")
def log_sql(self, expression: exp.Log) -> str:
args = list(expression.args.values())
if not self.LOG_BASE_FIRST:
args.reverse()
return self.func("LOG", *args)
def use_sql(self, expression: exp.Use) -> str:
kind = self.sql(expression, "kind")
kind = f" {kind}" if kind else ""

View file

@ -13,9 +13,10 @@ from itertools import count
if t.TYPE_CHECKING:
from sqlglot import exp
from sqlglot._typing import E, T
from sqlglot._typing import A, E, T
from sqlglot.expressions import Expression
CAMEL_CASE_PATTERN = re.compile("(?<!^)(?=[A-Z])")
PYTHON_VERSION = sys.version_info[:2]
logger = logging.getLogger("sqlglot")
@ -379,7 +380,9 @@ def is_iterable(value: t.Any) -> bool:
Returns:
A `bool` value indicating if it is an iterable.
"""
return hasattr(value, "__iter__") and not isinstance(value, (str, bytes))
from sqlglot import Expression
return hasattr(value, "__iter__") and not isinstance(value, (str, bytes, Expression))
def flatten(values: t.Iterable[t.Iterable[t.Any] | t.Any]) -> t.Iterator[t.Any]:
@ -435,3 +438,22 @@ def dict_depth(d: t.Dict) -> int:
def first(it: t.Iterable[T]) -> T:
"""Returns the first element from an iterable (useful for sets)."""
return next(i for i in it)
def merge_ranges(ranges: t.List[t.Tuple[A, A]]) -> t.List[t.Tuple[A, A]]:
if not ranges:
return []
ranges = sorted(ranges)
merged = [ranges[0]]
for start, end in ranges[1:]:
last_start, last_end = merged[-1]
if start <= last_end:
merged[-1] = (last_start, max(last_end, end))
else:
merged.append((start, end))
return merged

View file

@ -158,6 +158,7 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
exp.TimeAdd,
exp.TimeStrToTime,
exp.TimeSub,
exp.Timestamp,
exp.TimestampAdd,
exp.TimestampSub,
exp.UnixToTime,
@ -177,6 +178,7 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
exp.Initcap,
exp.Lower,
exp.SafeConcat,
exp.SafeDPipe,
exp.Substring,
exp.TimeToStr,
exp.TimeToTimeStr,
@ -242,6 +244,13 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
self.annotators = annotators or self.ANNOTATORS
self.coerces_to = coerces_to or self.COERCES_TO
# Caches the ids of annotated sub-Expressions, to ensure we only visit them once
self._visited: t.Set[int] = set()
def _set_type(self, expression: exp.Expression, target_type: exp.DataType) -> None:
expression.type = target_type
self._visited.add(id(expression))
def annotate(self, expression: E) -> E:
for scope in traverse_scope(expression):
selects = {}
@ -279,9 +288,9 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
source = scope.sources.get(col.table)
if isinstance(source, exp.Table):
col.type = self.schema.get_column_type(source, col)
self._set_type(col, self.schema.get_column_type(source, col))
elif source and col.table in selects and col.name in selects[col.table]:
col.type = selects[col.table][col.name].type
self._set_type(col, selects[col.table][col.name].type)
# Then (possibly) annotate the remaining expressions in the scope
self._maybe_annotate(scope.expression)
@ -289,7 +298,7 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
return self._maybe_annotate(expression) # This takes care of non-traversable expressions
def _maybe_annotate(self, expression: E) -> E:
if expression.type:
if id(expression) in self._visited:
return expression # We've already inferred the expression's type
annotator = self.annotators.get(expression.__class__)
@ -338,17 +347,18 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
if isinstance(expression, exp.Connector):
if left_type == exp.DataType.Type.NULL and right_type == exp.DataType.Type.NULL:
expression.type = exp.DataType.Type.NULL
self._set_type(expression, exp.DataType.Type.NULL)
elif exp.DataType.Type.NULL in (left_type, right_type):
expression.type = exp.DataType.build(
"NULLABLE", expressions=exp.DataType.build("BOOLEAN")
self._set_type(
expression,
exp.DataType.build("NULLABLE", expressions=exp.DataType.build("BOOLEAN")),
)
else:
expression.type = exp.DataType.Type.BOOLEAN
self._set_type(expression, exp.DataType.Type.BOOLEAN)
elif isinstance(expression, exp.Predicate):
expression.type = exp.DataType.Type.BOOLEAN
self._set_type(expression, exp.DataType.Type.BOOLEAN)
else:
expression.type = self._maybe_coerce(left_type, right_type)
self._set_type(expression, self._maybe_coerce(left_type, right_type))
return expression
@ -357,26 +367,26 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
self._annotate_args(expression)
if isinstance(expression, exp.Condition) and not isinstance(expression, exp.Paren):
expression.type = exp.DataType.Type.BOOLEAN
self._set_type(expression, exp.DataType.Type.BOOLEAN)
else:
expression.type = expression.this.type
self._set_type(expression, expression.this.type)
return expression
@t.no_type_check
def _annotate_literal(self, expression: exp.Literal) -> exp.Literal:
if expression.is_string:
expression.type = exp.DataType.Type.VARCHAR
self._set_type(expression, exp.DataType.Type.VARCHAR)
elif expression.is_int:
expression.type = exp.DataType.Type.INT
self._set_type(expression, exp.DataType.Type.INT)
else:
expression.type = exp.DataType.Type.DOUBLE
self._set_type(expression, exp.DataType.Type.DOUBLE)
return expression
@t.no_type_check
def _annotate_with_type(self, expression: E, target_type: exp.DataType.Type) -> E:
expression.type = target_type
self._set_type(expression, target_type)
return self._annotate_args(expression)
@t.no_type_check
@ -394,17 +404,20 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
for expr in expressions:
last_datatype = self._maybe_coerce(last_datatype or expr.type, expr.type)
expression.type = last_datatype or exp.DataType.Type.UNKNOWN
self._set_type(expression, last_datatype or exp.DataType.Type.UNKNOWN)
if promote:
if expression.type.this in exp.DataType.INTEGER_TYPES:
expression.type = exp.DataType.Type.BIGINT
self._set_type(expression, exp.DataType.Type.BIGINT)
elif expression.type.this in exp.DataType.FLOAT_TYPES:
expression.type = exp.DataType.Type.DOUBLE
self._set_type(expression, exp.DataType.Type.DOUBLE)
if array:
expression.type = exp.DataType(
self._set_type(
expression,
exp.DataType(
this=exp.DataType.Type.ARRAY, expressions=[expression.type], nested=True
),
)
return expression

View file

@ -17,9 +17,11 @@ def canonicalize(expression: exp.Expression) -> exp.Expression:
exp.replace_children(expression, canonicalize)
expression = add_text_to_concat(expression)
expression = replace_date_funcs(expression)
expression = coerce_type(expression)
expression = remove_redundant_casts(expression)
expression = ensure_bool_predicates(expression)
expression = remove_ascending_order(expression)
return expression
@ -30,6 +32,14 @@ def add_text_to_concat(node: exp.Expression) -> exp.Expression:
return node
def replace_date_funcs(node: exp.Expression) -> exp.Expression:
if isinstance(node, exp.Date) and not node.expressions and not node.args.get("zone"):
return exp.cast(node.this, to=exp.DataType.Type.DATE)
if isinstance(node, exp.Timestamp) and not node.expression:
return exp.cast(node.this, to=exp.DataType.Type.TIMESTAMP)
return node
def coerce_type(node: exp.Expression) -> exp.Expression:
if isinstance(node, exp.Binary):
_coerce_date(node.left, node.right)
@ -63,6 +73,14 @@ def ensure_bool_predicates(expression: exp.Expression) -> exp.Expression:
return expression
def remove_ascending_order(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Ordered) and expression.args.get("desc") is False:
# Convert ORDER BY a ASC to ORDER BY a
expression.set("desc", None)
return expression
def _coerce_date(a: exp.Expression, b: exp.Expression) -> None:
for a, b in itertools.permutations([a, b]):
if (
@ -75,10 +93,7 @@ def _coerce_date(a: exp.Expression, b: exp.Expression) -> None:
def _replace_cast(node: exp.Expression, to: str) -> None:
data_type = exp.DataType.build(to)
cast = exp.Cast(this=node.copy(), to=data_type)
cast.type = data_type
node.replace(cast)
node.replace(exp.cast(node.copy(), to=to))
def _replace_int_predicate(expression: exp.Expression) -> None:

View file

@ -1,17 +1,22 @@
import datetime
import functools
import itertools
import typing as t
from collections import deque
from decimal import Decimal
from sqlglot import exp
from sqlglot.generator import cached_generator
from sqlglot.helper import first, while_changing
from sqlglot.helper import first, merge_ranges, while_changing
# Final means that an expression should not be simplified
FINAL = "final"
class UnsupportedUnit(Exception):
pass
def simplify(expression):
"""
Rewrite sqlglot AST to simplify expressions.
@ -72,7 +77,9 @@ def simplify(expression):
node = simplify_coalesce(node)
node.parent = expression.parent
node = simplify_literals(node, root)
node = simplify_equality(node)
node = simplify_parens(node)
node = simplify_datetrunc_predicate(node)
if root:
expression.replace(node)
@ -84,6 +91,21 @@ def simplify(expression):
return expression
def catch(*exceptions):
"""Decorator that ignores a simplification function if any of `exceptions` are raised"""
def decorator(func):
def wrapped(expression, *args, **kwargs):
try:
return func(expression, *args, **kwargs)
except exceptions:
return expression
return wrapped
return decorator
def rewrite_between(expression: exp.Expression) -> exp.Expression:
"""Rewrite x between y and z to x >= y AND x <= z.
@ -196,7 +218,7 @@ COMPARISONS = (
exp.Is,
)
INVERSE_COMPARISONS = {
INVERSE_COMPARISONS: t.Dict[t.Type[exp.Expression], t.Type[exp.Expression]] = {
exp.LT: exp.GT,
exp.GT: exp.LT,
exp.LTE: exp.GTE,
@ -347,6 +369,87 @@ def absorb_and_eliminate(expression, root=True):
return expression
INVERSE_DATE_OPS: t.Dict[t.Type[exp.Expression], t.Type[exp.Expression]] = {
exp.DateAdd: exp.Sub,
exp.DateSub: exp.Add,
exp.DatetimeAdd: exp.Sub,
exp.DatetimeSub: exp.Add,
}
INVERSE_OPS: t.Dict[t.Type[exp.Expression], t.Type[exp.Expression]] = {
**INVERSE_DATE_OPS,
exp.Add: exp.Sub,
exp.Sub: exp.Add,
}
def _is_number(expression: exp.Expression) -> bool:
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:
return isinstance(expression, exp.Interval) and extract_interval(expression) is not None
@catch(ModuleNotFoundError, UnsupportedUnit)
def simplify_equality(expression: exp.Expression) -> exp.Expression:
"""
Use the subtraction and addition properties of equality to simplify expressions:
x + 1 = 3 becomes x = 2
There are two binary operations in the above expression: + and =
Here's how we reference all the operands in the code below:
l r
x + 1 = 3
a b
"""
if isinstance(expression, COMPARISONS):
l, r = expression.left, expression.right
if l.__class__ in INVERSE_OPS:
pass
elif r.__class__ in INVERSE_OPS:
l, r = r, l
else:
return expression
if r.is_number:
a_predicate = _is_number
b_predicate = _is_number
elif _is_date(r):
a_predicate = _is_date
b_predicate = _is_interval
else:
return expression
if l.__class__ in INVERSE_DATE_OPS:
a = l.this
b = exp.Interval(
this=l.expression.copy(),
unit=l.unit.copy(),
)
else:
a, b = l.left, l.right
if not a_predicate(a) and b_predicate(b):
pass
elif not a_predicate(b) and b_predicate(a):
a, b = b, a
else:
return expression
return expression.__class__(
this=a, expression=INVERSE_OPS[l.__class__](this=r, expression=b)
)
return expression
def simplify_literals(expression, root=True):
if isinstance(expression, exp.Binary) and not isinstance(expression, exp.Connector):
return _flat_simplify(expression, _simplify_binary, root)
@ -530,6 +633,123 @@ def simplify_concat(expression):
return new_args[0] if len(new_args) == 1 else concat_type(expressions=new_args)
DateRange = t.Tuple[datetime.date, datetime.date]
def _datetrunc_range(date: datetime.date, unit: str) -> t.Optional[DateRange]:
"""
Get the date range for a DATE_TRUNC equality comparison:
Example:
_datetrunc_range(date(2021-01-01), 'year') == (date(2021-01-01), date(2022-01-01))
Returns:
tuple of [min, max) or None if a value can never be equal to `date` for `unit`
"""
floor = date_floor(date, unit)
if date != floor:
# This will always be False, except for NULL values.
return None
return floor, floor + interval(unit)
def _datetrunc_eq_expression(left: exp.Expression, drange: DateRange) -> exp.Expression:
"""Get the logical expression for a date range"""
return exp.and_(
left >= date_literal(drange[0]),
left < date_literal(drange[1]),
copy=False,
)
def _datetrunc_eq(
left: exp.Expression, date: datetime.date, unit: str
) -> t.Optional[exp.Expression]:
drange = _datetrunc_range(date, unit)
if not drange:
return None
return _datetrunc_eq_expression(left, drange)
def _datetrunc_neq(
left: exp.Expression, date: datetime.date, unit: str
) -> t.Optional[exp.Expression]:
drange = _datetrunc_range(date, unit)
if not drange:
return None
return exp.and_(
left < date_literal(drange[0]),
left >= date_literal(drange[1]),
copy=False,
)
DateTruncBinaryTransform = t.Callable[
[exp.Expression, datetime.date, str], t.Optional[exp.Expression]
]
DATETRUNC_BINARY_COMPARISONS: t.Dict[t.Type[exp.Expression], DateTruncBinaryTransform] = {
exp.LT: lambda l, d, u: l < date_literal(date_floor(d, u)),
exp.GT: lambda l, d, u: l >= date_literal(date_floor(d, u) + interval(u)),
exp.LTE: lambda l, d, u: l < date_literal(date_floor(d, u) + interval(u)),
exp.GTE: lambda l, d, u: l >= date_literal(date_ceil(d, u)),
exp.EQ: _datetrunc_eq,
exp.NEQ: _datetrunc_neq,
}
DATETRUNC_COMPARISONS = {exp.In, *DATETRUNC_BINARY_COMPARISONS}
def _is_datetrunc_predicate(left: exp.Expression, right: exp.Expression) -> bool:
return (
isinstance(left, (exp.DateTrunc, exp.TimestampTrunc))
and isinstance(right, exp.Cast)
and right.is_type(*exp.DataType.TEMPORAL_TYPES)
)
@catch(ModuleNotFoundError, UnsupportedUnit)
def simplify_datetrunc_predicate(expression: exp.Expression) -> exp.Expression:
"""Simplify expressions like `DATE_TRUNC('year', x) >= CAST('2021-01-01' AS DATE)`"""
comparison = expression.__class__
if comparison not in DATETRUNC_COMPARISONS:
return expression
if isinstance(expression, exp.Binary):
l, r = expression.left, expression.right
if _is_datetrunc_predicate(l, r):
pass
elif _is_datetrunc_predicate(r, l):
comparison = INVERSE_COMPARISONS.get(comparison, comparison)
l, r = r, l
else:
return expression
unit = l.unit.name.lower()
date = extract_date(r)
return DATETRUNC_BINARY_COMPARISONS[comparison](l.this, date, unit) or expression
elif isinstance(expression, exp.In):
l = expression.this
rs = expression.expressions
if all(_is_datetrunc_predicate(l, r) for r in rs):
unit = l.unit.name.lower()
ranges = [r for r in [_datetrunc_range(extract_date(r), unit) for r in rs] if r]
if not ranges:
return expression
ranges = merge_ranges(ranges)
return exp.or_(*[_datetrunc_eq_expression(l, drange) for drange in ranges], copy=False)
return expression
# CROSS joins result in an empty table if the right table is empty.
# So we can only simplify certain types of joins to CROSS.
# Or in other words, LEFT JOIN x ON TRUE != CROSS JOIN x
@ -603,23 +823,13 @@ def extract_date(cast):
return None
def extract_interval(interval):
def extract_interval(expression):
n = int(expression.name)
unit = expression.text("unit").lower()
try:
from dateutil.relativedelta import relativedelta # type: ignore
except ModuleNotFoundError:
return None
n = int(interval.name)
unit = interval.text("unit").lower()
if unit == "year":
return relativedelta(years=n)
if unit == "month":
return relativedelta(months=n)
if unit == "week":
return relativedelta(weeks=n)
if unit == "day":
return relativedelta(days=n)
return interval(unit, n)
except (UnsupportedUnit, ModuleNotFoundError):
return None
@ -630,6 +840,61 @@ def date_literal(date):
)
def interval(unit: str, n: int = 1):
from dateutil.relativedelta import relativedelta
if unit == "year":
return relativedelta(years=1 * n)
if unit == "quarter":
return relativedelta(months=3 * n)
if unit == "month":
return relativedelta(months=1 * n)
if unit == "week":
return relativedelta(weeks=1 * n)
if unit == "day":
return relativedelta(days=1 * n)
if unit == "hour":
return relativedelta(hours=1 * n)
if unit == "minute":
return relativedelta(minutes=1 * n)
if unit == "second":
return relativedelta(seconds=1 * n)
raise UnsupportedUnit(f"Unsupported unit: {unit}")
def date_floor(d: datetime.date, unit: str) -> datetime.date:
if unit == "year":
return d.replace(month=1, day=1)
if unit == "quarter":
if d.month <= 3:
return d.replace(month=1, day=1)
elif d.month <= 6:
return d.replace(month=4, day=1)
elif d.month <= 9:
return d.replace(month=7, day=1)
else:
return d.replace(month=10, day=1)
if unit == "month":
return d.replace(month=d.month, day=1)
if unit == "week":
# Assuming week starts on Monday (0) and ends on Sunday (6)
return d - datetime.timedelta(days=d.weekday())
if unit == "day":
return d
raise UnsupportedUnit(f"Unsupported unit: {unit}")
def date_ceil(d: datetime.date, unit: str) -> datetime.date:
floor = date_floor(d, unit)
if floor == d:
return d
return floor + interval(unit)
def boolean_literal(condition):
return exp.true() if condition else exp.false()

View file

@ -43,7 +43,11 @@ def unnest(select, parent_select, next_alias_name):
predicate = select.find_ancestor(exp.Condition)
alias = next_alias_name()
if not predicate or parent_select is not predicate.parent_select:
if (
not predicate
or parent_select is not predicate.parent_select
or not parent_select.args.get("from")
):
return
# This subquery returns a scalar and can just be converted to a cross join

View file

@ -278,6 +278,7 @@ class Parser(metaclass=_Parser):
TokenType.ISNULL,
TokenType.INTERVAL,
TokenType.KEEP,
TokenType.KILL,
TokenType.LEFT,
TokenType.LOAD,
TokenType.MERGE,
@ -285,6 +286,7 @@ class Parser(metaclass=_Parser):
TokenType.NEXT,
TokenType.OFFSET,
TokenType.ORDINALITY,
TokenType.OVERLAPS,
TokenType.OVERWRITE,
TokenType.PARTITION,
TokenType.PERCENT,
@ -316,6 +318,7 @@ class Parser(metaclass=_Parser):
INTERVAL_VARS = ID_VAR_TOKENS - {TokenType.END}
TABLE_ALIAS_TOKENS = ID_VAR_TOKENS - {
TokenType.ANTI,
TokenType.APPLY,
TokenType.ASOF,
TokenType.FULL,
@ -324,6 +327,7 @@ class Parser(metaclass=_Parser):
TokenType.NATURAL,
TokenType.OFFSET,
TokenType.RIGHT,
TokenType.SEMI,
TokenType.WINDOW,
}
@ -541,6 +545,7 @@ class Parser(metaclass=_Parser):
TokenType.DESCRIBE: lambda self: self._parse_describe(),
TokenType.DROP: lambda self: self._parse_drop(),
TokenType.INSERT: lambda self: self._parse_insert(),
TokenType.KILL: lambda self: self._parse_kill(),
TokenType.LOAD: lambda self: self._parse_load(),
TokenType.MERGE: lambda self: self._parse_merge(),
TokenType.PIVOT: lambda self: self._parse_simplified_pivot(),
@ -856,6 +861,8 @@ class Parser(metaclass=_Parser):
DISTINCT_TOKENS = {TokenType.DISTINCT}
NULL_TOKENS = {TokenType.NULL}
STRICT_CAST = True
# A NULL arg in CONCAT yields NULL by default
@ -873,6 +880,9 @@ class Parser(metaclass=_Parser):
# Whether or not the table sample clause expects CSV syntax
TABLESAMPLE_CSV = False
# Whether or not the SET command needs a delimiter (e.g. "=") for assignments.
SET_REQUIRES_ASSIGNMENT_DELIMITER = True
__slots__ = (
"error_level",
"error_message_context",
@ -1280,6 +1290,13 @@ class Parser(metaclass=_Parser):
else:
begin = self._match(TokenType.BEGIN)
return_ = self._match_text_seq("RETURN")
if self._match(TokenType.STRING, advance=False):
# Takes care of BigQuery's JavaScript UDF definitions that end in an OPTIONS property
# # https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement
expression = self._parse_string()
extend_props(self._parse_properties())
else:
expression = self._parse_statement()
if return_:
@ -1400,21 +1417,19 @@ class Parser(metaclass=_Parser):
if self._match_text_seq("SQL", "SECURITY"):
return self.expression(exp.SqlSecurityProperty, definer=self._match_text_seq("DEFINER"))
assignment = self._match_pair(
TokenType.VAR, TokenType.EQ, advance=False
) or self._match_pair(TokenType.STRING, TokenType.EQ, advance=False)
index = self._index
key = self._parse_column()
if not self._match(TokenType.EQ):
self._retreat(index)
return None
if assignment:
key = self._parse_var_or_string()
self._match(TokenType.EQ)
return self.expression(
exp.Property,
this=key,
this=key.to_dot() if isinstance(key, exp.Column) else key,
value=self._parse_column() or self._parse_var(any_token=True),
)
return None
def _parse_stored(self) -> exp.FileFormatProperty:
self._match(TokenType.ALIAS)
@ -1818,6 +1833,15 @@ class Parser(metaclass=_Parser):
ignore=ignore,
)
def _parse_kill(self) -> exp.Kill:
kind = exp.var(self._prev.text) if self._match_texts(("CONNECTION", "QUERY")) else None
return self.expression(
exp.Kill,
this=self._parse_primary(),
kind=kind,
)
def _parse_on_conflict(self) -> t.Optional[exp.OnConflict]:
conflict = self._match_text_seq("ON", "CONFLICT")
duplicate = self._match_text_seq("ON", "DUPLICATE", "KEY")
@ -2459,7 +2483,7 @@ class Parser(metaclass=_Parser):
index = self._parse_id_var()
table = None
using = self._parse_field() 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):
columns = self._parse_wrapped_csv(self._parse_ordered)
@ -2476,6 +2500,7 @@ class Parser(metaclass=_Parser):
primary=primary,
amp=amp,
partition_by=self._parse_partition_by(),
where=self._parse_where(),
)
def _parse_table_hints(self) -> t.Optional[t.List[exp.Expression]]:
@ -2634,25 +2659,27 @@ class Parser(metaclass=_Parser):
return None
expressions = self._parse_wrapped_csv(self._parse_type)
ordinality = self._match_pair(TokenType.WITH, TokenType.ORDINALITY)
offset = self._match_pair(TokenType.WITH, TokenType.ORDINALITY)
alias = self._parse_table_alias() if with_alias else None
if alias and self.UNNEST_COLUMN_ONLY:
if alias:
if self.UNNEST_COLUMN_ONLY:
if alias.args.get("columns"):
self.raise_error("Unexpected extra column alias in unnest.")
alias.set("columns", [alias.this])
alias.set("this", None)
offset = None
if self._match_pair(TokenType.WITH, TokenType.OFFSET):
columns = alias.args.get("columns") or []
if offset and len(expressions) < len(columns):
offset = columns.pop()
if not offset and self._match_pair(TokenType.WITH, TokenType.OFFSET):
self._match(TokenType.ALIAS)
offset = self._parse_id_var() or exp.to_identifier("offset")
return self.expression(
exp.Unnest, expressions=expressions, ordinality=ordinality, alias=alias, offset=offset
)
return self.expression(exp.Unnest, expressions=expressions, alias=alias, offset=offset)
def _parse_derived_table_values(self) -> t.Optional[exp.Values]:
is_derived = self._match_pair(TokenType.L_PAREN, TokenType.VALUES)
@ -2940,20 +2967,20 @@ class Parser(metaclass=_Parser):
def _parse_ordered(self) -> exp.Ordered:
this = self._parse_conjunction()
self._match(TokenType.ASC)
is_desc = self._match(TokenType.DESC)
asc = self._match(TokenType.ASC)
desc = self._match(TokenType.DESC) or (asc and False)
is_nulls_first = self._match_text_seq("NULLS", "FIRST")
is_nulls_last = self._match_text_seq("NULLS", "LAST")
desc = is_desc or False
asc = not desc
nulls_first = is_nulls_first or False
explicitly_null_ordered = is_nulls_first or is_nulls_last
if (
not explicitly_null_ordered
and (
(asc and self.NULL_ORDERING == "nulls_are_small")
(not desc and self.NULL_ORDERING == "nulls_are_small")
or (desc and self.NULL_ORDERING != "nulls_are_small")
)
and self.NULL_ORDERING != "nulls_are_last"
@ -3227,8 +3254,8 @@ class Parser(metaclass=_Parser):
return self.UNARY_PARSERS[self._prev.token_type](self)
return self._parse_at_time_zone(self._parse_type())
def _parse_type(self) -> t.Optional[exp.Expression]:
interval = self._parse_interval()
def _parse_type(self, parse_interval: bool = True) -> t.Optional[exp.Expression]:
interval = parse_interval and self._parse_interval()
if interval:
return interval
@ -3247,7 +3274,7 @@ class Parser(metaclass=_Parser):
return self._parse_column()
return self._parse_column_ops(data_type)
return this
return this and self._parse_column_ops(this)
def _parse_type_size(self) -> t.Optional[exp.DataTypeParam]:
this = self._parse_type()
@ -3404,7 +3431,7 @@ class Parser(metaclass=_Parser):
return this
def _parse_struct_types(self) -> t.Optional[exp.Expression]:
this = self._parse_type() or self._parse_id_var()
this = self._parse_type(parse_interval=False) or self._parse_id_var()
self._match(TokenType.COLON)
return self._parse_column_def(this)
@ -3847,6 +3874,8 @@ class Parser(metaclass=_Parser):
action = "NO ACTION"
elif self._match_text_seq("CASCADE"):
action = "CASCADE"
elif self._match_text_seq("RESTRICT"):
action = "RESTRICT"
elif self._match_pair(TokenType.SET, TokenType.NULL):
action = "SET NULL"
elif self._match_pair(TokenType.SET, TokenType.DEFAULT):
@ -4573,7 +4602,7 @@ class Parser(metaclass=_Parser):
return self._parse_var() or self._parse_string()
def _parse_null(self) -> t.Optional[exp.Expression]:
if self._match(TokenType.NULL):
if self._match_set(self.NULL_TOKENS):
return self.PRIMARY_PARSERS[TokenType.NULL](self, self._prev)
return self._parse_placeholder()
@ -4608,14 +4637,18 @@ class Parser(metaclass=_Parser):
return None
if self._match(TokenType.L_PAREN, advance=False):
return self._parse_wrapped_csv(self._parse_column)
return self._parse_csv(self._parse_column)
except_column = self._parse_column()
return [except_column] if except_column else None
def _parse_replace(self) -> t.Optional[t.List[exp.Expression]]:
if not self._match(TokenType.REPLACE):
return None
if self._match(TokenType.L_PAREN, advance=False):
return self._parse_wrapped_csv(self._parse_expression)
return self._parse_expressions()
replace_expression = self._parse_expression()
return [replace_expression] if replace_expression else None
def _parse_csv(
self, parse_method: t.Callable, sep: TokenType = TokenType.COMMA
@ -4931,8 +4964,9 @@ class Parser(metaclass=_Parser):
return self._parse_set_transaction(global_=kind == "GLOBAL")
left = self._parse_primary() or self._parse_id_var()
assignment_delimiter = self._match_texts(("=", "TO"))
if not self._match_texts(("=", "TO")):
if not left or (self.SET_REQUIRES_ASSIGNMENT_DELIMITER and not assignment_delimiter):
self._retreat(index)
return None

View file

@ -247,6 +247,7 @@ class TokenType(AutoName):
JOIN = auto()
JOIN_MARKER = auto()
KEEP = auto()
KILL = auto()
LANGUAGE = auto()
LATERAL = auto()
LEFT = auto()
@ -595,6 +596,7 @@ class Tokenizer(metaclass=_Tokenizer):
"ISNULL": TokenType.ISNULL,
"JOIN": TokenType.JOIN,
"KEEP": TokenType.KEEP,
"KILL": TokenType.KILL,
"LATERAL": TokenType.LATERAL,
"LEFT": TokenType.LEFT,
"LIKE": TokenType.LIKE,

View file

@ -146,7 +146,7 @@ def unnest_to_explode(expression: exp.Expression) -> exp.Expression:
if isinstance(unnest, exp.Unnest):
alias = unnest.args.get("alias")
udtf = exp.Posexplode if unnest.args.get("ordinality") else exp.Explode
udtf = exp.Posexplode if unnest.args.get("offset") else exp.Explode
expression.args["joins"].remove(join)
@ -163,7 +163,8 @@ def unnest_to_explode(expression: exp.Expression) -> exp.Expression:
return expression
def explode_to_unnest(expression: exp.Expression) -> exp.Expression:
def explode_to_unnest(index_offset: int = 0) -> t.Callable[[exp.Expression], exp.Expression]:
def _explode_to_unnest(expression: exp.Expression) -> exp.Expression:
"""Convert explode/posexplode into unnest (used in hive -> presto)."""
if isinstance(expression, exp.Select):
from sqlglot.optimizer.scope import Scope
@ -171,58 +172,126 @@ def explode_to_unnest(expression: exp.Expression) -> exp.Expression:
taken_select_names = set(expression.named_selects)
taken_source_names = {name for name, _ in Scope(expression).references}
for select in expression.selects:
to_replace = select
def new_name(names: t.Set[str], name: str) -> str:
name = find_new_name(names, name)
names.add(name)
return name
arrays: t.List[exp.Condition] = []
series_alias = new_name(taken_select_names, "pos")
series = exp.alias_(
exp.Unnest(
expressions=[exp.GenerateSeries(start=exp.Literal.number(index_offset))]
),
new_name(taken_source_names, "_u"),
table=[series_alias],
)
# we use list here because expression.selects is mutated inside the loop
for select in expression.selects.copy():
explode = select.find(exp.Explode, exp.Posexplode)
if isinstance(explode, (exp.Explode, exp.Posexplode)):
pos_alias = ""
explode_alias = ""
if isinstance(select, exp.Alias):
explode_alias = select.alias
select = select.this
alias = select
elif isinstance(select, exp.Aliases):
pos_alias = select.aliases[0].name
explode_alias = select.aliases[1].name
select = select.this
alias = select.replace(exp.alias_(select.this, "", copy=False))
else:
alias = select.replace(exp.alias_(select, ""))
explode = alias.find(exp.Explode, exp.Posexplode)
assert explode
if isinstance(select, (exp.Explode, exp.Posexplode)):
is_posexplode = isinstance(select, exp.Posexplode)
explode_arg = select.this
unnest = exp.Unnest(expressions=[explode_arg.copy()], ordinality=is_posexplode)
is_posexplode = isinstance(explode, exp.Posexplode)
explode_arg = explode.this
# This ensures that we won't use [POS]EXPLODE's argument as a new selection
if isinstance(explode_arg, exp.Column):
taken_select_names.add(explode_arg.output_name)
unnest_source_alias = find_new_name(taken_source_names, "_u")
taken_source_names.add(unnest_source_alias)
unnest_source_alias = new_name(taken_source_names, "_u")
if not explode_alias:
explode_alias = find_new_name(taken_select_names, "col")
taken_select_names.add(explode_alias)
explode_alias = new_name(taken_select_names, "col")
if is_posexplode:
pos_alias = find_new_name(taken_select_names, "pos")
taken_select_names.add(pos_alias)
pos_alias = new_name(taken_select_names, "pos")
if not pos_alias:
pos_alias = new_name(taken_select_names, "pos")
alias.set("alias", exp.to_identifier(explode_alias))
column = exp.If(
this=exp.column(series_alias).eq(exp.column(pos_alias)),
true=exp.column(explode_alias),
)
explode.replace(column)
if is_posexplode:
column_names = [explode_alias, pos_alias]
to_replace.pop()
expression.select(pos_alias, explode_alias, copy=False)
else:
column_names = [explode_alias]
to_replace.replace(exp.column(explode_alias))
expressions = expression.expressions
expressions.insert(
expressions.index(alias) + 1,
exp.If(
this=exp.column(series_alias).eq(exp.column(pos_alias)),
true=exp.column(pos_alias),
).as_(pos_alias),
)
expression.set("expressions", expressions)
unnest = exp.alias_(unnest, unnest_source_alias, table=column_names)
if not expression.args.get("from"):
expression.from_(unnest, copy=False)
if not arrays:
if expression.args.get("from"):
expression.join(series, copy=False)
else:
expression.join(unnest, join_type="CROSS", copy=False)
expression.from_(series, copy=False)
size: exp.Condition = exp.ArraySize(this=explode_arg.copy())
arrays.append(size)
# trino doesn't support left join unnest with on conditions
# if it did, this would be much simpler
expression.join(
exp.alias_(
exp.Unnest(
expressions=[explode_arg.copy()],
offset=exp.to_identifier(pos_alias),
),
unnest_source_alias,
table=[explode_alias],
),
join_type="CROSS",
copy=False,
)
if index_offset != 1:
size = size - 1
expression.where(
exp.column(series_alias)
.eq(exp.column(pos_alias))
.or_(
(exp.column(series_alias) > size).and_(exp.column(pos_alias).eq(size))
),
copy=False,
)
if arrays:
end: exp.Condition = exp.Greatest(this=arrays[0], expressions=arrays[1:])
if index_offset != 1:
end = end - (1 - index_offset)
series.expressions[0].set("end", end)
return expression
return _explode_to_unnest
PERCENTILES = (exp.PercentileCont, exp.PercentileDisc)
@ -283,6 +352,31 @@ def epoch_cast_to_ts(expression: exp.Expression) -> exp.Expression:
return expression
def timestamp_to_cast(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Timestamp) and not expression.expression:
return exp.cast(
expression.this,
to=exp.DataType.Type.TIMESTAMP,
)
return expression
def eliminate_semi_and_anti_joins(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Select):
for join in expression.args.get("joins") or []:
on = join.args.get("on")
if on and join.kind in ("SEMI", "ANTI"):
subquery = exp.select("1").from_(join.this).where(on)
exists = exp.Exists(this=subquery)
if join.kind == "ANTI":
exists = exists.not_(copy=False)
join.pop()
expression.where(exists, copy=False)
return expression
def preprocess(
transforms: t.List[t.Callable[[exp.Expression], exp.Expression]],
) -> t.Callable[[Generator, exp.Expression], str]:
@ -327,12 +421,3 @@ def preprocess(
raise ValueError(f"Unsupported expression type {expression.__class__.__name__}.")
return _to_sql
def timestamp_to_cast(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Timestamp) and not expression.expression:
return exp.cast(
expression.this,
to=exp.DataType.Type.TIMESTAMP,
)
return expression

View file

@ -95,16 +95,16 @@ class TestDataframeColumn(unittest.TestCase):
self.assertEqual("cola IN (1, 2, 3)", F.col("cola").isin(1, 2, 3).sql())
def test_asc(self):
self.assertEqual("cola", F.col("cola").asc().sql())
self.assertEqual("cola ASC", F.col("cola").asc().sql())
def test_desc(self):
self.assertEqual("cola DESC", F.col("cola").desc().sql())
def test_asc_nulls_first(self):
self.assertEqual("cola", F.col("cola").asc_nulls_first().sql())
self.assertEqual("cola ASC", F.col("cola").asc_nulls_first().sql())
def test_asc_nulls_last(self):
self.assertEqual("cola NULLS LAST", F.col("cola").asc_nulls_last().sql())
self.assertEqual("cola ASC NULLS LAST", F.col("cola").asc_nulls_last().sql())
def test_desc_nulls_first(self):
self.assertEqual("cola DESC NULLS FIRST", F.col("cola").desc_nulls_first().sql())

View file

@ -335,18 +335,18 @@ class TestFunctions(unittest.TestCase):
def test_asc_nulls_first(self):
col_str = SF.asc_nulls_first("cola")
self.assertIsInstance(col_str.expression, exp.Ordered)
self.assertEqual("cola", col_str.sql())
self.assertEqual("cola ASC", col_str.sql())
col = SF.asc_nulls_first(SF.col("cola"))
self.assertIsInstance(col.expression, exp.Ordered)
self.assertEqual("cola", col.sql())
self.assertEqual("cola ASC", col.sql())
def test_asc_nulls_last(self):
col_str = SF.asc_nulls_last("cola")
self.assertIsInstance(col_str.expression, exp.Ordered)
self.assertEqual("cola NULLS LAST", col_str.sql())
self.assertEqual("cola ASC NULLS LAST", col_str.sql())
col = SF.asc_nulls_last(SF.col("cola"))
self.assertIsInstance(col.expression, exp.Ordered)
self.assertEqual("cola NULLS LAST", col.sql())
self.assertEqual("cola ASC NULLS LAST", col.sql())
def test_desc_nulls_first(self):
col_str = SF.desc_nulls_first("cola")

View file

@ -79,3 +79,9 @@ class TestSessionCaseSensitivity(DataFrameTestBase):
df.sql()
else:
self.compare_sql(df, expected)
def test_alias(self):
col = F.col('"Name"')
self.assertEqual(col.sql(dialect=self.spark.dialect), '"Name"')
self.assertEqual(col.alias("nAME").sql(dialect=self.spark.dialect), '"Name" AS NAME')
self.assertEqual(col.alias('"nAME"').sql(dialect=self.spark.dialect), '"Name" AS "nAME"')

View file

@ -9,36 +9,6 @@ class TestBigQuery(Validator):
maxDiff = None
def test_bigquery(self):
self.validate_identity("SELECT * FROM tbl FOR SYSTEM_TIME AS OF z")
self.validate_identity(
"""SELECT JSON '"foo"' AS json_data""",
"""SELECT PARSE_JSON('"foo"') AS json_data""",
)
self.validate_all(
"""SELECT
`u`.`harness_user_email` AS `harness_user_email`,
`d`.`harness_user_id` AS `harness_user_id`,
`harness_account_id` AS `harness_account_id`
FROM `analytics_staging`.`stg_mongodb__users` AS `u`, UNNEST(`u`.`harness_cluster_details`) AS `d`, UNNEST(`d`.`harness_account_ids`) AS `harness_account_id`
WHERE
NOT `harness_account_id` IS NULL""",
read={
"": """
SELECT
"u"."harness_user_email" AS "harness_user_email",
"_q_0"."d"."harness_user_id" AS "harness_user_id",
"_q_1"."harness_account_id" AS "harness_account_id"
FROM
"analytics_staging"."stg_mongodb__users" AS "u",
UNNEST("u"."harness_cluster_details") AS "_q_0"("d"),
UNNEST("_q_0"."d"."harness_account_ids") AS "_q_1"("harness_account_id")
WHERE
NOT "_q_1"."harness_account_id" IS NULL
"""
},
pretty=True,
)
with self.assertRaises(TokenError):
transpile("'\\'", read="bigquery")
@ -63,6 +33,9 @@ WHERE
with self.assertRaises(ParseError):
transpile("DATE_ADD(x, day)", read="bigquery")
self.validate_identity("SELECT test.Unknown FROM test")
self.validate_identity(r"SELECT '\n\r\a\v\f\t'")
self.validate_identity("SELECT * FROM tbl FOR SYSTEM_TIME AS OF z")
self.validate_identity("STRING_AGG(DISTINCT a ORDER BY b DESC, c DESC LIMIT 10)")
self.validate_identity("SELECT PARSE_TIMESTAMP('%c', 'Thu Dec 25 07:30:00 2008', 'UTC')")
self.validate_identity("SELECT ANY_VALUE(fruit HAVING MAX sold) FROM fruits")
@ -111,6 +84,7 @@ WHERE
self.validate_identity("COMMIT TRANSACTION")
self.validate_identity("ROLLBACK TRANSACTION")
self.validate_identity("CAST(x AS BIGNUMERIC)")
self.validate_identity("SELECT y + 1 FROM x GROUP BY y + 1 ORDER BY 1")
self.validate_identity(
"DATE(CAST('2016-12-25 05:30:00+07' AS DATETIME), 'America/Los_Angeles')"
)
@ -132,6 +106,22 @@ WHERE
self.validate_identity(
"SELECT LAST_VALUE(a IGNORE NULLS) OVER y FROM x WINDOW y AS (PARTITION BY CATEGORY)",
)
self.validate_identity(
"SELECT a overlaps",
"SELECT a AS overlaps",
)
self.validate_identity(
"SELECT y + 1 z FROM x GROUP BY y + 1 ORDER BY z",
"SELECT y + 1 AS z FROM x GROUP BY z ORDER BY z",
)
self.validate_identity(
"SELECT y + 1 z FROM x GROUP BY y + 1",
"SELECT y + 1 AS z FROM x GROUP BY y + 1",
)
self.validate_identity(
"""SELECT JSON '"foo"' AS json_data""",
"""SELECT PARSE_JSON('"foo"') AS json_data""",
)
self.validate_all("SELECT SPLIT(foo)", write={"bigquery": "SELECT SPLIT(foo, ',')"})
self.validate_all("SELECT 1 AS hash", write={"bigquery": "SELECT 1 AS `hash`"})
@ -246,7 +236,7 @@ WHERE
},
)
self.validate_all(
"WITH cte AS (SELECT [1, 2, 3] AS arr) SELECT col FROM cte CROSS JOIN UNNEST(arr) AS col",
"WITH cte AS (SELECT [1, 2, 3] AS arr) SELECT IF(pos = pos_2, col, NULL) AS col FROM cte, UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(arr)) - 1)) AS pos CROSS JOIN UNNEST(arr) AS col WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(arr) - 1) AND pos_2 = (ARRAY_LENGTH(arr) - 1))",
read={
"spark": "WITH cte AS (SELECT ARRAY(1, 2, 3) AS arr) SELECT EXPLODE(arr) FROM cte"
},
@ -291,6 +281,10 @@ WHERE
"bigquery": "SELECT ARRAY(SELECT AS STRUCT 1 AS a, 2 AS b)",
},
)
self.validate_identity(
r"REGEXP_EXTRACT(svc_plugin_output, r'\\\((.*)')",
r"REGEXP_EXTRACT(svc_plugin_output, '\\\\\\((.*)')",
)
self.validate_all(
"REGEXP_CONTAINS('foo', '.*')",
read={
@ -302,7 +296,7 @@ WHERE
"mysql": "REGEXP_LIKE('foo', '.*')",
"starrocks": "REGEXP('foo', '.*')",
},
),
)
self.validate_all(
'"""x"""',
write={
@ -453,7 +447,6 @@ WHERE
"SELECT ARRAY(SELECT * FROM foo JOIN bla ON x = y)",
write={"bigquery": "SELECT ARRAY(SELECT * FROM foo JOIN bla ON x = y)"},
)
self.validate_all(
"x IS unknown",
write={
@ -464,6 +457,16 @@ WHERE
"spark": "x IS NULL",
},
)
self.validate_all(
"x IS NOT unknown",
write={
"bigquery": "NOT x IS NULL",
"duckdb": "NOT x IS NULL",
"presto": "NOT x IS NULL",
"hive": "NOT x IS NULL",
"spark": "NOT x IS NULL",
},
)
self.validate_all(
"CURRENT_TIMESTAMP()",
read={
@ -682,16 +685,32 @@ WHERE
"spark": "TO_JSON(x)",
},
)
self.validate_all(
"""SELECT
`u`.`harness_user_email` AS `harness_user_email`,
`d`.`harness_user_id` AS `harness_user_id`,
`harness_account_id` AS `harness_account_id`
FROM `analytics_staging`.`stg_mongodb__users` AS `u`, UNNEST(`u`.`harness_cluster_details`) AS `d`, UNNEST(`d`.`harness_account_ids`) AS `harness_account_id`
WHERE
NOT `harness_account_id` IS NULL""",
read={
"": """
SELECT
"u"."harness_user_email" AS "harness_user_email",
"_q_0"."d"."harness_user_id" AS "harness_user_id",
"_q_1"."harness_account_id" AS "harness_account_id"
FROM
"analytics_staging"."stg_mongodb__users" AS "u",
UNNEST("u"."harness_cluster_details") AS "_q_0"("d"),
UNNEST("_q_0"."d"."harness_account_ids") AS "_q_1"("harness_account_id")
WHERE
NOT "_q_1"."harness_account_id" IS NULL
"""
},
pretty=True,
)
self.validate_identity(
"SELECT y + 1 z FROM x GROUP BY y + 1 ORDER BY z",
"SELECT y + 1 AS z FROM x GROUP BY z ORDER BY z",
)
self.validate_identity(
"SELECT y + 1 z FROM x GROUP BY y + 1",
"SELECT y + 1 AS z FROM x GROUP BY y + 1",
)
self.validate_identity("SELECT y + 1 FROM x GROUP BY y + 1 ORDER BY 1")
self.validate_identity("LOG(n, b)")
def test_user_defined_functions(self):
self.validate_identity(
@ -702,6 +721,10 @@ WHERE
self.validate_identity(
"CREATE TABLE FUNCTION a(x INT64) RETURNS TABLE <q STRING, r INT64> AS SELECT s, t"
)
self.validate_identity(
'''CREATE TEMPORARY FUNCTION string_length_0(strings ARRAY<STRING>) RETURNS FLOAT64 LANGUAGE js AS """'use strict'; function string_length(strings) { return _.sum(_.map(strings, ((x) => x.length))); } return string_length(strings);""" OPTIONS (library=['gs://ibis-testing-libraries/lodash.min.js'])''',
"CREATE TEMPORARY FUNCTION string_length_0(strings ARRAY<STRING>) RETURNS FLOAT64 LANGUAGE js OPTIONS (library=['gs://ibis-testing-libraries/lodash.min.js']) AS '\\'use strict\\'; function string_length(strings) { return _.sum(_.map(strings, ((x) => x.length))); } return string_length(strings);'",
)
def test_group_concat(self):
self.validate_all(

View file

@ -157,8 +157,8 @@ class TestClickhouse(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"clickhouse": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"clickhouse": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
},
)
self.validate_all(
@ -216,7 +216,7 @@ class TestClickhouse(Validator):
""",
write={
"clickhouse": "SELECT loyalty, count() FROM hits LEFT SEMI JOIN users USING (UserID)"
+ " GROUP BY loyalty ORDER BY loyalty"
" GROUP BY loyalty ORDER BY loyalty ASC"
},
)
self.validate_identity("SELECT s, arr FROM arrays_test ARRAY JOIN arr")

View file

@ -5,6 +5,9 @@ class TestDatabricks(Validator):
dialect = "databricks"
def test_databricks(self):
self.validate_identity("CREATE TABLE t (c STRUCT<interval: DOUBLE COMMENT 'aaa'>)")
self.validate_identity("CREATE TABLE my_table () TBLPROPERTIES (a.b=15)")
self.validate_identity("CREATE TABLE my_table () TBLPROPERTIES ('a.b'=15)")
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO HOUR)")
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO MINUTE)")
self.validate_identity("SELECT CAST('11 23:4:0' AS INTERVAL DAY TO SECOND)")

View file

@ -964,12 +964,12 @@ class TestDialect(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"bigquery": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"oracle": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"bigquery": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"oracle": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
},
)
@ -1354,7 +1354,7 @@ class TestDialect(Validator):
self.validate_all(
"SELECT IF(COALESCE(bar, 0) = 1, TRUE, FALSE) as foo FROM baz",
write={
"bigquery": "SELECT CASE WHEN COALESCE(bar, 0) = 1 THEN TRUE ELSE FALSE END AS foo FROM baz",
"bigquery": "SELECT IF(COALESCE(bar, 0) = 1, TRUE, FALSE) AS foo FROM baz",
"duckdb": "SELECT CASE WHEN COALESCE(bar, 0) = 1 THEN TRUE ELSE FALSE END AS foo FROM baz",
"presto": "SELECT IF(COALESCE(bar, 0) = 1, TRUE, FALSE) AS foo FROM baz",
"hive": "SELECT IF(COALESCE(bar, 0) = 1, TRUE, FALSE) AS foo FROM baz",

View file

@ -6,6 +6,92 @@ class TestDuckDB(Validator):
dialect = "duckdb"
def test_duckdb(self):
self.assertEqual(
parse_one("select * from t limit (select 5)").sql(dialect="duckdb"),
exp.select("*").from_("t").limit(exp.select("5").subquery()).sql(dialect="duckdb"),
)
for struct_value in ("{'a': 1}", "struct_pack(a := 1)"):
self.validate_all(struct_value, write={"presto": UnsupportedError})
for join_type in ("SEMI", "ANTI"):
exists = "EXISTS" if join_type == "SEMI" else "NOT EXISTS"
self.validate_all(
f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
write={
"bigquery": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"clickhouse": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"databricks": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"doris": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"drill": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"duckdb": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"hive": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"mysql": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"oracle": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"postgres": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"presto": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"redshift": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"snowflake": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"spark": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"sqlite": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"starrocks": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"teradata": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"trino": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
"tsql": f"SELECT * FROM t1 WHERE {exists}(SELECT 1 FROM t2 WHERE t1.x = t2.x)",
},
)
self.validate_all(
f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
read={
"duckdb": f"SELECT * FROM t1 {join_type} JOIN t2 ON t1.x = t2.x",
"spark": f"SELECT * FROM t1 LEFT {join_type} JOIN t2 ON t1.x = t2.x",
},
)
self.validate_all(
"WITH cte(x) AS (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) SELECT AVG(x) FILTER (WHERE x > 1) FROM cte",
write={
"duckdb": "WITH cte(x) AS (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) SELECT AVG(x) FILTER(WHERE x > 1) FROM cte",
"snowflake": "WITH cte(x) AS (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) SELECT AVG(IFF(x > 1, x, NULL)) FROM cte",
},
)
self.validate_all(
"SELECT AVG(x) FILTER (WHERE TRUE) FROM t",
write={
"duckdb": "SELECT AVG(x) FILTER(WHERE TRUE) FROM t",
"snowflake": "SELECT AVG(IFF(TRUE, x, NULL)) FROM t",
},
)
self.validate_all(
"SELECT UNNEST(ARRAY[1, 2, 3]), UNNEST(ARRAY[4, 5]), UNNEST(ARRAY[6])",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) AS col, IF(pos = pos_3, col_2, NULL) AS col_2, IF(pos = pos_4, col_3, NULL) AS col_3 FROM UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH([1, 2, 3]), ARRAY_LENGTH([4, 5]), ARRAY_LENGTH([6])) - 1)) AS pos CROSS JOIN UNNEST([1, 2, 3]) AS col WITH OFFSET AS pos_2 CROSS JOIN UNNEST([4, 5]) AS col_2 WITH OFFSET AS pos_3 CROSS JOIN UNNEST([6]) AS col_3 WITH OFFSET AS pos_4 WHERE ((pos = pos_2 OR (pos > (ARRAY_LENGTH([1, 2, 3]) - 1) AND pos_2 = (ARRAY_LENGTH([1, 2, 3]) - 1))) AND (pos = pos_3 OR (pos > (ARRAY_LENGTH([4, 5]) - 1) AND pos_3 = (ARRAY_LENGTH([4, 5]) - 1)))) AND (pos = pos_4 OR (pos > (ARRAY_LENGTH([6]) - 1) AND pos_4 = (ARRAY_LENGTH([6]) - 1)))",
"presto": "SELECT IF(pos = pos_2, col) AS col, IF(pos = pos_3, col_2) AS col_2, IF(pos = pos_4, col_3) AS col_3 FROM UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[1, 2, 3]), CARDINALITY(ARRAY[4, 5]), CARDINALITY(ARRAY[6])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[1, 2, 3]) WITH ORDINALITY AS _u_2(col, pos_2) CROSS JOIN UNNEST(ARRAY[4, 5]) WITH ORDINALITY AS _u_3(col_2, pos_3) CROSS JOIN UNNEST(ARRAY[6]) WITH ORDINALITY AS _u_4(col_3, pos_4) WHERE ((pos = pos_2 OR (pos > CARDINALITY(ARRAY[1, 2, 3]) AND pos_2 = CARDINALITY(ARRAY[1, 2, 3]))) AND (pos = pos_3 OR (pos > CARDINALITY(ARRAY[4, 5]) AND pos_3 = CARDINALITY(ARRAY[4, 5])))) AND (pos = pos_4 OR (pos > CARDINALITY(ARRAY[6]) AND pos_4 = CARDINALITY(ARRAY[6])))",
},
)
self.validate_all(
"SELECT UNNEST(ARRAY[1, 2, 3]), UNNEST(ARRAY[4, 5]), UNNEST(ARRAY[6]) FROM x",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) AS col, IF(pos = pos_3, col_2, NULL) AS col_2, IF(pos = pos_4, col_3, NULL) AS col_3 FROM x, UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH([1, 2, 3]), ARRAY_LENGTH([4, 5]), ARRAY_LENGTH([6])) - 1)) AS pos CROSS JOIN UNNEST([1, 2, 3]) AS col WITH OFFSET AS pos_2 CROSS JOIN UNNEST([4, 5]) AS col_2 WITH OFFSET AS pos_3 CROSS JOIN UNNEST([6]) AS col_3 WITH OFFSET AS pos_4 WHERE ((pos = pos_2 OR (pos > (ARRAY_LENGTH([1, 2, 3]) - 1) AND pos_2 = (ARRAY_LENGTH([1, 2, 3]) - 1))) AND (pos = pos_3 OR (pos > (ARRAY_LENGTH([4, 5]) - 1) AND pos_3 = (ARRAY_LENGTH([4, 5]) - 1)))) AND (pos = pos_4 OR (pos > (ARRAY_LENGTH([6]) - 1) AND pos_4 = (ARRAY_LENGTH([6]) - 1)))",
"presto": "SELECT IF(pos = pos_2, col) AS col, IF(pos = pos_3, col_2) AS col_2, IF(pos = pos_4, col_3) AS col_3 FROM x, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[1, 2, 3]), CARDINALITY(ARRAY[4, 5]), CARDINALITY(ARRAY[6])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[1, 2, 3]) WITH ORDINALITY AS _u_2(col, pos_2) CROSS JOIN UNNEST(ARRAY[4, 5]) WITH ORDINALITY AS _u_3(col_2, pos_3) CROSS JOIN UNNEST(ARRAY[6]) WITH ORDINALITY AS _u_4(col_3, pos_4) WHERE ((pos = pos_2 OR (pos > CARDINALITY(ARRAY[1, 2, 3]) AND pos_2 = CARDINALITY(ARRAY[1, 2, 3]))) AND (pos = pos_3 OR (pos > CARDINALITY(ARRAY[4, 5]) AND pos_3 = CARDINALITY(ARRAY[4, 5])))) AND (pos = pos_4 OR (pos > CARDINALITY(ARRAY[6]) AND pos_4 = CARDINALITY(ARRAY[6])))",
},
)
self.validate_all(
"SELECT UNNEST(x) + 1",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) + 1 AS col FROM UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(x)) - 1)) AS pos CROSS JOIN UNNEST(x) AS col WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(x) - 1) AND pos_2 = (ARRAY_LENGTH(x) - 1))",
},
)
self.validate_all(
"SELECT UNNEST(x) + 1 AS y",
write={
"bigquery": "SELECT IF(pos = pos_2, y, NULL) + 1 AS y FROM UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(x)) - 1)) AS pos CROSS JOIN UNNEST(x) AS y WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(x) - 1) AND pos_2 = (ARRAY_LENGTH(x) - 1))",
},
)
self.validate_identity("SELECT i FROM RANGE(5) AS _(i) ORDER BY i ASC")
self.validate_identity("[x.STRING_SPLIT(' ')[1] FOR x IN ['1', '2', 3] IF x.CONTAINS('1')]")
self.validate_identity("INSERT INTO x BY NAME SELECT 1 AS y")
self.validate_identity("SELECT 1 AS x UNION ALL BY NAME SELECT 2 AS x")
@ -61,6 +147,13 @@ class TestDuckDB(Validator):
self.validate_all("0x1010", write={"": "0 AS x1010"})
self.validate_all("x ~ y", write={"duckdb": "REGEXP_MATCHES(x, y)"})
self.validate_all("SELECT * FROM 'x.y'", write={"duckdb": 'SELECT * FROM "x.y"'})
self.validate_all(
"SELECT UNNEST([1, 2, 3])",
write={
"duckdb": "SELECT UNNEST([1, 2, 3])",
"snowflake": "SELECT IFF(pos = pos_2, col, NULL) AS col FROM (SELECT value FROM TABLE(FLATTEN(INPUT => ARRAY_GENERATE_RANGE(0, (GREATEST(ARRAY_SIZE([1, 2, 3])) - 1) + 1)))) AS _u(pos) CROSS JOIN (SELECT value, index FROM TABLE(FLATTEN(INPUT => [1, 2, 3]))) AS _u_2(col, pos_2) WHERE pos = pos_2 OR (pos > (ARRAY_SIZE([1, 2, 3]) - 1) AND pos_2 = (ARRAY_SIZE([1, 2, 3]) - 1))",
},
)
self.validate_all(
"VAR_POP(x)",
read={
@ -304,8 +397,8 @@ class TestDuckDB(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
},
)
self.validate_all(

View file

@ -382,10 +382,10 @@ class TestHive(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
},
)

View file

@ -498,6 +498,21 @@ class TestMySQL(Validator):
self.validate_identity("TIME_STR_TO_UNIX(x)", "UNIX_TIMESTAMP(x)")
def test_mysql(self):
self.validate_all(
"a XOR b",
read={
"mysql": "a XOR b",
"snowflake": "BOOLXOR(a, b)",
},
write={
"duckdb": "(a AND (NOT b)) OR ((NOT a) AND b)",
"mysql": "a XOR b",
"postgres": "(a AND (NOT b)) OR ((NOT a) AND b)",
"snowflake": "BOOLXOR(a, b)",
"trino": "(a AND (NOT b)) OR ((NOT a) AND b)",
},
)
self.validate_all(
"SELECT * FROM test LIMIT 0 + 1, 0 + 1",
write={

View file

@ -13,6 +13,7 @@ class TestPostgres(Validator):
"CREATE TABLE test (x TIMESTAMP WITHOUT TIME ZONE[][])",
"CREATE TABLE test (x TIMESTAMP[][])",
)
self.validate_identity("CREATE INDEX idx_x ON x USING BTREE(x, y) WHERE (NOT y IS NULL)")
self.validate_identity("CREATE TABLE test (elems JSONB[])")
self.validate_identity("CREATE TABLE public.y (x TSTZRANGE NOT NULL)")
self.validate_identity("CREATE TABLE test (foo HSTORE)")
@ -83,6 +84,28 @@ class TestPostgres(Validator):
" CONSTRAINT valid_discount CHECK (price > discounted_price))"
},
)
self.validate_identity(
"""
CREATE INDEX index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial
ON public.ci_builds
USING btree (commit_id, artifacts_expire_at, id)
WHERE (
((type)::text = 'Ci::Build'::text)
AND ((retried = false) OR (retried IS NULL))
AND ((name)::text = ANY (ARRAY[
('sast'::character varying)::text,
('dependency_scanning'::character varying)::text,
('sast:container'::character varying)::text,
('container_scanning'::character varying)::text,
('dast'::character varying)::text
]))
)
""",
"CREATE INDEX index_ci_builds_on_commit_id_and_artifacts_expireatandidpartial ON public.ci_builds USING btree(commit_id, artifacts_expire_at, id) WHERE ((CAST((type) AS TEXT) = CAST('Ci::Build' AS TEXT)) AND ((retried = FALSE) OR (retried IS NULL)) AND (CAST((name) AS TEXT) = ANY (ARRAY[CAST((CAST('sast' AS VARCHAR)) AS TEXT), CAST((CAST('dependency_scanning' AS VARCHAR)) AS TEXT), CAST((CAST('sast:container' AS VARCHAR)) AS TEXT), CAST((CAST('container_scanning' AS VARCHAR)) AS TEXT), CAST((CAST('dast' AS VARCHAR)) AS TEXT)])))",
)
self.validate_identity(
"CREATE INDEX index_ci_pipelines_on_project_idandrefandiddesc ON public.ci_pipelines USING btree(project_id, ref, id DESC)"
)
with self.assertRaises(ParseError):
transpile("CREATE TABLE products (price DECIMAL CHECK price > 0)", read="postgres")
@ -102,7 +125,7 @@ class TestPostgres(Validator):
write={
"hive": "SELECT EXPLODE(c) FROM t",
"postgres": "SELECT UNNEST(c) FROM t",
"presto": "SELECT col FROM t CROSS JOIN UNNEST(c) AS _u(col)",
"presto": "SELECT IF(pos = pos_2, col) AS col FROM t, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(c)))) AS _u(pos) CROSS JOIN UNNEST(c) WITH ORDINALITY AS _u_2(col, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(c) AND pos_2 = CARDINALITY(c))",
},
)
self.validate_all(
@ -110,7 +133,7 @@ class TestPostgres(Validator):
write={
"hive": "SELECT EXPLODE(ARRAY(1))",
"postgres": "SELECT UNNEST(ARRAY[1])",
"presto": "SELECT col FROM UNNEST(ARRAY[1]) AS _u(col)",
"presto": "SELECT IF(pos = pos_2, col) AS col FROM UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[1])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[1]) WITH ORDINALITY AS _u_2(col, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(ARRAY[1]) AND pos_2 = CARDINALITY(ARRAY[1]))",
},
)
@ -139,6 +162,16 @@ class TestPostgres(Validator):
self.assertIsInstance(expr, exp.AlterTable)
self.assertEqual(expr.sql(dialect="postgres"), alter_table_only)
self.validate_identity(
"SELECT ARRAY[]::INT[] AS foo",
"SELECT CAST(ARRAY[] AS INT[]) AS foo",
)
self.validate_identity(
"""ALTER TABLE ONLY "Album" ADD CONSTRAINT "FK_AlbumArtistId" FOREIGN KEY ("ArtistId") REFERENCES "Artist" ("ArtistId") ON DELETE CASCADE"""
)
self.validate_identity(
"""ALTER TABLE ONLY "Album" ADD CONSTRAINT "FK_AlbumArtistId" FOREIGN KEY ("ArtistId") REFERENCES "Artist" ("ArtistId") ON DELETE RESTRICT"""
)
self.validate_identity("x @@ y")
self.validate_identity("CAST(x AS MONEY)")
self.validate_identity("CAST(x AS INT4RANGE)")
@ -362,10 +395,10 @@ class TestPostgres(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname ASC, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
},
)
self.validate_all(

View file

@ -431,8 +431,8 @@ class TestPresto(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
},
)
@ -947,44 +947,6 @@ class TestPresto(Validator):
},
)
def test_explode_to_unnest(self):
self.validate_all(
"SELECT col FROM tbl CROSS JOIN UNNEST(x) AS _u(col)",
read={"spark": "SELECT EXPLODE(x) FROM tbl"},
)
self.validate_all(
"SELECT col_2 FROM _u CROSS JOIN UNNEST(col) AS _u_2(col_2)",
read={"spark": "SELECT EXPLODE(col) FROM _u"},
)
self.validate_all(
"SELECT exploded FROM schema.tbl CROSS JOIN UNNEST(col) AS _u(exploded)",
read={"spark": "SELECT EXPLODE(col) AS exploded FROM schema.tbl"},
)
self.validate_all(
"SELECT col FROM UNNEST(SEQUENCE(1, 2)) AS _u(col)",
read={"spark": "SELECT EXPLODE(SEQUENCE(1, 2))"},
)
self.validate_all(
"SELECT col FROM tbl AS t CROSS JOIN UNNEST(t.c) AS _u(col)",
read={"spark": "SELECT EXPLODE(t.c) FROM tbl t"},
)
self.validate_all(
"SELECT pos, col FROM UNNEST(SEQUENCE(2, 3)) WITH ORDINALITY AS _u(col, pos)",
read={"spark": "SELECT POSEXPLODE(SEQUENCE(2, 3))"},
)
self.validate_all(
"SELECT pos, col FROM tbl CROSS JOIN UNNEST(SEQUENCE(2, 3)) WITH ORDINALITY AS _u(col, pos)",
read={"spark": "SELECT POSEXPLODE(SEQUENCE(2, 3)) FROM tbl"},
)
self.validate_all(
"SELECT pos, col FROM tbl AS t CROSS JOIN UNNEST(t.c) WITH ORDINALITY AS _u(col, pos)",
read={"spark": "SELECT POSEXPLODE(t.c) FROM tbl t"},
)
self.validate_all(
"SELECT col, pos, pos_2, col_2 FROM _u CROSS JOIN UNNEST(SEQUENCE(2, 3)) WITH ORDINALITY AS _u_2(col_2, pos_2)",
read={"spark": "SELECT col, pos, POSEXPLODE(SEQUENCE(2, 3)) FROM _u"},
)
def test_match_recognize(self):
self.validate_identity(
"""SELECT

View file

@ -1,3 +1,4 @@
from sqlglot import transpile
from tests.dialects.test_dialect import Validator
@ -270,6 +271,26 @@ class TestRedshift(Validator):
)
def test_values(self):
# Test crazy-sized VALUES clause to UNION ALL conversion to ensure we don't get RecursionError
values = [str(v) for v in range(0, 10000)]
values_query = f"SELECT * FROM (VALUES {', '.join('(' + v + ')' for v in values)})"
union_query = f"SELECT * FROM ({' UNION ALL '.join('SELECT ' + v for v in values)})"
self.assertEqual(transpile(values_query, write="redshift")[0], union_query)
self.validate_identity(
"SELECT * FROM (VALUES (1), (2))",
"""SELECT
*
FROM (
SELECT
1
UNION ALL
SELECT
2
)""",
pretty=True,
)
self.validate_all(
"SELECT * FROM (VALUES (1, 2)) AS t",
write={
@ -291,9 +312,9 @@ class TestRedshift(Validator):
},
)
self.validate_all(
"SELECT a, b FROM (VALUES (1, 2), (3, 4)) AS t (a, b)",
'SELECT a, b FROM (VALUES (1, 2), (3, 4)) AS "t" (a, b)',
write={
"redshift": "SELECT a, b FROM (SELECT 1 AS a, 2 AS b UNION ALL SELECT 3, 4) AS t",
"redshift": 'SELECT a, b FROM (SELECT 1 AS a, 2 AS b UNION ALL SELECT 3, 4) AS "t"',
},
)
self.validate_all(
@ -320,6 +341,16 @@ class TestRedshift(Validator):
"redshift": "INSERT INTO t (a, b) VALUES (1, 2), (3, 4)",
},
)
self.validate_identity(
'SELECT * FROM (VALUES (1)) AS "t"(a)',
'''SELECT
*
FROM (
SELECT
1 AS a
) AS "t"''',
pretty=True,
)
def test_create_table_like(self):
self.validate_all(

View file

@ -78,11 +78,32 @@ class TestSnowflake(Validator):
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(
"ARRAY_GENERATE_RANGE(0, 3)",
write={
"bigquery": "GENERATE_ARRAY(0, 3 - 1)",
"postgres": "GENERATE_SERIES(0, 3 - 1)",
"presto": "SEQUENCE(0, 3 - 1)",
"snowflake": "ARRAY_GENERATE_RANGE(0, (3 - 1) + 1)",
},
)
self.validate_all(
"ARRAY_GENERATE_RANGE(0, 3 + 1)",
read={
"bigquery": "GENERATE_ARRAY(0, 3)",
"postgres": "GENERATE_SERIES(0, 3)",
"presto": "SEQUENCE(0, 3)",
},
)
self.validate_all(
"SELECT DATE_PART('year', TIMESTAMP '2020-01-01')",
write={
@ -258,13 +279,13 @@ class TestSnowflake(Validator):
self.validate_all(
"SELECT * EXCLUDE a, b FROM xxx",
write={
"snowflake": "SELECT * EXCLUDE (a, b) FROM xxx",
"snowflake": "SELECT * EXCLUDE (a), b FROM xxx",
},
)
self.validate_all(
"SELECT * RENAME a AS b, c AS d FROM xxx",
write={
"snowflake": "SELECT * RENAME (a AS b, c AS d) FROM xxx",
"snowflake": "SELECT * RENAME (a AS b), c AS d FROM xxx",
},
)
self.validate_all(
@ -364,12 +385,12 @@ class TestSnowflake(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname NULLS LAST",
"snowflake": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname, lname",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname ASC, lname",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname NULLS LAST",
"snowflake": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname ASC, lname",
},
)
self.validate_all(
@ -867,7 +888,7 @@ FROM persons AS p, LATERAL FLATTEN(input => p.c, path => 'contact') AS f, LATERA
"""SELECT $1 AS "_1" FROM VALUES ('a'), ('b')""",
write={
"snowflake": """SELECT $1 AS "_1" FROM (VALUES ('a'), ('b'))""",
"spark": """SELECT @1 AS `_1` FROM VALUES ('a'), ('b')""",
"spark": """SELECT ${1} AS `_1` FROM VALUES ('a'), ('b')""",
},
)

View file

@ -229,6 +229,7 @@ TBLPROPERTIES (
self.assertIsInstance(expr.args.get("ignore_nulls"), exp.Boolean)
self.assertEqual(expr.sql(dialect="spark"), "ANY_VALUE(col, TRUE)")
self.validate_identity("SELECT * FROM t1 SEMI JOIN t2 ON t1.x = t2.x")
self.validate_identity("SELECT TRANSFORM(ARRAY(1, 2, 3), x -> x + 1)")
self.validate_identity("SELECT TRANSFORM(ARRAY(1, 2, 3), (x, i) -> x + i)")
self.validate_identity("REFRESH table a.b.c")
@ -460,13 +461,13 @@ TBLPROPERTIES (
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"clickhouse": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname, lname NULLS FIRST",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"snowflake": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname, lname NULLS FIRST",
"clickhouse": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"duckdb": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"postgres": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname ASC, lname NULLS FIRST",
"presto": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC, lname NULLS FIRST",
"hive": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"snowflake": "SELECT fname, lname, age FROM person ORDER BY age DESC, fname ASC, lname NULLS FIRST",
},
)
self.validate_all(
@ -583,3 +584,60 @@ TBLPROPERTIES (
"databricks": "WITH cte AS (SELECT cola FROM other_table) INSERT OVERWRITE TABLE table SELECT cola FROM cte",
},
)
def test_explode_to_unnest(self):
self.validate_all(
"SELECT EXPLODE(x) FROM tbl",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) AS col FROM tbl, UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(x)) - 1)) AS pos CROSS JOIN UNNEST(x) AS col WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(x) - 1) AND pos_2 = (ARRAY_LENGTH(x) - 1))",
"presto": "SELECT IF(pos = pos_2, col) AS col FROM tbl, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(x)))) AS _u(pos) CROSS JOIN UNNEST(x) WITH ORDINALITY AS _u_2(col, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(x) AND pos_2 = CARDINALITY(x))",
"spark": "SELECT EXPLODE(x) FROM tbl",
},
)
self.validate_all(
"SELECT EXPLODE(col) FROM _u",
write={
"bigquery": "SELECT IF(pos = pos_2, col_2, NULL) AS col_2 FROM _u, UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH(col)) - 1)) AS pos CROSS JOIN UNNEST(col) AS col_2 WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH(col) - 1) AND pos_2 = (ARRAY_LENGTH(col) - 1))",
"presto": "SELECT IF(pos = pos_2, col_2) AS col_2 FROM _u, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(col)))) AS _u_2(pos) CROSS JOIN UNNEST(col) WITH ORDINALITY AS _u_3(col_2, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(col) AND pos_2 = CARDINALITY(col))",
"spark": "SELECT EXPLODE(col) FROM _u",
},
)
self.validate_all(
"SELECT EXPLODE(col) AS exploded FROM schema.tbl",
write={
"presto": "SELECT IF(pos = pos_2, exploded) AS exploded FROM schema.tbl, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(col)))) AS _u(pos) CROSS JOIN UNNEST(col) WITH ORDINALITY AS _u_2(exploded, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(col) AND pos_2 = CARDINALITY(col))",
},
)
self.validate_all(
"SELECT EXPLODE(ARRAY(1, 2))",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) AS col FROM UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH([1, 2])) - 1)) AS pos CROSS JOIN UNNEST([1, 2]) AS col WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH([1, 2]) - 1) AND pos_2 = (ARRAY_LENGTH([1, 2]) - 1))",
"presto": "SELECT IF(pos = pos_2, col) AS col FROM UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[1, 2])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[1, 2]) WITH ORDINALITY AS _u_2(col, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(ARRAY[1, 2]) AND pos_2 = CARDINALITY(ARRAY[1, 2]))",
},
)
self.validate_all(
"SELECT POSEXPLODE(ARRAY(2, 3)) AS x",
write={
"bigquery": "SELECT IF(pos = pos_2, x, NULL) AS x, IF(pos = pos_2, pos_2, NULL) AS pos_2 FROM UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH([2, 3])) - 1)) AS pos CROSS JOIN UNNEST([2, 3]) AS x WITH OFFSET AS pos_2 WHERE pos = pos_2 OR (pos > (ARRAY_LENGTH([2, 3]) - 1) AND pos_2 = (ARRAY_LENGTH([2, 3]) - 1))",
"presto": "SELECT IF(pos = pos_2, x) AS x, IF(pos = pos_2, pos_2) AS pos_2 FROM UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[2, 3])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[2, 3]) WITH ORDINALITY AS _u_2(x, pos_2) WHERE pos = pos_2 OR (pos > CARDINALITY(ARRAY[2, 3]) AND pos_2 = CARDINALITY(ARRAY[2, 3]))",
},
)
self.validate_all(
"SELECT POSEXPLODE(x) AS (a, b)",
write={
"presto": "SELECT IF(pos = a, b) AS b, IF(pos = a, a) AS a FROM UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(x)))) AS _u(pos) CROSS JOIN UNNEST(x) WITH ORDINALITY AS _u_2(b, a) WHERE pos = a OR (pos > CARDINALITY(x) AND a = CARDINALITY(x))",
},
)
self.validate_all(
"SELECT POSEXPLODE(ARRAY(2, 3)), EXPLODE(ARRAY(4, 5, 6)) FROM tbl",
write={
"bigquery": "SELECT IF(pos = pos_2, col, NULL) AS col, IF(pos = pos_2, pos_2, NULL) AS pos_2, IF(pos = pos_3, col_2, NULL) AS col_2 FROM tbl, UNNEST(GENERATE_ARRAY(0, GREATEST(ARRAY_LENGTH([2, 3]), ARRAY_LENGTH([4, 5, 6])) - 1)) AS pos CROSS JOIN UNNEST([2, 3]) AS col WITH OFFSET AS pos_2 CROSS JOIN UNNEST([4, 5, 6]) AS col_2 WITH OFFSET AS pos_3 WHERE (pos = pos_2 OR (pos > (ARRAY_LENGTH([2, 3]) - 1) AND pos_2 = (ARRAY_LENGTH([2, 3]) - 1))) AND (pos = pos_3 OR (pos > (ARRAY_LENGTH([4, 5, 6]) - 1) AND pos_3 = (ARRAY_LENGTH([4, 5, 6]) - 1)))",
"presto": "SELECT IF(pos = pos_2, col) AS col, IF(pos = pos_2, pos_2) AS pos_2, IF(pos = pos_3, col_2) AS col_2 FROM tbl, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[2, 3]), CARDINALITY(ARRAY[4, 5, 6])))) AS _u(pos) CROSS JOIN UNNEST(ARRAY[2, 3]) WITH ORDINALITY AS _u_2(col, pos_2) CROSS JOIN UNNEST(ARRAY[4, 5, 6]) WITH ORDINALITY AS _u_3(col_2, pos_3) WHERE (pos = pos_2 OR (pos > CARDINALITY(ARRAY[2, 3]) AND pos_2 = CARDINALITY(ARRAY[2, 3]))) AND (pos = pos_3 OR (pos > CARDINALITY(ARRAY[4, 5, 6]) AND pos_3 = CARDINALITY(ARRAY[4, 5, 6])))",
},
)
self.validate_all(
"SELECT col, pos, POSEXPLODE(ARRAY(2, 3)) FROM _u",
write={
"presto": "SELECT col, pos, IF(pos_2 = pos_3, col_2) AS col_2, IF(pos_2 = pos_3, pos_3) AS pos_3 FROM _u, UNNEST(SEQUENCE(1, GREATEST(CARDINALITY(ARRAY[2, 3])))) AS _u_2(pos_2) CROSS JOIN UNNEST(ARRAY[2, 3]) WITH ORDINALITY AS _u_3(col_2, pos_3) WHERE pos_2 = pos_3 OR (pos_2 > CARDINALITY(ARRAY[2, 3]) AND pos_3 = CARDINALITY(ARRAY[2, 3]))",
},
)

View file

@ -59,6 +59,23 @@ class TestSQLite(Validator):
)
def test_sqlite(self):
self.validate_identity("SELECT DATE()")
self.validate_identity("SELECT DATE('now', 'start of month', '+1 month', '-1 day')")
self.validate_identity("SELECT DATETIME(1092941466, 'unixepoch')")
self.validate_identity("SELECT DATETIME(1092941466, 'auto')")
self.validate_identity("SELECT DATETIME(1092941466, 'unixepoch', 'localtime')")
self.validate_identity("SELECT UNIXEPOCH()")
self.validate_identity("SELECT STRFTIME('%s')")
self.validate_identity("SELECT JULIANDAY('now') - JULIANDAY('1776-07-04')")
self.validate_identity("SELECT UNIXEPOCH() - UNIXEPOCH('2004-01-01 02:34:56')")
self.validate_identity("SELECT DATE('now', 'start of year', '+9 months', 'weekday 2')")
self.validate_identity("SELECT (JULIANDAY('now') - 2440587.5) * 86400.0")
self.validate_identity("SELECT UNIXEPOCH('now', 'subsec')")
self.validate_identity("SELECT TIMEDIFF('now', '1809-02-12')")
self.validate_identity(
"""SELECT item AS "item", some AS "some" FROM data WHERE (item = 'value_1' COLLATE NOCASE) AND (some = 't' COLLATE NOCASE) ORDER BY item ASC LIMIT 1 OFFSET 0"""
)
self.validate_all("SELECT LIKE(y, x)", write={"sqlite": "SELECT x LIKE y"})
self.validate_all("SELECT GLOB('*y*', 'xyz')", write={"sqlite": "SELECT 'xyz' GLOB '*y*'"})
self.validate_all(
@ -112,8 +129,8 @@ class TestSQLite(Validator):
self.validate_all(
"SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
write={
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"sqlite": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname NULLS LAST, lname",
"spark": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
"sqlite": "SELECT fname, lname, age FROM person ORDER BY age DESC NULLS FIRST, fname ASC NULLS LAST, lname",
},
)
self.validate_all("x", read={"snowflake": "LEAST(x)"})

View file

@ -18,16 +18,28 @@ class TestTSQL(Validator):
'CREATE TABLE x (CONSTRAINT "pk_mytable" UNIQUE NONCLUSTERED (a DESC)) ON b (c)'
)
self.validate_identity(
self.validate_all(
"""
CREATE TABLE x(
[zip_cd] [varchar](5) NULL NOT FOR REPLICATION
CONSTRAINT [pk_mytable] PRIMARY KEY CLUSTERED
([zip_cd_mkey] ASC)
WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF) ON [PRIMARY]
) ON [PRIMARY]
[zip_cd] [varchar](5) NULL NOT FOR REPLICATION,
[zip_cd_mkey] [varchar](5) NOT NULL,
CONSTRAINT [pk_mytable] PRIMARY KEY CLUSTERED ([zip_cd_mkey] ASC)
WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF) ON [INDEX]
) ON [SECONDARY]
""",
'CREATE TABLE x ("zip_cd" VARCHAR(5) NULL NOT FOR REPLICATION CONSTRAINT "pk_mytable" PRIMARY KEY CLUSTERED ("zip_cd_mkey") WITH (PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF) ON "PRIMARY") ON "PRIMARY"',
write={
"tsql": 'CREATE TABLE x ("zip_cd" VARCHAR(5) NULL NOT FOR REPLICATION, "zip_cd_mkey" VARCHAR(5) NOT NULL, CONSTRAINT "pk_mytable" PRIMARY KEY CLUSTERED ("zip_cd_mkey" ASC) WITH (PAD_INDEX=ON, STATISTICS_NORECOMPUTE=OFF) ON "INDEX") ON "SECONDARY"',
"spark2": "CREATE TABLE x (`zip_cd` VARCHAR(5), `zip_cd_mkey` VARCHAR(5) NOT NULL, CONSTRAINT `pk_mytable` PRIMARY KEY (`zip_cd_mkey`))",
},
)
self.validate_identity("CREATE TABLE x (A INTEGER NOT NULL, B INTEGER NULL)")
self.validate_all(
"CREATE TABLE x ( A INTEGER NOT NULL, B INTEGER NULL )",
write={
"hive": "CREATE TABLE x (A INT NOT NULL, B INT)",
},
)
self.validate_identity(
@ -123,10 +135,10 @@ class TestTSQL(Validator):
self.validate_all(
"STRING_AGG(x, '|') WITHIN GROUP (ORDER BY z ASC)",
write={
"tsql": "STRING_AGG(x, '|') WITHIN GROUP (ORDER BY z)",
"mysql": "GROUP_CONCAT(x ORDER BY z SEPARATOR '|')",
"tsql": "STRING_AGG(x, '|') WITHIN GROUP (ORDER BY z ASC)",
"mysql": "GROUP_CONCAT(x ORDER BY z ASC SEPARATOR '|')",
"sqlite": "GROUP_CONCAT(x, '|')",
"postgres": "STRING_AGG(x, '|' ORDER BY z NULLS FIRST)",
"postgres": "STRING_AGG(x, '|' ORDER BY z ASC NULLS FIRST)",
},
)
self.validate_all(
@ -186,6 +198,7 @@ class TestTSQL(Validator):
},
)
self.validate_identity("HASHBYTES('MD2', 'x')")
self.validate_identity("LOG(n, b)")
def test_types(self):
self.validate_identity("CAST(x AS XML)")
@ -493,6 +506,12 @@ class TestTSQL(Validator):
"tsql": "CREATE TABLE tbl (id INTEGER NOT NULL IDENTITY(10, 1) PRIMARY KEY)",
},
)
self.validate_all(
"SELECT * INTO foo.bar.baz FROM (SELECT * FROM a.b.c) AS temp",
read={
"": "CREATE TABLE foo.bar.baz AS SELECT * FROM a.b.c",
},
)
self.validate_all(
"IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id('db.tbl') AND name = 'idx') EXEC('CREATE INDEX idx ON db.tbl')",
read={
@ -507,12 +526,17 @@ class TestTSQL(Validator):
},
)
self.validate_all(
"IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'foo') EXEC('CREATE TABLE foo (a INTEGER)')",
"IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'baz' AND table_schema = 'bar' AND table_catalog = 'foo') EXEC('CREATE TABLE foo.bar.baz (a INTEGER)')",
read={
"": "CREATE TABLE IF NOT EXISTS foo (a INTEGER)",
"": "CREATE TABLE IF NOT EXISTS foo.bar.baz (a INTEGER)",
},
)
self.validate_all(
"IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'baz' AND table_schema = 'bar' AND table_catalog = 'foo') EXEC('SELECT * INTO foo.bar.baz FROM (SELECT ''2020'' AS z FROM a.b.c) AS temp')",
read={
"": "CREATE TABLE IF NOT EXISTS foo.bar.baz AS SELECT '2020' AS z FROM a.b.c",
},
)
self.validate_all(
"CREATE OR ALTER VIEW a.b AS SELECT 1",
read={
@ -553,15 +577,11 @@ class TestTSQL(Validator):
"oracle": "CREATE TEMPORARY TABLE mytemptable (a NUMBER)",
},
)
def test_insert_cte(self):
self.validate_all(
"CREATE TABLE #mytemptable AS SELECT a FROM Source_Table",
write={
"duckdb": "CREATE TEMPORARY TABLE mytemptable AS SELECT a FROM Source_Table",
"oracle": "CREATE TEMPORARY TABLE mytemptable AS SELECT a FROM Source_Table",
"snowflake": "CREATE TEMPORARY TABLE mytemptable AS SELECT a FROM Source_Table",
"spark": "CREATE TEMPORARY VIEW mytemptable AS SELECT a FROM Source_Table",
"tsql": "CREATE TABLE #mytemptable AS SELECT a FROM Source_Table",
},
"INSERT INTO foo.bar WITH cte AS (SELECT 1 AS one) SELECT * FROM cte",
write={"tsql": "WITH cte AS (SELECT 1 AS one) INSERT INTO foo.bar SELECT * FROM cte"},
)
def test_transaction(self):
@ -709,18 +729,14 @@ WHERE
SET @CurrentDate = CONVERT(VARCHAR(20), GETDATE(), 120);
CREATE TABLE [target_schema].[target_table]
WITH (DISTRIBUTION = REPLICATE, HEAP)
AS
SELECT
@CurrentDate AS DWCreatedDate
FROM source_schema.sourcetable;
(a INTEGER)
WITH (DISTRIBUTION = REPLICATE, HEAP);
"""
expected_sqls = [
'CREATE PROC "dbo"."transform_proc" AS DECLARE @CurrentDate VARCHAR(20)',
"SET @CurrentDate = CAST(FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss') AS VARCHAR(20))",
'CREATE TABLE "target_schema"."target_table" WITH (DISTRIBUTION=REPLICATE, HEAP) AS SELECT @CurrentDate AS DWCreatedDate FROM source_schema.sourcetable',
'CREATE TABLE "target_schema"."target_table" (a INTEGER) WITH (DISTRIBUTION=REPLICATE, HEAP)',
]
for expr, expected_sql in zip(parse(sql, read="tsql"), expected_sqls):
@ -1178,6 +1194,16 @@ WHERE
self.assertIsInstance(table.this, exp.Parameter)
self.assertIsInstance(table.this.this, exp.Var)
self.validate_all(
"SELECT @x",
write={
"databricks": "SELECT ${x}",
"hive": "SELECT ${x}",
"spark": "SELECT ${x}",
"tsql": "SELECT @x",
},
)
def test_temp_table(self):
self.validate_all(
"SELECT * FROM #mytemptable",
@ -1319,3 +1345,21 @@ FROM OPENJSON(@json) WITH (
},
pretty=True,
)
def test_set(self):
self.validate_all(
"SET KEY VALUE",
write={
"tsql": "SET KEY VALUE",
"duckdb": "SET KEY = VALUE",
"spark": "SET KEY = VALUE",
},
)
self.validate_all(
"SET @count = (SELECT COUNT(1) FROM x)",
write={
"databricks": "SET count = (SELECT COUNT(1) FROM x)",
"tsql": "SET @count = (SELECT COUNT(1) FROM x)",
"spark": "SET count = (SELECT COUNT(1) FROM x)",
},
)

View file

@ -401,6 +401,7 @@ SELECT 1 FROM a INNER JOIN b ON a.x = b.x
SELECT 1 FROM a LEFT JOIN b ON a.x = b.x
SELECT 1 FROM a RIGHT JOIN b ON a.x = b.x
SELECT 1 FROM a CROSS JOIN b ON a.x = b.x
SELECT 1 FROM a SEMI JOIN b ON a.x = b.x
SELECT 1 FROM a LEFT SEMI JOIN b ON a.x = b.x
SELECT 1 FROM a LEFT ANTI JOIN b ON a.x = b.x
SELECT 1 FROM a RIGHT SEMI JOIN b ON a.x = b.x
@ -859,3 +860,7 @@ SELECT * FROM (tbl1 CROSS JOIN (SELECT * FROM tbl2) AS t1)
/* comment */ CREATE TABLE foo AS SELECT 1
SELECT next, transform, if
SELECT "any", "case", "if", "next"
SELECT x FROM y ORDER BY x ASC
KILL '123'
KILL CONNECTION 123
KILL QUERY '123'

View file

@ -28,3 +28,15 @@ 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 "x"."a" AS "a" FROM "x" AS "x" WHERE 1 <> 0;
--------------------------------------
-- Replace date functions
--------------------------------------
DATE('2023-01-01');
CAST('2023-01-01' AS DATE);
TIMESTAMP('2023-01-01');
CAST('2023-01-01' AS TIMESTAMP);
TIMESTAMP('2023-01-01', '12:00:00');
TIMESTAMP('2023-01-01', '12:00:00');

View file

@ -680,3 +680,137 @@ CONCAT('a', x, y, 'bc');
'a' || 'b' || x;
CONCAT('ab', x);
--------------------------------------
-- DATE_TRUNC
--------------------------------------
DATE_TRUNC('year', x) = CAST('2021-01-01' AS DATE);
x < CAST('2022-01-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
DATE_TRUNC('quarter', x) = CAST('2021-01-01' AS DATE);
x < CAST('2021-04-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
DATE_TRUNC('month', x) = CAST('2021-01-01' AS DATE);
x < CAST('2021-02-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
DATE_TRUNC('week', x) = CAST('2021-01-04' AS DATE);
x < CAST('2021-01-11' AS DATE) AND x >= CAST('2021-01-04' AS DATE);
DATE_TRUNC('day', x) = CAST('2021-01-01' AS DATE);
x < CAST('2021-01-02' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
CAST('2021-01-01' AS DATE) = DATE_TRUNC('year', x);
x < CAST('2022-01-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
-- Always false, except for nulls
DATE_TRUNC('quarter', x) = CAST('2021-01-02' AS DATE);
DATE_TRUNC('quarter', x) = CAST('2021-01-02' AS DATE);
DATE_TRUNC('year', x) <> CAST('2021-01-01' AS DATE);
x < CAST('2021-01-01' AS DATE) AND x >= CAST('2022-01-01' AS DATE);
-- Always true, except for nulls
DATE_TRUNC('year', x) <> CAST('2021-01-02' AS DATE);
DATE_TRUNC('year', x) <> CAST('2021-01-02' AS DATE);
DATE_TRUNC('year', x) <= CAST('2021-01-01' AS DATE);
x < CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) <= CAST('2021-01-02' AS DATE);
x < CAST('2022-01-01' AS DATE);
CAST('2021-01-01' AS DATE) >= DATE_TRUNC('year', x);
x < CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) < CAST('2021-01-01' AS DATE);
x < CAST('2021-01-01' AS DATE);
DATE_TRUNC('year', x) < CAST('2021-01-02' AS DATE);
x < CAST('2021-01-01' AS DATE);
DATE_TRUNC('year', x) >= CAST('2021-01-01' AS DATE);
x >= CAST('2021-01-01' AS DATE);
DATE_TRUNC('year', x) >= CAST('2021-01-02' AS DATE);
x >= CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) > CAST('2021-01-01' AS DATE);
x >= CAST('2022-01-01' AS DATE);
DATE_TRUNC('year', x) > CAST('2021-01-02' AS DATE);
x >= CAST('2022-01-01' AS DATE);
-- right is not a date
DATE_TRUNC('year', x) <> '2021-01-02';
DATE_TRUNC('year', x) <> '2021-01-02';
DATE_TRUNC('year', x) IN (CAST('2021-01-01' AS DATE), CAST('2023-01-01' AS DATE));
(x < CAST('2022-01-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE)) OR (x < CAST('2024-01-01' AS DATE) AND x >= CAST('2023-01-01' AS DATE));
-- merge ranges
DATE_TRUNC('year', x) IN (CAST('2021-01-01' AS DATE), CAST('2022-01-01' AS DATE));
x < CAST('2023-01-01' AS DATE) AND x >= CAST('2021-01-01' AS DATE);
-- one of the values will always be false
DATE_TRUNC('year', x) IN (CAST('2021-01-01' AS DATE), CAST('2022-01-02' AS DATE));
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);
x < CAST('2022-01-01 00:00:00' AS DATETIME) AND x >= CAST('2021-01-01 00:00:00' AS DATETIME);
--------------------------------------
-- EQUALITY
--------------------------------------
x + 1 = 3;
x = 2;
1 + x = 3;
x = 2;
3 = x + 1;
x = 2;
x - 1 = 3;
x = 4;
x + 1 > 3;
x > 2;
x + 1 >= 3;
x >= 2;
x + 1 <= 3;
x <= 2;
x + 1 <= 3;
x <= 2;
x + 1 <> 3;
x <> 2;
1 + x + 1 = 3 + 1;
x = 2;
x - INTERVAL 1 DAY = CAST('2021-01-01' AS DATE);
x = CAST('2021-01-02' AS DATE);
x - INTERVAL 1 HOUR > CAST('2021-01-01' AS DATETIME);
x > CAST('2021-01-01 01:00:00' AS DATETIME);
DATETIME_ADD(x, 1, HOUR) < CAST('2021-01-01' AS DATETIME);
x < CAST('2020-12-31 23:00:00' AS DATETIME);
DATETIME_SUB(x, 1, DAY) >= CAST('2021-01-01' AS DATETIME);
x >= CAST('2021-01-02 00:00:00' AS DATETIME);
DATE_ADD(x, 1, DAY) <= CAST('2021-01-01' AS DATE);
x <= CAST('2020-12-31' AS DATE);
DATE_SUB(x, 1, DAY) <> CAST('2021-01-01' AS DATE);
x <> CAST('2021-01-02' AS DATE);
DATE_ADD(DATE_ADD(DATE_TRUNC('week', DATE_SUB(x, 1, DAY)), 1, DAY), 1, YEAR) < CAST('2021-01-08' AS DATE);
x < CAST('2020-01-07' AS DATE);
x - INTERVAL '1' day = CAST(y AS DATE);
x - INTERVAL '1' day = CAST(y AS DATE);

View file

@ -209,3 +209,15 @@ WHERE
)
AND ARRAY_ALL(_u_19."", _x -> _x = x.a)
AND x.a > COALESCE(_u_21.d, 0);
SELECT
CAST((
SELECT
x.a AS a
FROM x
) AS TEXT) AS a;
SELECT
CAST((
SELECT
x.a AS a
FROM x
) AS TEXT) AS a;

View file

@ -346,7 +346,7 @@ SELECT
fruit,
basket_index
FROM table_data
CROSS JOIN UNNEST(fruit_basket) AS fruit WITH OFFSET basket_index;
CROSS JOIN UNNEST(fruit_basket) WITH ORDINALITY AS fruit(basket_index);
WITH table_data AS (
SELECT
'bob' AS name,
@ -357,11 +357,12 @@ SELECT
fruit,
basket_index
FROM table_data
CROSS JOIN UNNEST(fruit_basket) AS fruit WITH OFFSET AS basket_index;
CROSS JOIN UNNEST(fruit_basket) WITH ORDINALITY AS fruit(basket_index);
SELECT A.* EXCEPT A.COL_1, A.COL_2 FROM TABLE_1 A;
SELECT
A.*
EXCEPT (A.COL_1, A.COL_2)
EXCEPT (A.COL_1),
A.COL_2
FROM TABLE_1 AS A;
SELECT *

View file

@ -14,6 +14,13 @@ class TestExpressions(unittest.TestCase):
def test_depth(self):
self.assertEqual(parse_one("x(1)").find(exp.Literal).depth, 1)
def test_iter(self):
self.assertEqual([exp.Literal.number(1), exp.Literal.number(2)], list(parse_one("[1, 2]")))
with self.assertRaises(TypeError):
for x in parse_one("1"):
pass
def test_eq(self):
self.assertNotEqual(exp.to_identifier("a"), exp.to_identifier("A"))

View file

@ -1,7 +1,7 @@
import unittest
from sqlglot.dialects import BigQuery, Dialect, Snowflake
from sqlglot.helper import name_sequence, tsort
from sqlglot.helper import merge_ranges, name_sequence, tsort
class TestHelper(unittest.TestCase):
@ -66,3 +66,10 @@ class TestHelper(unittest.TestCase):
self.assertEqual(s1(), "a2")
self.assertEqual(s2(), "b1")
self.assertEqual(s2(), "b2")
def test_merge_ranges(self):
self.assertEqual([], merge_ranges([]))
self.assertEqual([(0, 1)], merge_ranges([(0, 1)]))
self.assertEqual([(0, 1), (2, 3)], merge_ranges([(0, 1), (2, 3)]))
self.assertEqual([(0, 3)], merge_ranges([(0, 1), (1, 3)]))
self.assertEqual([(0, 1), (2, 4)], merge_ranges([(2, 3), (0, 1), (3, 4)]))

View file

@ -679,7 +679,7 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
def test_unknown_annotation(self):
schema = {"x": {"cola": "VARCHAR"}}
sql = "SELECT x.cola || SOME_ANONYMOUS_FUNC(x.cola) AS col FROM x AS x"
sql = "SELECT x.cola + SOME_ANONYMOUS_FUNC(x.cola) AS col FROM x AS x"
concat_expr_alias = annotate_types(parse_one(sql), schema=schema).expressions[0]
self.assertEqual(concat_expr_alias.type.this, exp.DataType.Type.UNKNOWN)
@ -702,7 +702,7 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
self.assertEqual(expression.right.type.this, exp.DataType.Type.INT)
# NULL <op> UNKNOWN should yield NULL
sql = "SELECT NULL || SOME_ANONYMOUS_FUNC() AS result"
sql = "SELECT NULL + SOME_ANONYMOUS_FUNC() AS result"
concat_expr_alias = annotate_types(parse_one(sql)).expressions[0]
self.assertEqual(concat_expr_alias.type.this, exp.DataType.Type.NULL)
@ -776,6 +776,17 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
self.assertEqual(exp.DataType.Type.ARRAY, expression.selects[0].type.this)
self.assertEqual(expression.selects[0].type.sql(), "ARRAY<INT>")
def test_type_annotation_cache(self):
sql = "SELECT 1 + 1"
expression = annotate_types(parse_one(sql))
self.assertEqual(exp.DataType.Type.INT, expression.selects[0].type.this)
expression.selects[0].this.replace(parse_one("1.2"))
expression = annotate_types(expression)
self.assertEqual(exp.DataType.Type.DOUBLE, expression.selects[0].type.this)
def test_user_defined_type_annotation(self):
schema = MappingSchema({"t": {"x": "int"}}, dialect="postgres")
expression = annotate_types(parse_one("SELECT CAST(x AS IPADDRESS) FROM t"), schema=schema)

View file

@ -44,9 +44,6 @@ class TestTranspile(unittest.TestCase):
with self.assertRaises(ParseError):
self.validate(f"SELECT x {key}", "")
def test_asc(self):
self.validate("SELECT x FROM y ORDER BY x ASC", "SELECT x FROM y ORDER BY x")
def test_unary(self):
self.validate("+++1", "1")
self.validate("+-1", "-1")