1
0
Fork 0

Adding upstream version 25.29.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:56:11 +01:00
parent dfac4c492f
commit c61927f460
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
97 changed files with 64720 additions and 61752 deletions

File diff suppressed because one or more lines are too long

View file

@ -76,8 +76,8 @@
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="n">__version_tuple__</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="n">version_tuple</span><span class="p">:</span> <span class="n">VERSION_TUPLE</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;25.25.1&#39;</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">25</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="n">__version__</span> <span class="o">=</span> <span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;25.28.0&#39;</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="n">__version_tuple__</span> <span class="o">=</span> <span class="n">version_tuple</span> <span class="o">=</span> <span class="p">(</span><span class="mi">25</span><span class="p">,</span> <span class="mi">28</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span></pre></div>
@ -97,7 +97,7 @@
<section id="version">
<div class="attr variable">
<span class="name">version</span><span class="annotation">: str</span> =
<span class="default_value">&#39;25.25.1&#39;</span>
<span class="default_value">&#39;25.28.0&#39;</span>
</div>
@ -109,7 +109,7 @@
<section id="version_tuple">
<div class="attr variable">
<span class="name">version_tuple</span><span class="annotation">: object</span> =
<span class="default_value">(25, 25, 1)</span>
<span class="default_value">(25, 28, 0)</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

View file

@ -1104,6 +1104,8 @@ Default: True</li>
<dd id="RisingWave.Generator.grantprincipal_sql" class="function"><a href="../generator.html#Generator.grantprincipal_sql">grantprincipal_sql</a></dd>
<dd id="RisingWave.Generator.columns_sql" class="function"><a href="../generator.html#Generator.columns_sql">columns_sql</a></dd>
<dd id="RisingWave.Generator.overlay_sql" class="function"><a href="../generator.html#Generator.overlay_sql">overlay_sql</a></dd>
<dd id="RisingWave.Generator.todouble_sql" class="function"><a href="../generator.html#Generator.todouble_sql">todouble_sql</a></dd>
<dd id="RisingWave.Generator.string_sql" class="function"><a href="../generator.html#Generator.string_sql">string_sql</a></dd>
</div>
<div><dt><a href="postgres.html#Postgres.Generator">sqlglot.dialects.postgres.Postgres.Generator</a></dt>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because 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

