1
0
Fork 0

Merging upstream version 26.29.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-06-19 07:53:46 +02:00
parent 141a93f866
commit 4c1ec9be5a
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
58 changed files with 17605 additions and 17151 deletions

View file

@ -1,6 +1,25 @@
Changelog
=========
## [v26.28.1] - 2025-06-13
### :boom: BREAKING CHANGES
- due to [`44297f1`](https://github.com/tobymao/sqlglot/commit/44297f1c5c8c2cb16fe77c318312f417b4281708) - JOIN pipe syntax, Set Operators as CTEs *(PR [#5215](https://github.com/tobymao/sqlglot/pull/5215) by [@geooo109](https://github.com/geooo109))*:
JOIN pipe syntax, Set Operators as CTEs (#5215)
### :sparkles: New Features
- [`44297f1`](https://github.com/tobymao/sqlglot/commit/44297f1c5c8c2cb16fe77c318312f417b4281708) - **parser**: JOIN pipe syntax, Set Operators as CTEs *(PR [#5215](https://github.com/tobymao/sqlglot/pull/5215) by [@geooo109](https://github.com/geooo109))*
- [`21cd3eb`](https://github.com/tobymao/sqlglot/commit/21cd3ebf5d0b57f5b102c5aadc3b24a598ebe918) - **parser**: PIVOT/UNPIVOT pipe syntax *(PR [#5222](https://github.com/tobymao/sqlglot/pull/5222) by [@geooo109](https://github.com/geooo109))*
### :bug: Bug Fixes
- [`28fed58`](https://github.com/tobymao/sqlglot/commit/28fed586a39df83aade4792217743a1a859fd039) - **optimizer**: UnboundLocalError in scope module *(commit by [@georgesittas](https://github.com/georgesittas))*
- [`809e05a`](https://github.com/tobymao/sqlglot/commit/809e05a743d5a2904a1d6f6813f24ca7549ac7ef) - **snowflake**: preserve STRTOK_TO_ARRAY roundtrip *(commit by [@georgesittas](https://github.com/georgesittas))*
### :recycle: Refactors
- [`aac70aa`](https://github.com/tobymao/sqlglot/commit/aac70aaaa8d840c267129e2307ccb65058cef0c9) - **parser**: simpler _parse_pipe_syntax_select *(commit by [@geooo109](https://github.com/geooo109))*
## [v26.27.0] - 2025-06-12
### :boom: BREAKING CHANGES
- due to [`ac6555b`](https://github.com/tobymao/sqlglot/commit/ac6555b4d6c162ef7b14b63307d01fd560138ea0) - preserve DIV binary operator, fixes [#5198](https://github.com/tobymao/sqlglot/pull/5198) *(PR [#5199](https://github.com/tobymao/sqlglot/pull/5199) by [@georgesittas](https://github.com/georgesittas))*:
@ -4882,3 +4901,4 @@ Changelog
[v26.25.3]: https://github.com/tobymao/sqlglot/compare/v26.25.2...v26.25.3
[v26.26.0]: https://github.com/tobymao/sqlglot/compare/v26.25.3...v26.26.0
[v26.27.0]: https://github.com/tobymao/sqlglot/compare/v26.26.0...v26.27.0
[v26.28.1]: https://github.com/tobymao/sqlglot/compare/v26.27.1...v26.28.1

File diff suppressed because one or more lines are too long

View file

@ -84,8 +84,8 @@
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;26.28.0&#39;</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</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">26</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;26.28.1&#39;</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</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">26</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span></pre></div>
@ -93,7 +93,7 @@
<section id="__version__">
<div class="attr variable">
<span class="name">__version__</span><span class="annotation">: str</span> =
<span class="default_value">&#39;26.28.0&#39;</span>
<span class="default_value">&#39;26.28.1&#39;</span>
</div>
@ -105,7 +105,7 @@
<section id="__version_tuple__">
<div class="attr variable">
<span class="name">__version_tuple__</span><span class="annotation">: object</span> =
<span class="default_value">(26, 28, 0)</span>
<span class="default_value">(26, 28, 1)</span>
</div>
@ -117,7 +117,7 @@
<section id="version">
<div class="attr variable">
<span class="name">version</span><span class="annotation">: str</span> =
<span class="default_value">&#39;26.28.0&#39;</span>
<span class="default_value">&#39;26.28.1&#39;</span>
</div>
@ -129,7 +129,7 @@
<section id="version_tuple">
<div class="attr variable">
<span class="name">version_tuple</span><span class="annotation">: object</span> =
<span class="default_value">(26, 28, 0)</span>
<span class="default_value">(26, 28, 1)</span>
</div>

View file

@ -359,7 +359,7 @@ dialect implementations in order to understand how their various components can
<section id="Athena">
<div class="attr variable">
<span class="name">Athena</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998209036672&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497524319680&#39;&gt;</span>
</div>
@ -371,7 +371,7 @@ dialect implementations in order to understand how their various components can
<section id="BigQuery">
<div class="attr variable">
<span class="name">BigQuery</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998207084000&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497508457712&#39;&gt;</span>
</div>
@ -383,7 +383,7 @@ dialect implementations in order to understand how their various components can
<section id="ClickHouse">
<div class="attr variable">
<span class="name">ClickHouse</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998207095232&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519058016&#39;&gt;</span>
</div>
@ -395,7 +395,7 @@ dialect implementations in order to understand how their various components can
<section id="Databricks">
<div class="attr variable">
<span class="name">Databricks</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998202197424&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497524139168&#39;&gt;</span>
</div>
@ -407,7 +407,7 @@ dialect implementations in order to understand how their various components can
<section id="Doris">
<div class="attr variable">
<span class="name">Doris</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213879552&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497511684976&#39;&gt;</span>
</div>
@ -419,7 +419,7 @@ dialect implementations in order to understand how their various components can
<section id="Drill">
<div class="attr variable">
<span class="name">Drill</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213878592&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519762720&#39;&gt;</span>
</div>
@ -431,7 +431,7 @@ dialect implementations in order to understand how their various components can
<section id="Druid">
<div class="attr variable">
<span class="name">Druid</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218182256&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519758784&#39;&gt;</span>
</div>
@ -443,7 +443,7 @@ dialect implementations in order to understand how their various components can
<section id="DuckDB">
<div class="attr variable">
<span class="name">DuckDB</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218189216&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497523534352&#39;&gt;</span>
</div>
@ -455,7 +455,7 @@ dialect implementations in order to understand how their various components can
<section id="Dune">
<div class="attr variable">
<span class="name">Dune</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998204697984&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497509326448&#39;&gt;</span>
</div>
@ -467,7 +467,7 @@ dialect implementations in order to understand how their various components can
<section id="Hive">
<div class="attr variable">
<span class="name">Hive</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218084672&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497509318864&#39;&gt;</span>
</div>
@ -479,7 +479,7 @@ dialect implementations in order to understand how their various components can
<section id="Materialize">
<div class="attr variable">
<span class="name">Materialize</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998210512240&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497509727008&#39;&gt;</span>
</div>
@ -491,7 +491,7 @@ dialect implementations in order to understand how their various components can
<section id="MySQL">
<div class="attr variable">
<span class="name">MySQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998210508736&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497518543968&#39;&gt;</span>
</div>
@ -503,7 +503,7 @@ dialect implementations in order to understand how their various components can
<section id="Oracle">
<div class="attr variable">
<span class="name">Oracle</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998204295152&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519443056&#39;&gt;</span>
</div>
@ -515,7 +515,7 @@ dialect implementations in order to understand how their various components can
<section id="Postgres">
<div class="attr variable">
<span class="name">Postgres</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213015728&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497523411792&#39;&gt;</span>
</div>
@ -527,7 +527,7 @@ dialect implementations in order to understand how their various components can
<section id="Presto">
<div class="attr variable">
<span class="name">Presto</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998207103072&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497523411840&#39;&gt;</span>
</div>
@ -539,7 +539,7 @@ dialect implementations in order to understand how their various components can
<section id="PRQL">
<div class="attr variable">
<span class="name">PRQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218107056&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519345280&#39;&gt;</span>
</div>
@ -551,7 +551,7 @@ dialect implementations in order to understand how their various components can
<section id="Redshift">
<div class="attr variable">
<span class="name">Redshift</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213994336&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519402464&#39;&gt;</span>
</div>
@ -563,7 +563,7 @@ dialect implementations in order to understand how their various components can
<section id="RisingWave">
<div class="attr variable">
<span class="name">RisingWave</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213988768&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519401648&#39;&gt;</span>
</div>
@ -575,7 +575,7 @@ dialect implementations in order to understand how their various components can
<section id="Snowflake">
<div class="attr variable">
<span class="name">Snowflake</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218915888&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519290464&#39;&gt;</span>
</div>
@ -587,7 +587,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark">
<div class="attr variable">
<span class="name">Spark</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218919824&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497514370800&#39;&gt;</span>
</div>
@ -599,7 +599,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark2">
<div class="attr variable">
<span class="name">Spark2</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998209784848&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497515049936&#39;&gt;</span>
</div>
@ -611,7 +611,7 @@ dialect implementations in order to understand how their various components can
<section id="SQLite">
<div class="attr variable">
<span class="name">SQLite</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998214271904&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497515046480&#39;&gt;</span>
</div>
@ -623,7 +623,7 @@ dialect implementations in order to understand how their various components can
<section id="StarRocks">
<div class="attr variable">
<span class="name">StarRocks</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998214272816&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497523919648&#39;&gt;</span>
</div>
@ -635,7 +635,7 @@ dialect implementations in order to understand how their various components can
<section id="Tableau">
<div class="attr variable">
<span class="name">Tableau</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998213207136&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497514866736&#39;&gt;</span>
</div>
@ -647,7 +647,7 @@ dialect implementations in order to understand how their various components can
<section id="Teradata">
<div class="attr variable">
<span class="name">Teradata</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218430752&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519546416&#39;&gt;</span>
</div>
@ -659,7 +659,7 @@ dialect implementations in order to understand how their various components can
<section id="Trino">
<div class="attr variable">
<span class="name">Trino</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998217361760&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497519550976&#39;&gt;</span>
</div>
@ -671,7 +671,7 @@ dialect implementations in order to understand how their various components can
<section id="TSQL">
<div class="attr variable">
<span class="name">TSQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218034608&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497523854880&#39;&gt;</span>
</div>
@ -683,7 +683,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialect">
<div class="attr variable">
<span class="name">Dialect</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998218028656&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497522700400&#39;&gt;</span>
</div>
@ -695,7 +695,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialects">
<div class="attr variable">
<span class="name">Dialects</span> =
<span class="default_value">&lt;MagicMock id=&#39;139998209690880&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140497510128688&#39;&gt;</span>
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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 one or more lines are too long

View file

@ -14760,7 +14760,7 @@ SQL expressions, such as <code><a href="#select">sqlglot.expressions.select</a><
</span><span id="L-5593"><a href="#L-5593"><span class="linenos">5593</span></a>
</span><span id="L-5594"><a href="#L-5594"><span class="linenos">5594</span></a>
</span><span id="L-5595"><a href="#L-5595"><span class="linenos">5595</span></a><span class="k">class</span><span class="w"> </span><span class="nc">StringToArray</span><span class="p">(</span><span class="n">Func</span><span class="p">):</span>
</span><span id="L-5596"><a href="#L-5596"><span class="linenos">5596</span></a> <span class="n">arg_types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;this&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;null&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
</span><span id="L-5596"><a href="#L-5596"><span class="linenos">5596</span></a> <span class="n">arg_types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;this&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;null&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
</span><span id="L-5597"><a href="#L-5597"><span class="linenos">5597</span></a> <span class="n">_sql_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;STRING_TO_ARRAY&quot;</span><span class="p">,</span> <span class="s2">&quot;SPLIT_BY_STRING&quot;</span><span class="p">,</span> <span class="s2">&quot;STRTOK_TO_ARRAY&quot;</span><span class="p">]</span>
</span><span id="L-5598"><a href="#L-5598"><span class="linenos">5598</span></a>
</span><span id="L-5599"><a href="#L-5599"><span class="linenos">5599</span></a>
@ -63316,7 +63316,7 @@ Otherwise, this resets the expressions.</li>
<div id="DataType.STRUCT_TYPES" class="classattr">
<div class="attr variable">
<span class="name">STRUCT_TYPES</span> =
<span class="default_value">{&lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;}</span>
<span class="default_value">{&lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;}</span>
</div>
@ -63341,7 +63341,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">NESTED_TYPES</span> =
<input id="DataType.NESTED_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{&lt;Type.LIST: &#39;LIST&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;, &lt;Type.MAP: &#39;MAP&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;, &lt;Type.ARRAY: &#39;ARRAY&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.NESTED_TYPES-view-value"></label><span class="default_value">{&lt;Type.LIST: &#39;LIST&#39;&gt;, &lt;Type.MAP: &#39;MAP&#39;&gt;, &lt;Type.ARRAY: &#39;ARRAY&#39;&gt;, &lt;Type.STRUCT: &#39;STRUCT&#39;&gt;, &lt;Type.NESTED: &#39;NESTED&#39;&gt;, &lt;Type.UNION: &#39;UNION&#39;&gt;, &lt;Type.OBJECT: &#39;OBJECT&#39;&gt;}</span>
</div>
@ -63354,7 +63354,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">TEXT_TYPES</span> =
<input id="DataType.TEXT_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{&lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.NAME: &#39;NAME&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.TEXT_TYPES-view-value"></label><span class="default_value">{&lt;Type.CHAR: &#39;CHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.TEXT: &#39;TEXT&#39;&gt;, &lt;Type.NAME: &#39;NAME&#39;&gt;}</span>
</div>
@ -63367,7 +63367,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">SIGNED_INTEGER_TYPES</span> =
<input id="DataType.SIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.SIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;}</span>
</div>
@ -63380,7 +63380,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">UNSIGNED_INTEGER_TYPES</span> =
<input id="DataType.UNSIGNED_INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.UNSIGNED_INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;}</span>
</div>
@ -63393,7 +63393,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">INTEGER_TYPES</span> =
<input id="DataType.INTEGER_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.INTEGER_TYPES-view-value"></label><span class="default_value">{&lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;}</span>
</div>
@ -63418,7 +63418,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">REAL_TYPES</span> =
<input id="DataType.REAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.REAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;}</span>
</div>
@ -63431,7 +63431,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">NUMERIC_TYPES</span> =
<input id="DataType.NUMERIC_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{&lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.NUMERIC_TYPES-view-value"></label><span class="default_value">{&lt;Type.DOUBLE: &#39;DOUBLE&#39;&gt;, &lt;Type.INT128: &#39;INT128&#39;&gt;, &lt;Type.MONEY: &#39;MONEY&#39;&gt;, &lt;Type.UINT128: &#39;UINT128&#39;&gt;, &lt;Type.BIGINT: &#39;BIGINT&#39;&gt;, &lt;Type.UINT256: &#39;UINT256&#39;&gt;, &lt;Type.DECIMAL64: &#39;DECIMAL64&#39;&gt;, &lt;Type.UDOUBLE: &#39;UDOUBLE&#39;&gt;, &lt;Type.UMEDIUMINT: &#39;UMEDIUMINT&#39;&gt;, &lt;Type.BIGDECIMAL: &#39;BIGDECIMAL&#39;&gt;, &lt;Type.TINYINT: &#39;TINYINT&#39;&gt;, &lt;Type.INT: &#39;INT&#39;&gt;, &lt;Type.UTINYINT: &#39;UTINYINT&#39;&gt;, &lt;Type.UBIGINT: &#39;UBIGINT&#39;&gt;, &lt;Type.UINT: &#39;UINT&#39;&gt;, &lt;Type.MEDIUMINT: &#39;MEDIUMINT&#39;&gt;, &lt;Type.SMALLINT: &#39;SMALLINT&#39;&gt;, &lt;Type.INT256: &#39;INT256&#39;&gt;, &lt;Type.DECIMAL: &#39;DECIMAL&#39;&gt;, &lt;Type.FLOAT: &#39;FLOAT&#39;&gt;, &lt;Type.DECIMAL128: &#39;DECIMAL128&#39;&gt;, &lt;Type.UDECIMAL: &#39;UDECIMAL&#39;&gt;, &lt;Type.SMALLMONEY: &#39;SMALLMONEY&#39;&gt;, &lt;Type.USMALLINT: &#39;USMALLINT&#39;&gt;, &lt;Type.DECIMAL256: &#39;DECIMAL256&#39;&gt;, &lt;Type.DECIMAL32: &#39;DECIMAL32&#39;&gt;, &lt;Type.BIT: &#39;BIT&#39;&gt;}</span>
</div>
@ -63444,7 +63444,7 @@ Otherwise, this resets the expressions.</li>
<div class="attr variable">
<span class="name">TEMPORAL_TYPES</span> =
<input id="DataType.TEMPORAL_TYPES-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DATETIME64: &#39;DATETIME64&#39;&gt;, &lt;Type.TIMESTAMP: &#39;TIMESTAMP&#39;&gt;, &lt;Type.TIMESTAMP_S: &#39;TIMESTAMP_S&#39;&gt;, &lt;Type.DATE: &#39;DATE&#39;&gt;, &lt;Type.TIMETZ: &#39;TIMETZ&#39;&gt;, &lt;Type.TIME: &#39;TIME&#39;&gt;, &lt;Type.TIMESTAMP_NS: &#39;TIMESTAMP_NS&#39;&gt;, &lt;Type.DATE32: &#39;DATE32&#39;&gt;, &lt;Type.DATETIME: &#39;DATETIME&#39;&gt;, &lt;Type.TIMESTAMPLTZ: &#39;TIMESTAMPLTZ&#39;&gt;, &lt;Type.TIMESTAMPNTZ: &#39;TIMESTAMPNTZ&#39;&gt;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;, &lt;Type.TIMESTAMPTZ: &#39;TIMESTAMPTZ&#39;&gt;, &lt;Type.TIMESTAMP_MS: &#39;TIMESTAMP_MS&#39;&gt;, &lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DataType.TEMPORAL_TYPES-view-value"></label><span class="default_value">{&lt;Type.DATETIME: &#39;DATETIME&#39;&gt;, &lt;Type.DATETIME2: &#39;DATETIME2&#39;&gt;, &lt;Type.TIMESTAMP_S: &#39;TIMESTAMP_S&#39;&gt;, &lt;Type.DATETIME64: &#39;DATETIME64&#39;&gt;, &lt;Type.DATE32: &#39;DATE32&#39;&gt;, &lt;Type.TIMESTAMP: &#39;TIMESTAMP&#39;&gt;, &lt;Type.TIMESTAMPLTZ: &#39;TIMESTAMPLTZ&#39;&gt;, &lt;Type.DATE: &#39;DATE&#39;&gt;, &lt;Type.TIMESTAMPNTZ: &#39;TIMESTAMPNTZ&#39;&gt;, &lt;Type.TIMESTAMP_NS: &#39;TIMESTAMP_NS&#39;&gt;, &lt;Type.TIMESTAMPTZ: &#39;TIMESTAMPTZ&#39;&gt;, &lt;Type.TIME: &#39;TIME&#39;&gt;, &lt;Type.TIMESTAMP_MS: &#39;TIMESTAMP_MS&#39;&gt;, &lt;Type.SMALLDATETIME: &#39;SMALLDATETIME&#39;&gt;, &lt;Type.TIMETZ: &#39;TIMETZ&#39;&gt;}</span>
</div>
@ -82091,7 +82091,7 @@ name is set to the expression's class name transformed to snake case.</li>
</div>
<a class="headerlink" href="#StringToArray"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="StringToArray-5596"><a href="#StringToArray-5596"><span class="linenos">5596</span></a><span class="k">class</span><span class="w"> </span><span class="nc">StringToArray</span><span class="p">(</span><span class="n">Func</span><span class="p">):</span>
</span><span id="StringToArray-5597"><a href="#StringToArray-5597"><span class="linenos">5597</span></a> <span class="n">arg_types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;this&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;null&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
</span><span id="StringToArray-5597"><a href="#StringToArray-5597"><span class="linenos">5597</span></a> <span class="n">arg_types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;this&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;expression&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;null&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
</span><span id="StringToArray-5598"><a href="#StringToArray-5598"><span class="linenos">5598</span></a> <span class="n">_sql_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;STRING_TO_ARRAY&quot;</span><span class="p">,</span> <span class="s2">&quot;SPLIT_BY_STRING&quot;</span><span class="p">,</span> <span class="s2">&quot;STRTOK_TO_ARRAY&quot;</span><span class="p">]</span>
</span></pre></div>
@ -82101,7 +82101,7 @@ name is set to the expression's class name transformed to snake case.</li>
<div id="StringToArray.arg_types" class="classattr">
<div class="attr variable">
<span class="name">arg_types</span> =
<span class="default_value">{&#39;this&#39;: True, &#39;expression&#39;: True, &#39;null&#39;: False}</span>
<span class="default_value">{&#39;this&#39;: True, &#39;expression&#39;: False, &#39;null&#39;: False}</span>
</div>

View file

@ -12413,7 +12413,7 @@ Default: True</li>
<div class="attr variable">
<span class="name">SUPPORTED_JSON_PATH_PARTS</span> =
<input id="Generator.SUPPORTED_JSON_PATH_PARTS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Generator.SUPPORTED_JSON_PATH_PARTS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="Generator.SUPPORTED_JSON_PATH_PARTS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;}</span>
</div>
@ -12875,7 +12875,7 @@ Default: True</li>
<div id="Generator.PARAMETERIZABLE_TEXT_TYPES" class="classattr">
<div class="attr variable">
<span class="name">PARAMETERIZABLE_TEXT_TYPES</span> =
<span class="default_value">{&lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;, &lt;Type.NCHAR: &#39;NCHAR&#39;&gt;}</span>
<span class="default_value">{&lt;Type.NCHAR: &#39;NCHAR&#39;&gt;, &lt;Type.NVARCHAR: &#39;NVARCHAR&#39;&gt;, &lt;Type.VARCHAR: &#39;VARCHAR&#39;&gt;, &lt;Type.CHAR: &#39;CHAR&#39;&gt;}</span>
</div>

View file

@ -2003,7 +2003,7 @@ belong to some totally-ordered set.</p>
<section id="DATE_UNITS">
<div class="attr variable">
<span class="name">DATE_UNITS</span> =
<span class="default_value">{&#39;year&#39;, &#39;year_month&#39;, &#39;month&#39;, &#39;week&#39;, &#39;day&#39;, &#39;quarter&#39;}</span>
<span class="default_value">{&#39;month&#39;, &#39;year&#39;, &#39;week&#39;, &#39;day&#39;, &#39;quarter&#39;, &#39;year_month&#39;}</span>
</div>

View file

@ -641,7 +641,7 @@
<div class="attr variable">
<span class="name">ALL_JSON_PATH_PARTS</span> =
<input id="ALL_JSON_PATH_PARTS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="ALL_JSON_PATH_PARTS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="ALL_JSON_PATH_PARTS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="expressions.html#JSONPathFilter">sqlglot.expressions.JSONPathFilter</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathUnion">sqlglot.expressions.JSONPathUnion</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSelector">sqlglot.expressions.JSONPathSelector</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathKey">sqlglot.expressions.JSONPathKey</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathSlice">sqlglot.expressions.JSONPathSlice</a>&#39;&gt;}</span>
</div>

File diff suppressed because one or more lines are too long

View file

@ -581,7 +581,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;windows&#39;, &#39;limit&#39;, &#39;settings&#39;, &#39;cluster&#39;, &#39;offset&#39;, &#39;options&#39;, &#39;format&#39;, &#39;connect&#39;, &#39;locks&#39;, &#39;distinct&#39;, &#39;distribute&#39;, &#39;pivots&#39;, &#39;operation_modifiers&#39;, &#39;having&#39;, &#39;sample&#39;, &#39;kind&#39;, &#39;prewhere&#39;, &#39;sort&#39;, &#39;match&#39;, &#39;group&#39;, &#39;with&#39;, &#39;qualify&#39;, &#39;laterals&#39;, &#39;into&#39;}</span>
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;operation_modifiers&#39;, &#39;sort&#39;, &#39;offset&#39;, &#39;format&#39;, &#39;into&#39;, &#39;kind&#39;, &#39;prewhere&#39;, &#39;options&#39;, &#39;match&#39;, &#39;having&#39;, &#39;sample&#39;, &#39;pivots&#39;, &#39;settings&#39;, &#39;connect&#39;, &#39;qualify&#39;, &#39;group&#39;, &#39;distribute&#39;, &#39;locks&#39;, &#39;cluster&#39;, &#39;with&#39;, &#39;distinct&#39;, &#39;windows&#39;, &#39;laterals&#39;, &#39;limit&#39;}</span>
</div>

View file

@ -1008,147 +1008,150 @@
</span><span id="L-758"><a href="#L-758"><span class="linenos">758</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">this</span> <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-759"><a href="#L-759"><span class="linenos">759</span></a> <span class="k">continue</span>
</span><span id="L-760"><a href="#L-760"><span class="linenos">760</span></a>
</span><span id="L-761"><a href="#L-761"><span class="linenos">761</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span>
</span><span id="L-762"><a href="#L-762"><span class="linenos">762</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-763"><a href="#L-763"><span class="linenos">763</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-764"><a href="#L-764"><span class="linenos">764</span></a> <span class="n">lateral_sources</span><span class="o">=</span><span class="n">lateral_sources</span><span class="p">,</span>
</span><span id="L-765"><a href="#L-765"><span class="linenos">765</span></a> <span class="n">outer_columns</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">alias_column_names</span><span class="p">,</span>
</span><span id="L-766"><a href="#L-766"><span class="linenos">766</span></a> <span class="n">scope_type</span><span class="o">=</span><span class="n">scope_type</span><span class="p">,</span>
</span><span id="L-767"><a href="#L-767"><span class="linenos">767</span></a> <span class="p">)</span>
</span><span id="L-768"><a href="#L-768"><span class="linenos">768</span></a> <span class="p">):</span>
</span><span id="L-769"><a href="#L-769"><span class="linenos">769</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-770"><a href="#L-770"><span class="linenos">770</span></a>
</span><span id="L-771"><a href="#L-771"><span class="linenos">771</span></a> <span class="c1"># Tables without aliases will be set as &quot;&quot;</span>
</span><span id="L-772"><a href="#L-772"><span class="linenos">772</span></a> <span class="c1"># This shouldn&#39;t be a problem once qualify_columns runs, as it adds aliases on everything.</span>
</span><span id="L-773"><a href="#L-773"><span class="linenos">773</span></a> <span class="c1"># Until then, this means that only a single, unaliased derived table is allowed (rather,</span>
</span><span id="L-774"><a href="#L-774"><span class="linenos">774</span></a> <span class="c1"># the latest one wins.</span>
</span><span id="L-775"><a href="#L-775"><span class="linenos">775</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">expression</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-776"><a href="#L-776"><span class="linenos">776</span></a>
</span><span id="L-777"><a href="#L-777"><span class="linenos">777</span></a> <span class="c1"># append the final child_scope yielded</span>
</span><span id="L-778"><a href="#L-778"><span class="linenos">778</span></a> <span class="n">scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">child_scope</span><span class="p">)</span>
</span><span id="L-779"><a href="#L-779"><span class="linenos">779</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">table_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">child_scope</span><span class="p">)</span>
</span><span id="L-780"><a href="#L-780"><span class="linenos">780</span></a>
</span><span id="L-781"><a href="#L-781"><span class="linenos">781</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">sources</span><span class="p">)</span>
</span><span id="L-782"><a href="#L-782"><span class="linenos">782</span></a>
</span><span id="L-761"><a href="#L-761"><span class="linenos">761</span></a> <span class="n">child_scope</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-762"><a href="#L-762"><span class="linenos">762</span></a>
</span><span id="L-763"><a href="#L-763"><span class="linenos">763</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span>
</span><span id="L-764"><a href="#L-764"><span class="linenos">764</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-765"><a href="#L-765"><span class="linenos">765</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-766"><a href="#L-766"><span class="linenos">766</span></a> <span class="n">lateral_sources</span><span class="o">=</span><span class="n">lateral_sources</span><span class="p">,</span>
</span><span id="L-767"><a href="#L-767"><span class="linenos">767</span></a> <span class="n">outer_columns</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">alias_column_names</span><span class="p">,</span>
</span><span id="L-768"><a href="#L-768"><span class="linenos">768</span></a> <span class="n">scope_type</span><span class="o">=</span><span class="n">scope_type</span><span class="p">,</span>
</span><span id="L-769"><a href="#L-769"><span class="linenos">769</span></a> <span class="p">)</span>
</span><span id="L-770"><a href="#L-770"><span class="linenos">770</span></a> <span class="p">):</span>
</span><span id="L-771"><a href="#L-771"><span class="linenos">771</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-772"><a href="#L-772"><span class="linenos">772</span></a>
</span><span id="L-773"><a href="#L-773"><span class="linenos">773</span></a> <span class="c1"># Tables without aliases will be set as &quot;&quot;</span>
</span><span id="L-774"><a href="#L-774"><span class="linenos">774</span></a> <span class="c1"># This shouldn&#39;t be a problem once qualify_columns runs, as it adds aliases on everything.</span>
</span><span id="L-775"><a href="#L-775"><span class="linenos">775</span></a> <span class="c1"># Until then, this means that only a single, unaliased derived table is allowed (rather,</span>
</span><span id="L-776"><a href="#L-776"><span class="linenos">776</span></a> <span class="c1"># the latest one wins.</span>
</span><span id="L-777"><a href="#L-777"><span class="linenos">777</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">expression</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-778"><a href="#L-778"><span class="linenos">778</span></a>
</span><span id="L-779"><a href="#L-779"><span class="linenos">779</span></a> <span class="c1"># append the final child_scope yielded</span>
</span><span id="L-780"><a href="#L-780"><span class="linenos">780</span></a> <span class="k">if</span> <span class="n">child_scope</span><span class="p">:</span>
</span><span id="L-781"><a href="#L-781"><span class="linenos">781</span></a> <span class="n">scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">child_scope</span><span class="p">)</span>
</span><span id="L-782"><a href="#L-782"><span class="linenos">782</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">table_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">child_scope</span><span class="p">)</span>
</span><span id="L-783"><a href="#L-783"><span class="linenos">783</span></a>
</span><span id="L-784"><a href="#L-784"><span class="linenos">784</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_traverse_subqueries</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-785"><a href="#L-785"><span class="linenos">785</span></a> <span class="k">for</span> <span class="n">subquery</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">subqueries</span><span class="p">:</span>
</span><span id="L-786"><a href="#L-786"><span class="linenos">786</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-787"><a href="#L-787"><span class="linenos">787</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span><span class="n">subquery</span><span class="p">,</span> <span class="n">scope_type</span><span class="o">=</span><span class="n">ScopeType</span><span class="o">.</span><span class="n">SUBQUERY</span><span class="p">)):</span>
</span><span id="L-788"><a href="#L-788"><span class="linenos">788</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-789"><a href="#L-789"><span class="linenos">789</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-790"><a href="#L-790"><span class="linenos">790</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">top</span><span class="p">)</span>
</span><span id="L-791"><a href="#L-791"><span class="linenos">791</span></a>
</span><span id="L-792"><a href="#L-792"><span class="linenos">792</span></a>
</span><span id="L-793"><a href="#L-793"><span class="linenos">793</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_traverse_udtfs</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-794"><a href="#L-794"><span class="linenos">794</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</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">Unnest</span><span class="p">):</span>
</span><span id="L-795"><a href="#L-795"><span class="linenos">795</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span>
</span><span id="L-796"><a href="#L-796"><span class="linenos">796</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</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">Lateral</span><span class="p">):</span>
</span><span id="L-797"><a href="#L-797"><span class="linenos">797</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">]</span>
</span><span id="L-798"><a href="#L-798"><span class="linenos">798</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-799"><a href="#L-799"><span class="linenos">799</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-800"><a href="#L-800"><span class="linenos">800</span></a>
</span><span id="L-801"><a href="#L-801"><span class="linenos">801</span></a> <span class="n">sources</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-802"><a href="#L-802"><span class="linenos">802</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">expressions</span><span class="p">:</span>
</span><span id="L-803"><a href="#L-803"><span class="linenos">803</span></a> <span class="k">if</span> <span class="n">_is_derived_table</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-804"><a href="#L-804"><span class="linenos">804</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-805"><a href="#L-805"><span class="linenos">805</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span>
</span><span id="L-806"><a href="#L-806"><span class="linenos">806</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-807"><a href="#L-807"><span class="linenos">807</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-808"><a href="#L-808"><span class="linenos">808</span></a> <span class="n">scope_type</span><span class="o">=</span><span class="n">ScopeType</span><span class="o">.</span><span class="n">SUBQUERY</span><span class="p">,</span>
</span><span id="L-809"><a href="#L-809"><span class="linenos">809</span></a> <span class="n">outer_columns</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">alias_column_names</span><span class="p">,</span>
</span><span id="L-810"><a href="#L-810"><span class="linenos">810</span></a> <span class="p">)</span>
</span><span id="L-811"><a href="#L-811"><span class="linenos">811</span></a> <span class="p">):</span>
</span><span id="L-812"><a href="#L-812"><span class="linenos">812</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-813"><a href="#L-813"><span class="linenos">813</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-814"><a href="#L-814"><span class="linenos">814</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">expression</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-815"><a href="#L-815"><span class="linenos">815</span></a>
</span><span id="L-816"><a href="#L-816"><span class="linenos">816</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">top</span><span class="p">)</span>
</span><span id="L-817"><a href="#L-817"><span class="linenos">817</span></a>
</span><span id="L-818"><a href="#L-818"><span class="linenos">818</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">sources</span><span class="p">)</span>
</span><span id="L-819"><a href="#L-819"><span class="linenos">819</span></a>
</span><span id="L-784"><a href="#L-784"><span class="linenos">784</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">sources</span><span class="p">)</span>
</span><span id="L-785"><a href="#L-785"><span class="linenos">785</span></a>
</span><span id="L-786"><a href="#L-786"><span class="linenos">786</span></a>
</span><span id="L-787"><a href="#L-787"><span class="linenos">787</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_traverse_subqueries</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-788"><a href="#L-788"><span class="linenos">788</span></a> <span class="k">for</span> <span class="n">subquery</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">subqueries</span><span class="p">:</span>
</span><span id="L-789"><a href="#L-789"><span class="linenos">789</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-790"><a href="#L-790"><span class="linenos">790</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span><span class="n">subquery</span><span class="p">,</span> <span class="n">scope_type</span><span class="o">=</span><span class="n">ScopeType</span><span class="o">.</span><span class="n">SUBQUERY</span><span class="p">)):</span>
</span><span id="L-791"><a href="#L-791"><span class="linenos">791</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-792"><a href="#L-792"><span class="linenos">792</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-793"><a href="#L-793"><span class="linenos">793</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">top</span><span class="p">)</span>
</span><span id="L-794"><a href="#L-794"><span class="linenos">794</span></a>
</span><span id="L-795"><a href="#L-795"><span class="linenos">795</span></a>
</span><span id="L-796"><a href="#L-796"><span class="linenos">796</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_traverse_udtfs</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-797"><a href="#L-797"><span class="linenos">797</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</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">Unnest</span><span class="p">):</span>
</span><span id="L-798"><a href="#L-798"><span class="linenos">798</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span>
</span><span id="L-799"><a href="#L-799"><span class="linenos">799</span></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</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">Lateral</span><span class="p">):</span>
</span><span id="L-800"><a href="#L-800"><span class="linenos">800</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">]</span>
</span><span id="L-801"><a href="#L-801"><span class="linenos">801</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-802"><a href="#L-802"><span class="linenos">802</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-803"><a href="#L-803"><span class="linenos">803</span></a>
</span><span id="L-804"><a href="#L-804"><span class="linenos">804</span></a> <span class="n">sources</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-805"><a href="#L-805"><span class="linenos">805</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">expressions</span><span class="p">:</span>
</span><span id="L-806"><a href="#L-806"><span class="linenos">806</span></a> <span class="k">if</span> <span class="n">_is_derived_table</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-807"><a href="#L-807"><span class="linenos">807</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-808"><a href="#L-808"><span class="linenos">808</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">_traverse_scope</span><span class="p">(</span>
</span><span id="L-809"><a href="#L-809"><span class="linenos">809</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-810"><a href="#L-810"><span class="linenos">810</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-811"><a href="#L-811"><span class="linenos">811</span></a> <span class="n">scope_type</span><span class="o">=</span><span class="n">ScopeType</span><span class="o">.</span><span class="n">SUBQUERY</span><span class="p">,</span>
</span><span id="L-812"><a href="#L-812"><span class="linenos">812</span></a> <span class="n">outer_columns</span><span class="o">=</span><span class="n">expression</span><span class="o">.</span><span class="n">alias_column_names</span><span class="p">,</span>
</span><span id="L-813"><a href="#L-813"><span class="linenos">813</span></a> <span class="p">)</span>
</span><span id="L-814"><a href="#L-814"><span class="linenos">814</span></a> <span class="p">):</span>
</span><span id="L-815"><a href="#L-815"><span class="linenos">815</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-816"><a href="#L-816"><span class="linenos">816</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-817"><a href="#L-817"><span class="linenos">817</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">expression</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-818"><a href="#L-818"><span class="linenos">818</span></a>
</span><span id="L-819"><a href="#L-819"><span class="linenos">819</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">top</span><span class="p">)</span>
</span><span id="L-820"><a href="#L-820"><span class="linenos">820</span></a>
</span><span id="L-821"><a href="#L-821"><span class="linenos">821</span></a><span class="k">def</span><span class="w"> </span><span class="nf">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="L-822"><a href="#L-822"><span class="linenos">822</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-823"><a href="#L-823"><span class="linenos">823</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="L-824"><a href="#L-824"><span class="linenos">824</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="L-825"><a href="#L-825"><span class="linenos">825</span></a>
</span><span id="L-826"><a href="#L-826"><span class="linenos">826</span></a><span class="sd"> Args:</span>
</span><span id="L-827"><a href="#L-827"><span class="linenos">827</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-828"><a href="#L-828"><span class="linenos">828</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="L-829"><a href="#L-829"><span class="linenos">829</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="L-830"><a href="#L-830"><span class="linenos">830</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="L-831"><a href="#L-831"><span class="linenos">831</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="L-832"><a href="#L-832"><span class="linenos">832</span></a>
</span><span id="L-833"><a href="#L-833"><span class="linenos">833</span></a><span class="sd"> Yields:</span>
</span><span id="L-834"><a href="#L-834"><span class="linenos">834</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="L-835"><a href="#L-835"><span class="linenos">835</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-836"><a href="#L-836"><span class="linenos">836</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="L-837"><a href="#L-837"><span class="linenos">837</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="L-838"><a href="#L-838"><span class="linenos">838</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-839"><a href="#L-839"><span class="linenos">839</span></a>
</span><span id="L-840"><a href="#L-840"><span class="linenos">840</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span>
</span><span id="L-841"><a href="#L-841"><span class="linenos">841</span></a> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">crossed_scope_boundary</span> <span class="ow">or</span> <span class="p">(</span><span class="n">prune</span> <span class="ow">and</span> <span class="n">prune</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
</span><span id="L-842"><a href="#L-842"><span class="linenos">842</span></a> <span class="p">):</span>
</span><span id="L-843"><a href="#L-843"><span class="linenos">843</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-844"><a href="#L-844"><span class="linenos">844</span></a>
</span><span id="L-845"><a href="#L-845"><span class="linenos">845</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="L-846"><a href="#L-846"><span class="linenos">846</span></a>
</span><span id="L-847"><a href="#L-847"><span class="linenos">847</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="L-848"><a href="#L-848"><span class="linenos">848</span></a> <span class="k">continue</span>
</span><span id="L-849"><a href="#L-849"><span class="linenos">849</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-850"><a href="#L-850"><span class="linenos">850</span></a> <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">CTE</span><span class="p">)</span>
</span><span id="L-851"><a href="#L-851"><span class="linenos">851</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-852"><a href="#L-852"><span class="linenos">852</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</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-853"><a href="#L-853"><span class="linenos">853</span></a> <span class="ow">and</span> <span class="p">(</span><span class="n">_is_derived_table</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> <span class="ow">or</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">UDTF</span><span class="p">))</span>
</span><span id="L-854"><a href="#L-854"><span class="linenos">854</span></a> <span class="p">)</span>
</span><span id="L-855"><a href="#L-855"><span class="linenos">855</span></a> <span class="ow">or</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">UNWRAPPED_QUERIES</span><span class="p">)</span>
</span><span id="L-856"><a href="#L-856"><span class="linenos">856</span></a> <span class="p">):</span>
</span><span id="L-857"><a href="#L-857"><span class="linenos">857</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-858"><a href="#L-858"><span class="linenos">858</span></a>
</span><span id="L-859"><a href="#L-859"><span class="linenos">859</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="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">UDTF</span><span class="p">)):</span>
</span><span id="L-860"><a href="#L-860"><span class="linenos">860</span></a> <span class="c1"># The following args are not actually in the inner scope, so we should visit them</span>
</span><span id="L-861"><a href="#L-861"><span class="linenos">861</span></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="s2">&quot;laterals&quot;</span><span class="p">,</span> <span class="s2">&quot;pivots&quot;</span><span class="p">):</span>
</span><span id="L-862"><a href="#L-862"><span class="linenos">862</span></a> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="L-863"><a href="#L-863"><span class="linenos">863</span></a> <span class="k">yield from</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">)</span>
</span><span id="L-864"><a href="#L-864"><span class="linenos">864</span></a>
</span><span id="L-865"><a href="#L-865"><span class="linenos">865</span></a>
</span><span id="L-866"><a href="#L-866"><span class="linenos">866</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-867"><a href="#L-867"><span class="linenos">867</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-868"><a href="#L-868"><span class="linenos">868</span></a><span class="sd"> Returns a generator object which visits all nodes in this scope and only yields those that</span>
</span><span id="L-869"><a href="#L-869"><span class="linenos">869</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="L-870"><a href="#L-870"><span class="linenos">870</span></a>
</span><span id="L-871"><a href="#L-871"><span class="linenos">871</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-872"><a href="#L-872"><span class="linenos">872</span></a>
</span><span id="L-873"><a href="#L-873"><span class="linenos">873</span></a><span class="sd"> Args:</span>
</span><span id="L-874"><a href="#L-874"><span class="linenos">874</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-875"><a href="#L-875"><span class="linenos">875</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-876"><a href="#L-876"><span class="linenos">876</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-877"><a href="#L-877"><span class="linenos">877</span></a>
</span><span id="L-878"><a href="#L-878"><span class="linenos">878</span></a><span class="sd"> Yields:</span>
</span><span id="L-879"><a href="#L-879"><span class="linenos">879</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="L-880"><a href="#L-880"><span class="linenos">880</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-881"><a href="#L-881"><span class="linenos">881</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">):</span>
</span><span id="L-882"><a href="#L-882"><span class="linenos">882</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">ensure_collection</span><span class="p">(</span><span class="n">expression_types</span><span class="p">))):</span>
</span><span id="L-883"><a href="#L-883"><span class="linenos">883</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span><span id="L-884"><a href="#L-884"><span class="linenos">884</span></a>
</span><span id="L-885"><a href="#L-885"><span class="linenos">885</span></a>
</span><span id="L-886"><a href="#L-886"><span class="linenos">886</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-887"><a href="#L-887"><span class="linenos">887</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-888"><a href="#L-888"><span class="linenos">888</span></a><span class="sd"> Returns the first node in this scope which matches at least one of the specified types.</span>
</span><span id="L-889"><a href="#L-889"><span class="linenos">889</span></a>
</span><span id="L-890"><a href="#L-890"><span class="linenos">890</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-891"><a href="#L-891"><span class="linenos">891</span></a>
</span><span id="L-892"><a href="#L-892"><span class="linenos">892</span></a><span class="sd"> Args:</span>
</span><span id="L-893"><a href="#L-893"><span class="linenos">893</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-894"><a href="#L-894"><span class="linenos">894</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-895"><a href="#L-895"><span class="linenos">895</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-896"><a href="#L-896"><span class="linenos">896</span></a>
</span><span id="L-897"><a href="#L-897"><span class="linenos">897</span></a><span class="sd"> Returns:</span>
</span><span id="L-898"><a href="#L-898"><span class="linenos">898</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="L-899"><a href="#L-899"><span class="linenos">899</span></a><span class="sd"> the criteria was found.</span>
</span><span id="L-900"><a href="#L-900"><span class="linenos">900</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-901"><a href="#L-901"><span class="linenos">901</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>
</span><span id="L-821"><a href="#L-821"><span class="linenos">821</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">sources</span><span class="p">)</span>
</span><span id="L-822"><a href="#L-822"><span class="linenos">822</span></a>
</span><span id="L-823"><a href="#L-823"><span class="linenos">823</span></a>
</span><span id="L-824"><a href="#L-824"><span class="linenos">824</span></a><span class="k">def</span><span class="w"> </span><span class="nf">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="L-825"><a href="#L-825"><span class="linenos">825</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-826"><a href="#L-826"><span class="linenos">826</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="L-827"><a href="#L-827"><span class="linenos">827</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="L-828"><a href="#L-828"><span class="linenos">828</span></a>
</span><span id="L-829"><a href="#L-829"><span class="linenos">829</span></a><span class="sd"> Args:</span>
</span><span id="L-830"><a href="#L-830"><span class="linenos">830</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-831"><a href="#L-831"><span class="linenos">831</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="L-832"><a href="#L-832"><span class="linenos">832</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="L-833"><a href="#L-833"><span class="linenos">833</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="L-834"><a href="#L-834"><span class="linenos">834</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="L-835"><a href="#L-835"><span class="linenos">835</span></a>
</span><span id="L-836"><a href="#L-836"><span class="linenos">836</span></a><span class="sd"> Yields:</span>
</span><span id="L-837"><a href="#L-837"><span class="linenos">837</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="L-838"><a href="#L-838"><span class="linenos">838</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-839"><a href="#L-839"><span class="linenos">839</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="L-840"><a href="#L-840"><span class="linenos">840</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="L-841"><a href="#L-841"><span class="linenos">841</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-842"><a href="#L-842"><span class="linenos">842</span></a>
</span><span id="L-843"><a href="#L-843"><span class="linenos">843</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span>
</span><span id="L-844"><a href="#L-844"><span class="linenos">844</span></a> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">crossed_scope_boundary</span> <span class="ow">or</span> <span class="p">(</span><span class="n">prune</span> <span class="ow">and</span> <span class="n">prune</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
</span><span id="L-845"><a href="#L-845"><span class="linenos">845</span></a> <span class="p">):</span>
</span><span id="L-846"><a href="#L-846"><span class="linenos">846</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-847"><a href="#L-847"><span class="linenos">847</span></a>
</span><span id="L-848"><a href="#L-848"><span class="linenos">848</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="L-849"><a href="#L-849"><span class="linenos">849</span></a>
</span><span id="L-850"><a href="#L-850"><span class="linenos">850</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="L-851"><a href="#L-851"><span class="linenos">851</span></a> <span class="k">continue</span>
</span><span id="L-852"><a href="#L-852"><span class="linenos">852</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-853"><a href="#L-853"><span class="linenos">853</span></a> <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">CTE</span><span class="p">)</span>
</span><span id="L-854"><a href="#L-854"><span class="linenos">854</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-855"><a href="#L-855"><span class="linenos">855</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</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-856"><a href="#L-856"><span class="linenos">856</span></a> <span class="ow">and</span> <span class="p">(</span><span class="n">_is_derived_table</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> <span class="ow">or</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">UDTF</span><span class="p">))</span>
</span><span id="L-857"><a href="#L-857"><span class="linenos">857</span></a> <span class="p">)</span>
</span><span id="L-858"><a href="#L-858"><span class="linenos">858</span></a> <span class="ow">or</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">UNWRAPPED_QUERIES</span><span class="p">)</span>
</span><span id="L-859"><a href="#L-859"><span class="linenos">859</span></a> <span class="p">):</span>
</span><span id="L-860"><a href="#L-860"><span class="linenos">860</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-861"><a href="#L-861"><span class="linenos">861</span></a>
</span><span id="L-862"><a href="#L-862"><span class="linenos">862</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="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">UDTF</span><span class="p">)):</span>
</span><span id="L-863"><a href="#L-863"><span class="linenos">863</span></a> <span class="c1"># The following args are not actually in the inner scope, so we should visit them</span>
</span><span id="L-864"><a href="#L-864"><span class="linenos">864</span></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="s2">&quot;laterals&quot;</span><span class="p">,</span> <span class="s2">&quot;pivots&quot;</span><span class="p">):</span>
</span><span id="L-865"><a href="#L-865"><span class="linenos">865</span></a> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="L-866"><a href="#L-866"><span class="linenos">866</span></a> <span class="k">yield from</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">)</span>
</span><span id="L-867"><a href="#L-867"><span class="linenos">867</span></a>
</span><span id="L-868"><a href="#L-868"><span class="linenos">868</span></a>
</span><span id="L-869"><a href="#L-869"><span class="linenos">869</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-870"><a href="#L-870"><span class="linenos">870</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-871"><a href="#L-871"><span class="linenos">871</span></a><span class="sd"> Returns a generator object which visits all nodes in this scope and only yields those that</span>
</span><span id="L-872"><a href="#L-872"><span class="linenos">872</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="L-873"><a href="#L-873"><span class="linenos">873</span></a>
</span><span id="L-874"><a href="#L-874"><span class="linenos">874</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-875"><a href="#L-875"><span class="linenos">875</span></a>
</span><span id="L-876"><a href="#L-876"><span class="linenos">876</span></a><span class="sd"> Args:</span>
</span><span id="L-877"><a href="#L-877"><span class="linenos">877</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-878"><a href="#L-878"><span class="linenos">878</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-879"><a href="#L-879"><span class="linenos">879</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-880"><a href="#L-880"><span class="linenos">880</span></a>
</span><span id="L-881"><a href="#L-881"><span class="linenos">881</span></a><span class="sd"> Yields:</span>
</span><span id="L-882"><a href="#L-882"><span class="linenos">882</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="L-883"><a href="#L-883"><span class="linenos">883</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-884"><a href="#L-884"><span class="linenos">884</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">):</span>
</span><span id="L-885"><a href="#L-885"><span class="linenos">885</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">ensure_collection</span><span class="p">(</span><span class="n">expression_types</span><span class="p">))):</span>
</span><span id="L-886"><a href="#L-886"><span class="linenos">886</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span><span id="L-887"><a href="#L-887"><span class="linenos">887</span></a>
</span><span id="L-888"><a href="#L-888"><span class="linenos">888</span></a>
</span><span id="L-889"><a href="#L-889"><span class="linenos">889</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-890"><a href="#L-890"><span class="linenos">890</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-891"><a href="#L-891"><span class="linenos">891</span></a><span class="sd"> Returns the first node in this scope which matches at least one of the specified types.</span>
</span><span id="L-892"><a href="#L-892"><span class="linenos">892</span></a>
</span><span id="L-893"><a href="#L-893"><span class="linenos">893</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-894"><a href="#L-894"><span class="linenos">894</span></a>
</span><span id="L-895"><a href="#L-895"><span class="linenos">895</span></a><span class="sd"> Args:</span>
</span><span id="L-896"><a href="#L-896"><span class="linenos">896</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-897"><a href="#L-897"><span class="linenos">897</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-898"><a href="#L-898"><span class="linenos">898</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-899"><a href="#L-899"><span class="linenos">899</span></a>
</span><span id="L-900"><a href="#L-900"><span class="linenos">900</span></a><span class="sd"> Returns:</span>
</span><span id="L-901"><a href="#L-901"><span class="linenos">901</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="L-902"><a href="#L-902"><span class="linenos">902</span></a><span class="sd"> the criteria was found.</span>
</span><span id="L-903"><a href="#L-903"><span class="linenos">903</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-904"><a href="#L-904"><span class="linenos">904</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>
</span></pre></div>
@ -3176,49 +3179,49 @@ incomplete properties which is confusing.</p>
</div>
<a class="headerlink" href="#walk_in_scope"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="walk_in_scope-822"><a href="#walk_in_scope-822"><span class="linenos">822</span></a><span class="k">def</span><span class="w"> </span><span class="nf">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="walk_in_scope-823"><a href="#walk_in_scope-823"><span class="linenos">823</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="walk_in_scope-824"><a href="#walk_in_scope-824"><span class="linenos">824</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="walk_in_scope-825"><a href="#walk_in_scope-825"><span class="linenos">825</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="walk_in_scope-826"><a href="#walk_in_scope-826"><span class="linenos">826</span></a>
</span><span id="walk_in_scope-827"><a href="#walk_in_scope-827"><span class="linenos">827</span></a><span class="sd"> Args:</span>
</span><span id="walk_in_scope-828"><a href="#walk_in_scope-828"><span class="linenos">828</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="walk_in_scope-829"><a href="#walk_in_scope-829"><span class="linenos">829</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="walk_in_scope-830"><a href="#walk_in_scope-830"><span class="linenos">830</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="walk_in_scope-831"><a href="#walk_in_scope-831"><span class="linenos">831</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="walk_in_scope-832"><a href="#walk_in_scope-832"><span class="linenos">832</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="walk_in_scope-833"><a href="#walk_in_scope-833"><span class="linenos">833</span></a>
</span><span id="walk_in_scope-834"><a href="#walk_in_scope-834"><span class="linenos">834</span></a><span class="sd"> Yields:</span>
</span><span id="walk_in_scope-835"><a href="#walk_in_scope-835"><span class="linenos">835</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="walk_in_scope-836"><a href="#walk_in_scope-836"><span class="linenos">836</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="walk_in_scope-837"><a href="#walk_in_scope-837"><span class="linenos">837</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="walk_in_scope-838"><a href="#walk_in_scope-838"><span class="linenos">838</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="walk_in_scope-839"><a href="#walk_in_scope-839"><span class="linenos">839</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-840"><a href="#walk_in_scope-840"><span class="linenos">840</span></a>
</span><span id="walk_in_scope-841"><a href="#walk_in_scope-841"><span class="linenos">841</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span>
</span><span id="walk_in_scope-842"><a href="#walk_in_scope-842"><span class="linenos">842</span></a> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">crossed_scope_boundary</span> <span class="ow">or</span> <span class="p">(</span><span class="n">prune</span> <span class="ow">and</span> <span class="n">prune</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
</span><span id="walk_in_scope-843"><a href="#walk_in_scope-843"><span class="linenos">843</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-844"><a href="#walk_in_scope-844"><span class="linenos">844</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-845"><a href="#walk_in_scope-845"><span class="linenos">845</span></a>
</span><span id="walk_in_scope-846"><a href="#walk_in_scope-846"><span class="linenos">846</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="walk_in_scope-847"><a href="#walk_in_scope-847"><span class="linenos">847</span></a>
</span><span id="walk_in_scope-848"><a href="#walk_in_scope-848"><span class="linenos">848</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="walk_in_scope-849"><a href="#walk_in_scope-849"><span class="linenos">849</span></a> <span class="k">continue</span>
</span><span id="walk_in_scope-850"><a href="#walk_in_scope-850"><span class="linenos">850</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="walk_in_scope-851"><a href="#walk_in_scope-851"><span class="linenos">851</span></a> <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">CTE</span><span class="p">)</span>
</span><span id="walk_in_scope-852"><a href="#walk_in_scope-852"><span class="linenos">852</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="walk_in_scope-853"><a href="#walk_in_scope-853"><span class="linenos">853</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</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="walk_in_scope-854"><a href="#walk_in_scope-854"><span class="linenos">854</span></a> <span class="ow">and</span> <span class="p">(</span><span class="n">_is_derived_table</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> <span class="ow">or</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">UDTF</span><span class="p">))</span>
</span><span id="walk_in_scope-855"><a href="#walk_in_scope-855"><span class="linenos">855</span></a> <span class="p">)</span>
</span><span id="walk_in_scope-856"><a href="#walk_in_scope-856"><span class="linenos">856</span></a> <span class="ow">or</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">UNWRAPPED_QUERIES</span><span class="p">)</span>
</span><span id="walk_in_scope-857"><a href="#walk_in_scope-857"><span class="linenos">857</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-858"><a href="#walk_in_scope-858"><span class="linenos">858</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="walk_in_scope-859"><a href="#walk_in_scope-859"><span class="linenos">859</span></a>
</span><span id="walk_in_scope-860"><a href="#walk_in_scope-860"><span class="linenos">860</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="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">UDTF</span><span class="p">)):</span>
</span><span id="walk_in_scope-861"><a href="#walk_in_scope-861"><span class="linenos">861</span></a> <span class="c1"># The following args are not actually in the inner scope, so we should visit them</span>
</span><span id="walk_in_scope-862"><a href="#walk_in_scope-862"><span class="linenos">862</span></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="s2">&quot;laterals&quot;</span><span class="p">,</span> <span class="s2">&quot;pivots&quot;</span><span class="p">):</span>
</span><span id="walk_in_scope-863"><a href="#walk_in_scope-863"><span class="linenos">863</span></a> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="walk_in_scope-864"><a href="#walk_in_scope-864"><span class="linenos">864</span></a> <span class="k">yield from</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="walk_in_scope-825"><a href="#walk_in_scope-825"><span class="linenos">825</span></a><span class="k">def</span><span class="w"> </span><span class="nf">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span><span id="walk_in_scope-826"><a href="#walk_in_scope-826"><span class="linenos">826</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="walk_in_scope-827"><a href="#walk_in_scope-827"><span class="linenos">827</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="walk_in_scope-828"><a href="#walk_in_scope-828"><span class="linenos">828</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="walk_in_scope-829"><a href="#walk_in_scope-829"><span class="linenos">829</span></a>
</span><span id="walk_in_scope-830"><a href="#walk_in_scope-830"><span class="linenos">830</span></a><span class="sd"> Args:</span>
</span><span id="walk_in_scope-831"><a href="#walk_in_scope-831"><span class="linenos">831</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="walk_in_scope-832"><a href="#walk_in_scope-832"><span class="linenos">832</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="walk_in_scope-833"><a href="#walk_in_scope-833"><span class="linenos">833</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="walk_in_scope-834"><a href="#walk_in_scope-834"><span class="linenos">834</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="walk_in_scope-835"><a href="#walk_in_scope-835"><span class="linenos">835</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="walk_in_scope-836"><a href="#walk_in_scope-836"><span class="linenos">836</span></a>
</span><span id="walk_in_scope-837"><a href="#walk_in_scope-837"><span class="linenos">837</span></a><span class="sd"> Yields:</span>
</span><span id="walk_in_scope-838"><a href="#walk_in_scope-838"><span class="linenos">838</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="walk_in_scope-839"><a href="#walk_in_scope-839"><span class="linenos">839</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="walk_in_scope-840"><a href="#walk_in_scope-840"><span class="linenos">840</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="walk_in_scope-841"><a href="#walk_in_scope-841"><span class="linenos">841</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="walk_in_scope-842"><a href="#walk_in_scope-842"><span class="linenos">842</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-843"><a href="#walk_in_scope-843"><span class="linenos">843</span></a>
</span><span id="walk_in_scope-844"><a href="#walk_in_scope-844"><span class="linenos">844</span></a> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span>
</span><span id="walk_in_scope-845"><a href="#walk_in_scope-845"><span class="linenos">845</span></a> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">,</span> <span class="n">prune</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">crossed_scope_boundary</span> <span class="ow">or</span> <span class="p">(</span><span class="n">prune</span> <span class="ow">and</span> <span class="n">prune</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>
</span><span id="walk_in_scope-846"><a href="#walk_in_scope-846"><span class="linenos">846</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-847"><a href="#walk_in_scope-847"><span class="linenos">847</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-848"><a href="#walk_in_scope-848"><span class="linenos">848</span></a>
</span><span id="walk_in_scope-849"><a href="#walk_in_scope-849"><span class="linenos">849</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="walk_in_scope-850"><a href="#walk_in_scope-850"><span class="linenos">850</span></a>
</span><span id="walk_in_scope-851"><a href="#walk_in_scope-851"><span class="linenos">851</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">expression</span><span class="p">:</span>
</span><span id="walk_in_scope-852"><a href="#walk_in_scope-852"><span class="linenos">852</span></a> <span class="k">continue</span>
</span><span id="walk_in_scope-853"><a href="#walk_in_scope-853"><span class="linenos">853</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="walk_in_scope-854"><a href="#walk_in_scope-854"><span class="linenos">854</span></a> <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">CTE</span><span class="p">)</span>
</span><span id="walk_in_scope-855"><a href="#walk_in_scope-855"><span class="linenos">855</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="walk_in_scope-856"><a href="#walk_in_scope-856"><span class="linenos">856</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</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="walk_in_scope-857"><a href="#walk_in_scope-857"><span class="linenos">857</span></a> <span class="ow">and</span> <span class="p">(</span><span class="n">_is_derived_table</span><span class="p">(</span><span class="n">node</span><span class="p">)</span> <span class="ow">or</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">UDTF</span><span class="p">))</span>
</span><span id="walk_in_scope-858"><a href="#walk_in_scope-858"><span class="linenos">858</span></a> <span class="p">)</span>
</span><span id="walk_in_scope-859"><a href="#walk_in_scope-859"><span class="linenos">859</span></a> <span class="ow">or</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">UNWRAPPED_QUERIES</span><span class="p">)</span>
</span><span id="walk_in_scope-860"><a href="#walk_in_scope-860"><span class="linenos">860</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-861"><a href="#walk_in_scope-861"><span class="linenos">861</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="walk_in_scope-862"><a href="#walk_in_scope-862"><span class="linenos">862</span></a>
</span><span id="walk_in_scope-863"><a href="#walk_in_scope-863"><span class="linenos">863</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="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">UDTF</span><span class="p">)):</span>
</span><span id="walk_in_scope-864"><a href="#walk_in_scope-864"><span class="linenos">864</span></a> <span class="c1"># The following args are not actually in the inner scope, so we should visit them</span>
</span><span id="walk_in_scope-865"><a href="#walk_in_scope-865"><span class="linenos">865</span></a> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="s2">&quot;laterals&quot;</span><span class="p">,</span> <span class="s2">&quot;pivots&quot;</span><span class="p">):</span>
</span><span id="walk_in_scope-866"><a href="#walk_in_scope-866"><span class="linenos">866</span></a> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">node</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]:</span>
</span><span id="walk_in_scope-867"><a href="#walk_in_scope-867"><span class="linenos">867</span></a> <span class="k">yield from</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">)</span>
</span></pre></div>
@ -3255,24 +3258,24 @@ the generator should stop traversing this branch of the tree.</li>
</div>
<a class="headerlink" href="#find_all_in_scope"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_all_in_scope-867"><a href="#find_all_in_scope-867"><span class="linenos">867</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="find_all_in_scope-868"><a href="#find_all_in_scope-868"><span class="linenos">868</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-869"><a href="#find_all_in_scope-869"><span class="linenos">869</span></a><span class="sd"> Returns a generator object which visits all nodes in this scope and only yields those that</span>
</span><span id="find_all_in_scope-870"><a href="#find_all_in_scope-870"><span class="linenos">870</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="find_all_in_scope-871"><a href="#find_all_in_scope-871"><span class="linenos">871</span></a>
</span><span id="find_all_in_scope-872"><a href="#find_all_in_scope-872"><span class="linenos">872</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_all_in_scope-873"><a href="#find_all_in_scope-873"><span class="linenos">873</span></a>
</span><span id="find_all_in_scope-874"><a href="#find_all_in_scope-874"><span class="linenos">874</span></a><span class="sd"> Args:</span>
</span><span id="find_all_in_scope-875"><a href="#find_all_in_scope-875"><span class="linenos">875</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_all_in_scope-876"><a href="#find_all_in_scope-876"><span class="linenos">876</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_all_in_scope-877"><a href="#find_all_in_scope-877"><span class="linenos">877</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="find_all_in_scope-878"><a href="#find_all_in_scope-878"><span class="linenos">878</span></a>
</span><span id="find_all_in_scope-879"><a href="#find_all_in_scope-879"><span class="linenos">879</span></a><span class="sd"> Yields:</span>
</span><span id="find_all_in_scope-880"><a href="#find_all_in_scope-880"><span class="linenos">880</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="find_all_in_scope-881"><a href="#find_all_in_scope-881"><span class="linenos">881</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-882"><a href="#find_all_in_scope-882"><span class="linenos">882</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">):</span>
</span><span id="find_all_in_scope-883"><a href="#find_all_in_scope-883"><span class="linenos">883</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">ensure_collection</span><span class="p">(</span><span class="n">expression_types</span><span class="p">))):</span>
</span><span id="find_all_in_scope-884"><a href="#find_all_in_scope-884"><span class="linenos">884</span></a> <span class="k">yield</span> <span class="n">expression</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_all_in_scope-870"><a href="#find_all_in_scope-870"><span class="linenos">870</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="find_all_in_scope-871"><a href="#find_all_in_scope-871"><span class="linenos">871</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-872"><a href="#find_all_in_scope-872"><span class="linenos">872</span></a><span class="sd"> Returns a generator object which visits all nodes in this scope and only yields those that</span>
</span><span id="find_all_in_scope-873"><a href="#find_all_in_scope-873"><span class="linenos">873</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="find_all_in_scope-874"><a href="#find_all_in_scope-874"><span class="linenos">874</span></a>
</span><span id="find_all_in_scope-875"><a href="#find_all_in_scope-875"><span class="linenos">875</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_all_in_scope-876"><a href="#find_all_in_scope-876"><span class="linenos">876</span></a>
</span><span id="find_all_in_scope-877"><a href="#find_all_in_scope-877"><span class="linenos">877</span></a><span class="sd"> Args:</span>
</span><span id="find_all_in_scope-878"><a href="#find_all_in_scope-878"><span class="linenos">878</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_all_in_scope-879"><a href="#find_all_in_scope-879"><span class="linenos">879</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_all_in_scope-880"><a href="#find_all_in_scope-880"><span class="linenos">880</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="find_all_in_scope-881"><a href="#find_all_in_scope-881"><span class="linenos">881</span></a>
</span><span id="find_all_in_scope-882"><a href="#find_all_in_scope-882"><span class="linenos">882</span></a><span class="sd"> Yields:</span>
</span><span id="find_all_in_scope-883"><a href="#find_all_in_scope-883"><span class="linenos">883</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="find_all_in_scope-884"><a href="#find_all_in_scope-884"><span class="linenos">884</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-885"><a href="#find_all_in_scope-885"><span class="linenos">885</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">walk_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">):</span>
</span><span id="find_all_in_scope-886"><a href="#find_all_in_scope-886"><span class="linenos">886</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">ensure_collection</span><span class="p">(</span><span class="n">expression_types</span><span class="p">))):</span>
</span><span id="find_all_in_scope-887"><a href="#find_all_in_scope-887"><span class="linenos">887</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span></pre></div>
@ -3309,22 +3312,22 @@ match at least one of the specified expression types.</p>
</div>
<a class="headerlink" href="#find_in_scope"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_in_scope-887"><a href="#find_in_scope-887"><span class="linenos">887</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="find_in_scope-888"><a href="#find_in_scope-888"><span class="linenos">888</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_in_scope-889"><a href="#find_in_scope-889"><span class="linenos">889</span></a><span class="sd"> Returns the first node in this scope which matches at least one of the specified types.</span>
</span><span id="find_in_scope-890"><a href="#find_in_scope-890"><span class="linenos">890</span></a>
</span><span id="find_in_scope-891"><a href="#find_in_scope-891"><span class="linenos">891</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_in_scope-892"><a href="#find_in_scope-892"><span class="linenos">892</span></a>
</span><span id="find_in_scope-893"><a href="#find_in_scope-893"><span class="linenos">893</span></a><span class="sd"> Args:</span>
</span><span id="find_in_scope-894"><a href="#find_in_scope-894"><span class="linenos">894</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_in_scope-895"><a href="#find_in_scope-895"><span class="linenos">895</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_in_scope-896"><a href="#find_in_scope-896"><span class="linenos">896</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="find_in_scope-897"><a href="#find_in_scope-897"><span class="linenos">897</span></a>
</span><span id="find_in_scope-898"><a href="#find_in_scope-898"><span class="linenos">898</span></a><span class="sd"> Returns:</span>
</span><span id="find_in_scope-899"><a href="#find_in_scope-899"><span class="linenos">899</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="find_in_scope-900"><a href="#find_in_scope-900"><span class="linenos">900</span></a><span class="sd"> the criteria was found.</span>
</span><span id="find_in_scope-901"><a href="#find_in_scope-901"><span class="linenos">901</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_in_scope-902"><a href="#find_in_scope-902"><span class="linenos">902</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_in_scope-890"><a href="#find_in_scope-890"><span class="linenos">890</span></a><span class="k">def</span><span class="w"> </span><span class="nf">find_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="find_in_scope-891"><a href="#find_in_scope-891"><span class="linenos">891</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_in_scope-892"><a href="#find_in_scope-892"><span class="linenos">892</span></a><span class="sd"> Returns the first node in this scope which matches at least one of the specified types.</span>
</span><span id="find_in_scope-893"><a href="#find_in_scope-893"><span class="linenos">893</span></a>
</span><span id="find_in_scope-894"><a href="#find_in_scope-894"><span class="linenos">894</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_in_scope-895"><a href="#find_in_scope-895"><span class="linenos">895</span></a>
</span><span id="find_in_scope-896"><a href="#find_in_scope-896"><span class="linenos">896</span></a><span class="sd"> Args:</span>
</span><span id="find_in_scope-897"><a href="#find_in_scope-897"><span class="linenos">897</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_in_scope-898"><a href="#find_in_scope-898"><span class="linenos">898</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_in_scope-899"><a href="#find_in_scope-899"><span class="linenos">899</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="find_in_scope-900"><a href="#find_in_scope-900"><span class="linenos">900</span></a>
</span><span id="find_in_scope-901"><a href="#find_in_scope-901"><span class="linenos">901</span></a><span class="sd"> Returns:</span>
</span><span id="find_in_scope-902"><a href="#find_in_scope-902"><span class="linenos">902</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="find_in_scope-903"><a href="#find_in_scope-903"><span class="linenos">903</span></a><span class="sd"> the criteria was found.</span>
</span><span id="find_in_scope-904"><a href="#find_in_scope-904"><span class="linenos">904</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_in_scope-905"><a href="#find_in_scope-905"><span class="linenos">905</span></a> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="n">find_all_in_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">expression_types</span><span class="p">,</span> <span class="n">bfs</span><span class="o">=</span><span class="n">bfs</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>
</span></pre></div>