@ -1874,7 +1874,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;month&#39;, &#39;week&#39;, &#39;day&#39;, &#39;quarter&#39;, &#39;year_month&#39;}</span>
<span class="default_value">{&#39;year_month&#39;, &#39;quarter&#39;, &#39;week&#39;, &#39;day&#39;, &#39;month&#39;, &#39;year&#39;}</span>
</div>

View file

@ -586,7 +586,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#JSONPathRecursive">sqlglot.expressions.JSONPathRecursive</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</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;, &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#JSONPathScript">sqlglot.expressions.JSONPathScript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathRoot">sqlglot.expressions.JSONPathRoot</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#JSONPathSubscript">sqlglot.expressions.JSONPathSubscript</a>&#39;&gt;, &lt;class &#39;<a href="expressions.html#JSONPathWildcard">sqlglot.expressions.JSONPathWildcard</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#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#JSONPathUnion">sqlglot.expressions.JSONPathUnion</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>
</div>

File diff suppressed because one or more lines are too long

View file

@ -56,178 +56,195 @@
<label class="view-source-button" for="mod-eliminate_subqueries-view-source"><span>View Source</span></label>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="kn">import</span> <span class="nn">itertools</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">expressions</span> <span class="k">as</span> <span class="n">exp</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">find_new_name</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">build_scope</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="k">def</span> <span class="nf">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="sd"> Rewrite derived tables as CTES, deduplicating if possible.</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="sd"> Example:</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y&quot;)</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y&#39;</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a><span class="sd"> This also deduplicates common subqueries:</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z&quot;)</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z&#39;</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="sd"> Args:</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a><span class="sd"> expression (sqlglot.Expression): expression</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> Returns:</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="sd"> sqlglot.Expression: expression</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</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-29"><a href="#L-29"><span class="linenos"> 29</span></a> <span class="c1"># It&#39;s possible to have subqueries at the root, e.g. (SELECT * FROM x) LIMIT 1</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="n">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a> <span class="n">root</span> <span class="o">=</span> <span class="n">build_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">root</span><span class="p">:</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="c1"># Map of alias-&gt;Scope|Table</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a> <span class="c1"># These are all aliases that are already used in the expression.</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="c1"># We don&#39;t want to create new CTEs that conflict with these names.</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="n">taken</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="c1"># All CTE aliases in the root scope are taken</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="n">taken</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">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="c1"># All table names are taken</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="n">taken</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="p">{</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="n">source</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> <span class="n">source</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="p">}</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="p">)</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="c1"># Map of Expression-&gt;alias</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="c1"># Existing CTES in the root expression. We&#39;ll use this for deduplication.</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="n">existing_ctes</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</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;with&quot;</span><span class="p">)</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="k">if</span> <span class="n">with_</span><span class="p">:</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">with_</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;recursive&quot;</span><span class="p">)</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">existing_ctes</span><span class="p">[</span><span class="n">cte</span><span class="o">.</span><span class="n">this</span><span class="p">]</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="n">new_ctes</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="c1"># We&#39;re adding more CTEs, but we want to maintain the DAG order.</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="c1"># Derived tables within an existing CTE need to come before the existing CTE.</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="k">for</span> <span class="n">cte_scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="c1"># Append all the new CTEs from this existing CTE</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">cte_scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="k">if</span> <span class="n">scope</span> <span class="ow">is</span> <span class="n">cte_scope</span><span class="p">:</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="c1"># Don&#39;t try to eliminate this CTE itself</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="k">continue</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="c1"># Append the existing CTE itself</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cte_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="c1"># Now append the rest</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">union_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">table_scopes</span><span class="p">):</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">child_scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="kn">import</span> <span class="nn">itertools</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span> <span class="nn">sqlglot</span> <span class="kn">import</span> <span class="n">expressions</span> <span class="k">as</span> <span class="n">exp</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span> <span class="nn">sqlglot.helper</span> <span class="kn">import</span> <span class="n">find_new_name</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="kn">from</span> <span class="nn">sqlglot.optimizer.scope</span> <span class="kn">import</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">build_scope</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">TYPE_CHECKING</span><span class="p">:</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a> <span class="n">ExistingCTEsMapping</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a> <span class="n">TakenNameMapping</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="n">Scope</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]]</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a><span class="k">def</span> <span class="nf">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a><span class="sd"> Rewrite derived tables as CTES, deduplicating if possible.</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a><span class="sd"> Example:</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y&quot;)</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y&#39;</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> This also deduplicates common subqueries:</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z&quot;)</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z&#39;</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd"> Args:</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd"> expression (sqlglot.Expression): expression</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a><span class="sd"> Returns:</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a><span class="sd"> sqlglot.Expression: expression</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</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-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="c1"># It&#39;s possible to have subqueries at the root, e.g. (SELECT * FROM x) LIMIT 1</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="n">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="n">root</span> <span class="o">=</span> <span class="n">build_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">root</span><span class="p">:</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="c1"># Map of alias-&gt;Scope|Table</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="c1"># These are all aliases that are already used in the expression.</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="c1"># We don&#39;t want to create new CTEs that conflict with these names.</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a> <span class="c1"># All CTE aliases in the root scope are taken</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="n">taken</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">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="c1"># All table names are taken</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a> <span class="n">taken</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="p">{</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="n">source</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> <span class="n">source</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="p">}</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="p">)</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="c1"># Map of Expression-&gt;alias</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="c1"># Existing CTES in the root expression. We&#39;ll use this for deduplication.</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</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;with&quot;</span><span class="p">)</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="k">if</span> <span class="n">with_</span><span class="p">:</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">with_</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;recursive&quot;</span><span class="p">)</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">existing_ctes</span><span class="p">[</span><span class="n">cte</span><span class="o">.</span><span class="n">this</span><span class="p">]</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="n">new_ctes</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="c1"># We&#39;re adding more CTEs, but we want to maintain the DAG order.</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="c1"># Derived tables within an existing CTE need to come before the existing CTE.</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="k">for</span> <span class="n">cte_scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="c1"># Append all the new CTEs from this existing CTE</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">cte_scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="k">if</span> <span class="n">scope</span> <span class="ow">is</span> <span class="n">cte_scope</span><span class="p">:</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="c1"># Don&#39;t try to eliminate this CTE itself</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="k">continue</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="c1"># Append the existing CTE itself</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cte_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="k">if</span> <span class="n">new_ctes</span><span class="p">:</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DDL</span><span class="p">)</span> <span class="k">else</span> <span class="n">expression</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="n">query</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;with&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">new_ctes</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="n">recursive</span><span class="p">))</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="c1"># Now append the rest</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">union_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">table_scopes</span><span class="p">):</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">child_scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a><span class="k">def</span> <span class="nf">_eliminate</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">):</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">is_derived_table</span><span class="p">:</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="k">return</span> <span class="n">_eliminate_derived_table</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">new_ctes</span><span class="p">:</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DDL</span><span class="p">)</span> <span class="k">else</span> <span class="n">expression</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="n">query</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;with&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">new_ctes</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="n">recursive</span><span class="p">))</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">is_cte</span><span class="p">:</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="k">return</span> <span class="n">_eliminate_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a><span class="k">def</span> <span class="nf">_eliminate_derived_table</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">):</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a> <span class="c1"># This makes sure that we don&#39;t:</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="c1"># - drop the &quot;pivot&quot; arg from a pivoted subquery</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="c1"># - eliminate a lateral correlated subquery</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">pivots</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">parent</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-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="c1"># Get rid of redundant exp.Subquery expressions, i.e. those that are just used as wrappers</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="n">to_replace</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">parent</span><span class="o">.</span><span class="n">unwrap</span><span class="p">()</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span> <span class="o">=</span> <span class="n">_new_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">table_</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">alias</span><span class="o">=</span><span class="n">to_replace</span><span class="o">.</span><span class="n">alias</span> <span class="ow">or</span> <span class="n">name</span><span class="p">)</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">to_replace</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><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="k">return</span> <span class="n">cte</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a><span class="k">def</span> <span class="nf">_eliminate_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">):</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="n">parent</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">parent</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span> <span class="o">=</span> <span class="n">_new_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">parent</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="n">parent</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">with_</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="c1"># Rename references to this CTE</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="k">for</span> <span class="n">table</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">child_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="k">if</span> <span class="n">source</span> <span class="ow">is</span> <span class="n">scope</span><span class="p">:</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="n">new_table</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">table_</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">alias</span><span class="o">=</span><span class="n">table</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">table</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">new_table</span><span class="p">)</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="k">return</span> <span class="n">cte</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a><span class="k">def</span> <span class="nf">_eliminate</span><span class="p">(</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="n">scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span><span class="p">,</span> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]:</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">is_derived_table</span><span class="p">:</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="k">return</span> <span class="n">_eliminate_derived_table</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">is_cte</span><span class="p">:</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a> <span class="k">return</span> <span class="n">_eliminate_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a><span class="k">def</span> <span class="nf">_eliminate_derived_table</span><span class="p">(</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="n">scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span><span class="p">,</span> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]:</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="c1"># This makes sure that we don&#39;t:</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="c1"># - drop the &quot;pivot&quot; arg from a pivoted subquery</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="c1"># - eliminate a lateral correlated subquery</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">pivots</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">parent</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-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">return</span> <span class="kc">None</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="c1"># Get rid of redundant exp.Subquery expressions, i.e. those that are just used as wrappers</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="n">to_replace</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">parent</span><span class="o">.</span><span class="n">unwrap</span><span class="p">()</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span> <span class="o">=</span> <span class="n">_new_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="n">table</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">table_</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">alias</span><span class="o">=</span><span class="n">to_replace</span><span class="o">.</span><span class="n">alias</span> <span class="ow">or</span> <span class="n">name</span><span class="p">)</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">to_replace</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><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="k">return</span> <span class="n">cte</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a><span class="k">def</span> <span class="nf">_eliminate_cte</span><span class="p">(</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span><span class="p">,</span> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]:</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="n">parent</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">parent</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span> <span class="o">=</span> <span class="n">_new_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a><span class="k">def</span> <span class="nf">_new_cte</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">):</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a><span class="sd"> Returns:</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a><span class="sd"> tuple of (name, cte)</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a><span class="sd"> where `name` is a new name for this CTE in the root scope and `cte` is a new CTE instance.</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a><span class="sd"> If this CTE duplicates an existing CTE, `cte` will be None.</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="n">duplicate_cte_alias</span> <span class="o">=</span> <span class="n">existing_ctes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="n">parent</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">parent</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">parent</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">name</span><span class="p">:</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="o">=</span><span class="n">taken</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="s2">&quot;cte&quot;</span><span class="p">)</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">parent</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="n">parent</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="n">with_</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a> <span class="c1"># Rename references to this CTE</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a> <span class="k">for</span> <span class="n">table</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">child_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a> <span class="k">if</span> <span class="n">source</span> <span class="ow">is</span> <span class="n">scope</span><span class="p">:</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a> <span class="n">new_table</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">table_</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">alias</span><span class="o">=</span><span class="n">table</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a> <span class="n">table</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">new_table</span><span class="p">)</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a> <span class="k">return</span> <span class="n">cte</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a> <span class="k">if</span> <span class="n">duplicate_cte_alias</span><span class="p">:</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">duplicate_cte_alias</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="k">elif</span> <span class="n">taken</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="o">=</span><span class="n">taken</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a> <span class="n">taken</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">duplicate_cte_alias</span><span class="p">:</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="n">existing_ctes</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="o">=</span> <span class="n">name</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">CTE</span><span class="p">(</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="n">this</span><span class="o">=</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="n">alias</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">name</span><span class="p">)),</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="p">)</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="k">return</span> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="k">def</span> <span class="nf">_new_cte</span><span class="p">(</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="n">scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span><span class="p">,</span> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">]]:</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a><span class="sd"> Returns:</span>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a><span class="sd"> tuple of (name, cte)</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a><span class="sd"> where `name` is a new name for this CTE in the root scope and `cte` is a new CTE instance.</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a><span class="sd"> If this CTE duplicates an existing CTE, `cte` will be None.</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="n">duplicate_cte_alias</span> <span class="o">=</span> <span class="n">existing_ctes</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="n">parent</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">parent</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">parent</span><span class="o">.</span><span class="n">alias</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">name</span><span class="p">:</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="o">=</span><span class="n">taken</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="s2">&quot;cte&quot;</span><span class="p">)</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="k">if</span> <span class="n">duplicate_cte_alias</span><span class="p">:</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">duplicate_cte_alias</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="k">elif</span> <span class="n">taken</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="o">=</span><span class="n">taken</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="n">name</span><span class="p">)</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a> <span class="n">taken</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">duplicate_cte_alias</span><span class="p">:</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="n">existing_ctes</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="o">=</span> <span class="n">name</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">CTE</span><span class="p">(</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="n">this</span><span class="o">=</span><span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">,</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="n">alias</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">name</span><span class="p">)),</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="p">)</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">return</span> <span class="n">name</span><span class="p">,</span> <span class="n">cte</span>
</span></pre></div>
@ -237,100 +254,100 @@
<div class="attr function">
<span class="def">def</span>
<span class="name">eliminate_subqueries</span><span class="signature pdoc-code condensed">(<span class="param"><span class="n">expression</span></span><span class="return-annotation">):</span></span>
<span class="name">eliminate_subqueries</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span></span><span class="return-annotation">) -> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>:</span></span>
<label class="view-source-button" for="eliminate_subqueries-view-source"><span>View Source</span></label>
</div>
<a class="headerlink" href="#eliminate_subqueries"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="eliminate_subqueries-9"><a href="#eliminate_subqueries-9"><span class="linenos"> 9</span></a><span class="k">def</span> <span class="nf">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
</span><span id="eliminate_subqueries-10"><a href="#eliminate_subqueries-10"><span class="linenos">10</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="eliminate_subqueries-11"><a href="#eliminate_subqueries-11"><span class="linenos">11</span></a><span class="sd"> Rewrite derived tables as CTES, deduplicating if possible.</span>
</span><span id="eliminate_subqueries-12"><a href="#eliminate_subqueries-12"><span class="linenos">12</span></a>
</span><span id="eliminate_subqueries-13"><a href="#eliminate_subqueries-13"><span class="linenos">13</span></a><span class="sd"> Example:</span>
</span><span id="eliminate_subqueries-14"><a href="#eliminate_subqueries-14"><span class="linenos">14</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="eliminate_subqueries-15"><a href="#eliminate_subqueries-15"><span class="linenos">15</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y&quot;)</span>
</span><span id="eliminate_subqueries-16"><a href="#eliminate_subqueries-16"><span class="linenos">16</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="eliminate_subqueries-17"><a href="#eliminate_subqueries-17"><span class="linenos">17</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y&#39;</span>
</span><span id="eliminate_subqueries-18"><a href="#eliminate_subqueries-18"><span class="linenos">18</span></a>
</span><span id="eliminate_subqueries-19"><a href="#eliminate_subqueries-19"><span class="linenos">19</span></a><span class="sd"> This also deduplicates common subqueries:</span>
</span><span id="eliminate_subqueries-20"><a href="#eliminate_subqueries-20"><span class="linenos">20</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z&quot;)</span>
</span><span id="eliminate_subqueries-21"><a href="#eliminate_subqueries-21"><span class="linenos">21</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="eliminate_subqueries-22"><a href="#eliminate_subqueries-22"><span class="linenos">22</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z&#39;</span>
</span><span id="eliminate_subqueries-23"><a href="#eliminate_subqueries-23"><span class="linenos">23</span></a>
</span><span id="eliminate_subqueries-24"><a href="#eliminate_subqueries-24"><span class="linenos">24</span></a><span class="sd"> Args:</span>
</span><span id="eliminate_subqueries-25"><a href="#eliminate_subqueries-25"><span class="linenos">25</span></a><span class="sd"> expression (sqlglot.Expression): expression</span>
</span><span id="eliminate_subqueries-26"><a href="#eliminate_subqueries-26"><span class="linenos">26</span></a><span class="sd"> Returns:</span>
</span><span id="eliminate_subqueries-27"><a href="#eliminate_subqueries-27"><span class="linenos">27</span></a><span class="sd"> sqlglot.Expression: expression</span>
</span><span id="eliminate_subqueries-28"><a href="#eliminate_subqueries-28"><span class="linenos">28</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="eliminate_subqueries-29"><a href="#eliminate_subqueries-29"><span class="linenos">29</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span>
</span><span id="eliminate_subqueries-30"><a href="#eliminate_subqueries-30"><span class="linenos">30</span></a> <span class="c1"># It&#39;s possible to have subqueries at the root, e.g. (SELECT * FROM x) LIMIT 1</span>
</span><span id="eliminate_subqueries-31"><a href="#eliminate_subqueries-31"><span class="linenos">31</span></a> <span class="n">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="eliminate_subqueries-32"><a href="#eliminate_subqueries-32"><span class="linenos">32</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-33"><a href="#eliminate_subqueries-33"><span class="linenos">33</span></a>
</span><span id="eliminate_subqueries-34"><a href="#eliminate_subqueries-34"><span class="linenos">34</span></a> <span class="n">root</span> <span class="o">=</span> <span class="n">build_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="eliminate_subqueries-35"><a href="#eliminate_subqueries-35"><span class="linenos">35</span></a>
</span><span id="eliminate_subqueries-36"><a href="#eliminate_subqueries-36"><span class="linenos">36</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">root</span><span class="p">:</span>
</span><span id="eliminate_subqueries-37"><a href="#eliminate_subqueries-37"><span class="linenos">37</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-38"><a href="#eliminate_subqueries-38"><span class="linenos">38</span></a>
</span><span id="eliminate_subqueries-39"><a href="#eliminate_subqueries-39"><span class="linenos">39</span></a> <span class="c1"># Map of alias-&gt;Scope|Table</span>
</span><span id="eliminate_subqueries-40"><a href="#eliminate_subqueries-40"><span class="linenos">40</span></a> <span class="c1"># These are all aliases that are already used in the expression.</span>
</span><span id="eliminate_subqueries-41"><a href="#eliminate_subqueries-41"><span class="linenos">41</span></a> <span class="c1"># We don&#39;t want to create new CTEs that conflict with these names.</span>
</span><span id="eliminate_subqueries-42"><a href="#eliminate_subqueries-42"><span class="linenos">42</span></a> <span class="n">taken</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="eliminate_subqueries-43"><a href="#eliminate_subqueries-43"><span class="linenos">43</span></a>
</span><span id="eliminate_subqueries-44"><a href="#eliminate_subqueries-44"><span class="linenos">44</span></a> <span class="c1"># All CTE aliases in the root scope are taken</span>
</span><span id="eliminate_subqueries-45"><a href="#eliminate_subqueries-45"><span class="linenos">45</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-46"><a href="#eliminate_subqueries-46"><span class="linenos">46</span></a> <span class="n">taken</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">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="eliminate_subqueries-47"><a href="#eliminate_subqueries-47"><span class="linenos">47</span></a>
</span><span id="eliminate_subqueries-48"><a href="#eliminate_subqueries-48"><span class="linenos">48</span></a> <span class="c1"># All table names are taken</span>
</span><span id="eliminate_subqueries-49"><a href="#eliminate_subqueries-49"><span class="linenos">49</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-50"><a href="#eliminate_subqueries-50"><span class="linenos">50</span></a> <span class="n">taken</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
</span><span id="eliminate_subqueries-51"><a href="#eliminate_subqueries-51"><span class="linenos">51</span></a> <span class="p">{</span>
</span><span id="eliminate_subqueries-52"><a href="#eliminate_subqueries-52"><span class="linenos">52</span></a> <span class="n">source</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> <span class="n">source</span>
</span><span id="eliminate_subqueries-53"><a href="#eliminate_subqueries-53"><span class="linenos">53</span></a> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span><span id="eliminate_subqueries-54"><a href="#eliminate_subqueries-54"><span class="linenos">54</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="eliminate_subqueries-55"><a href="#eliminate_subqueries-55"><span class="linenos">55</span></a> <span class="p">}</span>
</span><span id="eliminate_subqueries-56"><a href="#eliminate_subqueries-56"><span class="linenos">56</span></a> <span class="p">)</span>
</span><span id="eliminate_subqueries-57"><a href="#eliminate_subqueries-57"><span class="linenos">57</span></a>
</span><span id="eliminate_subqueries-58"><a href="#eliminate_subqueries-58"><span class="linenos">58</span></a> <span class="c1"># Map of Expression-&gt;alias</span>
</span><span id="eliminate_subqueries-59"><a href="#eliminate_subqueries-59"><span class="linenos">59</span></a> <span class="c1"># Existing CTES in the root expression. We&#39;ll use this for deduplication.</span>
</span><span id="eliminate_subqueries-60"><a href="#eliminate_subqueries-60"><span class="linenos">60</span></a> <span class="n">existing_ctes</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="eliminate_subqueries-61"><a href="#eliminate_subqueries-61"><span class="linenos">61</span></a>
</span><span id="eliminate_subqueries-62"><a href="#eliminate_subqueries-62"><span class="linenos">62</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</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;with&quot;</span><span class="p">)</span>
</span><span id="eliminate_subqueries-63"><a href="#eliminate_subqueries-63"><span class="linenos">63</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="eliminate_subqueries-64"><a href="#eliminate_subqueries-64"><span class="linenos">64</span></a> <span class="k">if</span> <span class="n">with_</span><span class="p">:</span>
</span><span id="eliminate_subqueries-65"><a href="#eliminate_subqueries-65"><span class="linenos">65</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">with_</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;recursive&quot;</span><span class="p">)</span>
</span><span id="eliminate_subqueries-66"><a href="#eliminate_subqueries-66"><span class="linenos">66</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="eliminate_subqueries-67"><a href="#eliminate_subqueries-67"><span class="linenos">67</span></a> <span class="n">existing_ctes</span><span class="p">[</span><span class="n">cte</span><span class="o">.</span><span class="n">this</span><span class="p">]</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">alias</span>
</span><span id="eliminate_subqueries-68"><a href="#eliminate_subqueries-68"><span class="linenos">68</span></a> <span class="n">new_ctes</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="eliminate_subqueries-69"><a href="#eliminate_subqueries-69"><span class="linenos">69</span></a>
</span><span id="eliminate_subqueries-70"><a href="#eliminate_subqueries-70"><span class="linenos">70</span></a> <span class="c1"># We&#39;re adding more CTEs, but we want to maintain the DAG order.</span>
</span><span id="eliminate_subqueries-71"><a href="#eliminate_subqueries-71"><span class="linenos">71</span></a> <span class="c1"># Derived tables within an existing CTE need to come before the existing CTE.</span>
</span><span id="eliminate_subqueries-72"><a href="#eliminate_subqueries-72"><span class="linenos">72</span></a> <span class="k">for</span> <span class="n">cte_scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-73"><a href="#eliminate_subqueries-73"><span class="linenos">73</span></a> <span class="c1"># Append all the new CTEs from this existing CTE</span>
</span><span id="eliminate_subqueries-74"><a href="#eliminate_subqueries-74"><span class="linenos">74</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">cte_scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-75"><a href="#eliminate_subqueries-75"><span class="linenos">75</span></a> <span class="k">if</span> <span class="n">scope</span> <span class="ow">is</span> <span class="n">cte_scope</span><span class="p">:</span>
</span><span id="eliminate_subqueries-76"><a href="#eliminate_subqueries-76"><span class="linenos">76</span></a> <span class="c1"># Don&#39;t try to eliminate this CTE itself</span>
</span><span id="eliminate_subqueries-77"><a href="#eliminate_subqueries-77"><span class="linenos">77</span></a> <span class="k">continue</span>
</span><span id="eliminate_subqueries-78"><a href="#eliminate_subqueries-78"><span class="linenos">78</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="eliminate_subqueries-79"><a href="#eliminate_subqueries-79"><span class="linenos">79</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="eliminate_subqueries-80"><a href="#eliminate_subqueries-80"><span class="linenos">80</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="eliminate_subqueries-81"><a href="#eliminate_subqueries-81"><span class="linenos">81</span></a>
</span><span id="eliminate_subqueries-82"><a href="#eliminate_subqueries-82"><span class="linenos">82</span></a> <span class="c1"># Append the existing CTE itself</span>
</span><span id="eliminate_subqueries-83"><a href="#eliminate_subqueries-83"><span class="linenos">83</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cte_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="eliminate_subqueries-84"><a href="#eliminate_subqueries-84"><span class="linenos">84</span></a>
</span><span id="eliminate_subqueries-85"><a href="#eliminate_subqueries-85"><span class="linenos">85</span></a> <span class="c1"># Now append the rest</span>
</span><span id="eliminate_subqueries-86"><a href="#eliminate_subqueries-86"><span class="linenos">86</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">union_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">table_scopes</span><span class="p">):</span>
</span><span id="eliminate_subqueries-87"><a href="#eliminate_subqueries-87"><span class="linenos">87</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-88"><a href="#eliminate_subqueries-88"><span class="linenos">88</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">child_scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="eliminate_subqueries-89"><a href="#eliminate_subqueries-89"><span class="linenos">89</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="eliminate_subqueries-90"><a href="#eliminate_subqueries-90"><span class="linenos">90</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="eliminate_subqueries-91"><a href="#eliminate_subqueries-91"><span class="linenos">91</span></a>
</span><span id="eliminate_subqueries-92"><a href="#eliminate_subqueries-92"><span class="linenos">92</span></a> <span class="k">if</span> <span class="n">new_ctes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-93"><a href="#eliminate_subqueries-93"><span class="linenos">93</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DDL</span><span class="p">)</span> <span class="k">else</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-94"><a href="#eliminate_subqueries-94"><span class="linenos">94</span></a> <span class="n">query</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;with&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">new_ctes</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="n">recursive</span><span class="p">))</span>
</span><span id="eliminate_subqueries-95"><a href="#eliminate_subqueries-95"><span class="linenos">95</span></a>
</span><span id="eliminate_subqueries-96"><a href="#eliminate_subqueries-96"><span class="linenos">96</span></a> <span class="k">return</span> <span class="n">expression</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="eliminate_subqueries-16"><a href="#eliminate_subqueries-16"><span class="linenos"> 16</span></a><span class="k">def</span> <span class="nf">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="p">:</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="eliminate_subqueries-17"><a href="#eliminate_subqueries-17"><span class="linenos"> 17</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="eliminate_subqueries-18"><a href="#eliminate_subqueries-18"><span class="linenos"> 18</span></a><span class="sd"> Rewrite derived tables as CTES, deduplicating if possible.</span>
</span><span id="eliminate_subqueries-19"><a href="#eliminate_subqueries-19"><span class="linenos"> 19</span></a>
</span><span id="eliminate_subqueries-20"><a href="#eliminate_subqueries-20"><span class="linenos"> 20</span></a><span class="sd"> Example:</span>
</span><span id="eliminate_subqueries-21"><a href="#eliminate_subqueries-21"><span class="linenos"> 21</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="eliminate_subqueries-22"><a href="#eliminate_subqueries-22"><span class="linenos"> 22</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y&quot;)</span>
</span><span id="eliminate_subqueries-23"><a href="#eliminate_subqueries-23"><span class="linenos"> 23</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="eliminate_subqueries-24"><a href="#eliminate_subqueries-24"><span class="linenos"> 24</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y&#39;</span>
</span><span id="eliminate_subqueries-25"><a href="#eliminate_subqueries-25"><span class="linenos"> 25</span></a>
</span><span id="eliminate_subqueries-26"><a href="#eliminate_subqueries-26"><span class="linenos"> 26</span></a><span class="sd"> This also deduplicates common subqueries:</span>
</span><span id="eliminate_subqueries-27"><a href="#eliminate_subqueries-27"><span class="linenos"> 27</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z&quot;)</span>
</span><span id="eliminate_subqueries-28"><a href="#eliminate_subqueries-28"><span class="linenos"> 28</span></a><span class="sd"> &gt;&gt;&gt; eliminate_subqueries(expression).sql()</span>
</span><span id="eliminate_subqueries-29"><a href="#eliminate_subqueries-29"><span class="linenos"> 29</span></a><span class="sd"> &#39;WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z&#39;</span>
</span><span id="eliminate_subqueries-30"><a href="#eliminate_subqueries-30"><span class="linenos"> 30</span></a>
</span><span id="eliminate_subqueries-31"><a href="#eliminate_subqueries-31"><span class="linenos"> 31</span></a><span class="sd"> Args:</span>
</span><span id="eliminate_subqueries-32"><a href="#eliminate_subqueries-32"><span class="linenos"> 32</span></a><span class="sd"> expression (sqlglot.Expression): expression</span>
</span><span id="eliminate_subqueries-33"><a href="#eliminate_subqueries-33"><span class="linenos"> 33</span></a><span class="sd"> Returns:</span>
</span><span id="eliminate_subqueries-34"><a href="#eliminate_subqueries-34"><span class="linenos"> 34</span></a><span class="sd"> sqlglot.Expression: expression</span>
</span><span id="eliminate_subqueries-35"><a href="#eliminate_subqueries-35"><span class="linenos"> 35</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="eliminate_subqueries-36"><a href="#eliminate_subqueries-36"><span class="linenos"> 36</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Subquery</span><span class="p">):</span>
</span><span id="eliminate_subqueries-37"><a href="#eliminate_subqueries-37"><span class="linenos"> 37</span></a> <span class="c1"># It&#39;s possible to have subqueries at the root, e.g. (SELECT * FROM x) LIMIT 1</span>
</span><span id="eliminate_subqueries-38"><a href="#eliminate_subqueries-38"><span class="linenos"> 38</span></a> <span class="n">eliminate_subqueries</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="eliminate_subqueries-39"><a href="#eliminate_subqueries-39"><span class="linenos"> 39</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-40"><a href="#eliminate_subqueries-40"><span class="linenos"> 40</span></a>
</span><span id="eliminate_subqueries-41"><a href="#eliminate_subqueries-41"><span class="linenos"> 41</span></a> <span class="n">root</span> <span class="o">=</span> <span class="n">build_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="eliminate_subqueries-42"><a href="#eliminate_subqueries-42"><span class="linenos"> 42</span></a>
</span><span id="eliminate_subqueries-43"><a href="#eliminate_subqueries-43"><span class="linenos"> 43</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">root</span><span class="p">:</span>
</span><span id="eliminate_subqueries-44"><a href="#eliminate_subqueries-44"><span class="linenos"> 44</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-45"><a href="#eliminate_subqueries-45"><span class="linenos"> 45</span></a>
</span><span id="eliminate_subqueries-46"><a href="#eliminate_subqueries-46"><span class="linenos"> 46</span></a> <span class="c1"># Map of alias-&gt;Scope|Table</span>
</span><span id="eliminate_subqueries-47"><a href="#eliminate_subqueries-47"><span class="linenos"> 47</span></a> <span class="c1"># These are all aliases that are already used in the expression.</span>
</span><span id="eliminate_subqueries-48"><a href="#eliminate_subqueries-48"><span class="linenos"> 48</span></a> <span class="c1"># We don&#39;t want to create new CTEs that conflict with these names.</span>
</span><span id="eliminate_subqueries-49"><a href="#eliminate_subqueries-49"><span class="linenos"> 49</span></a> <span class="n">taken</span><span class="p">:</span> <span class="n">TakenNameMapping</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="eliminate_subqueries-50"><a href="#eliminate_subqueries-50"><span class="linenos"> 50</span></a>
</span><span id="eliminate_subqueries-51"><a href="#eliminate_subqueries-51"><span class="linenos"> 51</span></a> <span class="c1"># All CTE aliases in the root scope are taken</span>
</span><span id="eliminate_subqueries-52"><a href="#eliminate_subqueries-52"><span class="linenos"> 52</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-53"><a href="#eliminate_subqueries-53"><span class="linenos"> 53</span></a> <span class="n">taken</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">parent</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span>
</span><span id="eliminate_subqueries-54"><a href="#eliminate_subqueries-54"><span class="linenos"> 54</span></a>
</span><span id="eliminate_subqueries-55"><a href="#eliminate_subqueries-55"><span class="linenos"> 55</span></a> <span class="c1"># All table names are taken</span>
</span><span id="eliminate_subqueries-56"><a href="#eliminate_subqueries-56"><span class="linenos"> 56</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-57"><a href="#eliminate_subqueries-57"><span class="linenos"> 57</span></a> <span class="n">taken</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
</span><span id="eliminate_subqueries-58"><a href="#eliminate_subqueries-58"><span class="linenos"> 58</span></a> <span class="p">{</span>
</span><span id="eliminate_subqueries-59"><a href="#eliminate_subqueries-59"><span class="linenos"> 59</span></a> <span class="n">source</span><span class="o">.</span><span class="n">name</span><span class="p">:</span> <span class="n">source</span>
</span><span id="eliminate_subqueries-60"><a href="#eliminate_subqueries-60"><span class="linenos"> 60</span></a> <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span><span id="eliminate_subqueries-61"><a href="#eliminate_subqueries-61"><span class="linenos"> 61</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">)</span>
</span><span id="eliminate_subqueries-62"><a href="#eliminate_subqueries-62"><span class="linenos"> 62</span></a> <span class="p">}</span>
</span><span id="eliminate_subqueries-63"><a href="#eliminate_subqueries-63"><span class="linenos"> 63</span></a> <span class="p">)</span>
</span><span id="eliminate_subqueries-64"><a href="#eliminate_subqueries-64"><span class="linenos"> 64</span></a>
</span><span id="eliminate_subqueries-65"><a href="#eliminate_subqueries-65"><span class="linenos"> 65</span></a> <span class="c1"># Map of Expression-&gt;alias</span>
</span><span id="eliminate_subqueries-66"><a href="#eliminate_subqueries-66"><span class="linenos"> 66</span></a> <span class="c1"># Existing CTES in the root expression. We&#39;ll use this for deduplication.</span>
</span><span id="eliminate_subqueries-67"><a href="#eliminate_subqueries-67"><span class="linenos"> 67</span></a> <span class="n">existing_ctes</span><span class="p">:</span> <span class="n">ExistingCTEsMapping</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="eliminate_subqueries-68"><a href="#eliminate_subqueries-68"><span class="linenos"> 68</span></a>
</span><span id="eliminate_subqueries-69"><a href="#eliminate_subqueries-69"><span class="linenos"> 69</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">root</span><span class="o">.</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;with&quot;</span><span class="p">)</span>
</span><span id="eliminate_subqueries-70"><a href="#eliminate_subqueries-70"><span class="linenos"> 70</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="eliminate_subqueries-71"><a href="#eliminate_subqueries-71"><span class="linenos"> 71</span></a> <span class="k">if</span> <span class="n">with_</span><span class="p">:</span>
</span><span id="eliminate_subqueries-72"><a href="#eliminate_subqueries-72"><span class="linenos"> 72</span></a> <span class="n">recursive</span> <span class="o">=</span> <span class="n">with_</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;recursive&quot;</span><span class="p">)</span>
</span><span id="eliminate_subqueries-73"><a href="#eliminate_subqueries-73"><span class="linenos"> 73</span></a> <span class="k">for</span> <span class="n">cte</span> <span class="ow">in</span> <span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="eliminate_subqueries-74"><a href="#eliminate_subqueries-74"><span class="linenos"> 74</span></a> <span class="n">existing_ctes</span><span class="p">[</span><span class="n">cte</span><span class="o">.</span><span class="n">this</span><span class="p">]</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">alias</span>
</span><span id="eliminate_subqueries-75"><a href="#eliminate_subqueries-75"><span class="linenos"> 75</span></a> <span class="n">new_ctes</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="eliminate_subqueries-76"><a href="#eliminate_subqueries-76"><span class="linenos"> 76</span></a>
</span><span id="eliminate_subqueries-77"><a href="#eliminate_subqueries-77"><span class="linenos"> 77</span></a> <span class="c1"># We&#39;re adding more CTEs, but we want to maintain the DAG order.</span>
</span><span id="eliminate_subqueries-78"><a href="#eliminate_subqueries-78"><span class="linenos"> 78</span></a> <span class="c1"># Derived tables within an existing CTE need to come before the existing CTE.</span>
</span><span id="eliminate_subqueries-79"><a href="#eliminate_subqueries-79"><span class="linenos"> 79</span></a> <span class="k">for</span> <span class="n">cte_scope</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">cte_scopes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-80"><a href="#eliminate_subqueries-80"><span class="linenos"> 80</span></a> <span class="c1"># Append all the new CTEs from this existing CTE</span>
</span><span id="eliminate_subqueries-81"><a href="#eliminate_subqueries-81"><span class="linenos"> 81</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">cte_scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-82"><a href="#eliminate_subqueries-82"><span class="linenos"> 82</span></a> <span class="k">if</span> <span class="n">scope</span> <span class="ow">is</span> <span class="n">cte_scope</span><span class="p">:</span>
</span><span id="eliminate_subqueries-83"><a href="#eliminate_subqueries-83"><span class="linenos"> 83</span></a> <span class="c1"># Don&#39;t try to eliminate this CTE itself</span>
</span><span id="eliminate_subqueries-84"><a href="#eliminate_subqueries-84"><span class="linenos"> 84</span></a> <span class="k">continue</span>
</span><span id="eliminate_subqueries-85"><a href="#eliminate_subqueries-85"><span class="linenos"> 85</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="eliminate_subqueries-86"><a href="#eliminate_subqueries-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="eliminate_subqueries-87"><a href="#eliminate_subqueries-87"><span class="linenos"> 87</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="eliminate_subqueries-88"><a href="#eliminate_subqueries-88"><span class="linenos"> 88</span></a>
</span><span id="eliminate_subqueries-89"><a href="#eliminate_subqueries-89"><span class="linenos"> 89</span></a> <span class="c1"># Append the existing CTE itself</span>
</span><span id="eliminate_subqueries-90"><a href="#eliminate_subqueries-90"><span class="linenos"> 90</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cte_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span><span class="p">)</span>
</span><span id="eliminate_subqueries-91"><a href="#eliminate_subqueries-91"><span class="linenos"> 91</span></a>
</span><span id="eliminate_subqueries-92"><a href="#eliminate_subqueries-92"><span class="linenos"> 92</span></a> <span class="c1"># Now append the rest</span>
</span><span id="eliminate_subqueries-93"><a href="#eliminate_subqueries-93"><span class="linenos"> 93</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">union_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">subquery_scopes</span><span class="p">,</span> <span class="n">root</span><span class="o">.</span><span class="n">table_scopes</span><span class="p">):</span>
</span><span id="eliminate_subqueries-94"><a href="#eliminate_subqueries-94"><span class="linenos"> 94</span></a> <span class="k">for</span> <span class="n">child_scope</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">traverse</span><span class="p">():</span>
</span><span id="eliminate_subqueries-95"><a href="#eliminate_subqueries-95"><span class="linenos"> 95</span></a> <span class="n">new_cte</span> <span class="o">=</span> <span class="n">_eliminate</span><span class="p">(</span><span class="n">child_scope</span><span class="p">,</span> <span class="n">existing_ctes</span><span class="p">,</span> <span class="n">taken</span><span class="p">)</span>
</span><span id="eliminate_subqueries-96"><a href="#eliminate_subqueries-96"><span class="linenos"> 96</span></a> <span class="k">if</span> <span class="n">new_cte</span><span class="p">:</span>
</span><span id="eliminate_subqueries-97"><a href="#eliminate_subqueries-97"><span class="linenos"> 97</span></a> <span class="n">new_ctes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_cte</span><span class="p">)</span>
</span><span id="eliminate_subqueries-98"><a href="#eliminate_subqueries-98"><span class="linenos"> 98</span></a>
</span><span id="eliminate_subqueries-99"><a href="#eliminate_subqueries-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">new_ctes</span><span class="p">:</span>
</span><span id="eliminate_subqueries-100"><a href="#eliminate_subqueries-100"><span class="linenos">100</span></a> <span class="n">query</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">expression</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DDL</span><span class="p">)</span> <span class="k">else</span> <span class="n">expression</span>
</span><span id="eliminate_subqueries-101"><a href="#eliminate_subqueries-101"><span class="linenos">101</span></a> <span class="n">query</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;with&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">With</span><span class="p">(</span><span class="n">expressions</span><span class="o">=</span><span class="n">new_ctes</span><span class="p">,</span> <span class="n">recursive</span><span class="o">=</span><span class="n">recursive</span><span class="p">))</span>
</span><span id="eliminate_subqueries-102"><a href="#eliminate_subqueries-102"><span class="linenos">102</span></a>
</span><span id="eliminate_subqueries-103"><a href="#eliminate_subqueries-103"><span class="linenos">103</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div>

File diff suppressed because it is too large Load diff

View file

@ -85,78 +85,81 @@
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a> <span class="n">infer_schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a> <span class="n">isolate_tables</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a> <span class="n">qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a><span class="sd"> Rewrite sqlglot AST to have normalized and qualified tables and columns.</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a><span class="sd"> This step is necessary for all further SQLGlot optimizations.</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a><span class="sd"> Example:</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a><span class="sd"> &gt;&gt;&gt; schema = {&quot;tbl&quot;: {&quot;col&quot;: &quot;INT&quot;}}</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT col FROM tbl&quot;)</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="sd"> &gt;&gt;&gt; qualify(expression, schema=schema).sql()</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a><span class="sd"> &#39;SELECT &quot;tbl&quot;.&quot;col&quot; AS &quot;col&quot; FROM &quot;tbl&quot; AS &quot;tbl&quot;&#39;</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a><span class="sd"> Args:</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a><span class="sd"> expression: Expression to qualify.</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a><span class="sd"> db: Default database name for tables.</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a><span class="sd"> catalog: Default catalog name for tables.</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a><span class="sd"> schema: Schema to infer column names and types.</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a><span class="sd"> expand_alias_refs: Whether to expand references to aliases.</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a><span class="sd"> expand_stars: Whether to expand star queries. This is a necessary step</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a><span class="sd"> for most of the optimizer&#39;s rules to work; do not set to False unless you</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a><span class="sd"> know what you&#39;re doing!</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a><span class="sd"> infer_schema: Whether to infer the schema if missing.</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a><span class="sd"> isolate_tables: Whether to isolate table selects.</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a><span class="sd"> qualify_columns: Whether to qualify columns.</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a><span class="sd"> validate_qualify_columns: Whether to validate columns.</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a><span class="sd"> quote_identifiers: Whether to run the quote_identifiers step.</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a><span class="sd"> This step is necessary to ensure correctness for case sensitive queries.</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a><span class="sd"> But this flag is provided in case this step is performed at a later time.</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a><span class="sd"> identify: If True, quote all identifiers, else only necessary ones.</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a><span class="sd"> infer_csv_schemas: Whether to scan READ_CSV calls in order to infer the CSVs&#39; schemas.</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a><span class="sd"> Returns:</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a><span class="sd"> The qualified expression.</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">,</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">infer_csv_schemas</span><span class="o">=</span><span class="n">infer_csv_schemas</span><span class="p">,</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="p">)</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="k">if</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">PREFER_CTE_ALIAS_COLUMN</span><span class="p">:</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">pushdown_cte_alias_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="n">qualify_columns</span><span class="p">:</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_columns_func</span><span class="p">(</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">schema</span><span class="p">,</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">expand_alias_refs</span><span class="o">=</span><span class="n">expand_alias_refs</span><span class="p">,</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="n">expand_stars</span><span class="o">=</span><span class="n">expand_stars</span><span class="p">,</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">infer_schema</span><span class="o">=</span><span class="n">infer_schema</span><span class="p">,</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="p">)</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="k">if</span> <span class="n">quote_identifiers</span><span class="p">:</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">quote_identifiers_func</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span> <span class="n">identify</span><span class="o">=</span><span class="n">identify</span><span class="p">)</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a> <span class="n">allow_partial_qualification</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a><span class="sd"> Rewrite sqlglot AST to have normalized and qualified tables and columns.</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a>
</span><span id="L-39"><a href="#L-39"><span class="linenos"> 39</span></a><span class="sd"> This step is necessary for all further SQLGlot optimizations.</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a><span class="sd"> Example:</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a><span class="sd"> &gt;&gt;&gt; schema = {&quot;tbl&quot;: {&quot;col&quot;: &quot;INT&quot;}}</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT col FROM tbl&quot;)</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a><span class="sd"> &gt;&gt;&gt; qualify(expression, schema=schema).sql()</span>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a><span class="sd"> &#39;SELECT &quot;tbl&quot;.&quot;col&quot; AS &quot;col&quot; FROM &quot;tbl&quot; AS &quot;tbl&quot;&#39;</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a><span class="sd"> Args:</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a><span class="sd"> expression: Expression to qualify.</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a><span class="sd"> db: Default database name for tables.</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a><span class="sd"> catalog: Default catalog name for tables.</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a><span class="sd"> schema: Schema to infer column names and types.</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a><span class="sd"> expand_alias_refs: Whether to expand references to aliases.</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a><span class="sd"> expand_stars: Whether to expand star queries. This is a necessary step</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a><span class="sd"> for most of the optimizer&#39;s rules to work; do not set to False unless you</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a><span class="sd"> know what you&#39;re doing!</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a><span class="sd"> infer_schema: Whether to infer the schema if missing.</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a><span class="sd"> isolate_tables: Whether to isolate table selects.</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a><span class="sd"> qualify_columns: Whether to qualify columns.</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a><span class="sd"> allow_partial_qualification: Whether to allow partial qualification.</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a><span class="sd"> validate_qualify_columns: Whether to validate columns.</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a><span class="sd"> quote_identifiers: Whether to run the quote_identifiers step.</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a><span class="sd"> This step is necessary to ensure correctness for case sensitive queries.</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a><span class="sd"> But this flag is provided in case this step is performed at a later time.</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a><span class="sd"> identify: If True, quote all identifiers, else only necessary ones.</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a><span class="sd"> infer_csv_schemas: Whether to scan READ_CSV calls in order to infer the CSVs&#39; schemas.</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a><span class="sd"> Returns:</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a><span class="sd"> The qualified expression.</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">,</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="n">infer_csv_schemas</span><span class="o">=</span><span class="n">infer_csv_schemas</span><span class="p">,</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="p">)</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="k">if</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">PREFER_CTE_ALIAS_COLUMN</span><span class="p">:</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">pushdown_cte_alias_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="n">qualify_columns</span><span class="p">:</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_columns_func</span><span class="p">(</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a> <span class="n">schema</span><span class="p">,</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">expand_alias_refs</span><span class="o">=</span><span class="n">expand_alias_refs</span><span class="p">,</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="n">expand_stars</span><span class="o">=</span><span class="n">expand_stars</span><span class="p">,</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">infer_schema</span><span class="o">=</span><span class="n">infer_schema</span><span class="p">,</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="n">allow_partial_qualification</span><span class="o">=</span><span class="n">allow_partial_qualification</span><span class="p">,</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="p">)</span>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">validate_qualify_columns</span><span class="p">:</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">validate_qualify_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="k">if</span> <span class="n">quote_identifiers</span><span class="p">:</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">quote_identifiers_func</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span> <span class="n">identify</span><span class="o">=</span><span class="n">identify</span><span class="p">)</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="k">if</span> <span class="n">validate_qualify_columns</span><span class="p">:</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a> <span class="n">validate_qualify_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div>
@ -166,7 +169,7 @@
<div class="attr function">
<span class="def">def</span>
<span class="name">qualify</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>,</span><span class="param"> <span class="n">dialect</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n"><a href="../dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></span><span class="p">,</span> <span class="n">Type</span><span class="p">[</span><span class="n"><a href="../dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></span><span class="p">],</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">db</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">catalog</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">schema</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n"><a href="../schema.html#Schema">sqlglot.schema.Schema</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">expand_alias_refs</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">expand_stars</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">infer_schema</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">isolate_tables</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>,</span><span class="param"> <span class="n">qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span></span><span class="return-annotation">) -> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>:</span></span>
<span class="name">qualify</span><span class="signature pdoc-code multiline">(<span class="param"> <span class="n">expression</span><span class="p">:</span> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>,</span><span class="param"> <span class="n">dialect</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n"><a href="../dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></span><span class="p">,</span> <span class="n">Type</span><span class="p">[</span><span class="n"><a href="../dialects/dialect.html#Dialect">sqlglot.dialects.dialect.Dialect</a></span><span class="p">],</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">db</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">catalog</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">schema</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">dict</span><span class="p">,</span> <span class="n"><a href="../schema.html#Schema">sqlglot.schema.Schema</a></span><span class="p">,</span> <span class="n">NoneType</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">expand_alias_refs</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">expand_stars</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">infer_schema</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>,</span><span class="param"> <span class="n">isolate_tables</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>,</span><span class="param"> <span class="n">qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">allow_partial_qualification</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>,</span><span class="param"> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span>,</span><span class="param"> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span></span><span class="return-annotation">) -> <span class="n"><a href="../expressions.html#Expression">sqlglot.expressions.Expression</a></span>:</span></span>
<label class="view-source-button" for="qualify-view-source"><span>View Source</span></label>
@ -183,78 +186,81 @@
</span><span id="qualify-28"><a href="#qualify-28"><span class="linenos"> 28</span></a> <span class="n">infer_schema</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span><span id="qualify-29"><a href="#qualify-29"><span class="linenos"> 29</span></a> <span class="n">isolate_tables</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="qualify-30"><a href="#qualify-30"><span class="linenos"> 30</span></a> <span class="n">qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-31"><a href="#qualify-31"><span class="linenos"> 31</span></a> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-32"><a href="#qualify-32"><span class="linenos"> 32</span></a> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-33"><a href="#qualify-33"><span class="linenos"> 33</span></a> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-34"><a href="#qualify-34"><span class="linenos"> 34</span></a> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="qualify-35"><a href="#qualify-35"><span class="linenos"> 35</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="qualify-36"><a href="#qualify-36"><span class="linenos"> 36</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="qualify-37"><a href="#qualify-37"><span class="linenos"> 37</span></a><span class="sd"> Rewrite sqlglot AST to have normalized and qualified tables and columns.</span>
</span><span id="qualify-38"><a href="#qualify-38"><span class="linenos"> 38</span></a>
</span><span id="qualify-39"><a href="#qualify-39"><span class="linenos"> 39</span></a><span class="sd"> This step is necessary for all further SQLGlot optimizations.</span>
</span><span id="qualify-40"><a href="#qualify-40"><span class="linenos"> 40</span></a>
</span><span id="qualify-41"><a href="#qualify-41"><span class="linenos"> 41</span></a><span class="sd"> Example:</span>
</span><span id="qualify-42"><a href="#qualify-42"><span class="linenos"> 42</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="qualify-43"><a href="#qualify-43"><span class="linenos"> 43</span></a><span class="sd"> &gt;&gt;&gt; schema = {&quot;tbl&quot;: {&quot;col&quot;: &quot;INT&quot;}}</span>
</span><span id="qualify-44"><a href="#qualify-44"><span class="linenos"> 44</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT col FROM tbl&quot;)</span>
</span><span id="qualify-45"><a href="#qualify-45"><span class="linenos"> 45</span></a><span class="sd"> &gt;&gt;&gt; qualify(expression, schema=schema).sql()</span>
</span><span id="qualify-46"><a href="#qualify-46"><span class="linenos"> 46</span></a><span class="sd"> &#39;SELECT &quot;tbl&quot;.&quot;col&quot; AS &quot;col&quot; FROM &quot;tbl&quot; AS &quot;tbl&quot;&#39;</span>
</span><span id="qualify-47"><a href="#qualify-47"><span class="linenos"> 47</span></a>
</span><span id="qualify-48"><a href="#qualify-48"><span class="linenos"> 48</span></a><span class="sd"> Args:</span>
</span><span id="qualify-49"><a href="#qualify-49"><span class="linenos"> 49</span></a><span class="sd"> expression: Expression to qualify.</span>
</span><span id="qualify-50"><a href="#qualify-50"><span class="linenos"> 50</span></a><span class="sd"> db: Default database name for tables.</span>
</span><span id="qualify-51"><a href="#qualify-51"><span class="linenos"> 51</span></a><span class="sd"> catalog: Default catalog name for tables.</span>
</span><span id="qualify-52"><a href="#qualify-52"><span class="linenos"> 52</span></a><span class="sd"> schema: Schema to infer column names and types.</span>
</span><span id="qualify-53"><a href="#qualify-53"><span class="linenos"> 53</span></a><span class="sd"> expand_alias_refs: Whether to expand references to aliases.</span>
</span><span id="qualify-54"><a href="#qualify-54"><span class="linenos"> 54</span></a><span class="sd"> expand_stars: Whether to expand star queries. This is a necessary step</span>
</span><span id="qualify-55"><a href="#qualify-55"><span class="linenos"> 55</span></a><span class="sd"> for most of the optimizer&#39;s rules to work; do not set to False unless you</span>
</span><span id="qualify-56"><a href="#qualify-56"><span class="linenos"> 56</span></a><span class="sd"> know what you&#39;re doing!</span>
</span><span id="qualify-57"><a href="#qualify-57"><span class="linenos"> 57</span></a><span class="sd"> infer_schema: Whether to infer the schema if missing.</span>
</span><span id="qualify-58"><a href="#qualify-58"><span class="linenos"> 58</span></a><span class="sd"> isolate_tables: Whether to isolate table selects.</span>
</span><span id="qualify-59"><a href="#qualify-59"><span class="linenos"> 59</span></a><span class="sd"> qualify_columns: Whether to qualify columns.</span>
</span><span id="qualify-60"><a href="#qualify-60"><span class="linenos"> 60</span></a><span class="sd"> validate_qualify_columns: Whether to validate columns.</span>
</span><span id="qualify-61"><a href="#qualify-61"><span class="linenos"> 61</span></a><span class="sd"> quote_identifiers: Whether to run the quote_identifiers step.</span>
</span><span id="qualify-62"><a href="#qualify-62"><span class="linenos"> 62</span></a><span class="sd"> This step is necessary to ensure correctness for case sensitive queries.</span>
</span><span id="qualify-63"><a href="#qualify-63"><span class="linenos"> 63</span></a><span class="sd"> But this flag is provided in case this step is performed at a later time.</span>
</span><span id="qualify-64"><a href="#qualify-64"><span class="linenos"> 64</span></a><span class="sd"> identify: If True, quote all identifiers, else only necessary ones.</span>
</span><span id="qualify-65"><a href="#qualify-65"><span class="linenos"> 65</span></a><span class="sd"> infer_csv_schemas: Whether to scan READ_CSV calls in order to infer the CSVs&#39; schemas.</span>
</span><span id="qualify-66"><a href="#qualify-66"><span class="linenos"> 66</span></a>
</span><span id="qualify-67"><a href="#qualify-67"><span class="linenos"> 67</span></a><span class="sd"> Returns:</span>
</span><span id="qualify-68"><a href="#qualify-68"><span class="linenos"> 68</span></a><span class="sd"> The qualified expression.</span>
</span><span id="qualify-69"><a href="#qualify-69"><span class="linenos"> 69</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="qualify-70"><a href="#qualify-70"><span class="linenos"> 70</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-71"><a href="#qualify-71"><span class="linenos"> 71</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-72"><a href="#qualify-72"><span class="linenos"> 72</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span>
</span><span id="qualify-73"><a href="#qualify-73"><span class="linenos"> 73</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="qualify-74"><a href="#qualify-74"><span class="linenos"> 74</span></a> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span>
</span><span id="qualify-75"><a href="#qualify-75"><span class="linenos"> 75</span></a> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span>
</span><span id="qualify-76"><a href="#qualify-76"><span class="linenos"> 76</span></a> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">,</span>
</span><span id="qualify-77"><a href="#qualify-77"><span class="linenos"> 77</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="qualify-78"><a href="#qualify-78"><span class="linenos"> 78</span></a> <span class="n">infer_csv_schemas</span><span class="o">=</span><span class="n">infer_csv_schemas</span><span class="p">,</span>
</span><span id="qualify-79"><a href="#qualify-79"><span class="linenos"> 79</span></a> <span class="p">)</span>
</span><span id="qualify-80"><a href="#qualify-80"><span class="linenos"> 80</span></a>
</span><span id="qualify-81"><a href="#qualify-81"><span class="linenos"> 81</span></a> <span class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="qualify-82"><a href="#qualify-82"><span class="linenos"> 82</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="qualify-83"><a href="#qualify-83"><span class="linenos"> 83</span></a>
</span><span id="qualify-84"><a href="#qualify-84"><span class="linenos"> 84</span></a> <span class="k">if</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">PREFER_CTE_ALIAS_COLUMN</span><span class="p">:</span>
</span><span id="qualify-85"><a href="#qualify-85"><span class="linenos"> 85</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">pushdown_cte_alias_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="qualify-86"><a href="#qualify-86"><span class="linenos"> 86</span></a>
</span><span id="qualify-87"><a href="#qualify-87"><span class="linenos"> 87</span></a> <span class="k">if</span> <span class="n">qualify_columns</span><span class="p">:</span>
</span><span id="qualify-88"><a href="#qualify-88"><span class="linenos"> 88</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_columns_func</span><span class="p">(</span>
</span><span id="qualify-89"><a href="#qualify-89"><span class="linenos"> 89</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="qualify-90"><a href="#qualify-90"><span class="linenos"> 90</span></a> <span class="n">schema</span><span class="p">,</span>
</span><span id="qualify-91"><a href="#qualify-91"><span class="linenos"> 91</span></a> <span class="n">expand_alias_refs</span><span class="o">=</span><span class="n">expand_alias_refs</span><span class="p">,</span>
</span><span id="qualify-92"><a href="#qualify-92"><span class="linenos"> 92</span></a> <span class="n">expand_stars</span><span class="o">=</span><span class="n">expand_stars</span><span class="p">,</span>
</span><span id="qualify-93"><a href="#qualify-93"><span class="linenos"> 93</span></a> <span class="n">infer_schema</span><span class="o">=</span><span class="n">infer_schema</span><span class="p">,</span>
</span><span id="qualify-94"><a href="#qualify-94"><span class="linenos"> 94</span></a> <span class="p">)</span>
</span><span id="qualify-95"><a href="#qualify-95"><span class="linenos"> 95</span></a>
</span><span id="qualify-96"><a href="#qualify-96"><span class="linenos"> 96</span></a> <span class="k">if</span> <span class="n">quote_identifiers</span><span class="p">:</span>
</span><span id="qualify-97"><a href="#qualify-97"><span class="linenos"> 97</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">quote_identifiers_func</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span> <span class="n">identify</span><span class="o">=</span><span class="n">identify</span><span class="p">)</span>
</span><span id="qualify-31"><a href="#qualify-31"><span class="linenos"> 31</span></a> <span class="n">allow_partial_qualification</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="qualify-32"><a href="#qualify-32"><span class="linenos"> 32</span></a> <span class="n">validate_qualify_columns</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-33"><a href="#qualify-33"><span class="linenos"> 33</span></a> <span class="n">quote_identifiers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-34"><a href="#qualify-34"><span class="linenos"> 34</span></a> <span class="n">identify</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
</span><span id="qualify-35"><a href="#qualify-35"><span class="linenos"> 35</span></a> <span class="n">infer_csv_schemas</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
</span><span id="qualify-36"><a href="#qualify-36"><span class="linenos"> 36</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Expression</span><span class="p">:</span>
</span><span id="qualify-37"><a href="#qualify-37"><span class="linenos"> 37</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="qualify-38"><a href="#qualify-38"><span class="linenos"> 38</span></a><span class="sd"> Rewrite sqlglot AST to have normalized and qualified tables and columns.</span>
</span><span id="qualify-39"><a href="#qualify-39"><span class="linenos"> 39</span></a>
</span><span id="qualify-40"><a href="#qualify-40"><span class="linenos"> 40</span></a><span class="sd"> This step is necessary for all further SQLGlot optimizations.</span>
</span><span id="qualify-41"><a href="#qualify-41"><span class="linenos"> 41</span></a>
</span><span id="qualify-42"><a href="#qualify-42"><span class="linenos"> 42</span></a><span class="sd"> Example:</span>
</span><span id="qualify-43"><a href="#qualify-43"><span class="linenos"> 43</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="qualify-44"><a href="#qualify-44"><span class="linenos"> 44</span></a><span class="sd"> &gt;&gt;&gt; schema = {&quot;tbl&quot;: {&quot;col&quot;: &quot;INT&quot;}}</span>
</span><span id="qualify-45"><a href="#qualify-45"><span class="linenos"> 45</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(&quot;SELECT col FROM tbl&quot;)</span>
</span><span id="qualify-46"><a href="#qualify-46"><span class="linenos"> 46</span></a><span class="sd"> &gt;&gt;&gt; qualify(expression, schema=schema).sql()</span>
</span><span id="qualify-47"><a href="#qualify-47"><span class="linenos"> 47</span></a><span class="sd"> &#39;SELECT &quot;tbl&quot;.&quot;col&quot; AS &quot;col&quot; FROM &quot;tbl&quot; AS &quot;tbl&quot;&#39;</span>
</span><span id="qualify-48"><a href="#qualify-48"><span class="linenos"> 48</span></a>
</span><span id="qualify-49"><a href="#qualify-49"><span class="linenos"> 49</span></a><span class="sd"> Args:</span>
</span><span id="qualify-50"><a href="#qualify-50"><span class="linenos"> 50</span></a><span class="sd"> expression: Expression to qualify.</span>
</span><span id="qualify-51"><a href="#qualify-51"><span class="linenos"> 51</span></a><span class="sd"> db: Default database name for tables.</span>
</span><span id="qualify-52"><a href="#qualify-52"><span class="linenos"> 52</span></a><span class="sd"> catalog: Default catalog name for tables.</span>
</span><span id="qualify-53"><a href="#qualify-53"><span class="linenos"> 53</span></a><span class="sd"> schema: Schema to infer column names and types.</span>
</span><span id="qualify-54"><a href="#qualify-54"><span class="linenos"> 54</span></a><span class="sd"> expand_alias_refs: Whether to expand references to aliases.</span>
</span><span id="qualify-55"><a href="#qualify-55"><span class="linenos"> 55</span></a><span class="sd"> expand_stars: Whether to expand star queries. This is a necessary step</span>
</span><span id="qualify-56"><a href="#qualify-56"><span class="linenos"> 56</span></a><span class="sd"> for most of the optimizer&#39;s rules to work; do not set to False unless you</span>
</span><span id="qualify-57"><a href="#qualify-57"><span class="linenos"> 57</span></a><span class="sd"> know what you&#39;re doing!</span>
</span><span id="qualify-58"><a href="#qualify-58"><span class="linenos"> 58</span></a><span class="sd"> infer_schema: Whether to infer the schema if missing.</span>
</span><span id="qualify-59"><a href="#qualify-59"><span class="linenos"> 59</span></a><span class="sd"> isolate_tables: Whether to isolate table selects.</span>
</span><span id="qualify-60"><a href="#qualify-60"><span class="linenos"> 60</span></a><span class="sd"> qualify_columns: Whether to qualify columns.</span>
</span><span id="qualify-61"><a href="#qualify-61"><span class="linenos"> 61</span></a><span class="sd"> allow_partial_qualification: Whether to allow partial qualification.</span>
</span><span id="qualify-62"><a href="#qualify-62"><span class="linenos"> 62</span></a><span class="sd"> validate_qualify_columns: Whether to validate columns.</span>
</span><span id="qualify-63"><a href="#qualify-63"><span class="linenos"> 63</span></a><span class="sd"> quote_identifiers: Whether to run the quote_identifiers step.</span>
</span><span id="qualify-64"><a href="#qualify-64"><span class="linenos"> 64</span></a><span class="sd"> This step is necessary to ensure correctness for case sensitive queries.</span>
</span><span id="qualify-65"><a href="#qualify-65"><span class="linenos"> 65</span></a><span class="sd"> But this flag is provided in case this step is performed at a later time.</span>
</span><span id="qualify-66"><a href="#qualify-66"><span class="linenos"> 66</span></a><span class="sd"> identify: If True, quote all identifiers, else only necessary ones.</span>
</span><span id="qualify-67"><a href="#qualify-67"><span class="linenos"> 67</span></a><span class="sd"> infer_csv_schemas: Whether to scan READ_CSV calls in order to infer the CSVs&#39; schemas.</span>
</span><span id="qualify-68"><a href="#qualify-68"><span class="linenos"> 68</span></a>
</span><span id="qualify-69"><a href="#qualify-69"><span class="linenos"> 69</span></a><span class="sd"> Returns:</span>
</span><span id="qualify-70"><a href="#qualify-70"><span class="linenos"> 70</span></a><span class="sd"> The qualified expression.</span>
</span><span id="qualify-71"><a href="#qualify-71"><span class="linenos"> 71</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="qualify-72"><a href="#qualify-72"><span class="linenos"> 72</span></a> <span class="n">schema</span> <span class="o">=</span> <span class="n">ensure_schema</span><span class="p">(</span><span class="n">schema</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-73"><a href="#qualify-73"><span class="linenos"> 73</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">normalize_identifiers</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">)</span>
</span><span id="qualify-74"><a href="#qualify-74"><span class="linenos"> 74</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_tables</span><span class="p">(</span>
</span><span id="qualify-75"><a href="#qualify-75"><span class="linenos"> 75</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="qualify-76"><a href="#qualify-76"><span class="linenos"> 76</span></a> <span class="n">db</span><span class="o">=</span><span class="n">db</span><span class="p">,</span>
</span><span id="qualify-77"><a href="#qualify-77"><span class="linenos"> 77</span></a> <span class="n">catalog</span><span class="o">=</span><span class="n">catalog</span><span class="p">,</span>
</span><span id="qualify-78"><a href="#qualify-78"><span class="linenos"> 78</span></a> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">,</span>
</span><span id="qualify-79"><a href="#qualify-79"><span class="linenos"> 79</span></a> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span>
</span><span id="qualify-80"><a href="#qualify-80"><span class="linenos"> 80</span></a> <span class="n">infer_csv_schemas</span><span class="o">=</span><span class="n">infer_csv_schemas</span><span class="p">,</span>
</span><span id="qualify-81"><a href="#qualify-81"><span class="linenos"> 81</span></a> <span class="p">)</span>
</span><span id="qualify-82"><a href="#qualify-82"><span class="linenos"> 82</span></a>
</span><span id="qualify-83"><a href="#qualify-83"><span class="linenos"> 83</span></a> <span class="k">if</span> <span class="n">isolate_tables</span><span class="p">:</span>
</span><span id="qualify-84"><a href="#qualify-84"><span class="linenos"> 84</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">isolate_table_selects</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span><span id="qualify-85"><a href="#qualify-85"><span class="linenos"> 85</span></a>
</span><span id="qualify-86"><a href="#qualify-86"><span class="linenos"> 86</span></a> <span class="k">if</span> <span class="n">Dialect</span><span class="o">.</span><span class="n">get_or_raise</span><span class="p">(</span><span class="n">dialect</span><span class="p">)</span><span class="o">.</span><span class="n">PREFER_CTE_ALIAS_COLUMN</span><span class="p">:</span>
</span><span id="qualify-87"><a href="#qualify-87"><span class="linenos"> 87</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">pushdown_cte_alias_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="qualify-88"><a href="#qualify-88"><span class="linenos"> 88</span></a>
</span><span id="qualify-89"><a href="#qualify-89"><span class="linenos"> 89</span></a> <span class="k">if</span> <span class="n">qualify_columns</span><span class="p">:</span>
</span><span id="qualify-90"><a href="#qualify-90"><span class="linenos"> 90</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">qualify_columns_func</span><span class="p">(</span>
</span><span id="qualify-91"><a href="#qualify-91"><span class="linenos"> 91</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="qualify-92"><a href="#qualify-92"><span class="linenos"> 92</span></a> <span class="n">schema</span><span class="p">,</span>
</span><span id="qualify-93"><a href="#qualify-93"><span class="linenos"> 93</span></a> <span class="n">expand_alias_refs</span><span class="o">=</span><span class="n">expand_alias_refs</span><span class="p">,</span>
</span><span id="qualify-94"><a href="#qualify-94"><span class="linenos"> 94</span></a> <span class="n">expand_stars</span><span class="o">=</span><span class="n">expand_stars</span><span class="p">,</span>
</span><span id="qualify-95"><a href="#qualify-95"><span class="linenos"> 95</span></a> <span class="n">infer_schema</span><span class="o">=</span><span class="n">infer_schema</span><span class="p">,</span>
</span><span id="qualify-96"><a href="#qualify-96"><span class="linenos"> 96</span></a> <span class="n">allow_partial_qualification</span><span class="o">=</span><span class="n">allow_partial_qualification</span><span class="p">,</span>
</span><span id="qualify-97"><a href="#qualify-97"><span class="linenos"> 97</span></a> <span class="p">)</span>
</span><span id="qualify-98"><a href="#qualify-98"><span class="linenos"> 98</span></a>
</span><span id="qualify-99"><a href="#qualify-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">validate_qualify_columns</span><span class="p">:</span>
</span><span id="qualify-100"><a href="#qualify-100"><span class="linenos">100</span></a> <span class="n">validate_qualify_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="qualify-99"><a href="#qualify-99"><span class="linenos"> 99</span></a> <span class="k">if</span> <span class="n">quote_identifiers</span><span class="p">:</span>
</span><span id="qualify-100"><a href="#qualify-100"><span class="linenos">100</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">quote_identifiers_func</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="n">dialect</span><span class="p">,</span> <span class="n">identify</span><span class="o">=</span><span class="n">identify</span><span class="p">)</span>
</span><span id="qualify-101"><a href="#qualify-101"><span class="linenos">101</span></a>
</span><span id="qualify-102"><a href="#qualify-102"><span class="linenos">102</span></a> <span class="k">return</span> <span class="n">expression</span>
</span><span id="qualify-102"><a href="#qualify-102"><span class="linenos">102</span></a> <span class="k">if</span> <span class="n">validate_qualify_columns</span><span class="p">:</span>
</span><span id="qualify-103"><a href="#qualify-103"><span class="linenos">103</span></a> <span class="n">validate_qualify_columns_func</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
</span><span id="qualify-104"><a href="#qualify-104"><span class="linenos">104</span></a>
</span><span id="qualify-105"><a href="#qualify-105"><span class="linenos">105</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div>
@ -289,6 +295,7 @@ know what you're doing!</li>
<li><strong>infer_schema:</strong> Whether to infer the schema if missing.</li>
<li><strong>isolate_tables:</strong> Whether to isolate table selects.</li>
<li><strong>qualify_columns:</strong> Whether to qualify columns.</li>
<li><strong>allow_partial_qualification:</strong> Whether to allow partial qualification.</li>
<li><strong>validate_qualify_columns:</strong> Whether to validate columns.</li>
<li><strong>quote_identifiers:</strong> Whether to run the quote_identifiers step.
This step is necessary to ensure correctness for case sensitive queries.