View file

@ -3201,7 +3201,7 @@ prefix are statically known.</p>
<div class="attr variable">
<span class="name">DATETRUNC_COMPARISONS</span> =
<input id="DATETRUNC_COMPARISONS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="DATETRUNC_COMPARISONS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LT">sqlglot.expressions.LT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#EQ">sqlglot.expressions.EQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GTE">sqlglot.expressions.GTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LTE">sqlglot.expressions.LTE</a>&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="DATETRUNC_COMPARISONS-view-value"></label><span class="default_value">{&lt;class &#39;<a href="../expressions.html#GTE">sqlglot.expressions.GTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#EQ">sqlglot.expressions.EQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LTE">sqlglot.expressions.LTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LT">sqlglot.expressions.LT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;}</span>
</div>
@ -3285,7 +3285,7 @@ prefix are statically known.</p>
<section id="JOINS">
<div class="attr variable">
<span class="name">JOINS</span> =
<span class="default_value">{(&#39;&#39;, &#39;INNER&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;RIGHT&#39;, &#39;&#39;), (&#39;&#39;, &#39;&#39;)}</span>
<span class="default_value">{(&#39;&#39;, &#39;INNER&#39;), (&#39;RIGHT&#39;, &#39;&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;&#39;, &#39;&#39;)}</span>
</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

@ -9516,7 +9516,7 @@
<div class="attr variable">
<span class="name">TOKENS_PRECEDING_HINT</span> =
<input id="Tokenizer.TOKENS_PRECEDING_HINT-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.DELETE">TokenType.DELETE</a>: &#39;DELETE&#39;&gt;, &lt;<a href="#TokenType.SELECT">TokenType.SELECT</a>: &#39;SELECT&#39;&gt;, &lt;<a href="#TokenType.INSERT">TokenType.INSERT</a>: &#39;INSERT&#39;&gt;, &lt;<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: &#39;UPDATE&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="Tokenizer.TOKENS_PRECEDING_HINT-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.DELETE">TokenType.DELETE</a>: &#39;DELETE&#39;&gt;, &lt;<a href="#TokenType.INSERT">TokenType.INSERT</a>: &#39;INSERT&#39;&gt;, &lt;<a href="#TokenType.UPDATE">TokenType.UPDATE</a>: &#39;UPDATE&#39;&gt;, &lt;<a href="#TokenType.SELECT">TokenType.SELECT</a>: &#39;SELECT&#39;&gt;}</span>
</div>
@ -9555,7 +9555,7 @@
<div class="attr variable">
<span class="name">COMMANDS</span> =
<input id="Tokenizer.COMMANDS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="Tokenizer.COMMANDS-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.SHOW">TokenType.SHOW</a>: &#39;SHOW&#39;&gt;, &lt;<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: &#39;COMMAND&#39;&gt;, &lt;<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: &#39;EXECUTE&#39;&gt;, &lt;<a href="#TokenType.RENAME">TokenType.RENAME</a>: &#39;RENAME&#39;&gt;, &lt;<a href="#TokenType.FETCH">TokenType.FETCH</a>: &#39;FETCH&#39;&gt;}</span>
<label class="view-value-button pdoc-button" for="Tokenizer.COMMANDS-view-value"></label><span class="default_value">{&lt;<a href="#TokenType.RENAME">TokenType.RENAME</a>: &#39;RENAME&#39;&gt;, &lt;<a href="#TokenType.EXECUTE">TokenType.EXECUTE</a>: &#39;EXECUTE&#39;&gt;, &lt;<a href="#TokenType.SHOW">TokenType.SHOW</a>: &#39;SHOW&#39;&gt;, &lt;<a href="#TokenType.COMMAND">TokenType.COMMAND</a>: &#39;COMMAND&#39;&gt;, &lt;<a href="#TokenType.FETCH">TokenType.FETCH</a>: &#39;FETCH&#39;&gt;}</span>
</div>
@ -9567,7 +9567,7 @@
<div id="Tokenizer.COMMAND_PREFIX_TOKENS" class="classattr">
<div class="attr variable">
<span class="name">COMMAND_PREFIX_TOKENS</span> =
<span class="default_value">{&lt;<a href="#TokenType.SEMICOLON">TokenType.SEMICOLON</a>: &#39;SEMICOLON&#39;&gt;, &lt;<a href="#TokenType.BEGIN">TokenType.BEGIN</a>: &#39;BEGIN&#39;&gt;}</span>
<span class="default_value">{&lt;<a href="#TokenType.BEGIN">TokenType.BEGIN</a>: &#39;BEGIN&#39;&gt;, &lt;<a href="#TokenType.SEMICOLON">TokenType.SEMICOLON</a>: &#39;SEMICOLON&#39;&gt;}</span>
</div>

View file

@ -108,6 +108,7 @@ class Athena(Trino):
"""
IDENTIFIERS = ['"', "`"]
STRING_ESCAPES = ["'", "\\"]
KEYWORDS = {
**Hive.Tokenizer.KEYWORDS,
**Trino.Tokenizer.KEYWORDS,

View file

@ -1621,7 +1621,10 @@ def map_date_part(part, dialect: DialectType = Dialect):
mapped = (
Dialect.get_or_raise(dialect).DATE_PART_MAPPING.get(part.name.upper()) if part else None
)
return exp.var(mapped) if mapped else part
if mapped:
return exp.Literal.string(mapped) if part.is_string else exp.var(mapped)
return part
def no_last_day_sql(self: Generator, expression: exp.LastDay) -> str:

View file

@ -290,6 +290,12 @@ class DuckDB(Dialect):
# https://duckdb.org/docs/sql/introduction.html#creating-a-new-table
NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
DATE_PART_MAPPING = {
**Dialect.DATE_PART_MAPPING,
"DAYOFWEEKISO": "ISODOW",
}
DATE_PART_MAPPING.pop("WEEKDAY")
def to_json_path(self, path: t.Optional[exp.Expression]) -> t.Optional[exp.Expression]:
if isinstance(path, exp.Literal):
# DuckDB also supports the JSON pointer syntax, where every path starts with a `/`.
@ -620,6 +626,7 @@ class DuckDB(Dialect):
PAD_FILL_PATTERN_IS_REQUIRED = True
ARRAY_CONCAT_IS_VAR_LEN = False
ARRAY_SIZE_DIM_REQUIRED = False
NORMALIZE_EXTRACT_DATE_PARTS = True
TRANSFORMS = {
**generator.Generator.TRANSFORMS,

View file

@ -31,6 +31,7 @@ from sqlglot.dialects.dialect import (
)
from sqlglot.generator import unsupported_args
from sqlglot.helper import flatten, is_float, is_int, seq_get
from sqlglot.optimizer.scope import find_all_in_scope
from sqlglot.tokens import TokenType
if t.TYPE_CHECKING:
@ -333,6 +334,34 @@ def _json_extract_value_array_sql(
return self.func("TRANSFORM", json_extract, transform_lambda)
def _eliminate_dot_variant_lookup(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Select):
# This transformation is used to facilitate transpilation of BigQuery `UNNEST` operations
# to Snowflake. It should not affect roundtrip because `Unnest` nodes cannot be produced
# by Snowflake's parser.
#
# Additionally, at the time of writing this, BigQuery is the only dialect that produces a
# `TableAlias` node that only fills `columns` and not `this`, due to `UNNEST_COLUMN_ONLY`.
unnest_aliases = set()
for unnest in find_all_in_scope(expression, exp.Unnest):
unnest_alias = unnest.args.get("alias")
if (
isinstance(unnest_alias, exp.TableAlias)
and not unnest_alias.this
and len(unnest_alias.columns) == 1
):
unnest_aliases.add(unnest_alias.columns[0].name)
if unnest_aliases:
for c in find_all_in_scope(expression, exp.Column):
if c.table in unnest_aliases:
bracket_lhs = c.args["table"]
bracket_rhs = exp.Literal.string(c.name)
c.replace(exp.Bracket(this=bracket_lhs, expressions=[bracket_rhs]))
return expression
class Snowflake(Dialect):
# https://docs.snowflake.com/en/sql-reference/identifiers-syntax
NORMALIZATION_STRATEGY = NormalizationStrategy.UPPERCASE
@ -1096,6 +1125,7 @@ class Snowflake(Dialect):
transforms.explode_projection_to_unnest(),
transforms.eliminate_semi_and_anti_joins,
_transform_generate_date_array,
_eliminate_dot_variant_lookup,
]
),
exp.SHA: rename_func("SHA1"),
@ -1314,7 +1344,14 @@ class Snowflake(Dialect):
start = f" START {start}" if start else ""
increment = expression.args.get("increment")
increment = f" INCREMENT {increment}" if increment else ""
return f"AUTOINCREMENT{start}{increment}"
order = expression.args.get("order")
if order is not None:
order_clause = " ORDER" if order else " NOORDER"
else:
order_clause = ""
return f"AUTOINCREMENT{start}{increment}{order_clause}"
def cluster_sql(self, expression: exp.Cluster) -> str:
return f"CLUSTER BY ({self.expressions(expression, flat=True)})"

View file

@ -1224,8 +1224,6 @@ class TSQL(Dialect):
# to amend the AST by moving the CTEs to the CREATE VIEW statement's query.
ctas_expression.set("with", with_.pop())
sql = super().create_sql(expression)
table = expression.find(exp.Table)
# Convert CTAS statement to SELECT .. INTO ..
@ -1243,6 +1241,8 @@ class TSQL(Dialect):
select_into.limit(0, copy=False)
sql = self.sql(select_into)
else:
sql = super().create_sql(expression)
if exists:
identifier = self.sql(exp.Literal.string(exp.table_name(table) if table else ""))

View file

@ -1947,6 +1947,7 @@ class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
"minvalue": False,
"maxvalue": False,
"cycle": False,
"order": False,
}
@ -7044,6 +7045,12 @@ class Semicolon(Expression):
arg_types = {}
# BigQuery allows SELECT t FROM t and treats the projection as a struct value. This expression
# type is intended to be constructed by qualify so that we can properly annotate its type later
class TableColumn(Expression):
pass
def _norm_arg(arg):
return arg.lower() if type(arg) is str else arg

View file

@ -201,6 +201,7 @@ class Generator(metaclass=_Generator):
exp.StreamingTableProperty: lambda *_: "STREAMING",
exp.StrictProperty: lambda *_: "STRICT",
exp.SwapTable: lambda self, e: f"SWAP WITH {self.sql(e, 'this')}",
exp.TableColumn: lambda self, e: self.sql(e.this),
exp.Tags: lambda self, e: f"TAG ({self.expressions(e, flat=True)})",
exp.TemporaryProperty: lambda *_: "TEMPORARY",
exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}",
@ -463,6 +464,11 @@ class Generator(metaclass=_Generator):
# Whether to wrap <props> in `AlterSet`, e.g., ALTER ... SET (<props>)
ALTER_SET_WRAPPED = False
# Whether to normalize the date parts in EXTRACT(<date_part> FROM <expr>) into a common representation
# For instance, to extract the day of week in ISO semantics, one can use ISODOW, DAYOFWEEKISO etc depending on the dialect.
# TODO: The normalization should be done by default once we've tested it across all dialects.
NORMALIZE_EXTRACT_DATE_PARTS = False
# The name to generate for the JSONPath expression. If `None`, only `this` will be generated
PARSE_JSON_NAME: t.Optional[str] = "PARSE_JSON"
@ -2909,9 +2915,17 @@ class Generator(metaclass=_Generator):
return f"NEXT VALUE FOR {self.sql(expression, 'this')}{order}"
def extract_sql(self, expression: exp.Extract) -> str:
this = self.sql(expression, "this") if self.EXTRACT_ALLOWS_QUOTES else expression.this.name
from sqlglot.dialects.dialect import map_date_part
this = (
map_date_part(expression.this, self.dialect)
if self.NORMALIZE_EXTRACT_DATE_PARTS
else expression.this
)
this_sql = self.sql(this) if self.EXTRACT_ALLOWS_QUOTES else this.name
expression_sql = self.sql(expression, "expression")
return f"EXTRACT({this} FROM {expression_sql})"
return f"EXTRACT({this_sql} FROM {expression_sql})"
def trim_sql(self, expression: exp.Trim) -> str:
trim_type = self.sql(expression, "position")
@ -4766,7 +4780,10 @@ class Generator(metaclass=_Generator):
def detach_sql(self, expression: exp.Detach) -> str:
this = self.sql(expression, "this")
exists_sql = " IF EXISTS" if expression.args.get("exists") else ""
# the DATABASE keyword is required if IF EXISTS is set
# without it, DuckDB throws an error: Parser Error: syntax error at or near "exists" (Line Number: 1)
# ref: https://duckdb.org/docs/stable/sql/statements/attach.html#detach-syntax
exists_sql = " DATABASE IF EXISTS" if expression.args.get("exists") else ""
return f"DETACH{exists_sql} {this}"

View file

@ -12,7 +12,7 @@ from sqlglot.helper import (
seq_get,
)
from sqlglot.optimizer.scope import Scope, traverse_scope
from sqlglot.schema import Schema, ensure_schema
from sqlglot.schema import MappingSchema, Schema, ensure_schema
from sqlglot.dialects.dialect import Dialect
if t.TYPE_CHECKING:
@ -290,9 +290,52 @@ class TypeAnnotator(metaclass=_TypeAnnotator):
elif isinstance(source.expression, exp.Unnest):
self._set_type(col, source.expression.type)
if isinstance(self.schema, MappingSchema):
for table_column in scope.table_columns:
source = scope.sources.get(table_column.name)
if isinstance(source, exp.Table):
schema = self.schema.find(
source, raise_on_missing=False, ensure_data_types=True
)
if not isinstance(schema, dict):
continue
struct_type = exp.DataType(
this=exp.DataType.Type.STRUCT,
expressions=[
exp.ColumnDef(this=exp.to_identifier(c), kind=kind)
for c, kind in schema.items()
],
nested=True,
)
self._set_type(table_column, struct_type)
elif (
isinstance(source, Scope)
and isinstance(source.expression, exp.Query)
and source.expression.is_type(exp.DataType.Type.STRUCT)
):
self._set_type(table_column, source.expression.type)
# Then (possibly) annotate the remaining expressions in the scope
self._maybe_annotate(scope.expression)
if self.schema.dialect == "bigquery" and isinstance(scope.expression, exp.Query):
struct_type = exp.DataType(
this=exp.DataType.Type.STRUCT,
expressions=[
exp.ColumnDef(this=exp.to_identifier(select.output_name), kind=select.type)
for select in scope.expression.selects
],
nested=True,
)
if not any(
cd.kind.is_type(exp.DataType.Type.UNKNOWN)
for cd in struct_type.expressions
if cd.kind
):
self._set_type(scope.expression, struct_type)
def _maybe_annotate(self, expression: E) -> E:
if id(expression) in self._visited:
return expression # We've already inferred the expression's type

View file

@ -529,6 +529,13 @@ def _qualify_columns(scope: Scope, resolver: Resolver, allow_partial_qualificati
column_table = resolver.get_table(column_name)
if column_table:
column.set("table", column_table)
elif (
resolver.schema.dialect == "bigquery"
and len(column.parts) == 1
and column_name in scope.selected_sources
):
# BigQuery allows tables to be referenced as columns, treating them as structs
scope.replace(column, exp.TableColumn(this=column.this))
for pivot in scope.pivots:
for column in pivot.find_all(exp.Column):

View file

@ -88,6 +88,7 @@ class Scope:
def clear_cache(self):
self._collected = False
self._raw_columns = None
self._table_columns = None
self._stars = None
self._derived_tables = None
self._udtfs = None
@ -125,6 +126,7 @@ class Scope:
self._derived_tables = []
self._udtfs = []
self._raw_columns = []
self._table_columns = []
self._stars = []
self._join_hints = []
self._semi_anti_join_tables = set()
@ -156,6 +158,8 @@ class Scope:
self._derived_tables.append(node)
elif isinstance(node, exp.UNWRAPPED_QUERIES):
self._subqueries.append(node)
elif isinstance(node, exp.TableColumn):
self._table_columns.append(node)
self._collected = True
@ -309,6 +313,13 @@ class Scope:
return self._columns
@property
def table_columns(self):
if self._table_columns is None:
self._ensure_collected()
return self._table_columns
@property
def selected_sources(self):
"""
@ -849,12 +860,14 @@ def walk_in_scope(expression, bfs=True, prune=None):
if node is expression:
continue
if (
isinstance(node, exp.CTE)
or (
isinstance(node.parent, (exp.From, exp.Join, exp.Subquery))
and (_is_derived_table(node) or isinstance(node, exp.UDTF))
and _is_derived_table(node)
)
or (isinstance(node.parent, exp.UDTF) and isinstance(node, exp.Query))
or isinstance(node, exp.UNWRAPPED_QUERIES)
):
crossed_scope_boundary = True

View file

@ -931,15 +931,22 @@ class Parser(metaclass=_Parser):
}
PIPE_SYNTAX_TRANSFORM_PARSERS = {
"SELECT": lambda self, query: self._parse_pipe_syntax_select(query),
"WHERE": lambda self, query: query.where(self._parse_where(), copy=False),
"AGGREGATE": lambda self, query: self._parse_pipe_syntax_aggregate(query),
"AS": lambda self, query: self._build_pipe_cte(
query, [exp.Star()], self._parse_table_alias()
),
"DROP": lambda self, query: self._parse_pipe_syntax_drop(query),
"EXTEND": lambda self, query: self._parse_pipe_syntax_extend(query),
"LIMIT": lambda self, query: self._parse_pipe_syntax_limit(query),
"ORDER BY": lambda self, query: query.order_by(
self._parse_order(), append=False, copy=False
),
"LIMIT": lambda self, query: self._parse_pipe_syntax_limit(query),
"AGGREGATE": lambda self, query: self._parse_pipe_syntax_aggregate(query),
"PIVOT": lambda self, query: self._parse_pipe_syntax_pivot(query),
"SELECT": lambda self, query: self._parse_pipe_syntax_select(query),
"SET": lambda self, query: self._parse_pipe_syntax_set(query),
"TABLESAMPLE": lambda self, query: self._parse_pipe_syntax_tablesample(query),
"UNPIVOT": lambda self, query: self._parse_pipe_syntax_pivot(query),
"WHERE": lambda self, query: query.where(self._parse_where(), copy=False),
}
PROPERTY_PARSERS: t.Dict[str, t.Callable] = {
@ -3252,11 +3259,9 @@ class Parser(metaclass=_Parser):
elif self._match(TokenType.VALUES, advance=False):
this = self._parse_derived_table_values()
elif from_:
if self._match(TokenType.PIPE_GT, advance=False):
return self._parse_pipe_syntax_query(
exp.Select().from_(from_.this, append=False, copy=False)
)
this = exp.select("*").from_(from_.this, copy=False)
if self._match(TokenType.PIPE_GT, advance=False):
return self._parse_pipe_syntax_query(this)
elif self._match(TokenType.SUMMARIZE):
table = self._match(TokenType.TABLE)
this = self._parse_select() or self._parse_string() or self._parse_table()
@ -5543,6 +5548,37 @@ class Parser(metaclass=_Parser):
return self._parse_colon_as_variant_extract(this) if self.COLON_IS_VARIANT_EXTRACT else this
def _parse_paren(self) -> t.Optional[exp.Expression]:
if not self._match(TokenType.L_PAREN):
return None
comments = self._prev_comments
query = self._parse_select()
if query:
expressions = [query]
else:
expressions = self._parse_expressions()
this = self._parse_query_modifiers(seq_get(expressions, 0))
if not this and self._match(TokenType.R_PAREN, advance=False):
this = self.expression(exp.Tuple)
elif isinstance(this, exp.UNWRAPPED_QUERIES):
this = self._parse_subquery(this=this, parse_alias=False)
elif isinstance(this, exp.Subquery):
this = self._parse_subquery(this=self._parse_set_operations(this), parse_alias=False)
elif len(expressions) > 1 or self._prev.token_type == TokenType.COMMA:
this = self.expression(exp.Tuple, expressions=expressions)
else:
this = self.expression(exp.Paren, this=this)
if this:
this.add_comments(comments)
self._match_r_paren(expression=this)
return this
def _parse_primary(self) -> t.Optional[exp.Expression]:
if self._match_set(self.PRIMARY_PARSERS):
token_type = self._prev.token_type
@ -5561,37 +5597,7 @@ class Parser(metaclass=_Parser):
if self._match_pair(TokenType.DOT, TokenType.NUMBER):
return exp.Literal.number(f"0.{self._prev.text}")
if self._match(TokenType.L_PAREN):
comments = self._prev_comments
query = self._parse_select()
if query:
expressions = [query]
else:
expressions = self._parse_expressions()
this = self._parse_query_modifiers(seq_get(expressions, 0))
if not this and self._match(TokenType.R_PAREN, advance=False):
this = self.expression(exp.Tuple)
elif isinstance(this, exp.UNWRAPPED_QUERIES):
this = self._parse_subquery(this=this, parse_alias=False)
elif isinstance(this, exp.Subquery):
this = self._parse_subquery(
this=self._parse_set_operations(this), parse_alias=False
)
elif len(expressions) > 1 or self._prev.token_type == TokenType.COMMA:
this = self.expression(exp.Tuple, expressions=expressions)
else:
this = self.expression(exp.Paren, this=this)
if this:
this.add_comments(comments)
self._match_r_paren(expression=this)
return this
return None
return self._parse_paren()
def _parse_field(
self,
@ -5913,6 +5919,7 @@ class Parser(metaclass=_Parser):
) -> exp.GeneratedAsIdentityColumnConstraint | exp.AutoIncrementColumnConstraint:
start = None
increment = None
order = None
if self._match(TokenType.L_PAREN, advance=False):
args = self._parse_wrapped_csv(self._parse_bitwise)
@ -5922,10 +5929,14 @@ class Parser(metaclass=_Parser):
start = self._parse_bitwise()
self._match_text_seq("INCREMENT")
increment = self._parse_bitwise()
if self._match_text_seq("ORDER"):
order = True
elif self._match_text_seq("NOORDER"):
order = False
if start and increment:
return exp.GeneratedAsIdentityColumnConstraint(
start=start, increment=increment, this=False
start=start, increment=increment, this=False, order=order
)
return exp.AutoIncrementColumnConstraint()
@ -8328,12 +8339,18 @@ class Parser(metaclass=_Parser):
expression.update_positions(token)
return expression
def _build_pipe_cte(self, query: exp.Query, expressions: t.List[exp.Expression]) -> exp.Select:
if not query.selects:
query = query.select("*", copy=False)
self._pipe_cte_counter += 1
new_cte = f"__tmp{self._pipe_cte_counter}"
def _build_pipe_cte(
self,
query: exp.Query,
expressions: t.List[exp.Expression],
alias_cte: t.Optional[exp.TableAlias] = None,
) -> exp.Select:
new_cte: t.Optional[t.Union[str, exp.TableAlias]]
if alias_cte:
new_cte = alias_cte
else:
self._pipe_cte_counter += 1
new_cte = f"__tmp{self._pipe_cte_counter}"
with_ = query.args.get("with")
ctes = with_.pop() if with_ else None
@ -8344,15 +8361,34 @@ class Parser(metaclass=_Parser):
return new_select.with_(new_cte, as_=query, copy=False)
def _build_pipe_ctes(
self,
query: exp.Select,
expressions: t.List[exp.Expression],
alias_cte: t.Optional[exp.TableAlias] = None,
) -> exp.Select:
select = query.selects[0].assert_is(exp.Star)
if select.args.get("except") or select.args.get("replace"):
query = self._build_pipe_cte(
query=query.select(
*[expr for expr in expressions if not expr.is_star and expr.args.get("alias")],
copy=False,
),
expressions=[
projection.args.get("alias", projection) for projection in expressions
],
)
else:
query.select(*expressions, append=False, copy=False)
return self._build_pipe_cte(query=query, expressions=[exp.Star()], alias_cte=alias_cte)
def _parse_pipe_syntax_select(self, query: exp.Select) -> exp.Select:
select = self._parse_select()
if not select:
return query
if not query.selects:
return self._build_pipe_cte(query.select(*select.expressions), [exp.Star()])
return self._build_pipe_cte(query, select.expressions)
return self._build_pipe_ctes(query=query, expressions=select.expressions)
def _parse_pipe_syntax_limit(self, query: exp.Select) -> exp.Select:
limit = self._parse_limit()
@ -8396,12 +8432,12 @@ class Parser(metaclass=_Parser):
aggregates_or_groups.append(this)
if group_by_exists:
query = query.select(*aggregates_or_groups, copy=False).group_by(
query.select(*aggregates_or_groups, copy=False).group_by(
*[projection.args.get("alias", projection) for projection in aggregates_or_groups],
copy=False,
)
else:
query = query.select(*aggregates_or_groups, copy=False)
query.select(*aggregates_or_groups, copy=False)
if orders:
return query.order_by(*orders, append=False, copy=False)
@ -8417,34 +8453,40 @@ class Parser(metaclass=_Parser):
):
query = self._parse_pipe_syntax_aggregate_group_order_by(query)
return self._build_pipe_cte(query, [exp.Star()])
return self._build_pipe_ctes(
query=query, expressions=[expr for expr in query.selects if not expr.is_star]
)
def _parse_pipe_syntax_set_operator(
self, query: t.Optional[exp.Query]
) -> t.Optional[exp.Select]:
def _parse_pipe_syntax_set_operator(self, query: exp.Query) -> t.Optional[exp.Select]:
first_setop = self.parse_set_operation(this=query)
if not first_setop or not query:
if not first_setop:
return None
first_setop.this.pop()
distinct = first_setop.args.pop("distinct")
setops = [first_setop.expression.pop(), *self._parse_expressions()]
def _parse_and_unwrap_query() -> t.Optional[exp.Select]:
expr = self._parse_paren()
return expr.assert_is(exp.Subquery).unnest() if expr else None
query = self._build_pipe_cte(query, [exp.Star()])
first_setop.this.pop()
setops = [
first_setop.expression.pop().assert_is(exp.Subquery).unnest(),
*self._parse_csv(_parse_and_unwrap_query),
]
query = self._build_pipe_cte(query=query, expressions=[exp.Star()])
with_ = query.args.get("with")
ctes = with_.pop() if with_ else None
if isinstance(first_setop, exp.Union):
query = query.union(*setops, distinct=distinct, copy=False, **first_setop.args)
query = query.union(*setops, copy=False, **first_setop.args)
elif isinstance(first_setop, exp.Except):
query = query.except_(*setops, distinct=distinct, copy=False, **first_setop.args)
query = query.except_(*setops, copy=False, **first_setop.args)
else:
query = query.intersect(*setops, distinct=distinct, copy=False, **first_setop.args)
query = query.intersect(*setops, copy=False, **first_setop.args)
query.set("with", ctes)
return self._build_pipe_cte(query, [exp.Star()])
return self._build_pipe_cte(query=query, expressions=[exp.Star()])
def _parse_pipe_syntax_join(self, query: exp.Select) -> t.Optional[exp.Select]:
join = self._parse_join()
@ -8462,16 +8504,60 @@ class Parser(metaclass=_Parser):
if from_:
from_.this.set("pivots", pivots)
return self._build_pipe_cte(query, [exp.Star()])
return self._build_pipe_ctes(query=query, expressions=[exp.Star()])
def _parse_pipe_syntax_extend(self, query: exp.Select) -> exp.Select:
self._match_text_seq("EXTEND")
return self._build_pipe_ctes(
query=query,
expressions=[query.selects[0].assert_is(exp.Star), *self._parse_expressions()],
)
def _parse_pipe_syntax_drop(self, query: exp.Select) -> exp.Select:
self._match_text_seq("DROP")
dropped_columns = self._parse_csv(self._parse_assignment)
select = query.selects[0].assert_is(exp.Star)
except_ = select.args.get("except") or []
select.set("except", [*except_, *dropped_columns])
return query
def _parse_pipe_syntax_set(self, query: exp.Select) -> exp.Select:
self._match_text_seq("SET")
replaced_columns = [
self.expression(exp.Alias, this=expr.expression, alias=expr.this)
for expr in self._parse_csv(self._parse_assignment)
]
select = query.selects[0].assert_is(exp.Star)
replace_ = select.args.get("replace") or []
select.set("replace", [*replace_, *replaced_columns])
return query
def _parse_pipe_syntax_tablesample(self, query: exp.Select) -> exp.Select:
sample = self._parse_table_sample()
with_ = query.args.get("with")
if with_:
with_.expressions[-1].this.set("sample", sample)
else:
query.set("sample", sample)
return query
def _parse_pipe_syntax_query(self, query: exp.Select) -> t.Optional[exp.Select]:
while self._match(TokenType.PIPE_GT):
start = self._curr
parser = self.PIPE_SYNTAX_TRANSFORM_PARSERS.get(self._curr.text.upper())
if not parser:
parsed_query = self._parse_pipe_syntax_set_operator(
query
) or self._parse_pipe_syntax_join(query)
# The set operators (UNION, etc) and the JOIN operator have a few common starting
# keywords, making it tricky to disambiguate them without lookahead. The approach
# here is to try and parse a set operation and if that fails, then try to parse a
# join operator. If that fails as well, then the operator is not supported.
parsed_query = self._parse_pipe_syntax_set_operator(query)
parsed_query = parsed_query or self._parse_pipe_syntax_join(query)
if not parsed_query:
self._retreat(start)
self.raise_error(f"Unsupported pipe syntax operator: '{start.text.upper()}'.")
@ -8480,7 +8566,4 @@ class Parser(metaclass=_Parser):
else:
query = parser(self, query)
if query and not query.selects:
return query.select("*", copy=False)
return query

View file

@ -7,6 +7,7 @@ class TestAthena(Validator):
maxDiff = None
def test_athena(self):
self.validate_identity("SELECT 'foo''bar'")
self.validate_identity(
"CREATE TABLE IF NOT EXISTS t (name STRING) LOCATION 's3://bucket/tmp/mytable/' TBLPROPERTIES ('table_type'='iceberg', 'FORMAT'='parquet')"
)
@ -39,6 +40,9 @@ class TestAthena(Validator):
def test_ddl(self):
# Hive-like, https://docs.aws.amazon.com/athena/latest/ug/create-table.html
self.validate_identity("CREATE EXTERNAL TABLE foo (id INT) COMMENT 'test comment'")
self.validate_identity(
"CREATE EXTERNAL TABLE my_table (id BIGINT COMMENT 'this is the row\\'s id') LOCATION 's3://my-s3-bucket'"
)
self.validate_identity(
"CREATE EXTERNAL TABLE foo (id INT, val STRING) CLUSTERED BY (id, val) INTO 10 BUCKETS"
)

View file

@ -1494,7 +1494,11 @@ class TestDuckDB(Validator):
# DETACH
self.validate_identity("DETACH new_database")
self.validate_identity("DETACH IF EXISTS file")
# when 'if exists' is set, the syntax is DETACH DATABASE, not DETACH
# ref: https://duckdb.org/docs/stable/sql/statements/attach.html#detach-syntax
self.validate_identity("DETACH IF EXISTS file", "DETACH DATABASE IF EXISTS file")
self.validate_identity("DETACH DATABASE IF EXISTS file", "DETACH DATABASE IF EXISTS file")
self.validate_identity("DETACH DATABASE db", "DETACH db")
@ -1652,3 +1656,20 @@ class TestDuckDB(Validator):
def test_show_tables(self):
self.validate_identity("SHOW TABLES").assert_is(exp.Show)
self.validate_identity("SHOW ALL TABLES").assert_is(exp.Show)
def test_extract_date_parts(self):
for part in ("WEEK", "WEEKOFYEAR"):
# Both are synonyms for ISO week
self.validate_identity(f"EXTRACT({part} FROM foo)", "EXTRACT(WEEK FROM foo)")
for part in (
"WEEKDAY",
"ISOYEAR",
"ISODOW",
"YEARWEEK",
"TIMEZONE_HOUR",
"TIMEZONE_MINUTE",
):
with self.subTest(f"Testing DuckDB EXTRACT({part} FROM foo)"):
# All of these should remain as is, they don't have synonyms
self.validate_identity(f"EXTRACT({part} FROM foo)")

View file

@ -21,7 +21,7 @@ class TestPipeSyntax(Validator):
)
self.validate_identity(
"FROM x |> SELECT x1 + 1 as x1_a, x2 - 1 as x2_a |> WHERE x1_a > 1 |> SELECT x2_a",
"WITH __tmp1 AS (SELECT x1 + 1 AS x1_a, x2 - 1 AS x2_a FROM x), __tmp2 AS (SELECT * FROM __tmp1 WHERE x1_a > 1) SELECT x2_a FROM __tmp2",
"WITH __tmp1 AS (SELECT x1 + 1 AS x1_a, x2 - 1 AS x2_a FROM x), __tmp2 AS (SELECT x2_a FROM __tmp1 WHERE x1_a > 1) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> WHERE x1 > 0 OR x2 > 0 |> WHERE x3 > 1 AND x4 > 1 |> SELECT x1, x4",
@ -33,7 +33,7 @@ class TestPipeSyntax(Validator):
)
self.validate_identity(
"FROM x |> WHERE x1 > 1 AND x2 > 2 |> SELECT x1 as gt1, x2 as gt2 |> SELECT gt1 * 2 + gt2 * 2 AS gt2_2",
"WITH __tmp1 AS (SELECT x1 AS gt1, x2 AS gt2 FROM x WHERE x1 > 1 AND x2 > 2), __tmp2 AS (SELECT * FROM __tmp1) SELECT gt1 * 2 + gt2 * 2 AS gt2_2 FROM __tmp2",
"WITH __tmp1 AS (SELECT x1 AS gt1, x2 AS gt2 FROM x WHERE x1 > 1 AND x2 > 2), __tmp2 AS (SELECT gt1 * 2 + gt2 * 2 AS gt2_2 FROM __tmp1) SELECT * FROM __tmp2",
)
def test_order_by(self):
@ -87,7 +87,7 @@ class TestPipeSyntax(Validator):
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) AS s_x1 |> SELECT s_x1",
"WITH __tmp1 AS (SELECT SUM(x1) AS s_x1 FROM x), __tmp2 AS (SELECT * FROM __tmp1) SELECT s_x1 FROM __tmp2",
"WITH __tmp1 AS (SELECT SUM(x1) AS s_x1 FROM x), __tmp2 AS (SELECT s_x1 FROM __tmp1) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1), MAX(x2), MIN(x3) GROUP BY x4, x5",
@ -99,7 +99,7 @@ class TestPipeSyntax(Validator):
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) as s_x1 GROUP BY x1 |> SELECT s_x1, x1 as ss_x1",
"WITH __tmp1 AS (SELECT SUM(x1) AS s_x1, x1 FROM x GROUP BY x1), __tmp2 AS (SELECT * FROM __tmp1) SELECT s_x1, x1 AS ss_x1 FROM __tmp2",
"WITH __tmp1 AS (SELECT SUM(x1) AS s_x1, x1 FROM x GROUP BY x1), __tmp2 AS (SELECT s_x1, x1 AS ss_x1 FROM __tmp1) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> AGGREGATE SUM(x1) GROUP",
@ -127,7 +127,7 @@ class TestPipeSyntax(Validator):
f"Testing pipe syntax AGGREGATE with GROUP AND ORDER BY for order option: {order_option}"
):
self.validate_all(
f"WITH __tmp1 AS (SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM x GROUP BY g_x1 ORDER BY g_x1 {order_option}), __tmp2 AS (SELECT * FROM __tmp1) SELECT g_x1, x_s FROM __tmp2",
f"WITH __tmp1 AS (SELECT SUM(x1) AS x_s, x1 AS g_x1 FROM x GROUP BY g_x1 ORDER BY g_x1 {order_option}), __tmp2 AS (SELECT g_x1, x_s FROM __tmp1) SELECT * FROM __tmp2",
read={
"bigquery": f"FROM x |> AGGREGATE SUM(x1) AS x_s GROUP AND ORDER BY x1 AS g_x1 {order_option} |> SELECT g_x1, x_s",
},
@ -136,7 +136,7 @@ class TestPipeSyntax(Validator):
def test_set_operators(self):
self.validate_identity(
"FROM x |> SELECT x.x1 |> UNION ALL (SELECT 1 AS c)",
"WITH __tmp1 AS (SELECT x.x1 FROM x), __tmp2 AS (SELECT * FROM __tmp1), __tmp3 AS (SELECT * FROM __tmp2 UNION ALL (SELECT 1 AS c)) SELECT * FROM __tmp3",
"WITH __tmp1 AS (SELECT x.x1 FROM x), __tmp2 AS (SELECT * FROM __tmp1), __tmp3 AS (SELECT * FROM __tmp2 UNION ALL SELECT 1 AS c) SELECT * FROM __tmp3",
)
for op_operator in (
@ -149,7 +149,7 @@ class TestPipeSyntax(Validator):
self.validate_all(
f"FROM x|> {op_operator} (SELECT y1 FROM y), (SELECT z1 FROM z)",
write={
"bigquery": f"WITH __tmp1 AS (SELECT * FROM x), __tmp2 AS (SELECT * FROM __tmp1 {op_operator} (SELECT y1 FROM y) {op_operator} (SELECT z1 FROM z)) SELECT * FROM __tmp2"
"bigquery": f"WITH __tmp1 AS (SELECT * FROM x), __tmp2 AS (SELECT * FROM __tmp1 {op_operator} SELECT y1 FROM y {op_operator} SELECT z1 FROM z) SELECT * FROM __tmp2"
},
)
@ -164,7 +164,7 @@ class TestPipeSyntax(Validator):
self.validate_all(
f"FROM x|> SELECT x1, x2 |> {op_prefix} {op_operator} BY NAME (SELECT y1, y2 FROM y), (SELECT z1, z2 FROM z)",
write={
"bigquery": f"WITH __tmp1 AS (SELECT x1, x2 FROM x), __tmp2 AS (SELECT * FROM __tmp1), __tmp3 AS (SELECT * FROM __tmp2 {op_prefix} {op_operator} BY NAME (SELECT y1, y2 FROM y) {op_prefix} {op_operator} BY NAME (SELECT z1, z2 FROM z)) SELECT * FROM __tmp3",
"bigquery": f"WITH __tmp1 AS (SELECT x1, x2 FROM x), __tmp2 AS (SELECT * FROM __tmp1), __tmp3 AS (SELECT * FROM __tmp2 {op_prefix} {op_operator} BY NAME SELECT y1, y2 FROM y {op_prefix} {op_operator} BY NAME SELECT z1, z2 FROM z) SELECT * FROM __tmp3",
},
)
@ -183,34 +183,30 @@ class TestPipeSyntax(Validator):
*
FROM __tmp2
UNION
(
SELECT
2 AS a1
)
SELECT
2 AS a1
), __tmp4 AS (
SELECT
*
x1
FROM __tmp3
), __tmp5 AS (
SELECT
x1
*
FROM __tmp4
), __tmp6 AS (
SELECT
*
FROM __tmp5
UNION
(
SELECT
3 AS a2
)
SELECT
3 AS a2
), __tmp7 AS (
SELECT
*
x1
FROM __tmp6
)
SELECT
x1
*
FROM __tmp7
WHERE
x1 > 100""",
@ -227,14 +223,11 @@ WHERE
*
FROM __tmp1
UNION ALL
(
SELECT
2 AS a1,
'2' AS a2
)
SELECT
2 AS a1,
'2' AS a2
), __tmp3 AS (
SELECT
*,
AVG(x1) AS m_x1
FROM __tmp2
), __tmp4 AS (
@ -250,18 +243,16 @@ WHERE
*
FROM __tmp5
UNION ALL
(
SELECT
y1
FROM c.y
)
SELECT
y1
FROM c.y
), __tmp7 AS (
SELECT
*
m_x1
FROM __tmp6
)
SELECT
m_x1
*
FROM __tmp7""",
pretty=True,
)
@ -277,11 +268,9 @@ FROM __tmp7""",
*
FROM __tmp1
UNION ALL
(
SELECT
2 AS a1,
'2' AS a2
)
SELECT
2 AS a1,
'2' AS a2
), __tmp3 AS (
SELECT
*
@ -291,11 +280,9 @@ FROM __tmp7""",
*
FROM __tmp3
UNION ALL
(
SELECT
y1
FROM c.y
)
SELECT
y1
FROM c.y
)
SELECT
*
@ -346,11 +333,9 @@ WHERE
*
FROM __tmp2
UNION ALL
(
SELECT
1,
2
)
SELECT
1,
2
)
SELECT
*
@ -378,3 +363,90 @@ WHERE
"FROM x |> JOIN y on x.id = y.id |> UNPIVOT(col FOR item IN (foo1, foo2))",
"WITH __tmp1 AS (SELECT * FROM x UNPIVOT(col FOR item IN (foo1, foo2)) JOIN y ON x.id = y.id) SELECT * FROM __tmp1",
)
def test_as(self):
self.validate_identity(
"FROM x |> AS a_x |> WHERE a_x.x1 > 0",
"WITH a_x AS (SELECT * FROM x) SELECT * FROM a_x WHERE a_x.x1 > 0",
)
self.validate_identity(
"FROM x AS t |> AGGREGATE SUM(x1) AS s_x1 GROUP BY id, x2 |> AS t1 |> JOIN y AS t2 ON t1.id = t2.id |> SELECT t2.id, s_x1",
"WITH __tmp1 AS (SELECT SUM(x1) AS s_x1, id, x2 FROM x AS t GROUP BY id, x2), t1 AS (SELECT * FROM __tmp1), __tmp2 AS (SELECT t2.id, s_x1 FROM t1 JOIN y AS t2 ON t1.id = t2.id) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> JOIN y ON x.x1 = y.y1 |> AS a |> WHERE a.x2 > 1",
"WITH a AS (SELECT * FROM x JOIN y ON x.x1 = y.y1) SELECT * FROM a WHERE a.x2 > 1",
)
def test_extend(self):
self.validate_identity(
"FROM x |> EXTEND id IN (1, 2) AS is_1_2, id + 1 as a_id",
"WITH __tmp1 AS (SELECT *, id IN (1, 2) AS is_1_2, id + 1 AS a_id FROM x) SELECT * FROM __tmp1",
)
self.validate_identity(
"FROM x |> SELECT x.x1, x.x2 |> EXTEND x1 + 1 as x1_1, x2 + 1 as x2_1 |> WHERE x1_1 > 0 AND x2_1 > 0",
"WITH __tmp1 AS (SELECT x.x1, x.x2 FROM x), __tmp2 AS (SELECT *, x1 + 1 AS x1_1, x2 + 1 AS x2_1 FROM __tmp1) SELECT * FROM __tmp2 WHERE x1_1 > 0 AND x2_1 > 0",
)
self.validate_identity(
"FROM (SELECT 'foo1' AS item1, 2 AS item2 UNION ALL SELECT 'foo2' AS item1, 5 AS item2) |> EXTEND SUM(item2) OVER() AS item2_sum",
"WITH __tmp1 AS (SELECT *, SUM(item2) OVER () AS item2_sum FROM (SELECT 'foo1' AS item1, 2 AS item2 UNION ALL SELECT 'foo2' AS item1, 5 AS item2)) SELECT * FROM __tmp1",
)
def test_drop(self):
self.validate_identity(
"FROM x |> DROP x1, x2",
"SELECT * EXCEPT (x1, x2) FROM x",
)
self.validate_identity("FROM x |> DROP x1 |> DROP x2", "SELECT * EXCEPT (x1, x2) FROM x")
self.validate_identity(
"FROM x |> SELECT x.x1, x.x2, x.x3 |> DROP x1, x2 |> WHERE x3 > 0",
"WITH __tmp1 AS (SELECT x.x1, x.x2, x.x3 FROM x) SELECT * EXCEPT (x1, x2) FROM __tmp1 WHERE x3 > 0",
)
self.validate_identity(
"FROM x |> SELECT x.x1, x.x2, x.x3 |> DROP x1, x2 |> WHERE x3 > 0",
"WITH __tmp1 AS (SELECT x.x1, x.x2, x.x3 FROM x) SELECT * EXCEPT (x1, x2) FROM __tmp1 WHERE x3 > 0",
)
self.validate_identity(
"FROM (SELECT 1 AS x, 2 AS y) AS t |> DROP x |> SELECT t.x AS original_x, y",
"WITH __tmp1 AS (SELECT * EXCEPT (x), t.x AS original_x FROM (SELECT 1 AS x, 2 AS y) AS t), __tmp2 AS (SELECT original_x, y FROM __tmp1) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2')) |> DROP Q1 |> SELECT *",
"WITH __tmp1 AS (SELECT * FROM x PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2'))), __tmp2 AS (SELECT * EXCEPT (Q1) FROM __tmp1), __tmp3 AS (SELECT * FROM __tmp2) SELECT * FROM __tmp3",
)
self.validate_identity(
"FROM x |> DROP x1 |> DROP x2 |> UNION ALL (SELECT 1 AS c)",
"WITH __tmp1 AS (SELECT * EXCEPT (x1, x2) FROM x), __tmp2 AS (SELECT * FROM __tmp1 UNION ALL SELECT 1 AS c) SELECT * FROM __tmp2",
)
def test_set(self):
self.validate_identity(
"FROM x |> SET x1 = 8 * x1", "SELECT * REPLACE (8 * x1 AS x1) FROM x"
)
self.validate_identity(
"FROM x |> SET x1 = 8 * x1 |> SET x2 = 2",
"SELECT * REPLACE (8 * x1 AS x1, 2 AS x2) FROM x",
)
self.validate_identity(
"FROM (SELECT 2 AS x, 3 AS y) AS t |> SET x = t.x * t.x, y = 8 |> SELECT t.x AS original_x, x, y",
"WITH __tmp1 AS (SELECT * REPLACE (t.x * t.x AS x, 8 AS y), t.x AS original_x FROM (SELECT 2 AS x, 3 AS y) AS t), __tmp2 AS (SELECT original_x, x, y FROM __tmp1) SELECT * FROM __tmp2",
)
self.validate_identity(
"FROM x |> DROP x1 |> DROP x2 |> SET x3 = 2 * x3 |> UNION ALL (SELECT 1 AS c)",
"WITH __tmp1 AS (SELECT * EXCEPT (x1, x2) REPLACE (2 * x3 AS x3) FROM x), __tmp2 AS (SELECT * FROM __tmp1 UNION ALL SELECT 1 AS c) SELECT * FROM __tmp2",
)
def test_tablesample(self):
self.validate_identity(
"FROM x |> TABLESAMPLE SYSTEM (1 PERCENT)",
"SELECT * FROM x TABLESAMPLE SYSTEM (1 PERCENT)",
)
self.validate_identity(
"FROM x |> SELECT x.x1 |> TABLESAMPLE SYSTEM (1 PERCENT)",
"WITH __tmp1 AS (SELECT x.x1 FROM x TABLESAMPLE SYSTEM (1 PERCENT)) SELECT * FROM __tmp1",
)
self.validate_identity(
"FROM x |> TABLESAMPLE SYSTEM (1 PERCENT) |> WHERE x.x1 > 0 |> SELECT x1, x2",
"WITH __tmp1 AS (SELECT x1, x2 FROM x WHERE x.x1 > 0 TABLESAMPLE SYSTEM (1 PERCENT)) SELECT * FROM __tmp1",
)

View file

@ -286,6 +286,14 @@ class TestSnowflake(Validator):
"CREATE TEMPORARY TABLE x (y NUMBER AUTOINCREMENT(0, 1))",
"CREATE TEMPORARY TABLE x (y DECIMAL(38, 0) AUTOINCREMENT START 0 INCREMENT 1)",
)
self.validate_identity(
"CREATE OR REPLACE TABLE x (y NUMBER(38, 0) NOT NULL AUTOINCREMENT START 1 INCREMENT 1 ORDER)",
"CREATE OR REPLACE TABLE x (y DECIMAL(38, 0) NOT NULL AUTOINCREMENT START 1 INCREMENT 1 ORDER)",
)
self.validate_identity(
"CREATE OR REPLACE TABLE x (y NUMBER(38, 0) NOT NULL AUTOINCREMENT START 1 INCREMENT 1 NOORDER)",
"CREATE OR REPLACE TABLE x (y DECIMAL(38, 0) NOT NULL AUTOINCREMENT START 1 INCREMENT 1 NOORDER)",
)
self.validate_identity(
"CREATE TABLE x (y NUMBER IDENTITY START 0 INCREMENT 1)",
"CREATE TABLE x (y DECIMAL(38, 0) AUTOINCREMENT START 0 INCREMENT 1)",
@ -325,13 +333,31 @@ class TestSnowflake(Validator):
"SELECT * FROM xxx, yyy, zzz",
)
self.validate_all(
"SELECT _u['foo'], bar, baz FROM TABLE(FLATTEN(INPUT => [OBJECT_CONSTRUCT('foo', 'x', 'bars', ['y', 'z'], 'bazs', ['w'])])) AS _t0(seq, key, path, index, _u, this), TABLE(FLATTEN(INPUT => _u['bars'])) AS _t1(seq, key, path, index, bar, this), TABLE(FLATTEN(INPUT => _u['bazs'])) AS _t2(seq, key, path, index, baz, this)",
read={
"bigquery": "SELECT _u.foo, bar, baz FROM UNNEST([struct('x' AS foo, ['y', 'z'] AS bars, ['w'] AS bazs)]) AS _u, UNNEST(_u.bars) AS bar, UNNEST(_u.bazs) AS baz",
},
)
self.validate_all(
"SELECT _u, _u['foo'], _u['bar'] FROM TABLE(FLATTEN(INPUT => [OBJECT_CONSTRUCT('foo', 'x', 'bar', 'y')])) AS _t0(seq, key, path, index, _u, this)",
read={
"bigquery": "select _u, _u.foo, _u.bar from unnest([struct('x' as foo, 'y' AS bar)]) as _u",
},
)
self.validate_all(
"SELECT _u['foo'][0].bar FROM TABLE(FLATTEN(INPUT => [OBJECT_CONSTRUCT('foo', [OBJECT_CONSTRUCT('bar', 1)])])) AS _t0(seq, key, path, index, _u, this)",
read={
"bigquery": "select _u.foo[0].bar from unnest([struct([struct(1 as bar)] as foo)]) as _u",
},
)
self.validate_all(
"SELECT ARRAY_INTERSECTION([1, 2], [2, 3])",
write={
"snowflake": "SELECT ARRAY_INTERSECTION([1, 2], [2, 3])",
"starrocks": "SELECT ARRAY_INTERSECT([1, 2], [2, 3])",
},
)
self.validate_all(
"CREATE TABLE test_table (id NUMERIC NOT NULL AUTOINCREMENT)",
write={
@ -1109,6 +1135,17 @@ class TestSnowflake(Validator):
},
)
self.validate_all(
"SELECT DATE_PART(DAYOFWEEKISO, foo)",
read={
"snowflake": "SELECT DATE_PART(WEEKDAY_ISO, foo)",
},
write={
"snowflake": "SELECT DATE_PART(DAYOFWEEKISO, foo)",
"duckdb": "SELECT EXTRACT(ISODOW FROM foo)",
},
)
def test_null_treatment(self):
self.validate_all(
r"SELECT FIRST_VALUE(TABLE1.COLUMN1) OVER (PARTITION BY RANDOM_COLUMN1, RANDOM_COLUMN2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MY_ALIAS FROM TABLE1",

View file

@ -1856,6 +1856,10 @@ WHERE
"spark": "SELECT * FROM A LIMIT 3",
},
)
self.validate_identity(
"CREATE TABLE schema.table AS SELECT a, id FROM (SELECT a, (SELECT id FROM tb ORDER BY t DESC LIMIT 1) as id FROM tbl) AS _subquery",
"SELECT * INTO schema.table FROM (SELECT a AS a, id AS id FROM (SELECT a AS a, (SELECT TOP 1 id FROM tb ORDER BY t DESC) AS id FROM tbl) AS _subquery) AS temp",
)
self.validate_identity("SELECT TOP 10 PERCENT")
self.validate_identity("SELECT TOP 10 PERCENT WITH TIES")