File diff suppressed because it is too large Load diff

View file

@ -926,188 +926,190 @@
</span><span id="L-679"><a href="#L-679"><span class="linenos">679</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">extend</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">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;laterals&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[])</span>
</span><span id="L-680"><a href="#L-680"><span class="linenos">680</span></a>
</span><span id="L-681"><a href="#L-681"><span class="linenos">681</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-682"><a href="#L-682"><span class="linenos">682</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="L-683"><a href="#L-683"><span class="linenos">683</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-684"><a href="#L-684"><span class="linenos">684</span></a> <span class="n">source_name</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-685"><a href="#L-685"><span class="linenos">685</span></a>
</span><span id="L-686"><a href="#L-686"><span class="linenos">686</span></a> <span class="k">if</span> <span class="n">table_name</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">db</span><span class="p">:</span>
</span><span id="L-687"><a href="#L-687"><span class="linenos">687</span></a> <span class="c1"># This is a reference to a parent source (e.g. a CTE), not an actual table, unless</span>
</span><span id="L-688"><a href="#L-688"><span class="linenos">688</span></a> <span class="c1"># it is pivoted, because then we get back a new table and hence a new source.</span>
</span><span id="L-689"><a href="#L-689"><span class="linenos">689</span></a> <span class="n">pivots</span> <span class="o">=</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;pivots&quot;</span><span class="p">)</span>
</span><span id="L-690"><a href="#L-690"><span class="linenos">690</span></a> <span class="k">if</span> <span class="n">pivots</span><span class="p">:</span>
</span><span id="L-691"><a href="#L-691"><span class="linenos">691</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-692"><a href="#L-692"><span class="linenos">692</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-693"><a href="#L-693"><span class="linenos">693</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">source_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span>
</span><span id="L-694"><a href="#L-694"><span class="linenos">694</span></a> <span class="k">elif</span> <span class="n">source_name</span> <span class="ow">in</span> <span class="n">sources</span><span class="p">:</span>
</span><span id="L-695"><a href="#L-695"><span class="linenos">695</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">find_new_name</span><span class="p">(</span><span class="n">sources</span><span class="p">,</span> <span class="n">table_name</span><span class="p">)]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-696"><a href="#L-696"><span class="linenos">696</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-697"><a href="#L-697"><span class="linenos">697</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">source_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-698"><a href="#L-698"><span class="linenos">698</span></a>
</span><span id="L-699"><a href="#L-699"><span class="linenos">699</span></a> <span class="c1"># Make sure to not include the joins twice</span>
</span><span id="L-700"><a href="#L-700"><span class="linenos">700</span></a> <span class="k">if</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="L-701"><a href="#L-701"><span class="linenos">701</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-702"><a href="#L-702"><span class="linenos">702</span></a>
</span><span id="L-703"><a href="#L-703"><span class="linenos">703</span></a> <span class="k">continue</span>
</span><span id="L-682"><a href="#L-682"><span class="linenos">682</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Final</span><span class="p">):</span>
</span><span id="L-683"><a href="#L-683"><span class="linenos">683</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-684"><a href="#L-684"><span class="linenos">684</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Table</span><span class="p">):</span>
</span><span id="L-685"><a href="#L-685"><span class="linenos">685</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-686"><a href="#L-686"><span class="linenos">686</span></a> <span class="n">source_name</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-687"><a href="#L-687"><span class="linenos">687</span></a>
</span><span id="L-688"><a href="#L-688"><span class="linenos">688</span></a> <span class="k">if</span> <span class="n">table_name</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">expression</span><span class="o">.</span><span class="n">db</span><span class="p">:</span>
</span><span id="L-689"><a href="#L-689"><span class="linenos">689</span></a> <span class="c1"># This is a reference to a parent source (e.g. a CTE), not an actual table, unless</span>
</span><span id="L-690"><a href="#L-690"><span class="linenos">690</span></a> <span class="c1"># it is pivoted, because then we get back a new table and hence a new source.</span>
</span><span id="L-691"><a href="#L-691"><span class="linenos">691</span></a> <span class="n">pivots</span> <span class="o">=</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;pivots&quot;</span><span class="p">)</span>
</span><span id="L-692"><a href="#L-692"><span class="linenos">692</span></a> <span class="k">if</span> <span class="n">pivots</span><span class="p">:</span>
</span><span id="L-693"><a href="#L-693"><span class="linenos">693</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">pivots</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-694"><a href="#L-694"><span class="linenos">694</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-695"><a href="#L-695"><span class="linenos">695</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">source_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span>
</span><span id="L-696"><a href="#L-696"><span class="linenos">696</span></a> <span class="k">elif</span> <span class="n">source_name</span> <span class="ow">in</span> <span class="n">sources</span><span class="p">:</span>
</span><span id="L-697"><a href="#L-697"><span class="linenos">697</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">find_new_name</span><span class="p">(</span><span class="n">sources</span><span class="p">,</span> <span class="n">table_name</span><span class="p">)]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-698"><a href="#L-698"><span class="linenos">698</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-699"><a href="#L-699"><span class="linenos">699</span></a> <span class="n">sources</span><span class="p">[</span><span class="n">source_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">expression</span>
</span><span id="L-700"><a href="#L-700"><span class="linenos">700</span></a>
</span><span id="L-701"><a href="#L-701"><span class="linenos">701</span></a> <span class="c1"># Make sure to not include the joins twice</span>
</span><span id="L-702"><a href="#L-702"><span class="linenos">702</span></a> <span class="k">if</span> <span class="n">expression</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="p">:</span>
</span><span id="L-703"><a href="#L-703"><span class="linenos">703</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-704"><a href="#L-704"><span class="linenos">704</span></a>
</span><span id="L-705"><a href="#L-705"><span class="linenos">705</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DerivedTable</span><span class="p">):</span>
</span><span id="L-706"><a href="#L-706"><span class="linenos">706</span></a> <span class="k">continue</span>
</span><span id="L-707"><a href="#L-707"><span class="linenos">707</span></a>
</span><span id="L-708"><a href="#L-708"><span class="linenos">708</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">UDTF</span><span class="p">):</span>
</span><span id="L-709"><a href="#L-709"><span class="linenos">709</span></a> <span class="n">lateral_sources</span> <span class="o">=</span> <span class="n">sources</span>
</span><span id="L-710"><a href="#L-710"><span class="linenos">710</span></a> <span class="n">scope_type</span> <span class="o">=</span> <span class="n">ScopeType</span><span class="o">.</span><span class="n">UDTF</span>
</span><span id="L-711"><a href="#L-711"><span class="linenos">711</span></a> <span class="n">scopes</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">udtf_scopes</span>
</span><span id="L-712"><a href="#L-712"><span class="linenos">712</span></a> <span class="k">elif</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-713"><a href="#L-713"><span class="linenos">713</span></a> <span class="n">lateral_sources</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-714"><a href="#L-714"><span class="linenos">714</span></a> <span class="n">scope_type</span> <span class="o">=</span> <span class="n">ScopeType</span><span class="o">.</span><span class="n">DERIVED_TABLE</span>
</span><span id="L-715"><a href="#L-715"><span class="linenos">715</span></a> <span class="n">scopes</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_table_scopes</span>
</span><span id="L-716"><a href="#L-716"><span class="linenos">716</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-717"><a href="#L-717"><span class="linenos">717</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-718"><a href="#L-718"><span class="linenos">718</span></a> <span class="c1"># Makes sure we check for possible sources in nested table constructs</span>
</span><span id="L-719"><a href="#L-719"><span class="linenos">719</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="L-720"><a href="#L-720"><span class="linenos">720</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-721"><a href="#L-721"><span class="linenos">721</span></a> <span class="k">continue</span>
</span><span id="L-722"><a href="#L-722"><span class="linenos">722</span></a>
</span><span id="L-723"><a href="#L-723"><span class="linenos">723</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-724"><a href="#L-724"><span class="linenos">724</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-725"><a href="#L-725"><span class="linenos">725</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-726"><a href="#L-726"><span class="linenos">726</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-727"><a href="#L-727"><span class="linenos">727</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-728"><a href="#L-728"><span class="linenos">728</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-729"><a href="#L-729"><span class="linenos">729</span></a> <span class="p">)</span>
</span><span id="L-730"><a href="#L-730"><span class="linenos">730</span></a> <span class="p">):</span>
</span><span id="L-731"><a href="#L-731"><span class="linenos">731</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-732"><a href="#L-732"><span class="linenos">732</span></a>
</span><span id="L-733"><a href="#L-733"><span class="linenos">733</span></a> <span class="c1"># Tables without aliases will be set as &quot;&quot;</span>
</span><span id="L-734"><a href="#L-734"><span class="linenos">734</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-735"><a href="#L-735"><span class="linenos">735</span></a> <span class="c1"># Until then, this means that only a single, unaliased derived table is allowed (rather,</span>
</span><span id="L-736"><a href="#L-736"><span class="linenos">736</span></a> <span class="c1"># the latest one wins.</span>
</span><span id="L-737"><a href="#L-737"><span class="linenos">737</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-738"><a href="#L-738"><span class="linenos">738</span></a>
</span><span id="L-739"><a href="#L-739"><span class="linenos">739</span></a> <span class="c1"># append the final child_scope yielded</span>
</span><span id="L-740"><a href="#L-740"><span class="linenos">740</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-741"><a href="#L-741"><span class="linenos">741</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-742"><a href="#L-742"><span class="linenos">742</span></a>
</span><span id="L-743"><a href="#L-743"><span class="linenos">743</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-705"><a href="#L-705"><span class="linenos">705</span></a> <span class="k">continue</span>
</span><span id="L-706"><a href="#L-706"><span class="linenos">706</span></a>
</span><span id="L-707"><a href="#L-707"><span class="linenos">707</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">DerivedTable</span><span class="p">):</span>
</span><span id="L-708"><a href="#L-708"><span class="linenos">708</span></a> <span class="k">continue</span>
</span><span id="L-709"><a href="#L-709"><span class="linenos">709</span></a>
</span><span id="L-710"><a href="#L-710"><span class="linenos">710</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">UDTF</span><span class="p">):</span>
</span><span id="L-711"><a href="#L-711"><span class="linenos">711</span></a> <span class="n">lateral_sources</span> <span class="o">=</span> <span class="n">sources</span>
</span><span id="L-712"><a href="#L-712"><span class="linenos">712</span></a> <span class="n">scope_type</span> <span class="o">=</span> <span class="n">ScopeType</span><span class="o">.</span><span class="n">UDTF</span>
</span><span id="L-713"><a href="#L-713"><span class="linenos">713</span></a> <span class="n">scopes</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">udtf_scopes</span>
</span><span id="L-714"><a href="#L-714"><span class="linenos">714</span></a> <span class="k">elif</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-715"><a href="#L-715"><span class="linenos">715</span></a> <span class="n">lateral_sources</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-716"><a href="#L-716"><span class="linenos">716</span></a> <span class="n">scope_type</span> <span class="o">=</span> <span class="n">ScopeType</span><span class="o">.</span><span class="n">DERIVED_TABLE</span>
</span><span id="L-717"><a href="#L-717"><span class="linenos">717</span></a> <span class="n">scopes</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">derived_table_scopes</span>
</span><span id="L-718"><a href="#L-718"><span class="linenos">718</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-719"><a href="#L-719"><span class="linenos">719</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-720"><a href="#L-720"><span class="linenos">720</span></a> <span class="c1"># Makes sure we check for possible sources in nested table constructs</span>
</span><span id="L-721"><a href="#L-721"><span class="linenos">721</span></a> <span class="n">expressions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">this</span><span class="p">)</span>
</span><span id="L-722"><a href="#L-722"><span class="linenos">722</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-723"><a href="#L-723"><span class="linenos">723</span></a> <span class="k">continue</span>
</span><span id="L-724"><a href="#L-724"><span class="linenos">724</span></a>
</span><span id="L-725"><a href="#L-725"><span class="linenos">725</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-726"><a href="#L-726"><span class="linenos">726</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-727"><a href="#L-727"><span class="linenos">727</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-728"><a href="#L-728"><span class="linenos">728</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-729"><a href="#L-729"><span class="linenos">729</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-730"><a href="#L-730"><span class="linenos">730</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-731"><a href="#L-731"><span class="linenos">731</span></a> <span class="p">)</span>
</span><span id="L-732"><a href="#L-732"><span class="linenos">732</span></a> <span class="p">):</span>
</span><span id="L-733"><a href="#L-733"><span class="linenos">733</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-734"><a href="#L-734"><span class="linenos">734</span></a>
</span><span id="L-735"><a href="#L-735"><span class="linenos">735</span></a> <span class="c1"># Tables without aliases will be set as &quot;&quot;</span>
</span><span id="L-736"><a href="#L-736"><span class="linenos">736</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-737"><a href="#L-737"><span class="linenos">737</span></a> <span class="c1"># Until then, this means that only a single, unaliased derived table is allowed (rather,</span>
</span><span id="L-738"><a href="#L-738"><span class="linenos">738</span></a> <span class="c1"># the latest one wins.</span>
</span><span id="L-739"><a href="#L-739"><span class="linenos">739</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-740"><a href="#L-740"><span class="linenos">740</span></a>
</span><span id="L-741"><a href="#L-741"><span class="linenos">741</span></a> <span class="c1"># append the final child_scope yielded</span>
</span><span id="L-742"><a href="#L-742"><span class="linenos">742</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-743"><a href="#L-743"><span class="linenos">743</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-744"><a href="#L-744"><span class="linenos">744</span></a>
</span><span id="L-745"><a href="#L-745"><span class="linenos">745</span></a>
</span><span id="L-746"><a href="#L-746"><span class="linenos">746</span></a><span class="k">def</span> <span class="nf">_traverse_subqueries</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-747"><a href="#L-747"><span class="linenos">747</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-748"><a href="#L-748"><span class="linenos">748</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-749"><a href="#L-749"><span class="linenos">749</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-750"><a href="#L-750"><span class="linenos">750</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-751"><a href="#L-751"><span class="linenos">751</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-752"><a href="#L-752"><span class="linenos">752</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-753"><a href="#L-753"><span class="linenos">753</span></a>
</span><span id="L-754"><a href="#L-754"><span class="linenos">754</span></a>
</span><span id="L-755"><a href="#L-755"><span class="linenos">755</span></a><span class="k">def</span> <span class="nf">_traverse_udtfs</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-756"><a href="#L-756"><span class="linenos">756</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-757"><a href="#L-757"><span class="linenos">757</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-758"><a href="#L-758"><span class="linenos">758</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-759"><a href="#L-759"><span class="linenos">759</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-760"><a href="#L-760"><span class="linenos">760</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-761"><a href="#L-761"><span class="linenos">761</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[]</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="n">sources</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-764"><a href="#L-764"><span class="linenos">764</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-765"><a href="#L-765"><span class="linenos">765</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-766"><a href="#L-766"><span class="linenos">766</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-767"><a href="#L-767"><span class="linenos">767</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-768"><a href="#L-768"><span class="linenos">768</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-769"><a href="#L-769"><span class="linenos">769</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-770"><a href="#L-770"><span class="linenos">770</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-771"><a href="#L-771"><span class="linenos">771</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-772"><a href="#L-772"><span class="linenos">772</span></a> <span class="p">)</span>
</span><span id="L-773"><a href="#L-773"><span class="linenos">773</span></a> <span class="p">):</span>
</span><span id="L-774"><a href="#L-774"><span class="linenos">774</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-775"><a href="#L-775"><span class="linenos">775</span></a> <span class="n">top</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 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-777"><a href="#L-777"><span class="linenos">777</span></a>
</span><span id="L-778"><a href="#L-778"><span class="linenos">778</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-745"><a href="#L-745"><span class="linenos">745</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-746"><a href="#L-746"><span class="linenos">746</span></a>
</span><span id="L-747"><a href="#L-747"><span class="linenos">747</span></a>
</span><span id="L-748"><a href="#L-748"><span class="linenos">748</span></a><span class="k">def</span> <span class="nf">_traverse_subqueries</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-749"><a href="#L-749"><span class="linenos">749</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-750"><a href="#L-750"><span class="linenos">750</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-751"><a href="#L-751"><span class="linenos">751</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-752"><a href="#L-752"><span class="linenos">752</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-753"><a href="#L-753"><span class="linenos">753</span></a> <span class="n">top</span> <span class="o">=</span> <span class="n">child_scope</span>
</span><span id="L-754"><a href="#L-754"><span class="linenos">754</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-755"><a href="#L-755"><span class="linenos">755</span></a>
</span><span id="L-756"><a href="#L-756"><span class="linenos">756</span></a>
</span><span id="L-757"><a href="#L-757"><span class="linenos">757</span></a><span class="k">def</span> <span class="nf">_traverse_udtfs</span><span class="p">(</span><span class="n">scope</span><span class="p">):</span>
</span><span id="L-758"><a href="#L-758"><span class="linenos">758</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-759"><a href="#L-759"><span class="linenos">759</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-760"><a href="#L-760"><span class="linenos">760</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-761"><a href="#L-761"><span class="linenos">761</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-762"><a href="#L-762"><span class="linenos">762</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-763"><a href="#L-763"><span class="linenos">763</span></a> <span class="n">expressions</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-764"><a href="#L-764"><span class="linenos">764</span></a>
</span><span id="L-765"><a href="#L-765"><span class="linenos">765</span></a> <span class="n">sources</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-766"><a href="#L-766"><span class="linenos">766</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-767"><a href="#L-767"><span class="linenos">767</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-768"><a href="#L-768"><span class="linenos">768</span></a> <span class="n">top</span> <span class="o">=</span> <span class="kc">None</span>
</span><span id="L-769"><a href="#L-769"><span class="linenos">769</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-770"><a href="#L-770"><span class="linenos">770</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">branch</span><span class="p">(</span>
</span><span id="L-771"><a href="#L-771"><span class="linenos">771</span></a> <span class="n">expression</span><span class="p">,</span>
</span><span id="L-772"><a href="#L-772"><span class="linenos">772</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-773"><a href="#L-773"><span class="linenos">773</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-774"><a href="#L-774"><span class="linenos">774</span></a> <span class="p">)</span>
</span><span id="L-775"><a href="#L-775"><span class="linenos">775</span></a> <span class="p">):</span>
</span><span id="L-776"><a href="#L-776"><span class="linenos">776</span></a> <span class="k">yield</span> <span class="n">child_scope</span>
</span><span id="L-777"><a href="#L-777"><span class="linenos">777</span></a> <span class="n">top</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 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-779"><a href="#L-779"><span class="linenos">779</span></a>
</span><span id="L-780"><a href="#L-780"><span class="linenos">780</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-780"><a href="#L-780"><span class="linenos">780</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-781"><a href="#L-781"><span class="linenos">781</span></a>
</span><span id="L-782"><a href="#L-782"><span class="linenos">782</span></a>
</span><span id="L-783"><a href="#L-783"><span class="linenos">783</span></a><span class="k">def</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-784"><a href="#L-784"><span class="linenos">784</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-785"><a href="#L-785"><span class="linenos">785</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="L-786"><a href="#L-786"><span class="linenos">786</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="L-787"><a href="#L-787"><span class="linenos">787</span></a>
</span><span id="L-788"><a href="#L-788"><span class="linenos">788</span></a><span class="sd"> Args:</span>
</span><span id="L-789"><a href="#L-789"><span class="linenos">789</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-790"><a href="#L-790"><span class="linenos">790</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="L-791"><a href="#L-791"><span class="linenos">791</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="L-792"><a href="#L-792"><span class="linenos">792</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="L-793"><a href="#L-793"><span class="linenos">793</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</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 class="sd"> Yields:</span>
</span><span id="L-796"><a href="#L-796"><span class="linenos">796</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="L-797"><a href="#L-797"><span class="linenos">797</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-798"><a href="#L-798"><span class="linenos">798</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="L-799"><a href="#L-799"><span class="linenos">799</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="L-800"><a href="#L-800"><span class="linenos">800</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-801"><a href="#L-801"><span class="linenos">801</span></a>
</span><span id="L-802"><a href="#L-802"><span class="linenos">802</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-803"><a href="#L-803"><span class="linenos">803</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-804"><a href="#L-804"><span class="linenos">804</span></a> <span class="p">):</span>
</span><span id="L-805"><a href="#L-805"><span class="linenos">805</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-806"><a href="#L-806"><span class="linenos">806</span></a>
</span><span id="L-807"><a href="#L-807"><span class="linenos">807</span></a> <span class="k">yield</span> <span class="n">node</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">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-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><span id="L-785"><a href="#L-785"><span class="linenos">785</span></a><span class="k">def</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-786"><a href="#L-786"><span class="linenos">786</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-787"><a href="#L-787"><span class="linenos">787</span></a><span class="sd"> Returns a generator object which visits all nodes in the syntrax tree, stopping at</span>
</span><span id="L-788"><a href="#L-788"><span class="linenos">788</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="L-789"><a href="#L-789"><span class="linenos">789</span></a>
</span><span id="L-790"><a href="#L-790"><span class="linenos">790</span></a><span class="sd"> Args:</span>
</span><span id="L-791"><a href="#L-791"><span class="linenos">791</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-792"><a href="#L-792"><span class="linenos">792</span></a><span class="sd"> bfs (bool): if set to True the BFS traversal order will be applied,</span>
</span><span id="L-793"><a href="#L-793"><span class="linenos">793</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="L-794"><a href="#L-794"><span class="linenos">794</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="L-795"><a href="#L-795"><span class="linenos">795</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="L-796"><a href="#L-796"><span class="linenos">796</span></a>
</span><span id="L-797"><a href="#L-797"><span class="linenos">797</span></a><span class="sd"> Yields:</span>
</span><span id="L-798"><a href="#L-798"><span class="linenos">798</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="L-799"><a href="#L-799"><span class="linenos">799</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-800"><a href="#L-800"><span class="linenos">800</span></a> <span class="c1"># We&#39;ll use this variable to pass state into the dfs generator.</span>
</span><span id="L-801"><a href="#L-801"><span class="linenos">801</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="L-802"><a href="#L-802"><span class="linenos">802</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</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="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-805"><a href="#L-805"><span class="linenos">805</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-806"><a href="#L-806"><span class="linenos">806</span></a> <span class="p">):</span>
</span><span id="L-807"><a href="#L-807"><span class="linenos">807</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-808"><a href="#L-808"><span class="linenos">808</span></a>
</span><span id="L-809"><a href="#L-809"><span class="linenos">809</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-810"><a href="#L-810"><span class="linenos">810</span></a> <span class="k">continue</span>
</span><span id="L-811"><a href="#L-811"><span class="linenos">811</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-812"><a href="#L-812"><span class="linenos">812</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-813"><a href="#L-813"><span class="linenos">813</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-814"><a href="#L-814"><span class="linenos">814</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-815"><a href="#L-815"><span class="linenos">815</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-816"><a href="#L-816"><span class="linenos">816</span></a> <span class="p">)</span>
</span><span id="L-817"><a href="#L-817"><span class="linenos">817</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-818"><a href="#L-818"><span class="linenos">818</span></a> <span class="p">):</span>
</span><span id="L-819"><a href="#L-819"><span class="linenos">819</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</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">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-822"><a href="#L-822"><span class="linenos">822</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-823"><a href="#L-823"><span class="linenos">823</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-824"><a href="#L-824"><span class="linenos">824</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-825"><a href="#L-825"><span class="linenos">825</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-826"><a href="#L-826"><span class="linenos">826</span></a>
</span><span id="L-827"><a href="#L-827"><span class="linenos">827</span></a>
</span><span id="L-828"><a href="#L-828"><span class="linenos">828</span></a><span class="k">def</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-829"><a href="#L-829"><span class="linenos">829</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-830"><a href="#L-830"><span class="linenos">830</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-831"><a href="#L-831"><span class="linenos">831</span></a><span class="sd"> match at least one of the specified expression types.</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"> This does NOT traverse into subscopes.</span>
</span><span id="L-809"><a href="#L-809"><span class="linenos">809</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="L-810"><a href="#L-810"><span class="linenos">810</span></a>
</span><span id="L-811"><a href="#L-811"><span class="linenos">811</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-812"><a href="#L-812"><span class="linenos">812</span></a> <span class="k">continue</span>
</span><span id="L-813"><a href="#L-813"><span class="linenos">813</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-814"><a href="#L-814"><span class="linenos">814</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-815"><a href="#L-815"><span class="linenos">815</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="L-816"><a href="#L-816"><span class="linenos">816</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-817"><a href="#L-817"><span class="linenos">817</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-818"><a href="#L-818"><span class="linenos">818</span></a> <span class="p">)</span>
</span><span id="L-819"><a href="#L-819"><span class="linenos">819</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-820"><a href="#L-820"><span class="linenos">820</span></a> <span class="p">):</span>
</span><span id="L-821"><a href="#L-821"><span class="linenos">821</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</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 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-824"><a href="#L-824"><span class="linenos">824</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-825"><a href="#L-825"><span class="linenos">825</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-826"><a href="#L-826"><span class="linenos">826</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-827"><a href="#L-827"><span class="linenos">827</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-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><span id="L-830"><a href="#L-830"><span class="linenos">830</span></a><span class="k">def</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-831"><a href="#L-831"><span class="linenos">831</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-832"><a href="#L-832"><span class="linenos">832</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-833"><a href="#L-833"><span class="linenos">833</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="L-834"><a href="#L-834"><span class="linenos">834</span></a>
</span><span id="L-835"><a href="#L-835"><span class="linenos">835</span></a><span class="sd"> Args:</span>
</span><span id="L-836"><a href="#L-836"><span class="linenos">836</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-837"><a href="#L-837"><span class="linenos">837</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-838"><a href="#L-838"><span class="linenos">838</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</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="sd"> Yields:</span>
</span><span id="L-841"><a href="#L-841"><span class="linenos">841</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="L-842"><a href="#L-842"><span class="linenos">842</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-843"><a href="#L-843"><span class="linenos">843</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-844"><a href="#L-844"><span class="linenos">844</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-845"><a href="#L-845"><span class="linenos">845</span></a> <span class="k">yield</span> <span class="n">expression</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><span id="L-848"><a href="#L-848"><span class="linenos">848</span></a><span class="k">def</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-849"><a href="#L-849"><span class="linenos">849</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-850"><a href="#L-850"><span class="linenos">850</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-851"><a href="#L-851"><span class="linenos">851</span></a>
</span><span id="L-852"><a href="#L-852"><span class="linenos">852</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-835"><a href="#L-835"><span class="linenos">835</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-836"><a href="#L-836"><span class="linenos">836</span></a>
</span><span id="L-837"><a href="#L-837"><span class="linenos">837</span></a><span class="sd"> Args:</span>
</span><span id="L-838"><a href="#L-838"><span class="linenos">838</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-839"><a href="#L-839"><span class="linenos">839</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-840"><a href="#L-840"><span class="linenos">840</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-841"><a href="#L-841"><span class="linenos">841</span></a>
</span><span id="L-842"><a href="#L-842"><span class="linenos">842</span></a><span class="sd"> Yields:</span>
</span><span id="L-843"><a href="#L-843"><span class="linenos">843</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="L-844"><a href="#L-844"><span class="linenos">844</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-845"><a href="#L-845"><span class="linenos">845</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-846"><a href="#L-846"><span class="linenos">846</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-847"><a href="#L-847"><span class="linenos">847</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span><span id="L-848"><a href="#L-848"><span class="linenos">848</span></a>
</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">def</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-851"><a href="#L-851"><span class="linenos">851</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-852"><a href="#L-852"><span class="linenos">852</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-853"><a href="#L-853"><span class="linenos">853</span></a>
</span><span id="L-854"><a href="#L-854"><span class="linenos">854</span></a><span class="sd"> Args:</span>
</span><span id="L-855"><a href="#L-855"><span class="linenos">855</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-856"><a href="#L-856"><span class="linenos">856</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-857"><a href="#L-857"><span class="linenos">857</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</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="sd"> Returns:</span>
</span><span id="L-860"><a href="#L-860"><span class="linenos">860</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="L-861"><a href="#L-861"><span class="linenos">861</span></a><span class="sd"> the criteria was found.</span>
</span><span id="L-862"><a href="#L-862"><span class="linenos">862</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-863"><a href="#L-863"><span class="linenos">863</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-854"><a href="#L-854"><span class="linenos">854</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="L-855"><a href="#L-855"><span class="linenos">855</span></a>
</span><span id="L-856"><a href="#L-856"><span class="linenos">856</span></a><span class="sd"> Args:</span>
</span><span id="L-857"><a href="#L-857"><span class="linenos">857</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="L-858"><a href="#L-858"><span class="linenos">858</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="L-859"><a href="#L-859"><span class="linenos">859</span></a><span class="sd"> bfs (bool): True to use breadth-first search, False to use depth-first.</span>
</span><span id="L-860"><a href="#L-860"><span class="linenos">860</span></a>
</span><span id="L-861"><a href="#L-861"><span class="linenos">861</span></a><span class="sd"> Returns:</span>
</span><span id="L-862"><a href="#L-862"><span class="linenos">862</span></a><span class="sd"> exp.Expression: the node which matches the criteria or None if no node matching</span>
</span><span id="L-863"><a href="#L-863"><span class="linenos">863</span></a><span class="sd"> the criteria was found.</span>
</span><span id="L-864"><a href="#L-864"><span class="linenos">864</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-865"><a href="#L-865"><span class="linenos">865</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>
@ -3078,49 +3080,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-784"><a href="#walk_in_scope-784"><span class="linenos">784</span></a><span class="k">def</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-785"><a href="#walk_in_scope-785"><span class="linenos">785</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="walk_in_scope-786"><a href="#walk_in_scope-786"><span class="linenos">786</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-787"><a href="#walk_in_scope-787"><span class="linenos">787</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="walk_in_scope-788"><a href="#walk_in_scope-788"><span class="linenos">788</span></a>
</span><span id="walk_in_scope-789"><a href="#walk_in_scope-789"><span class="linenos">789</span></a><span class="sd"> Args:</span>
</span><span id="walk_in_scope-790"><a href="#walk_in_scope-790"><span class="linenos">790</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="walk_in_scope-791"><a href="#walk_in_scope-791"><span class="linenos">791</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-792"><a href="#walk_in_scope-792"><span class="linenos">792</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="walk_in_scope-793"><a href="#walk_in_scope-793"><span class="linenos">793</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="walk_in_scope-794"><a href="#walk_in_scope-794"><span class="linenos">794</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="walk_in_scope-795"><a href="#walk_in_scope-795"><span class="linenos">795</span></a>
</span><span id="walk_in_scope-796"><a href="#walk_in_scope-796"><span class="linenos">796</span></a><span class="sd"> Yields:</span>
</span><span id="walk_in_scope-797"><a href="#walk_in_scope-797"><span class="linenos">797</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="walk_in_scope-798"><a href="#walk_in_scope-798"><span class="linenos">798</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="walk_in_scope-799"><a href="#walk_in_scope-799"><span class="linenos">799</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-800"><a href="#walk_in_scope-800"><span class="linenos">800</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="walk_in_scope-801"><a href="#walk_in_scope-801"><span class="linenos">801</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-802"><a href="#walk_in_scope-802"><span class="linenos">802</span></a>
</span><span id="walk_in_scope-803"><a href="#walk_in_scope-803"><span class="linenos">803</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-804"><a href="#walk_in_scope-804"><span class="linenos">804</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-805"><a href="#walk_in_scope-805"><span class="linenos">805</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-806"><a href="#walk_in_scope-806"><span class="linenos">806</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-807"><a href="#walk_in_scope-807"><span class="linenos">807</span></a>
</span><span id="walk_in_scope-808"><a href="#walk_in_scope-808"><span class="linenos">808</span></a> <span class="k">yield</span> <span class="n">node</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="walk_in_scope-786"><a href="#walk_in_scope-786"><span class="linenos">786</span></a><span class="k">def</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-787"><a href="#walk_in_scope-787"><span class="linenos">787</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="walk_in_scope-788"><a href="#walk_in_scope-788"><span class="linenos">788</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-789"><a href="#walk_in_scope-789"><span class="linenos">789</span></a><span class="sd"> nodes that start child scopes.</span>
</span><span id="walk_in_scope-790"><a href="#walk_in_scope-790"><span class="linenos">790</span></a>
</span><span id="walk_in_scope-791"><a href="#walk_in_scope-791"><span class="linenos">791</span></a><span class="sd"> Args:</span>
</span><span id="walk_in_scope-792"><a href="#walk_in_scope-792"><span class="linenos">792</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="walk_in_scope-793"><a href="#walk_in_scope-793"><span class="linenos">793</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-794"><a href="#walk_in_scope-794"><span class="linenos">794</span></a><span class="sd"> otherwise the DFS traversal will be used instead.</span>
</span><span id="walk_in_scope-795"><a href="#walk_in_scope-795"><span class="linenos">795</span></a><span class="sd"> prune ((node, parent, arg_key) -&gt; bool): callable that returns True if</span>
</span><span id="walk_in_scope-796"><a href="#walk_in_scope-796"><span class="linenos">796</span></a><span class="sd"> the generator should stop traversing this branch of the tree.</span>
</span><span id="walk_in_scope-797"><a href="#walk_in_scope-797"><span class="linenos">797</span></a>
</span><span id="walk_in_scope-798"><a href="#walk_in_scope-798"><span class="linenos">798</span></a><span class="sd"> Yields:</span>
</span><span id="walk_in_scope-799"><a href="#walk_in_scope-799"><span class="linenos">799</span></a><span class="sd"> tuple[exp.Expression, Optional[exp.Expression], str]: node, parent, arg key</span>
</span><span id="walk_in_scope-800"><a href="#walk_in_scope-800"><span class="linenos">800</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="walk_in_scope-801"><a href="#walk_in_scope-801"><span class="linenos">801</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-802"><a href="#walk_in_scope-802"><span class="linenos">802</span></a> <span class="c1"># Whenever we set it to True, we exclude a subtree from traversal.</span>
</span><span id="walk_in_scope-803"><a href="#walk_in_scope-803"><span class="linenos">803</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-804"><a href="#walk_in_scope-804"><span class="linenos">804</span></a>
</span><span id="walk_in_scope-805"><a href="#walk_in_scope-805"><span class="linenos">805</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-806"><a href="#walk_in_scope-806"><span class="linenos">806</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-807"><a href="#walk_in_scope-807"><span class="linenos">807</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-808"><a href="#walk_in_scope-808"><span class="linenos">808</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="walk_in_scope-809"><a href="#walk_in_scope-809"><span class="linenos">809</span></a>
</span><span id="walk_in_scope-810"><a href="#walk_in_scope-810"><span class="linenos">810</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-811"><a href="#walk_in_scope-811"><span class="linenos">811</span></a> <span class="k">continue</span>
</span><span id="walk_in_scope-812"><a href="#walk_in_scope-812"><span class="linenos">812</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="walk_in_scope-813"><a href="#walk_in_scope-813"><span class="linenos">813</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-814"><a href="#walk_in_scope-814"><span class="linenos">814</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="walk_in_scope-815"><a href="#walk_in_scope-815"><span class="linenos">815</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-816"><a href="#walk_in_scope-816"><span class="linenos">816</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-817"><a href="#walk_in_scope-817"><span class="linenos">817</span></a> <span class="p">)</span>
</span><span id="walk_in_scope-818"><a href="#walk_in_scope-818"><span class="linenos">818</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-819"><a href="#walk_in_scope-819"><span class="linenos">819</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-820"><a href="#walk_in_scope-820"><span class="linenos">820</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="walk_in_scope-821"><a href="#walk_in_scope-821"><span class="linenos">821</span></a>
</span><span id="walk_in_scope-822"><a href="#walk_in_scope-822"><span class="linenos">822</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-823"><a href="#walk_in_scope-823"><span class="linenos">823</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-824"><a href="#walk_in_scope-824"><span class="linenos">824</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-825"><a href="#walk_in_scope-825"><span class="linenos">825</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-826"><a href="#walk_in_scope-826"><span class="linenos">826</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="walk_in_scope-810"><a href="#walk_in_scope-810"><span class="linenos">810</span></a> <span class="k">yield</span> <span class="n">node</span>
</span><span id="walk_in_scope-811"><a href="#walk_in_scope-811"><span class="linenos">811</span></a>
</span><span id="walk_in_scope-812"><a href="#walk_in_scope-812"><span class="linenos">812</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-813"><a href="#walk_in_scope-813"><span class="linenos">813</span></a> <span class="k">continue</span>
</span><span id="walk_in_scope-814"><a href="#walk_in_scope-814"><span class="linenos">814</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="walk_in_scope-815"><a href="#walk_in_scope-815"><span class="linenos">815</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-816"><a href="#walk_in_scope-816"><span class="linenos">816</span></a> <span class="ow">or</span> <span class="p">(</span>
</span><span id="walk_in_scope-817"><a href="#walk_in_scope-817"><span class="linenos">817</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-818"><a href="#walk_in_scope-818"><span class="linenos">818</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-819"><a href="#walk_in_scope-819"><span class="linenos">819</span></a> <span class="p">)</span>
</span><span id="walk_in_scope-820"><a href="#walk_in_scope-820"><span class="linenos">820</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-821"><a href="#walk_in_scope-821"><span class="linenos">821</span></a> <span class="p">):</span>
</span><span id="walk_in_scope-822"><a href="#walk_in_scope-822"><span class="linenos">822</span></a> <span class="n">crossed_scope_boundary</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="walk_in_scope-823"><a href="#walk_in_scope-823"><span class="linenos">823</span></a>
</span><span id="walk_in_scope-824"><a href="#walk_in_scope-824"><span class="linenos">824</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-825"><a href="#walk_in_scope-825"><span class="linenos">825</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-826"><a href="#walk_in_scope-826"><span class="linenos">826</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-827"><a href="#walk_in_scope-827"><span class="linenos">827</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-828"><a href="#walk_in_scope-828"><span class="linenos">828</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>
@ -3157,24 +3159,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-829"><a href="#find_all_in_scope-829"><span class="linenos">829</span></a><span class="k">def</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-830"><a href="#find_all_in_scope-830"><span class="linenos">830</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-831"><a href="#find_all_in_scope-831"><span class="linenos">831</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-832"><a href="#find_all_in_scope-832"><span class="linenos">832</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="find_all_in_scope-833"><a href="#find_all_in_scope-833"><span class="linenos">833</span></a>
</span><span id="find_all_in_scope-834"><a href="#find_all_in_scope-834"><span class="linenos">834</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_all_in_scope-831"><a href="#find_all_in_scope-831"><span class="linenos">831</span></a><span class="k">def</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-832"><a href="#find_all_in_scope-832"><span class="linenos">832</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-833"><a href="#find_all_in_scope-833"><span class="linenos">833</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-834"><a href="#find_all_in_scope-834"><span class="linenos">834</span></a><span class="sd"> match at least one of the specified expression types.</span>
</span><span id="find_all_in_scope-835"><a href="#find_all_in_scope-835"><span class="linenos">835</span></a>
</span><span id="find_all_in_scope-836"><a href="#find_all_in_scope-836"><span class="linenos">836</span></a><span class="sd"> Args:</span>
</span><span id="find_all_in_scope-837"><a href="#find_all_in_scope-837"><span class="linenos">837</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_all_in_scope-838"><a href="#find_all_in_scope-838"><span class="linenos">838</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_all_in_scope-839"><a href="#find_all_in_scope-839"><span class="linenos">839</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-840"><a href="#find_all_in_scope-840"><span class="linenos">840</span></a>
</span><span id="find_all_in_scope-841"><a href="#find_all_in_scope-841"><span class="linenos">841</span></a><span class="sd"> Yields:</span>
</span><span id="find_all_in_scope-842"><a href="#find_all_in_scope-842"><span class="linenos">842</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="find_all_in_scope-843"><a href="#find_all_in_scope-843"><span class="linenos">843</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-844"><a href="#find_all_in_scope-844"><span class="linenos">844</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-845"><a href="#find_all_in_scope-845"><span class="linenos">845</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-846"><a href="#find_all_in_scope-846"><span class="linenos">846</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span><span id="find_all_in_scope-836"><a href="#find_all_in_scope-836"><span class="linenos">836</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_all_in_scope-837"><a href="#find_all_in_scope-837"><span class="linenos">837</span></a>
</span><span id="find_all_in_scope-838"><a href="#find_all_in_scope-838"><span class="linenos">838</span></a><span class="sd"> Args:</span>
</span><span id="find_all_in_scope-839"><a href="#find_all_in_scope-839"><span class="linenos">839</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_all_in_scope-840"><a href="#find_all_in_scope-840"><span class="linenos">840</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_all_in_scope-841"><a href="#find_all_in_scope-841"><span class="linenos">841</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-842"><a href="#find_all_in_scope-842"><span class="linenos">842</span></a>
</span><span id="find_all_in_scope-843"><a href="#find_all_in_scope-843"><span class="linenos">843</span></a><span class="sd"> Yields:</span>
</span><span id="find_all_in_scope-844"><a href="#find_all_in_scope-844"><span class="linenos">844</span></a><span class="sd"> exp.Expression: nodes</span>
</span><span id="find_all_in_scope-845"><a href="#find_all_in_scope-845"><span class="linenos">845</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_all_in_scope-846"><a href="#find_all_in_scope-846"><span class="linenos">846</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-847"><a href="#find_all_in_scope-847"><span class="linenos">847</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-848"><a href="#find_all_in_scope-848"><span class="linenos">848</span></a> <span class="k">yield</span> <span class="n">expression</span>
</span></pre></div>
@ -3211,22 +3213,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-849"><a href="#find_in_scope-849"><span class="linenos">849</span></a><span class="k">def</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-850"><a href="#find_in_scope-850"><span class="linenos">850</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_in_scope-851"><a href="#find_in_scope-851"><span class="linenos">851</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-852"><a href="#find_in_scope-852"><span class="linenos">852</span></a>
</span><span id="find_in_scope-853"><a href="#find_in_scope-853"><span class="linenos">853</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="find_in_scope-851"><a href="#find_in_scope-851"><span class="linenos">851</span></a><span class="k">def</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-852"><a href="#find_in_scope-852"><span class="linenos">852</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="find_in_scope-853"><a href="#find_in_scope-853"><span class="linenos">853</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-854"><a href="#find_in_scope-854"><span class="linenos">854</span></a>
</span><span id="find_in_scope-855"><a href="#find_in_scope-855"><span class="linenos">855</span></a><span class="sd"> Args:</span>
</span><span id="find_in_scope-856"><a href="#find_in_scope-856"><span class="linenos">856</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_in_scope-857"><a href="#find_in_scope-857"><span class="linenos">857</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_in_scope-858"><a href="#find_in_scope-858"><span class="linenos">858</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-859"><a href="#find_in_scope-859"><span class="linenos">859</span></a>
</span><span id="find_in_scope-860"><a href="#find_in_scope-860"><span class="linenos">860</span></a><span class="sd"> Returns:</span>
</span><span id="find_in_scope-861"><a href="#find_in_scope-861"><span class="linenos">861</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-862"><a href="#find_in_scope-862"><span class="linenos">862</span></a><span class="sd"> the criteria was found.</span>
</span><span id="find_in_scope-863"><a href="#find_in_scope-863"><span class="linenos">863</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_in_scope-864"><a href="#find_in_scope-864"><span class="linenos">864</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="find_in_scope-855"><a href="#find_in_scope-855"><span class="linenos">855</span></a><span class="sd"> This does NOT traverse into subscopes.</span>
</span><span id="find_in_scope-856"><a href="#find_in_scope-856"><span class="linenos">856</span></a>
</span><span id="find_in_scope-857"><a href="#find_in_scope-857"><span class="linenos">857</span></a><span class="sd"> Args:</span>
</span><span id="find_in_scope-858"><a href="#find_in_scope-858"><span class="linenos">858</span></a><span class="sd"> expression (exp.Expression):</span>
</span><span id="find_in_scope-859"><a href="#find_in_scope-859"><span class="linenos">859</span></a><span class="sd"> expression_types (tuple[type]|type): the expression type(s) to match.</span>
</span><span id="find_in_scope-860"><a href="#find_in_scope-860"><span class="linenos">860</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-861"><a href="#find_in_scope-861"><span class="linenos">861</span></a>
</span><span id="find_in_scope-862"><a href="#find_in_scope-862"><span class="linenos">862</span></a><span class="sd"> Returns:</span>
</span><span id="find_in_scope-863"><a href="#find_in_scope-863"><span class="linenos">863</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-864"><a href="#find_in_scope-864"><span class="linenos">864</span></a><span class="sd"> the criteria was found.</span>
</span><span id="find_in_scope-865"><a href="#find_in_scope-865"><span class="linenos">865</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="find_in_scope-866"><a href="#find_in_scope-866"><span class="linenos">866</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

@ -3231,7 +3231,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#LT">sqlglot.expressions.LT</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#GTE">sqlglot.expressions.GTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</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#LT">sqlglot.expressions.LT</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#LTE">sqlglot.expressions.LTE</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#EQ">sqlglot.expressions.EQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#In">sqlglot.expressions.In</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#NEQ">sqlglot.expressions.NEQ</a>&#39;&gt;, &lt;class &#39;<a href="../expressions.html#GT">sqlglot.expressions.GT</a>&#39;&gt;}</span>
</div>
@ -3315,7 +3315,7 @@ prefix are statically known.</p>
<section id="JOINS">
<div class="attr variable">
<span class="name">JOINS</span> =
<span class="default_value">{(&#39;RIGHT&#39;, &#39;&#39;), (&#39;&#39;, &#39;&#39;), (&#39;&#39;, &#39;INNER&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;)}</span>
<span class="default_value">{(&#39;&#39;, &#39;&#39;), (&#39;RIGHT&#39;, &#39;&#39;), (&#39;RIGHT&#39;, &#39;OUTER&#39;), (&#39;&#39;, &#39;INNER&#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

File diff suppressed because one or more lines are too long