View file

@ -273,6 +273,11 @@ SELECT * FROM QUARTERLY_SALES AS QUARTERLY_SALES PIVOT(SUM(QUARTERLY_SALES.AMOUN
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x) AS x FROM t;
SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY t.x) AS x FROM t AS t;
# execute: false
# dialect: bigquery
WITH t AS (SELECT 1 AS c) SELECT TO_JSON_STRING(t) FROM t;
WITH t AS (SELECT 1 AS c) SELECT TO_JSON_STRING(t) AS _col_0 FROM t AS t;
--------------------------------------
-- Derived tables
--------------------------------------

View file

@ -1580,3 +1580,40 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
self.assertTrue(annotated.selects[0].is_type("INT"))
self.assertTrue(annotated.selects[1].is_type("VARCHAR"))
def test_annotate_table_as_struct_bigquery(self):
dialect = "bigquery"
schema = {"d": {"s": {"t": {"c1": "int64", "c2": "struct<f1 int64, f2 string>"}}}}
def _annotate(query: str) -> exp.Expression:
expression = parse_one(example_query, dialect=dialect)
qual = optimizer.qualify.qualify(expression, schema=schema, dialect=dialect)
return optimizer.annotate_types.annotate_types(qual, schema=schema, dialect=dialect)
example_query = "SELECT t FROM d.s.t"
annotated = _annotate(example_query)
self.assertIsInstance(annotated.selects[0].this, exp.TableColumn)
self.assertEqual(
annotated.sql("bigquery"), "SELECT `t` AS `_col_0` FROM `d`.`s`.`t` AS `t`"
)
self.assertTrue(
annotated.selects[0].is_type("STRUCT<c1 BIGINT, c2 STRUCT<f1 BIGINT, f2 TEXT>>")
)
example_query = "SELECT subq FROM (SELECT * from d.s.t) subq"
annotated = _annotate(example_query)
self.assertTrue(
annotated.selects[0].is_type("STRUCT<c1 BIGINT, c2 STRUCT<f1 BIGINT, f2 TEXT>>")
)
example_query = "WITH t AS (SELECT 1 AS c) SELECT t FROM t"
annotated = _annotate(example_query)
self.assertTrue(annotated.selects[0].is_type("STRUCT<c INT>"))
example_query = "WITH t AS (SELECT FOO() AS c) SELECT t FROM t"
annotated = _annotate(example_query)
self.assertTrue(annotated.selects[0].is_type("UNKNOWN"))