1
0
Fork 0

Adding upstream version 26.12.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-04-06 10:16:57 +02:00
parent 4118582692
commit 539faf8d40
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
45 changed files with 49860 additions and 49289 deletions

File diff suppressed because one or more lines are too long

View file

@ -103,7 +103,7 @@
<p>You can easily <a href="#custom-dialects">customize</a> the parser, <a href="#metadata">analyze</a> queries, traverse expression trees, and programmatically <a href="#build-and-modify-sql">build</a> SQL.</p>
<p>Syntax <a href="#parser-errors">errors</a> are highlighted and dialect incompatibilities can warn or raise depending on configurations. However, SQLGlot does not aim to be a SQL validator, so it may fail to detect certain syntax errors.</p>
<p>SQLGlot can detect a variety of <a href="#parser-errors">syntax errors</a>, such as unbalanced parentheses, incorrect usage of reserved keywords, and so on. These errors are highlighted and dialect incompatibilities can warn or raise depending on configurations.</p>
<p>Learn more about SQLGlot in the API <a href="https://sqlglot.com/">documentation</a> and the expression tree <a href="https://github.com/tobymao/sqlglot/blob/main/posts/ast_primer.md">primer</a>.</p>
@ -186,12 +186,6 @@
<li>Like parsing, generating SQL also requires the target dialect to be specified, otherwise the SQLGlot dialect will be used by default. For example, to transpile a query from Spark SQL to DuckDB, do <code>parse_one(sql, dialect="spark").sql(dialect="duckdb")</code> (alternatively: <code>transpile(sql, read="spark", write="duckdb")</code>).</li>
</ul>
<p>I tried to parse invalid SQL and it worked, even though it should raise an error! Why didn't it validate my SQL?</p>
<ul>
<li>SQLGlot does not aim to be a SQL validator - it is designed to be very forgiving. This makes the codebase more comprehensive and also gives more flexibility to its users, e.g. by allowing them to include trailing commas in their projection lists.</li>
</ul>
<p>What happened to sqlglot.dataframe?</p>
<ul>

View file

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

View file

@ -355,7 +355,7 @@ dialect implementations in order to understand how their various components can
<section id="Athena">
<div class="attr variable">
<span class="name">Athena</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418209935328&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858791888&#39;&gt;</span>
</div>
@ -367,7 +367,7 @@ dialect implementations in order to understand how their various components can
<section id="BigQuery">
<div class="attr variable">
<span class="name">BigQuery</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418205943792&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858927520&#39;&gt;</span>
</div>
@ -379,7 +379,7 @@ dialect implementations in order to understand how their various components can
<section id="ClickHouse">
<div class="attr variable">
<span class="name">ClickHouse</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418205949984&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858929872&#39;&gt;</span>
</div>
@ -391,7 +391,7 @@ dialect implementations in order to understand how their various components can
<section id="Databricks">
<div class="attr variable">
<span class="name">Databricks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418215278000&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454845664752&#39;&gt;</span>
</div>
@ -403,7 +403,7 @@ dialect implementations in order to understand how their various components can
<section id="Doris">
<div class="attr variable">
<span class="name">Doris</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418215269648&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858558240&#39;&gt;</span>
</div>
@ -415,7 +415,7 @@ dialect implementations in order to understand how their various components can
<section id="Drill">
<div class="attr variable">
<span class="name">Drill</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418200239984&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454850442672&#39;&gt;</span>
</div>
@ -427,7 +427,7 @@ dialect implementations in order to understand how their various components can
<section id="Druid">
<div class="attr variable">
<span class="name">Druid</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197294864&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454847995360&#39;&gt;</span>
</div>
@ -439,7 +439,7 @@ dialect implementations in order to understand how their various components can
<section id="DuckDB">
<div class="attr variable">
<span class="name">DuckDB</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197298800&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454847990128&#39;&gt;</span>
</div>
@ -451,7 +451,7 @@ dialect implementations in order to understand how their various components can
<section id="Dune">
<div class="attr variable">
<span class="name">Dune</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418213604720&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454845577680&#39;&gt;</span>
</div>
@ -463,7 +463,7 @@ dialect implementations in order to understand how their various components can
<section id="Hive">
<div class="attr variable">
<span class="name">Hive</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418209176576&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858206336&#39;&gt;</span>
</div>
@ -475,7 +475,7 @@ dialect implementations in order to understand how their various components can
<section id="Materialize">
<div class="attr variable">
<span class="name">Materialize</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418208748144&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858281296&#39;&gt;</span>
</div>
@ -487,7 +487,7 @@ dialect implementations in order to understand how their various components can
<section id="MySQL">
<div class="attr variable">
<span class="name">MySQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418214865088&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858280144&#39;&gt;</span>
</div>
@ -499,7 +499,7 @@ dialect implementations in order to understand how their various components can
<section id="Oracle">
<div class="attr variable">
<span class="name">Oracle</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418201758272&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454846419376&#39;&gt;</span>
</div>
@ -511,7 +511,7 @@ dialect implementations in order to understand how their various components can
<section id="Postgres">
<div class="attr variable">
<span class="name">Postgres</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418214345936&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454846428928&#39;&gt;</span>
</div>
@ -523,7 +523,7 @@ dialect implementations in order to understand how their various components can
<section id="Presto">
<div class="attr variable">
<span class="name">Presto</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418214346464&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454855261584&#39;&gt;</span>
</div>
@ -535,7 +535,7 @@ dialect implementations in order to understand how their various components can
<section id="PRQL">
<div class="attr variable">
<span class="name">PRQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418209194880&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454850711264&#39;&gt;</span>
</div>
@ -547,7 +547,7 @@ dialect implementations in order to understand how their various components can
<section id="Redshift">
<div class="attr variable">
<span class="name">Redshift</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418214694144&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454850716784&#39;&gt;</span>
</div>
@ -559,7 +559,7 @@ dialect implementations in order to understand how their various components can
<section id="RisingWave">
<div class="attr variable">
<span class="name">RisingWave</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418214346864&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858183376&#39;&gt;</span>
</div>
@ -571,7 +571,7 @@ dialect implementations in order to understand how their various components can
<section id="Snowflake">
<div class="attr variable">
<span class="name">Snowflake</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418199975440&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454855514176&#39;&gt;</span>
</div>
@ -583,7 +583,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark">
<div class="attr variable">
<span class="name">Spark</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418199977648&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454855522336&#39;&gt;</span>
</div>
@ -595,7 +595,7 @@ dialect implementations in order to understand how their various components can
<section id="Spark2">
<div class="attr variable">
<span class="name">Spark2</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418210304528&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454855108272&#39;&gt;</span>
</div>
@ -607,7 +607,7 @@ dialect implementations in order to understand how their various components can
<section id="SQLite">
<div class="attr variable">
<span class="name">SQLite</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418210310144&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454859099536&#39;&gt;</span>
</div>
@ -619,7 +619,7 @@ dialect implementations in order to understand how their various components can
<section id="StarRocks">
<div class="attr variable">
<span class="name">StarRocks</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418205976656&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454847968784&#39;&gt;</span>
</div>
@ -631,7 +631,7 @@ dialect implementations in order to understand how their various components can
<section id="Tableau">
<div class="attr variable">
<span class="name">Tableau</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418205977952&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454847969312&#39;&gt;</span>
</div>
@ -643,7 +643,7 @@ dialect implementations in order to understand how their various components can
<section id="Teradata">
<div class="attr variable">
<span class="name">Teradata</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197655408&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454845998624&#39;&gt;</span>
</div>
@ -655,7 +655,7 @@ dialect implementations in order to understand how their various components can
<section id="Trino">
<div class="attr variable">
<span class="name">Trino</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197663280&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454846001408&#39;&gt;</span>
</div>
@ -667,7 +667,7 @@ dialect implementations in order to understand how their various components can
<section id="TSQL">
<div class="attr variable">
<span class="name">TSQL</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197671264&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858272208&#39;&gt;</span>
</div>
@ -679,7 +679,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialect">
<div class="attr variable">
<span class="name">Dialect</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197679184&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454847899456&#39;&gt;</span>
</div>
@ -691,7 +691,7 @@ dialect implementations in order to understand how their various components can
<section id="Dialects">
<div class="attr variable">
<span class="name">Dialects</span> =
<span class="default_value">&lt;MagicMock id=&#39;140418197703552&#39;&gt;</span>
<span class="default_value">&lt;MagicMock id=&#39;140454858724864&#39;&gt;</span>
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

View file

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

View file

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

File diff suppressed because one or more lines are too long

View file

@ -199,290 +199,289 @@
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="n">inner_select</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">unnest</span><span class="p">()</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="k">def</span><span class="w"> </span><span class="nf">_is_a_window_expression_in_unmergable_operation</span><span class="p">():</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">window_expressions</span> <span class="o">=</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Window</span><span class="p">)</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="n">window_alias_names</span> <span class="o">=</span> <span class="p">{</span><span class="n">window</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="k">for</span> <span class="n">window</span> <span class="ow">in</span> <span class="n">window_expressions</span><span class="p">}</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="n">inner_select_name</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">unmergable_window_columns</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="n">column</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">columns</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Group</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</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">Having</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="p">)</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="p">]</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="n">window_expressions_in_unmergable</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="n">column</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">unmergable_window_columns</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">inner_select_name</span> <span class="ow">and</span> <span class="n">column</span><span class="o">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">window_alias_names</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="p">]</span>
</span><span id="L-147"><a href="#L-147"><span class="linenos">147</span></a> <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">window_expressions_in_unmergable</span><span class="p">)</span>
</span><span id="L-148"><a href="#L-148"><span class="linenos">148</span></a>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a> <span class="k">def</span><span class="w"> </span><span class="nf">_outer_select_joins_on_inner_select_join</span><span class="p">():</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a><span class="sd"> All columns from the inner select in the ON clause must be from the first FROM table.</span>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a><span class="sd"> That is, this can be merged:</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a><span class="sd"> SELECT * FROM x JOIN (SELECT y.a AS a FROM y JOIN z) AS q ON x.a = q.a</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a><span class="sd"> ^^^ ^</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a><span class="sd"> But this can&#39;t:</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a><span class="sd"> SELECT * FROM x JOIN (SELECT z.a AS a FROM y JOIN z) AS q ON x.a = q.a</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="sd"> ^^^ ^</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">):</span>
</span><span id="L-161"><a href="#L-161"><span class="linenos">161</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-162"><a href="#L-162"><span class="linenos">162</span></a>
</span><span id="L-163"><a href="#L-163"><span class="linenos">163</span></a> <span class="n">alias</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-164"><a href="#L-164"><span class="linenos">164</span></a>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="n">on</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">on</span><span class="p">:</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="n">selections</span> <span class="o">=</span> <span class="p">[</span><span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">on</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span> <span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">alias</span><span class="p">]</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="n">inner_from</span> <span class="o">=</span> <span class="n">inner_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;from&quot;</span><span class="p">)</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">inner_from</span><span class="p">:</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">inner_from_table</span> <span class="o">=</span> <span class="n">inner_from</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="n">inner_projections</span> <span class="o">=</span> <span class="p">{</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span> <span class="n">s</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">}</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="k">return</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="n">col</span><span class="o">.</span><span class="n">table</span> <span class="o">!=</span> <span class="n">inner_from_table</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="k">for</span> <span class="n">selection</span> <span class="ow">in</span> <span class="n">selections</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">inner_projections</span><span class="p">[</span><span class="n">selection</span><span class="p">]</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span>
</span><span id="L-178"><a href="#L-178"><span class="linenos">178</span></a> <span class="p">)</span>
</span><span id="L-179"><a href="#L-179"><span class="linenos">179</span></a>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="k">def</span><span class="w"> </span><span class="nf">_is_recursive</span><span class="p">():</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="c1"># Recursive CTEs look like this:</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="c1"># WITH RECURSIVE cte AS (</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="c1"># SELECT * FROM x &lt;-- inner scope</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="c1"># UNION ALL</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="c1"># SELECT * FROM cte &lt;-- outer scope</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="c1"># )</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="k">while</span> <span class="n">node</span><span class="p">:</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">cte</span><span class="p">:</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="k">return</span> <span class="p">(</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">outer_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">Select</span><span class="p">)</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner_select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">)</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">UNMERGABLE_ARGS</span><span class="p">)</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">pivots</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">leave_tables_isolated</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">)</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;where&quot;</span><span class="p">)</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="ow">and</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">side</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;FULL&quot;</span><span class="p">,</span> <span class="s2">&quot;LEFT&quot;</span><span class="p">,</span> <span class="s2">&quot;RIGHT&quot;</span><span class="p">)</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="p">)</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">)</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;where&quot;</span><span class="p">)</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="ow">and</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="n">j</span><span class="o">.</span><span class="n">side</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;FULL&quot;</span><span class="p">,</span> <span class="s2">&quot;RIGHT&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">outer_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;joins&quot;</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="p">)</span>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> <span class="p">)</span>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_outer_select_joins_on_inner_select_join</span><span class="p">()</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_a_window_expression_in_unmergable_operation</span><span class="p">()</span>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_recursive</span><span class="p">()</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;order&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">is_union</span><span class="p">)</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a> <span class="p">)</span>
</span><span id="L-132"><a href="#L-132"><span class="linenos">132</span></a> <span class="n">window_aliases</span> <span class="o">=</span> <span class="p">{</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">selects</span> <span class="k">if</span> <span class="n">s</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Window</span><span class="p">)}</span>
</span><span id="L-133"><a href="#L-133"><span class="linenos">133</span></a> <span class="n">inner_select_name</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="n">unmergable_window_columns</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">column</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">columns</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">find_ancestor</span><span class="p">(</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">exp</span><span class="o">.</span><span class="n">Where</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Group</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Order</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">Having</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="p">)</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="p">]</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">window_expressions_in_unmergable</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-142"><a href="#L-142"><span class="linenos">142</span></a> <span class="n">column</span>
</span><span id="L-143"><a href="#L-143"><span class="linenos">143</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">unmergable_window_columns</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">inner_select_name</span> <span class="ow">and</span> <span class="n">column</span><span class="o">.</span><span class="n">name</span> <span class="ow">in</span> <span class="n">window_aliases</span>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="p">]</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="k">return</span> <span class="nb">any</span><span class="p">(</span><span class="n">window_expressions_in_unmergable</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="k">def</span><span class="w"> </span><span class="nf">_outer_select_joins_on_inner_select_join</span><span class="p">():</span>
</span><span id="L-149"><a href="#L-149"><span class="linenos">149</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-150"><a href="#L-150"><span class="linenos">150</span></a><span class="sd"> All columns from the inner select in the ON clause must be from the first FROM table.</span>
</span><span id="L-151"><a href="#L-151"><span class="linenos">151</span></a>
</span><span id="L-152"><a href="#L-152"><span class="linenos">152</span></a><span class="sd"> That is, this can be merged:</span>
</span><span id="L-153"><a href="#L-153"><span class="linenos">153</span></a><span class="sd"> SELECT * FROM x JOIN (SELECT y.a AS a FROM y JOIN z) AS q ON x.a = q.a</span>
</span><span id="L-154"><a href="#L-154"><span class="linenos">154</span></a><span class="sd"> ^^^ ^</span>
</span><span id="L-155"><a href="#L-155"><span class="linenos">155</span></a><span class="sd"> But this can&#39;t:</span>
</span><span id="L-156"><a href="#L-156"><span class="linenos">156</span></a><span class="sd"> SELECT * FROM x JOIN (SELECT z.a AS a FROM y JOIN z) AS q ON x.a = q.a</span>
</span><span id="L-157"><a href="#L-157"><span class="linenos">157</span></a><span class="sd"> ^^^ ^</span>
</span><span id="L-158"><a href="#L-158"><span class="linenos">158</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-159"><a href="#L-159"><span class="linenos">159</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">):</span>
</span><span id="L-160"><a href="#L-160"><span class="linenos">160</span></a> <span class="k">return</span> <span class="kc">False</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">alias</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</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="n">on</span> <span class="o">=</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">)</span>
</span><span id="L-165"><a href="#L-165"><span class="linenos">165</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">on</span><span class="p">:</span>
</span><span id="L-166"><a href="#L-166"><span class="linenos">166</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-167"><a href="#L-167"><span class="linenos">167</span></a> <span class="n">selections</span> <span class="o">=</span> <span class="p">[</span><span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">on</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span> <span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">alias</span><span class="p">]</span>
</span><span id="L-168"><a href="#L-168"><span class="linenos">168</span></a> <span class="n">inner_from</span> <span class="o">=</span> <span class="n">inner_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;from&quot;</span><span class="p">)</span>
</span><span id="L-169"><a href="#L-169"><span class="linenos">169</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">inner_from</span><span class="p">:</span>
</span><span id="L-170"><a href="#L-170"><span class="linenos">170</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-171"><a href="#L-171"><span class="linenos">171</span></a> <span class="n">inner_from_table</span> <span class="o">=</span> <span class="n">inner_from</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-172"><a href="#L-172"><span class="linenos">172</span></a> <span class="n">inner_projections</span> <span class="o">=</span> <span class="p">{</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span> <span class="n">s</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">}</span>
</span><span id="L-173"><a href="#L-173"><span class="linenos">173</span></a> <span class="k">return</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-174"><a href="#L-174"><span class="linenos">174</span></a> <span class="n">col</span><span class="o">.</span><span class="n">table</span> <span class="o">!=</span> <span class="n">inner_from_table</span>
</span><span id="L-175"><a href="#L-175"><span class="linenos">175</span></a> <span class="k">for</span> <span class="n">selection</span> <span class="ow">in</span> <span class="n">selections</span>
</span><span id="L-176"><a href="#L-176"><span class="linenos">176</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">inner_projections</span><span class="p">[</span><span class="n">selection</span><span class="p">]</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span>
</span><span id="L-177"><a href="#L-177"><span class="linenos">177</span></a> <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="k">def</span><span class="w"> </span><span class="nf">_is_recursive</span><span class="p">():</span>
</span><span id="L-180"><a href="#L-180"><span class="linenos">180</span></a> <span class="c1"># Recursive CTEs look like this:</span>
</span><span id="L-181"><a href="#L-181"><span class="linenos">181</span></a> <span class="c1"># WITH RECURSIVE cte AS (</span>
</span><span id="L-182"><a href="#L-182"><span class="linenos">182</span></a> <span class="c1"># SELECT * FROM x &lt;-- inner scope</span>
</span><span id="L-183"><a href="#L-183"><span class="linenos">183</span></a> <span class="c1"># UNION ALL</span>
</span><span id="L-184"><a href="#L-184"><span class="linenos">184</span></a> <span class="c1"># SELECT * FROM cte &lt;-- outer scope</span>
</span><span id="L-185"><a href="#L-185"><span class="linenos">185</span></a> <span class="c1"># )</span>
</span><span id="L-186"><a href="#L-186"><span class="linenos">186</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-187"><a href="#L-187"><span class="linenos">187</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-188"><a href="#L-188"><span class="linenos">188</span></a>
</span><span id="L-189"><a href="#L-189"><span class="linenos">189</span></a> <span class="k">while</span> <span class="n">node</span><span class="p">:</span>
</span><span id="L-190"><a href="#L-190"><span class="linenos">190</span></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="n">cte</span><span class="p">:</span>
</span><span id="L-191"><a href="#L-191"><span class="linenos">191</span></a> <span class="k">return</span> <span class="kc">True</span>
</span><span id="L-192"><a href="#L-192"><span class="linenos">192</span></a> <span class="n">node</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-193"><a href="#L-193"><span class="linenos">193</span></a> <span class="k">return</span> <span class="kc">False</span>
</span><span id="L-194"><a href="#L-194"><span class="linenos">194</span></a>
</span><span id="L-195"><a href="#L-195"><span class="linenos">195</span></a> <span class="k">return</span> <span class="p">(</span>
</span><span id="L-196"><a href="#L-196"><span class="linenos">196</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">outer_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">Select</span><span class="p">)</span>
</span><span id="L-197"><a href="#L-197"><span class="linenos">197</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span>
</span><span id="L-198"><a href="#L-198"><span class="linenos">198</span></a> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">inner_select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">)</span>
</span><span id="L-199"><a href="#L-199"><span class="linenos">199</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">UNMERGABLE_ARGS</span><span class="p">)</span>
</span><span id="L-200"><a href="#L-200"><span class="linenos">200</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;from&quot;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span><span id="L-201"><a href="#L-201"><span class="linenos">201</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">pivots</span>
</span><span id="L-202"><a href="#L-202"><span class="linenos">202</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Select</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Explode</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-203"><a href="#L-203"><span class="linenos">203</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">leave_tables_isolated</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span>
</span><span id="L-204"><a href="#L-204"><span class="linenos">204</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
</span><span id="L-205"><a href="#L-205"><span class="linenos">205</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">)</span>
</span><span id="L-206"><a href="#L-206"><span class="linenos">206</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;where&quot;</span><span class="p">)</span>
</span><span id="L-207"><a href="#L-207"><span class="linenos">207</span></a> <span class="ow">and</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">side</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;FULL&quot;</span><span class="p">,</span> <span class="s2">&quot;LEFT&quot;</span><span class="p">,</span> <span class="s2">&quot;RIGHT&quot;</span><span class="p">)</span>
</span><span id="L-208"><a href="#L-208"><span class="linenos">208</span></a> <span class="p">)</span>
</span><span id="L-209"><a href="#L-209"><span class="linenos">209</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
</span><span id="L-210"><a href="#L-210"><span class="linenos">210</span></a> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">)</span>
</span><span id="L-211"><a href="#L-211"><span class="linenos">211</span></a> <span class="ow">and</span> <span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;where&quot;</span><span class="p">)</span>
</span><span id="L-212"><a href="#L-212"><span class="linenos">212</span></a> <span class="ow">and</span> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-213"><a href="#L-213"><span class="linenos">213</span></a> <span class="n">j</span><span class="o">.</span><span class="n">side</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;FULL&quot;</span><span class="p">,</span> <span class="s2">&quot;RIGHT&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">outer_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;joins&quot;</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-214"><a href="#L-214"><span class="linenos">214</span></a> <span class="p">)</span>
</span><span id="L-215"><a href="#L-215"><span class="linenos">215</span></a> <span class="p">)</span>
</span><span id="L-216"><a href="#L-216"><span class="linenos">216</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_outer_select_joins_on_inner_select_join</span><span class="p">()</span>
</span><span id="L-217"><a href="#L-217"><span class="linenos">217</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_a_window_expression_in_unmergable_operation</span><span class="p">()</span>
</span><span id="L-218"><a href="#L-218"><span class="linenos">218</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="n">_is_recursive</span><span class="p">()</span>
</span><span id="L-219"><a href="#L-219"><span class="linenos">219</span></a> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">inner_select</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;order&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">is_union</span><span class="p">)</span>
</span><span id="L-220"><a href="#L-220"><span class="linenos">220</span></a> <span class="p">)</span>
</span><span id="L-221"><a href="#L-221"><span class="linenos">221</span></a>
</span><span id="L-222"><a href="#L-222"><span class="linenos">222</span></a>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_rename_inner_sources</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a><span class="sd"> Renames any sources in the inner query that conflict with names in the outer query.</span>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="n">inner_taken</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">inner_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="n">outer_taken</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">conflicts</span> <span class="o">=</span> <span class="n">outer_taken</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">inner_taken</span><span class="p">)</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a> <span class="n">conflicts</span> <span class="o">-=</span> <span class="p">{</span><span class="n">alias</span><span class="p">}</span>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a> <span class="n">taken</span> <span class="o">=</span> <span class="n">outer_taken</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">inner_taken</span><span class="p">)</span>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="k">for</span> <span class="n">conflict</span> <span class="ow">in</span> <span class="n">conflicts</span><span class="p">:</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a> <span class="n">new_name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="p">,</span> <span class="n">conflict</span><span class="p">)</span>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="n">source</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">[</span><span class="n">conflict</span><span class="p">]</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a> <span class="n">new_alias</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">new_name</span><span class="p">)</span>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="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">Subquery</span><span class="p">):</span>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="n">source</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">new_alias</span><span class="p">))</span>
</span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a> <span class="k">elif</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 class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a> <span class="n">source</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">new_alias</span><span class="p">)</span>
</span><span id="L-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="k">elif</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-246"><a href="#L-246"><span class="linenos">246</span></a> <span class="n">source</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">new_alias</span><span class="p">))</span>
</span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">source_columns</span><span class="p">(</span><span class="n">conflict</span><span class="p">):</span>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a> <span class="n">column</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;table&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">new_name</span><span class="p">))</span>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a>
</span><span id="L-251"><a href="#L-251"><span class="linenos">251</span></a> <span class="n">inner_scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="n">conflict</span><span class="p">,</span> <span class="n">new_name</span><span class="p">)</span>
</span><span id="L-223"><a href="#L-223"><span class="linenos">223</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_rename_inner_sources</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-224"><a href="#L-224"><span class="linenos">224</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-225"><a href="#L-225"><span class="linenos">225</span></a><span class="sd"> Renames any sources in the inner query that conflict with names in the outer query.</span>
</span><span id="L-226"><a href="#L-226"><span class="linenos">226</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-227"><a href="#L-227"><span class="linenos">227</span></a> <span class="n">inner_taken</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">inner_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span>
</span><span id="L-228"><a href="#L-228"><span class="linenos">228</span></a> <span class="n">outer_taken</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span>
</span><span id="L-229"><a href="#L-229"><span class="linenos">229</span></a> <span class="n">conflicts</span> <span class="o">=</span> <span class="n">outer_taken</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">inner_taken</span><span class="p">)</span>
</span><span id="L-230"><a href="#L-230"><span class="linenos">230</span></a> <span class="n">conflicts</span> <span class="o">-=</span> <span class="p">{</span><span class="n">alias</span><span class="p">}</span>
</span><span id="L-231"><a href="#L-231"><span class="linenos">231</span></a>
</span><span id="L-232"><a href="#L-232"><span class="linenos">232</span></a> <span class="n">taken</span> <span class="o">=</span> <span class="n">outer_taken</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">inner_taken</span><span class="p">)</span>
</span><span id="L-233"><a href="#L-233"><span class="linenos">233</span></a>
</span><span id="L-234"><a href="#L-234"><span class="linenos">234</span></a> <span class="k">for</span> <span class="n">conflict</span> <span class="ow">in</span> <span class="n">conflicts</span><span class="p">:</span>
</span><span id="L-235"><a href="#L-235"><span class="linenos">235</span></a> <span class="n">new_name</span> <span class="o">=</span> <span class="n">find_new_name</span><span class="p">(</span><span class="n">taken</span><span class="p">,</span> <span class="n">conflict</span><span class="p">)</span>
</span><span id="L-236"><a href="#L-236"><span class="linenos">236</span></a>
</span><span id="L-237"><a href="#L-237"><span class="linenos">237</span></a> <span class="n">source</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">[</span><span class="n">conflict</span><span class="p">]</span>
</span><span id="L-238"><a href="#L-238"><span class="linenos">238</span></a> <span class="n">new_alias</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">new_name</span><span class="p">)</span>
</span><span id="L-239"><a href="#L-239"><span class="linenos">239</span></a>
</span><span id="L-240"><a href="#L-240"><span class="linenos">240</span></a> <span class="k">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">Subquery</span><span class="p">):</span>
</span><span id="L-241"><a href="#L-241"><span class="linenos">241</span></a> <span class="n">source</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">TableAlias</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">new_alias</span><span class="p">))</span>
</span><span id="L-242"><a href="#L-242"><span class="linenos">242</span></a> <span class="k">elif</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 class="ow">and</span> <span class="n">source</span><span class="o">.</span><span class="n">alias</span><span class="p">:</span>
</span><span id="L-243"><a href="#L-243"><span class="linenos">243</span></a> <span class="n">source</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;alias&quot;</span><span class="p">,</span> <span class="n">new_alias</span><span class="p">)</span>
</span><span id="L-244"><a href="#L-244"><span class="linenos">244</span></a> <span class="k">elif</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-245"><a href="#L-245"><span class="linenos">245</span></a> <span class="n">source</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">alias_</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">new_alias</span><span class="p">))</span>
</span><span id="L-246"><a href="#L-246"><span class="linenos">246</span></a>
</span><span id="L-247"><a href="#L-247"><span class="linenos">247</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">source_columns</span><span class="p">(</span><span class="n">conflict</span><span class="p">):</span>
</span><span id="L-248"><a href="#L-248"><span class="linenos">248</span></a> <span class="n">column</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;table&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">new_name</span><span class="p">))</span>
</span><span id="L-249"><a href="#L-249"><span class="linenos">249</span></a>
</span><span id="L-250"><a href="#L-250"><span class="linenos">250</span></a> <span class="n">inner_scope</span><span class="o">.</span><span class="n">rename_source</span><span class="p">(</span><span class="n">conflict</span><span class="p">,</span> <span class="n">new_name</span><span class="p">)</span>
</span><span id="L-251"><a href="#L-251"><span class="linenos">251</span></a>
</span><span id="L-252"><a href="#L-252"><span class="linenos">252</span></a>
</span><span id="L-253"><a href="#L-253"><span class="linenos">253</span></a>
</span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_from</span><span class="p">(</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a> <span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span>
</span><span id="L-256"><a href="#L-256"><span class="linenos">256</span></a> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span>
</span><span id="L-257"><a href="#L-257"><span class="linenos">257</span></a> <span class="n">node_to_replace</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">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">Table</span><span class="p">],</span>
</span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-261"><a href="#L-261"><span class="linenos">261</span></a><span class="sd"> Merge FROM clause of inner query into outer query.</span>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="n">new_subquery</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;from&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-264"><a href="#L-264"><span class="linenos">264</span></a> <span class="n">new_subquery</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">node_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-265"><a href="#L-265"><span class="linenos">265</span></a> <span class="n">node_to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">new_subquery</span><span class="p">)</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="k">for</span> <span class="n">join_hint</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">join_hints</span><span class="p">:</span>
</span><span id="L-267"><a href="#L-267"><span class="linenos">267</span></a> <span class="n">tables</span> <span class="o">=</span> <span class="n">join_hint</span><span class="o">.</span><span class="n">find_all</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-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="n">tables</span><span class="p">:</span>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a> <span class="k">if</span> <span class="n">table</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="o">==</span> <span class="n">node_to_replace</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span>
</span><span id="L-270"><a href="#L-270"><span class="linenos">270</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">))</span>
</span><span id="L-271"><a href="#L-271"><span class="linenos">271</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">remove_source</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
</span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">add_source</span><span class="p">(</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a> <span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">]</span>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a> <span class="p">)</span>
</span><span id="L-253"><a href="#L-253"><span class="linenos">253</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_from</span><span class="p">(</span>
</span><span id="L-254"><a href="#L-254"><span class="linenos">254</span></a> <span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span>
</span><span id="L-255"><a href="#L-255"><span class="linenos">255</span></a> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span>
</span><span id="L-256"><a href="#L-256"><span class="linenos">256</span></a> <span class="n">node_to_replace</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">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">Table</span><span class="p">],</span>
</span><span id="L-257"><a href="#L-257"><span class="linenos">257</span></a> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span><span id="L-258"><a href="#L-258"><span class="linenos">258</span></a><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-259"><a href="#L-259"><span class="linenos">259</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-260"><a href="#L-260"><span class="linenos">260</span></a><span class="sd"> Merge FROM clause of inner query into outer query.</span>
</span><span id="L-261"><a href="#L-261"><span class="linenos">261</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-262"><a href="#L-262"><span class="linenos">262</span></a> <span class="n">new_subquery</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;from&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">this</span>
</span><span id="L-263"><a href="#L-263"><span class="linenos">263</span></a> <span class="n">new_subquery</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">node_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-264"><a href="#L-264"><span class="linenos">264</span></a> <span class="n">node_to_replace</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">new_subquery</span><span class="p">)</span>
</span><span id="L-265"><a href="#L-265"><span class="linenos">265</span></a> <span class="k">for</span> <span class="n">join_hint</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">join_hints</span><span class="p">:</span>
</span><span id="L-266"><a href="#L-266"><span class="linenos">266</span></a> <span class="n">tables</span> <span class="o">=</span> <span class="n">join_hint</span><span class="o">.</span><span class="n">find_all</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-267"><a href="#L-267"><span class="linenos">267</span></a> <span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="n">tables</span><span class="p">:</span>
</span><span id="L-268"><a href="#L-268"><span class="linenos">268</span></a> <span class="k">if</span> <span class="n">table</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="o">==</span> <span class="n">node_to_replace</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span>
</span><span id="L-269"><a href="#L-269"><span class="linenos">269</span></a> <span class="n">table</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">to_identifier</span><span class="p">(</span><span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">))</span>
</span><span id="L-270"><a href="#L-270"><span class="linenos">270</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">remove_source</span><span class="p">(</span><span class="n">alias</span><span class="p">)</span>
</span><span id="L-271"><a href="#L-271"><span class="linenos">271</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">add_source</span><span class="p">(</span>
</span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a> <span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">new_subquery</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">]</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a> <span class="p">)</span>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a>
</span><span id="L-275"><a href="#L-275"><span class="linenos">275</span></a>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_joins</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">from_or_join</span><span class="p">:</span> <span class="n">FromOrJoin</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a><span class="sd"> Merge JOIN clauses of inner query into outer query.</span>
</span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a>
</span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a> <span class="n">new_joins</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-283"><a href="#L-283"><span class="linenos">283</span></a>
</span><span id="L-284"><a href="#L-284"><span class="linenos">284</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">inner_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;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
</span><span id="L-285"><a href="#L-285"><span class="linenos">285</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">joins</span><span class="p">:</span>
</span><span id="L-286"><a href="#L-286"><span class="linenos">286</span></a> <span class="n">new_joins</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">join</span><span class="p">)</span>
</span><span id="L-287"><a href="#L-287"><span class="linenos">287</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">add_source</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">])</span>
</span><span id="L-288"><a href="#L-288"><span class="linenos">288</span></a>
</span><span id="L-289"><a href="#L-289"><span class="linenos">289</span></a> <span class="k">if</span> <span class="n">new_joins</span><span class="p">:</span>
</span><span id="L-290"><a href="#L-290"><span class="linenos">290</span></a> <span class="n">outer_joins</span> <span class="o">=</span> <span class="n">outer_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;joins&quot;</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-291"><a href="#L-291"><span class="linenos">291</span></a>
</span><span id="L-292"><a href="#L-292"><span class="linenos">292</span></a> <span class="c1"># Maintain the join order</span>
</span><span id="L-293"><a href="#L-293"><span class="linenos">293</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">):</span>
</span><span id="L-294"><a href="#L-294"><span class="linenos">294</span></a> <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="L-295"><a href="#L-295"><span class="linenos">295</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-296"><a href="#L-296"><span class="linenos">296</span></a> <span class="n">position</span> <span class="o">=</span> <span class="n">outer_joins</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
</span><span id="L-297"><a href="#L-297"><span class="linenos">297</span></a> <span class="n">outer_joins</span><span class="p">[</span><span class="n">position</span><span class="p">:</span><span class="n">position</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_joins</span>
</span><span id="L-298"><a href="#L-298"><span class="linenos">298</span></a>
</span><span id="L-299"><a href="#L-299"><span class="linenos">299</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">outer_joins</span><span class="p">)</span>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_joins</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">from_or_join</span><span class="p">:</span> <span class="n">FromOrJoin</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a><span class="sd"> Merge JOIN clauses of inner query into outer query.</span>
</span><span id="L-279"><a href="#L-279"><span class="linenos">279</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-280"><a href="#L-280"><span class="linenos">280</span></a>
</span><span id="L-281"><a href="#L-281"><span class="linenos">281</span></a> <span class="n">new_joins</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-282"><a href="#L-282"><span class="linenos">282</span></a>
</span><span id="L-283"><a href="#L-283"><span class="linenos">283</span></a> <span class="n">joins</span> <span class="o">=</span> <span class="n">inner_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;joins&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="p">[]</span>
</span><span id="L-284"><a href="#L-284"><span class="linenos">284</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">joins</span><span class="p">:</span>
</span><span id="L-285"><a href="#L-285"><span class="linenos">285</span></a> <span class="n">new_joins</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">join</span><span class="p">)</span>
</span><span id="L-286"><a href="#L-286"><span class="linenos">286</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">add_source</span><span class="p">(</span><span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">,</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">sources</span><span class="p">[</span><span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">])</span>
</span><span id="L-287"><a href="#L-287"><span class="linenos">287</span></a>
</span><span id="L-288"><a href="#L-288"><span class="linenos">288</span></a> <span class="k">if</span> <span class="n">new_joins</span><span class="p">:</span>
</span><span id="L-289"><a href="#L-289"><span class="linenos">289</span></a> <span class="n">outer_joins</span> <span class="o">=</span> <span class="n">outer_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;joins&quot;</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-290"><a href="#L-290"><span class="linenos">290</span></a>
</span><span id="L-291"><a href="#L-291"><span class="linenos">291</span></a> <span class="c1"># Maintain the join order</span>
</span><span id="L-292"><a href="#L-292"><span class="linenos">292</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">From</span><span class="p">):</span>
</span><span id="L-293"><a href="#L-293"><span class="linenos">293</span></a> <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span>
</span><span id="L-294"><a href="#L-294"><span class="linenos">294</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-295"><a href="#L-295"><span class="linenos">295</span></a> <span class="n">position</span> <span class="o">=</span> <span class="n">outer_joins</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
</span><span id="L-296"><a href="#L-296"><span class="linenos">296</span></a> <span class="n">outer_joins</span><span class="p">[</span><span class="n">position</span><span class="p">:</span><span class="n">position</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_joins</span>
</span><span id="L-297"><a href="#L-297"><span class="linenos">297</span></a>
</span><span id="L-298"><a href="#L-298"><span class="linenos">298</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;joins&quot;</span><span class="p">,</span> <span class="n">outer_joins</span><span class="p">)</span>
</span><span id="L-299"><a href="#L-299"><span class="linenos">299</span></a>
</span><span id="L-300"><a href="#L-300"><span class="linenos">300</span></a>
</span><span id="L-301"><a href="#L-301"><span class="linenos">301</span></a>
</span><span id="L-302"><a href="#L-302"><span class="linenos">302</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_expressions</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-303"><a href="#L-303"><span class="linenos">303</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a><span class="sd"> Merge projections of inner query into outer query.</span>
</span><span id="L-305"><a href="#L-305"><span class="linenos">305</span></a>
</span><span id="L-306"><a href="#L-306"><span class="linenos">306</span></a><span class="sd"> Args:</span>
</span><span id="L-307"><a href="#L-307"><span class="linenos">307</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a><span class="sd"> alias (str)</span>
</span><span id="L-310"><a href="#L-310"><span class="linenos">310</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-311"><a href="#L-311"><span class="linenos">311</span></a> <span class="c1"># Collect all columns that reference the alias of the inner query</span>
</span><span id="L-312"><a href="#L-312"><span class="linenos">312</span></a> <span class="n">outer_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
</span><span id="L-313"><a href="#L-313"><span class="linenos">313</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-314"><a href="#L-314"><span class="linenos">314</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">alias</span><span class="p">:</span>
</span><span id="L-315"><a href="#L-315"><span class="linenos">315</span></a> <span class="n">outer_columns</span><span class="p">[</span><span class="n">column</span><span class="o">.</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">column</span><span class="p">)</span>
</span><span id="L-316"><a href="#L-316"><span class="linenos">316</span></a>
</span><span id="L-317"><a href="#L-317"><span class="linenos">317</span></a> <span class="c1"># Replace columns with the projection expression in the inner query</span>
</span><span id="L-318"><a href="#L-318"><span class="linenos">318</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-319"><a href="#L-319"><span class="linenos">319</span></a> <span class="n">projection_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-320"><a href="#L-320"><span class="linenos">320</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">projection_name</span><span class="p">:</span>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a> <span class="k">continue</span>
</span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a> <span class="n">columns_to_replace</span> <span class="o">=</span> <span class="n">outer_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">projection_name</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a>
</span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">unalias</span><span class="p">()</span>
</span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a> <span class="n">must_wrap_expression</span> <span class="o">=</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">SAFE_TO_REPLACE_UNWRAPPED</span><span class="p">)</span>
</span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a>
</span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">columns_to_replace</span><span class="p">:</span>
</span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> <span class="c1"># Ensures we don&#39;t alter the intended operator precedence if there&#39;s additional</span>
</span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a> <span class="c1"># context surrounding the outer expression (i.e. it&#39;s not a simple projection).</span>
</span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">column</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">Unary</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">))</span> <span class="ow">and</span> <span class="n">must_wrap_expression</span><span class="p">:</span>
</span><span id="L-331"><a href="#L-331"><span class="linenos">331</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">paren</span><span class="p">(</span><span class="n">expression</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-332"><a href="#L-332"><span class="linenos">332</span></a>
</span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a> <span class="n">column</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="L-301"><a href="#L-301"><span class="linenos">301</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_expressions</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">alias</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-302"><a href="#L-302"><span class="linenos">302</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-303"><a href="#L-303"><span class="linenos">303</span></a><span class="sd"> Merge projections of inner query into outer query.</span>
</span><span id="L-304"><a href="#L-304"><span class="linenos">304</span></a>
</span><span id="L-305"><a href="#L-305"><span class="linenos">305</span></a><span class="sd"> Args:</span>
</span><span id="L-306"><a href="#L-306"><span class="linenos">306</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-307"><a href="#L-307"><span class="linenos">307</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-308"><a href="#L-308"><span class="linenos">308</span></a><span class="sd"> alias (str)</span>
</span><span id="L-309"><a href="#L-309"><span class="linenos">309</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-310"><a href="#L-310"><span class="linenos">310</span></a> <span class="c1"># Collect all columns that reference the alias of the inner query</span>
</span><span id="L-311"><a href="#L-311"><span class="linenos">311</span></a> <span class="n">outer_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>
</span><span id="L-312"><a href="#L-312"><span class="linenos">312</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-313"><a href="#L-313"><span class="linenos">313</span></a> <span class="k">if</span> <span class="n">column</span><span class="o">.</span><span class="n">table</span> <span class="o">==</span> <span class="n">alias</span><span class="p">:</span>
</span><span id="L-314"><a href="#L-314"><span class="linenos">314</span></a> <span class="n">outer_columns</span><span class="p">[</span><span class="n">column</span><span class="o">.</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">column</span><span class="p">)</span>
</span><span id="L-315"><a href="#L-315"><span class="linenos">315</span></a>
</span><span id="L-316"><a href="#L-316"><span class="linenos">316</span></a> <span class="c1"># Replace columns with the projection expression in the inner query</span>
</span><span id="L-317"><a href="#L-317"><span class="linenos">317</span></a> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-318"><a href="#L-318"><span class="linenos">318</span></a> <span class="n">projection_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-319"><a href="#L-319"><span class="linenos">319</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">projection_name</span><span class="p">:</span>
</span><span id="L-320"><a href="#L-320"><span class="linenos">320</span></a> <span class="k">continue</span>
</span><span id="L-321"><a href="#L-321"><span class="linenos">321</span></a> <span class="n">columns_to_replace</span> <span class="o">=</span> <span class="n">outer_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">projection_name</span><span class="p">,</span> <span class="p">[])</span>
</span><span id="L-322"><a href="#L-322"><span class="linenos">322</span></a>
</span><span id="L-323"><a href="#L-323"><span class="linenos">323</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span><span class="o">.</span><span class="n">unalias</span><span class="p">()</span>
</span><span id="L-324"><a href="#L-324"><span class="linenos">324</span></a> <span class="n">must_wrap_expression</span> <span class="o">=</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">SAFE_TO_REPLACE_UNWRAPPED</span><span class="p">)</span>
</span><span id="L-325"><a href="#L-325"><span class="linenos">325</span></a>
</span><span id="L-326"><a href="#L-326"><span class="linenos">326</span></a> <span class="k">for</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">columns_to_replace</span><span class="p">:</span>
</span><span id="L-327"><a href="#L-327"><span class="linenos">327</span></a> <span class="c1"># Ensures we don&#39;t alter the intended operator precedence if there&#39;s additional</span>
</span><span id="L-328"><a href="#L-328"><span class="linenos">328</span></a> <span class="c1"># context surrounding the outer expression (i.e. it&#39;s not a simple projection).</span>
</span><span id="L-329"><a href="#L-329"><span class="linenos">329</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">column</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">Unary</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Binary</span><span class="p">))</span> <span class="ow">and</span> <span class="n">must_wrap_expression</span><span class="p">:</span>
</span><span id="L-330"><a href="#L-330"><span class="linenos">330</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">exp</span><span class="o">.</span><span class="n">paren</span><span class="p">(</span><span class="n">expression</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-331"><a href="#L-331"><span class="linenos">331</span></a>
</span><span id="L-332"><a href="#L-332"><span class="linenos">332</span></a> <span class="n">column</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">copy</span><span class="p">())</span>
</span><span id="L-333"><a href="#L-333"><span class="linenos">333</span></a>
</span><span id="L-334"><a href="#L-334"><span class="linenos">334</span></a>
</span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_where</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">from_or_join</span><span class="p">:</span> <span class="n">FromOrJoin</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a><span class="sd"> Merge WHERE clause of inner query into outer query.</span>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a>
</span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a><span class="sd"> Args:</span>
</span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a><span class="sd"> from_or_join (exp.From|exp.Join)</span>
</span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">inner_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;where&quot;</span><span class="p">)</span>
</span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a> <span class="k">return</span>
</span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a>
</span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span>
</span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a>
</span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">):</span>
</span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a> <span class="c1"># Merge predicates from an outer join to the ON clause</span>
</span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a> <span class="c1"># if it only has columns that are already joined</span>
</span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a> <span class="n">from_</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;from&quot;</span><span class="p">)</span>
</span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a> <span class="n">sources</span> <span class="o">=</span> <span class="p">{</span><span class="n">from_</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">}</span> <span class="k">if</span> <span class="n">from_</span> <span class="k">else</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a>
</span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;joins&quot;</span><span class="p">]:</span>
</span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a> <span class="n">sources</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
</span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a> <span class="k">if</span> <span class="n">source</span> <span class="o">==</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span>
</span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a> <span class="k">break</span>
</span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a>
</span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a> <span class="k">if</span> <span class="n">exp</span><span class="o">.</span><span class="n">column_table_names</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">sources</span><span class="p">:</span>
</span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a> <span class="n">from_or_join</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a> <span class="n">from_or_join</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">,</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">))</span>
</span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a> <span class="k">return</span>
</span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a>
</span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-335"><a href="#L-335"><span class="linenos">335</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_where</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">from_or_join</span><span class="p">:</span> <span class="n">FromOrJoin</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-336"><a href="#L-336"><span class="linenos">336</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-337"><a href="#L-337"><span class="linenos">337</span></a><span class="sd"> Merge WHERE clause of inner query into outer query.</span>
</span><span id="L-338"><a href="#L-338"><span class="linenos">338</span></a>
</span><span id="L-339"><a href="#L-339"><span class="linenos">339</span></a><span class="sd"> Args:</span>
</span><span id="L-340"><a href="#L-340"><span class="linenos">340</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-341"><a href="#L-341"><span class="linenos">341</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-342"><a href="#L-342"><span class="linenos">342</span></a><span class="sd"> from_or_join (exp.From|exp.Join)</span>
</span><span id="L-343"><a href="#L-343"><span class="linenos">343</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-344"><a href="#L-344"><span class="linenos">344</span></a> <span class="n">where</span> <span class="o">=</span> <span class="n">inner_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;where&quot;</span><span class="p">)</span>
</span><span id="L-345"><a href="#L-345"><span class="linenos">345</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">where</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">:</span>
</span><span id="L-346"><a href="#L-346"><span class="linenos">346</span></a> <span class="k">return</span>
</span><span id="L-347"><a href="#L-347"><span class="linenos">347</span></a>
</span><span id="L-348"><a href="#L-348"><span class="linenos">348</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span>
</span><span id="L-349"><a href="#L-349"><span class="linenos">349</span></a>
</span><span id="L-350"><a href="#L-350"><span class="linenos">350</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">from_or_join</span><span class="p">,</span> <span class="n">exp</span><span class="o">.</span><span class="n">Join</span><span class="p">):</span>
</span><span id="L-351"><a href="#L-351"><span class="linenos">351</span></a> <span class="c1"># Merge predicates from an outer join to the ON clause</span>
</span><span id="L-352"><a href="#L-352"><span class="linenos">352</span></a> <span class="c1"># if it only has columns that are already joined</span>
</span><span id="L-353"><a href="#L-353"><span class="linenos">353</span></a> <span class="n">from_</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;from&quot;</span><span class="p">)</span>
</span><span id="L-354"><a href="#L-354"><span class="linenos">354</span></a> <span class="n">sources</span> <span class="o">=</span> <span class="p">{</span><span class="n">from_</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">}</span> <span class="k">if</span> <span class="n">from_</span> <span class="k">else</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-355"><a href="#L-355"><span class="linenos">355</span></a>
</span><span id="L-356"><a href="#L-356"><span class="linenos">356</span></a> <span class="k">for</span> <span class="n">join</span> <span class="ow">in</span> <span class="n">expression</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">&quot;joins&quot;</span><span class="p">]:</span>
</span><span id="L-357"><a href="#L-357"><span class="linenos">357</span></a> <span class="n">source</span> <span class="o">=</span> <span class="n">join</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-358"><a href="#L-358"><span class="linenos">358</span></a> <span class="n">sources</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">source</span><span class="p">)</span>
</span><span id="L-359"><a href="#L-359"><span class="linenos">359</span></a> <span class="k">if</span> <span class="n">source</span> <span class="o">==</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">alias_or_name</span><span class="p">:</span>
</span><span id="L-360"><a href="#L-360"><span class="linenos">360</span></a> <span class="k">break</span>
</span><span id="L-361"><a href="#L-361"><span class="linenos">361</span></a>
</span><span id="L-362"><a href="#L-362"><span class="linenos">362</span></a> <span class="k">if</span> <span class="n">exp</span><span class="o">.</span><span class="n">column_table_names</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">sources</span><span class="p">:</span>
</span><span id="L-363"><a href="#L-363"><span class="linenos">363</span></a> <span class="n">from_or_join</span><span class="o">.</span><span class="n">on</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-364"><a href="#L-364"><span class="linenos">364</span></a> <span class="n">from_or_join</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">,</span> <span class="n">from_or_join</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;on&quot;</span><span class="p">))</span>
</span><span id="L-365"><a href="#L-365"><span class="linenos">365</span></a> <span class="k">return</span>
</span><span id="L-366"><a href="#L-366"><span class="linenos">366</span></a>
</span><span id="L-367"><a href="#L-367"><span class="linenos">367</span></a> <span class="n">expression</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="n">where</span><span class="o">.</span><span class="n">this</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-368"><a href="#L-368"><span class="linenos">368</span></a>
</span><span id="L-369"><a href="#L-369"><span class="linenos">369</span></a>
</span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a>
</span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_order</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a><span class="sd"> Merge ORDER clause of inner query into outer query.</span>
</span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a>
</span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a><span class="sd"> Args:</span>
</span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a> <span class="n">outer_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="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;group&quot;</span><span class="p">,</span> <span class="s2">&quot;distinct&quot;</span><span class="p">,</span> <span class="s2">&quot;having&quot;</span><span class="p">,</span> <span class="s2">&quot;order&quot;</span><span class="p">]</span>
</span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a> <span class="p">)</span>
</span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span>
</span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">)</span> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a> <span class="p">):</span>
</span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a> <span class="k">return</span>
</span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a>
</span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;order&quot;</span><span class="p">,</span> <span class="n">inner_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;order&quot;</span><span class="p">))</span>
</span><span id="L-370"><a href="#L-370"><span class="linenos">370</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_order</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-371"><a href="#L-371"><span class="linenos">371</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-372"><a href="#L-372"><span class="linenos">372</span></a><span class="sd"> Merge ORDER clause of inner query into outer query.</span>
</span><span id="L-373"><a href="#L-373"><span class="linenos">373</span></a>
</span><span id="L-374"><a href="#L-374"><span class="linenos">374</span></a><span class="sd"> Args:</span>
</span><span id="L-375"><a href="#L-375"><span class="linenos">375</span></a><span class="sd"> outer_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-376"><a href="#L-376"><span class="linenos">376</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-377"><a href="#L-377"><span class="linenos">377</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-378"><a href="#L-378"><span class="linenos">378</span></a> <span class="k">if</span> <span class="p">(</span>
</span><span id="L-379"><a href="#L-379"><span class="linenos">379</span></a> <span class="nb">any</span><span class="p">(</span>
</span><span id="L-380"><a href="#L-380"><span class="linenos">380</span></a> <span class="n">outer_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="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;group&quot;</span><span class="p">,</span> <span class="s2">&quot;distinct&quot;</span><span class="p">,</span> <span class="s2">&quot;having&quot;</span><span class="p">,</span> <span class="s2">&quot;order&quot;</span><span class="p">]</span>
</span><span id="L-381"><a href="#L-381"><span class="linenos">381</span></a> <span class="p">)</span>
</span><span id="L-382"><a href="#L-382"><span class="linenos">382</span></a> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">outer_scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span>
</span><span id="L-383"><a href="#L-383"><span class="linenos">383</span></a> <span class="ow">or</span> <span class="nb">any</span><span class="p">(</span><span class="n">expression</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">)</span> <span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span>
</span><span id="L-384"><a href="#L-384"><span class="linenos">384</span></a> <span class="p">):</span>
</span><span id="L-385"><a href="#L-385"><span class="linenos">385</span></a> <span class="k">return</span>
</span><span id="L-386"><a href="#L-386"><span class="linenos">386</span></a>
</span><span id="L-387"><a href="#L-387"><span class="linenos">387</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;order&quot;</span><span class="p">,</span> <span class="n">inner_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;order&quot;</span><span class="p">))</span>
</span><span id="L-388"><a href="#L-388"><span class="linenos">388</span></a>
</span><span id="L-389"><a href="#L-389"><span class="linenos">389</span></a>
</span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a>
</span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_hints</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a> <span class="n">inner_scope_hint</span> <span class="o">=</span> <span class="n">inner_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;hint&quot;</span><span class="p">)</span>
</span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">inner_scope_hint</span><span class="p">:</span>
</span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a> <span class="k">return</span>
</span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a> <span class="n">outer_scope_hint</span> <span class="o">=</span> <span class="n">outer_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;hint&quot;</span><span class="p">)</span>
</span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a> <span class="k">if</span> <span class="n">outer_scope_hint</span><span class="p">:</span>
</span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a> <span class="k">for</span> <span class="n">hint_expression</span> <span class="ow">in</span> <span class="n">inner_scope_hint</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a> <span class="n">outer_scope_hint</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">hint_expression</span><span class="p">)</span>
</span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;hint&quot;</span><span class="p">,</span> <span class="n">inner_scope_hint</span><span class="p">)</span>
</span><span id="L-390"><a href="#L-390"><span class="linenos">390</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_merge_hints</span><span class="p">(</span><span class="n">outer_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-391"><a href="#L-391"><span class="linenos">391</span></a> <span class="n">inner_scope_hint</span> <span class="o">=</span> <span class="n">inner_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;hint&quot;</span><span class="p">)</span>
</span><span id="L-392"><a href="#L-392"><span class="linenos">392</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">inner_scope_hint</span><span class="p">:</span>
</span><span id="L-393"><a href="#L-393"><span class="linenos">393</span></a> <span class="k">return</span>
</span><span id="L-394"><a href="#L-394"><span class="linenos">394</span></a> <span class="n">outer_scope_hint</span> <span class="o">=</span> <span class="n">outer_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;hint&quot;</span><span class="p">)</span>
</span><span id="L-395"><a href="#L-395"><span class="linenos">395</span></a> <span class="k">if</span> <span class="n">outer_scope_hint</span><span class="p">:</span>
</span><span id="L-396"><a href="#L-396"><span class="linenos">396</span></a> <span class="k">for</span> <span class="n">hint_expression</span> <span class="ow">in</span> <span class="n">inner_scope_hint</span><span class="o">.</span><span class="n">expressions</span><span class="p">:</span>
</span><span id="L-397"><a href="#L-397"><span class="linenos">397</span></a> <span class="n">outer_scope_hint</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;expressions&quot;</span><span class="p">,</span> <span class="n">hint_expression</span><span class="p">)</span>
</span><span id="L-398"><a href="#L-398"><span class="linenos">398</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-399"><a href="#L-399"><span class="linenos">399</span></a> <span class="n">outer_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;hint&quot;</span><span class="p">,</span> <span class="n">inner_scope_hint</span><span class="p">)</span>
</span><span id="L-400"><a href="#L-400"><span class="linenos">400</span></a>
</span><span id="L-401"><a href="#L-401"><span class="linenos">401</span></a>
</span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a>
</span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_pop_cte</span><span class="p">(</span><span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a><span class="sd"> Remove CTE from the AST.</span>
</span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a>
</span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a><span class="sd"> Args:</span>
</span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="n">with_</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-415"><a href="#L-415"><span class="linenos">415</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-402"><a href="#L-402"><span class="linenos">402</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_pop_cte</span><span class="p">(</span><span class="n">inner_scope</span><span class="p">:</span> <span class="n">Scope</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span><span id="L-403"><a href="#L-403"><span class="linenos">403</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-404"><a href="#L-404"><span class="linenos">404</span></a><span class="sd"> Remove CTE from the AST.</span>
</span><span id="L-405"><a href="#L-405"><span class="linenos">405</span></a>
</span><span id="L-406"><a href="#L-406"><span class="linenos">406</span></a><span class="sd"> Args:</span>
</span><span id="L-407"><a href="#L-407"><span class="linenos">407</span></a><span class="sd"> inner_scope (sqlglot.optimizer.scope.Scope)</span>
</span><span id="L-408"><a href="#L-408"><span class="linenos">408</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-409"><a href="#L-409"><span class="linenos">409</span></a> <span class="n">cte</span> <span class="o">=</span> <span class="n">inner_scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-410"><a href="#L-410"><span class="linenos">410</span></a> <span class="n">with_</span> <span class="o">=</span> <span class="n">cte</span><span class="o">.</span><span class="n">parent</span>
</span><span id="L-411"><a href="#L-411"><span class="linenos">411</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">with_</span><span class="o">.</span><span class="n">expressions</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
</span><span id="L-412"><a href="#L-412"><span class="linenos">412</span></a> <span class="n">with_</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span><span id="L-413"><a href="#L-413"><span class="linenos">413</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-414"><a href="#L-414"><span class="linenos">414</span></a> <span class="n">cte</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span></pre></div>
@ -581,7 +580,7 @@ queries if it would result in multiple table selects in a single query:</p>
<div class="attr variable">
<span class="name">UNMERGABLE_ARGS</span> =
<input id="UNMERGABLE_ARGS-view-value" class="view-value-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;offset&#39;, &#39;cluster&#39;, &#39;distinct&#39;, &#39;qualify&#39;, &#39;connect&#39;, &#39;into&#39;, &#39;distribute&#39;, &#39;windows&#39;, &#39;having&#39;, &#39;prewhere&#39;, &#39;limit&#39;, &#39;format&#39;, &#39;with&#39;, &#39;sort&#39;, &#39;settings&#39;, &#39;kind&#39;, &#39;locks&#39;, &#39;sample&#39;, &#39;match&#39;, &#39;options&#39;, &#39;group&#39;, &#39;laterals&#39;, &#39;pivots&#39;, &#39;operation_modifiers&#39;}</span>
<label class="view-value-button pdoc-button" for="UNMERGABLE_ARGS-view-value"></label><span class="default_value">{&#39;prewhere&#39;, &#39;locks&#39;, &#39;with&#39;, &#39;sample&#39;, &#39;sort&#39;, &#39;settings&#39;, &#39;format&#39;, &#39;having&#39;, &#39;cluster&#39;, &#39;match&#39;, &#39;windows&#39;, &#39;group&#39;, &#39;qualify&#39;, &#39;laterals&#39;, &#39;kind&#39;, &#39;limit&#39;, &#39;pivots&#39;, &#39;offset&#39;, &#39;connect&#39;, &#39;into&#39;, &#39;operation_modifiers&#39;, &#39;distinct&#39;, &#39;distribute&#39;, &#39;options&#39;}</span>
</div>

View file

@ -68,141 +68,146 @@
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlglot.optimizer.qualify_columns</span><span class="w"> </span><span class="kn">import</span> <span class="n">Resolver</span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlglot.optimizer.scope</span><span class="w"> </span><span class="kn">import</span> <span class="n">Scope</span><span class="p">,</span> <span class="n">traverse_scope</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlglot.schema</span><span class="w"> </span><span class="kn">import</span> <span class="n">ensure_schema</span>
</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="c1"># Sentinel value that means an outer query selecting ALL columns</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="n">SELECT_ALL</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a><span class="kn">from</span><span class="w"> </span><span class="nn">sqlglot.errors</span><span class="w"> </span><span class="kn">import</span> <span class="n">OptimizeError</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a><span class="c1"># Sentinel value that means an outer query selecting ALL columns</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos"> 10</span></a><span class="n">SELECT_ALL</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos"> 11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a><span class="c1"># Selection to use if selection list is empty</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="k">def</span><span class="w"> </span><span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos"> 12</span></a>
</span><span id="L-13"><a href="#L-13"><span class="linenos"> 13</span></a><span class="c1"># Selection to use if selection list is empty</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos"> 14</span></a><span class="k">def</span><span class="w"> </span><span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos"> 15</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos"> 16</span></a>
</span><span id="L-17"><a href="#L-17"><span class="linenos"> 17</span></a><span class="k">def</span><span class="w"> </span><span class="nf">pushdown_projections</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="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-18"><a href="#L-18"><span class="linenos"> 18</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a><span class="sd"> Rewrite sqlglot AST to remove unused columns projections.</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a><span class="sd"> Example:</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="sd"> &gt;&gt;&gt; sql = &quot;SELECT y.a AS a FROM (SELECT x.a AS a, x.b AS b FROM x) AS y&quot;</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(sql)</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> &gt;&gt;&gt; pushdown_projections(expression).sql()</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="sd"> &#39;SELECT y.a AS a FROM (SELECT x.a AS a FROM x) AS y&#39;</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a><span class="sd"> Args:</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="sd"> expression (sqlglot.Expression): expression to optimize</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd"> remove_unused_selections (bool): remove selects that are unused</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd"> Returns:</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos"> 32</span></a><span class="sd"> sqlglot.Expression: optimized expression</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos"> 33</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos"> 34</span></a> <span class="c1"># Map of Scope to all columns being selected by outer queries.</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos"> 35</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><span id="L-36"><a href="#L-36"><span class="linenos"> 36</span></a> <span class="n">source_column_alias_count</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="n">referenced_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</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="c1"># We build the scope tree (which is traversed in DFS postorder), then iterate</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos"> 40</span></a> <span class="c1"># over the result in reverse order. This should ensure that the set of selected</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="c1"># columns for a particular scope are completely build by the time we get to it.</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)):</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">})</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="n">alias_count</span> <span class="o">=</span> <span class="n">source_column_alias_count</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a>
</span><span id="L-46"><a href="#L-46"><span class="linenos"> 46</span></a> <span class="c1"># We can&#39;t remove columns SELECT DISTINCT nor UNION DISTINCT.</span>
</span><span id="L-47"><a href="#L-47"><span class="linenos"> 47</span></a> <span class="k">if</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;distinct&quot;</span><span class="p">):</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</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="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">SetOperation</span><span class="p">):</span>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">union_scopes</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</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="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a> <span class="k">elif</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="k">if</span> <span class="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;by_name&quot;</span><span class="p">):</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="k">if</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="ow">or</span> <span class="n">select</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="p">]</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</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">Select</span><span class="p">):</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="k">if</span> <span class="n">remove_unused_selections</span><span class="p">:</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="n">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</span><span class="p">)</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">continue</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="c1"># Group columns by source name</span>
</span><span id="L-75"><a href="#L-75"><span class="linenos"> 75</span></a> <span class="n">selects</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="L-76"><a href="#L-76"><span class="linenos"> 76</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">table</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a> <span class="n">col_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="n">selects</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">col_name</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"># Push the selected columns down to the next scope</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</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">Scope</span><span class="p">):</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">pivots</span> <span class="k">else</span> <span class="n">selects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-85"><a href="#L-85"><span class="linenos"> 85</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">source</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</span><span id="L-86"><a href="#L-86"><span class="linenos"> 86</span></a>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="n">column_aliases</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">alias_column_names</span>
</span><span id="L-88"><a href="#L-88"><span class="linenos"> 88</span></a> <span class="k">if</span> <span class="n">column_aliases</span><span class="p">:</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">source_column_alias_count</span><span class="p">[</span><span class="n">source</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">column_aliases</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">return</span> <span class="n">expression</span>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</span><span class="p">):</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a> <span class="n">order</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">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;order&quot;</span><span class="p">)</span>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a>
</span><span id="L-97"><a href="#L-97"><span class="linenos"> 97</span></a> <span class="k">if</span> <span class="n">order</span><span class="p">:</span>
</span><span id="L-98"><a href="#L-98"><span class="linenos"> 98</span></a> <span class="c1"># Assume columns without a qualified table are references to output columns</span>
</span><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a> <span class="n">order_refs</span> <span class="o">=</span> <span class="p">{</span><span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">order</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">table</span><span class="p">}</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-101"><a href="#L-101"><span class="linenos">101</span></a> <span class="n">order_refs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-102"><a href="#L-102"><span class="linenos">102</span></a>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="n">new_selections</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">removed</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="n">star</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="n">is_agg</span> <span class="o">=</span> <span class="kc">False</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="k">def</span><span class="w"> </span><span class="nf">pushdown_projections</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="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="L-19"><a href="#L-19"><span class="linenos"> 19</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos"> 20</span></a><span class="sd"> Rewrite sqlglot AST to remove unused columns projections.</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos"> 21</span></a>
</span><span id="L-22"><a href="#L-22"><span class="linenos"> 22</span></a><span class="sd"> Example:</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos"> 23</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="L-24"><a href="#L-24"><span class="linenos"> 24</span></a><span class="sd"> &gt;&gt;&gt; sql = &quot;SELECT y.a AS a FROM (SELECT x.a AS a, x.b AS b FROM x) AS y&quot;</span>
</span><span id="L-25"><a href="#L-25"><span class="linenos"> 25</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(sql)</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos"> 26</span></a><span class="sd"> &gt;&gt;&gt; pushdown_projections(expression).sql()</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos"> 27</span></a><span class="sd"> &#39;SELECT y.a AS a FROM (SELECT x.a AS a FROM x) AS y&#39;</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos"> 28</span></a>
</span><span id="L-29"><a href="#L-29"><span class="linenos"> 29</span></a><span class="sd"> Args:</span>
</span><span id="L-30"><a href="#L-30"><span class="linenos"> 30</span></a><span class="sd"> expression (sqlglot.Expression): expression to optimize</span>
</span><span id="L-31"><a href="#L-31"><span class="linenos"> 31</span></a><span class="sd"> remove_unused_selections (bool): remove selects that are unused</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: optimized 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="c1"># Map of Scope to all columns being selected by outer queries.</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos"> 36</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><span id="L-37"><a href="#L-37"><span class="linenos"> 37</span></a> <span class="n">source_column_alias_count</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="L-38"><a href="#L-38"><span class="linenos"> 38</span></a> <span class="n">referenced_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</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="c1"># We build the scope tree (which is traversed in DFS postorder), then iterate</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos"> 41</span></a> <span class="c1"># over the result in reverse order. This should ensure that the set of selected</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos"> 42</span></a> <span class="c1"># columns for a particular scope are completely build by the time we get to it.</span>
</span><span id="L-43"><a href="#L-43"><span class="linenos"> 43</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)):</span>
</span><span id="L-44"><a href="#L-44"><span class="linenos"> 44</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">})</span>
</span><span id="L-45"><a href="#L-45"><span class="linenos"> 45</span></a> <span class="n">alias_count</span> <span class="o">=</span> <span class="n">source_column_alias_count</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</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"># We can&#39;t remove columns SELECT DISTINCT nor UNION DISTINCT.</span>
</span><span id="L-48"><a href="#L-48"><span class="linenos"> 48</span></a> <span class="k">if</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;distinct&quot;</span><span class="p">):</span>
</span><span id="L-49"><a href="#L-49"><span class="linenos"> 49</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span>
</span><span id="L-50"><a href="#L-50"><span class="linenos"> 50</span></a>
</span><span id="L-51"><a href="#L-51"><span class="linenos"> 51</span></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">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">SetOperation</span><span class="p">):</span>
</span><span id="L-52"><a href="#L-52"><span class="linenos"> 52</span></a> <span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">union_scopes</span>
</span><span id="L-53"><a href="#L-53"><span class="linenos"> 53</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="L-54"><a href="#L-54"><span class="linenos"> 54</span></a> <span class="n">scope_sql</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">sql</span><span class="p">()</span>
</span><span id="L-55"><a href="#L-55"><span class="linenos"> 55</span></a> <span class="k">raise</span> <span class="n">OptimizeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Invalid set operation due to column mismatch: </span><span class="si">{</span><span class="n">scope_sql</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="L-56"><a href="#L-56"><span class="linenos"> 56</span></a>
</span><span id="L-57"><a href="#L-57"><span class="linenos"> 57</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="L-58"><a href="#L-58"><span class="linenos"> 58</span></a>
</span><span id="L-59"><a href="#L-59"><span class="linenos"> 59</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="L-60"><a href="#L-60"><span class="linenos"> 60</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="L-61"><a href="#L-61"><span class="linenos"> 61</span></a> <span class="k">elif</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="L-62"><a href="#L-62"><span class="linenos"> 62</span></a> <span class="k">if</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;by_name&quot;</span><span class="p">):</span>
</span><span id="L-63"><a href="#L-63"><span class="linenos"> 63</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span>
</span><span id="L-64"><a href="#L-64"><span class="linenos"> 64</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-65"><a href="#L-65"><span class="linenos"> 65</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="L-66"><a href="#L-66"><span class="linenos"> 66</span></a> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-67"><a href="#L-67"><span class="linenos"> 67</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="L-68"><a href="#L-68"><span class="linenos"> 68</span></a> <span class="k">if</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-69"><a href="#L-69"><span class="linenos"> 69</span></a> <span class="ow">or</span> <span class="n">select</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-70"><a href="#L-70"><span class="linenos"> 70</span></a> <span class="p">]</span>
</span><span id="L-71"><a href="#L-71"><span class="linenos"> 71</span></a>
</span><span id="L-72"><a href="#L-72"><span class="linenos"> 72</span></a> <span class="k">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">Select</span><span class="p">):</span>
</span><span id="L-73"><a href="#L-73"><span class="linenos"> 73</span></a> <span class="k">if</span> <span class="n">remove_unused_selections</span><span class="p">:</span>
</span><span id="L-74"><a href="#L-74"><span class="linenos"> 74</span></a> <span class="n">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</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="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="L-77"><a href="#L-77"><span class="linenos"> 77</span></a> <span class="k">continue</span>
</span><span id="L-78"><a href="#L-78"><span class="linenos"> 78</span></a>
</span><span id="L-79"><a href="#L-79"><span class="linenos"> 79</span></a> <span class="c1"># Group columns by source name</span>
</span><span id="L-80"><a href="#L-80"><span class="linenos"> 80</span></a> <span class="n">selects</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="L-81"><a href="#L-81"><span class="linenos"> 81</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="L-82"><a href="#L-82"><span class="linenos"> 82</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">table</span>
</span><span id="L-83"><a href="#L-83"><span class="linenos"> 83</span></a> <span class="n">col_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span>
</span><span id="L-84"><a href="#L-84"><span class="linenos"> 84</span></a> <span class="n">selects</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">col_name</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="c1"># Push the selected columns down to the next scope</span>
</span><span id="L-87"><a href="#L-87"><span class="linenos"> 87</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">items</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="nb">isinstance</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">Scope</span><span class="p">):</span>
</span><span id="L-89"><a href="#L-89"><span class="linenos"> 89</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">pivots</span> <span class="k">else</span> <span class="n">selects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-90"><a href="#L-90"><span class="linenos"> 90</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">source</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</span><span id="L-91"><a href="#L-91"><span class="linenos"> 91</span></a>
</span><span id="L-92"><a href="#L-92"><span class="linenos"> 92</span></a> <span class="n">column_aliases</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">alias_column_names</span>
</span><span id="L-93"><a href="#L-93"><span class="linenos"> 93</span></a> <span class="k">if</span> <span class="n">column_aliases</span><span class="p">:</span>
</span><span id="L-94"><a href="#L-94"><span class="linenos"> 94</span></a> <span class="n">source_column_alias_count</span><span class="p">[</span><span class="n">source</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">column_aliases</span><span class="p">)</span>
</span><span id="L-95"><a href="#L-95"><span class="linenos"> 95</span></a>
</span><span id="L-96"><a href="#L-96"><span class="linenos"> 96</span></a> <span class="k">return</span> <span class="n">expression</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><span id="L-99"><a href="#L-99"><span class="linenos"> 99</span></a><span class="k">def</span><span class="w"> </span><span class="nf">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</span><span class="p">):</span>
</span><span id="L-100"><a href="#L-100"><span class="linenos">100</span></a> <span class="n">order</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">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;order&quot;</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">order</span><span class="p">:</span>
</span><span id="L-103"><a href="#L-103"><span class="linenos">103</span></a> <span class="c1"># Assume columns without a qualified table are references to output columns</span>
</span><span id="L-104"><a href="#L-104"><span class="linenos">104</span></a> <span class="n">order_refs</span> <span class="o">=</span> <span class="p">{</span><span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">order</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Column</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">table</span><span class="p">}</span>
</span><span id="L-105"><a href="#L-105"><span class="linenos">105</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-106"><a href="#L-106"><span class="linenos">106</span></a> <span class="n">order_refs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="L-107"><a href="#L-107"><span class="linenos">107</span></a>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="n">select_all</span> <span class="o">=</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="k">for</span> <span class="n">selection</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">:</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">selection</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-108"><a href="#L-108"><span class="linenos">108</span></a> <span class="n">new_selections</span> <span class="o">=</span> <span class="p">[]</span>
</span><span id="L-109"><a href="#L-109"><span class="linenos">109</span></a> <span class="n">removed</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-110"><a href="#L-110"><span class="linenos">110</span></a> <span class="n">star</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-111"><a href="#L-111"><span class="linenos">111</span></a> <span class="n">is_agg</span> <span class="o">=</span> <span class="kc">False</span>
</span><span id="L-112"><a href="#L-112"><span class="linenos">112</span></a>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="k">if</span> <span class="n">select_all</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">parent_selections</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">order_refs</span> <span class="ow">or</span> <span class="n">alias_count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">selection</span><span class="p">)</span>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="n">alias_count</span> <span class="o">-=</span> <span class="mi">1</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a> <span class="k">if</span> <span class="n">selection</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="n">star</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">removed</span> <span class="o">=</span> <span class="kc">True</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">if</span> <span class="ow">not</span> <span class="n">is_agg</span> <span class="ow">and</span> <span class="n">selection</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">):</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="n">is_agg</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="k">if</span> <span class="n">star</span><span class="p">:</span>
</span><span id="L-125"><a href="#L-125"><span class="linenos">125</span></a> <span class="n">resolver</span> <span class="o">=</span> <span class="n">Resolver</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span>
</span><span id="L-126"><a href="#L-126"><span class="linenos">126</span></a> <span class="n">names</span> <span class="o">=</span> <span class="p">{</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">new_selections</span><span class="p">}</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">parent_selections</span><span class="p">):</span>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="n">resolver</span><span class="o">.</span><span class="n">get_table</span><span class="p">(</span><span class="n">name</span><span class="p">)),</span> <span class="n">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-132"><a href="#L-132"><span class="linenos">132</span></a> <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="c1"># If there are no remaining selections, just select a single constant</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">new_selections</span><span class="p">:</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">))</span>
</span><span id="L-137"><a href="#L-137"><span class="linenos">137</span></a>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="o">*</span><span class="n">new_selections</span><span class="p">,</span> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-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">if</span> <span class="n">removed</span><span class="p">:</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span>
</span><span id="L-113"><a href="#L-113"><span class="linenos">113</span></a> <span class="n">select_all</span> <span class="o">=</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="L-114"><a href="#L-114"><span class="linenos">114</span></a>
</span><span id="L-115"><a href="#L-115"><span class="linenos">115</span></a> <span class="k">for</span> <span class="n">selection</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">:</span>
</span><span id="L-116"><a href="#L-116"><span class="linenos">116</span></a> <span class="n">name</span> <span class="o">=</span> <span class="n">selection</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="L-117"><a href="#L-117"><span class="linenos">117</span></a>
</span><span id="L-118"><a href="#L-118"><span class="linenos">118</span></a> <span class="k">if</span> <span class="n">select_all</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">parent_selections</span> <span class="ow">or</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">order_refs</span> <span class="ow">or</span> <span class="n">alias_count</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span><span id="L-119"><a href="#L-119"><span class="linenos">119</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">selection</span><span class="p">)</span>
</span><span id="L-120"><a href="#L-120"><span class="linenos">120</span></a> <span class="n">alias_count</span> <span class="o">-=</span> <span class="mi">1</span>
</span><span id="L-121"><a href="#L-121"><span class="linenos">121</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="L-122"><a href="#L-122"><span class="linenos">122</span></a> <span class="k">if</span> <span class="n">selection</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="L-123"><a href="#L-123"><span class="linenos">123</span></a> <span class="n">star</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-124"><a href="#L-124"><span class="linenos">124</span></a> <span class="n">removed</span> <span class="o">=</span> <span class="kc">True</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="k">if</span> <span class="ow">not</span> <span class="n">is_agg</span> <span class="ow">and</span> <span class="n">selection</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">AggFunc</span><span class="p">):</span>
</span><span id="L-127"><a href="#L-127"><span class="linenos">127</span></a> <span class="n">is_agg</span> <span class="o">=</span> <span class="kc">True</span>
</span><span id="L-128"><a href="#L-128"><span class="linenos">128</span></a>
</span><span id="L-129"><a href="#L-129"><span class="linenos">129</span></a> <span class="k">if</span> <span class="n">star</span><span class="p">:</span>
</span><span id="L-130"><a href="#L-130"><span class="linenos">130</span></a> <span class="n">resolver</span> <span class="o">=</span> <span class="n">Resolver</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">schema</span><span class="p">)</span>
</span><span id="L-131"><a href="#L-131"><span class="linenos">131</span></a> <span class="n">names</span> <span class="o">=</span> <span class="p">{</span><span class="n">s</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">new_selections</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="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">parent_selections</span><span class="p">):</span>
</span><span id="L-134"><a href="#L-134"><span class="linenos">134</span></a> <span class="k">if</span> <span class="n">name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
</span><span id="L-135"><a href="#L-135"><span class="linenos">135</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
</span><span id="L-136"><a href="#L-136"><span class="linenos">136</span></a> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">column</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">table</span><span class="o">=</span><span class="n">resolver</span><span class="o">.</span><span class="n">get_table</span><span class="p">(</span><span class="n">name</span><span class="p">)),</span> <span class="n">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-137"><a href="#L-137"><span class="linenos">137</span></a> <span class="p">)</span>
</span><span id="L-138"><a href="#L-138"><span class="linenos">138</span></a>
</span><span id="L-139"><a href="#L-139"><span class="linenos">139</span></a> <span class="c1"># If there are no remaining selections, just select a single constant</span>
</span><span id="L-140"><a href="#L-140"><span class="linenos">140</span></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">new_selections</span><span class="p">:</span>
</span><span id="L-141"><a href="#L-141"><span class="linenos">141</span></a> <span class="n">new_selections</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">default_selection</span><span class="p">(</span><span class="n">is_agg</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="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="o">*</span><span class="n">new_selections</span><span class="p">,</span> <span class="n">append</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">copy</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span><span id="L-144"><a href="#L-144"><span class="linenos">144</span></a>
</span><span id="L-145"><a href="#L-145"><span class="linenos">145</span></a> <span class="k">if</span> <span class="n">removed</span><span class="p">:</span>
</span><span id="L-146"><a href="#L-146"><span class="linenos">146</span></a> <span class="n">scope</span><span class="o">.</span><span class="n">clear_cache</span><span class="p">()</span>
</span></pre></div>
@ -230,8 +235,8 @@
</div>
<a class="headerlink" href="#default_selection"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="default_selection-14"><a href="#default_selection-14"><span class="linenos">14</span></a><span class="k">def</span><span class="w"> </span><span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="default_selection-15"><a href="#default_selection-15"><span class="linenos">15</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="default_selection-15"><a href="#default_selection-15"><span class="linenos">15</span></a><span class="k">def</span><span class="w"> </span><span class="nf">default_selection</span><span class="p">(</span><span class="n">is_agg</span><span class="p">:</span> <span class="nb">bool</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">exp</span><span class="o">.</span><span class="n">Alias</span><span class="p">:</span>
</span><span id="default_selection-16"><a href="#default_selection-16"><span class="linenos">16</span></a> <span class="k">return</span> <span class="n">alias</span><span class="p">(</span><span class="n">exp</span><span class="o">.</span><span class="n">Max</span><span class="p">(</span><span class="n">this</span><span class="o">=</span><span class="n">exp</span><span class="o">.</span><span class="n">Literal</span><span class="o">.</span><span class="n">number</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_agg</span> <span class="k">else</span> <span class="s2">&quot;1&quot;</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span>
</span></pre></div>
@ -249,81 +254,85 @@
</div>
<a class="headerlink" href="#pushdown_projections"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="pushdown_projections-18"><a href="#pushdown_projections-18"><span class="linenos">18</span></a><span class="k">def</span><span class="w"> </span><span class="nf">pushdown_projections</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="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="pushdown_projections-19"><a href="#pushdown_projections-19"><span class="linenos">19</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="pushdown_projections-20"><a href="#pushdown_projections-20"><span class="linenos">20</span></a><span class="sd"> Rewrite sqlglot AST to remove unused columns projections.</span>
</span><span id="pushdown_projections-21"><a href="#pushdown_projections-21"><span class="linenos">21</span></a>
</span><span id="pushdown_projections-22"><a href="#pushdown_projections-22"><span class="linenos">22</span></a><span class="sd"> Example:</span>
</span><span id="pushdown_projections-23"><a href="#pushdown_projections-23"><span class="linenos">23</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="pushdown_projections-24"><a href="#pushdown_projections-24"><span class="linenos">24</span></a><span class="sd"> &gt;&gt;&gt; sql = &quot;SELECT y.a AS a FROM (SELECT x.a AS a, x.b AS b FROM x) AS y&quot;</span>
</span><span id="pushdown_projections-25"><a href="#pushdown_projections-25"><span class="linenos">25</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(sql)</span>
</span><span id="pushdown_projections-26"><a href="#pushdown_projections-26"><span class="linenos">26</span></a><span class="sd"> &gt;&gt;&gt; pushdown_projections(expression).sql()</span>
</span><span id="pushdown_projections-27"><a href="#pushdown_projections-27"><span class="linenos">27</span></a><span class="sd"> &#39;SELECT y.a AS a FROM (SELECT x.a AS a FROM x) AS y&#39;</span>
</span><span id="pushdown_projections-28"><a href="#pushdown_projections-28"><span class="linenos">28</span></a>
</span><span id="pushdown_projections-29"><a href="#pushdown_projections-29"><span class="linenos">29</span></a><span class="sd"> Args:</span>
</span><span id="pushdown_projections-30"><a href="#pushdown_projections-30"><span class="linenos">30</span></a><span class="sd"> expression (sqlglot.Expression): expression to optimize</span>
</span><span id="pushdown_projections-31"><a href="#pushdown_projections-31"><span class="linenos">31</span></a><span class="sd"> remove_unused_selections (bool): remove selects that are unused</span>
</span><span id="pushdown_projections-32"><a href="#pushdown_projections-32"><span class="linenos">32</span></a><span class="sd"> Returns:</span>
</span><span id="pushdown_projections-33"><a href="#pushdown_projections-33"><span class="linenos">33</span></a><span class="sd"> sqlglot.Expression: optimized expression</span>
</span><span id="pushdown_projections-34"><a href="#pushdown_projections-34"><span class="linenos">34</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="pushdown_projections-35"><a href="#pushdown_projections-35"><span class="linenos">35</span></a> <span class="c1"># Map of Scope to all columns being selected by outer queries.</span>
</span><span id="pushdown_projections-36"><a href="#pushdown_projections-36"><span class="linenos">36</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><span id="pushdown_projections-37"><a href="#pushdown_projections-37"><span class="linenos">37</span></a> <span class="n">source_column_alias_count</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="pushdown_projections-38"><a href="#pushdown_projections-38"><span class="linenos">38</span></a> <span class="n">referenced_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="pushdown_projections-39"><a href="#pushdown_projections-39"><span class="linenos">39</span></a>
</span><span id="pushdown_projections-40"><a href="#pushdown_projections-40"><span class="linenos">40</span></a> <span class="c1"># We build the scope tree (which is traversed in DFS postorder), then iterate</span>
</span><span id="pushdown_projections-41"><a href="#pushdown_projections-41"><span class="linenos">41</span></a> <span class="c1"># over the result in reverse order. This should ensure that the set of selected</span>
</span><span id="pushdown_projections-42"><a href="#pushdown_projections-42"><span class="linenos">42</span></a> <span class="c1"># columns for a particular scope are completely build by the time we get to it.</span>
</span><span id="pushdown_projections-43"><a href="#pushdown_projections-43"><span class="linenos">43</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)):</span>
</span><span id="pushdown_projections-44"><a href="#pushdown_projections-44"><span class="linenos">44</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">})</span>
</span><span id="pushdown_projections-45"><a href="#pushdown_projections-45"><span class="linenos">45</span></a> <span class="n">alias_count</span> <span class="o">=</span> <span class="n">source_column_alias_count</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span id="pushdown_projections-46"><a href="#pushdown_projections-46"><span class="linenos">46</span></a>
</span><span id="pushdown_projections-47"><a href="#pushdown_projections-47"><span class="linenos">47</span></a> <span class="c1"># We can&#39;t remove columns SELECT DISTINCT nor UNION DISTINCT.</span>
</span><span id="pushdown_projections-48"><a href="#pushdown_projections-48"><span class="linenos">48</span></a> <span class="k">if</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;distinct&quot;</span><span class="p">):</span>
</span><span id="pushdown_projections-49"><a href="#pushdown_projections-49"><span class="linenos">49</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span>
</span><span id="pushdown_projections-50"><a href="#pushdown_projections-50"><span class="linenos">50</span></a>
</span><span id="pushdown_projections-51"><a href="#pushdown_projections-51"><span class="linenos">51</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">SetOperation</span><span class="p">):</span>
</span><span id="pushdown_projections-52"><a href="#pushdown_projections-52"><span class="linenos">52</span></a> <span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">union_scopes</span>
</span><span id="pushdown_projections-53"><a href="#pushdown_projections-53"><span class="linenos">53</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-54"><a href="#pushdown_projections-54"><span class="linenos">54</span></a>
</span><span id="pushdown_projections-55"><a href="#pushdown_projections-55"><span class="linenos">55</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="pushdown_projections-56"><a href="#pushdown_projections-56"><span class="linenos">56</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-57"><a href="#pushdown_projections-57"><span class="linenos">57</span></a> <span class="k">elif</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="pushdown_projections-58"><a href="#pushdown_projections-58"><span class="linenos">58</span></a> <span class="k">if</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;by_name&quot;</span><span class="p">):</span>
</span><span id="pushdown_projections-59"><a href="#pushdown_projections-59"><span class="linenos">59</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span>
</span><span id="pushdown_projections-60"><a href="#pushdown_projections-60"><span class="linenos">60</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="pushdown_projections-61"><a href="#pushdown_projections-61"><span class="linenos">61</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="pushdown_projections-62"><a href="#pushdown_projections-62"><span class="linenos">62</span></a> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="pushdown_projections-63"><a href="#pushdown_projections-63"><span class="linenos">63</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="pushdown_projections-64"><a href="#pushdown_projections-64"><span class="linenos">64</span></a> <span class="k">if</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-65"><a href="#pushdown_projections-65"><span class="linenos">65</span></a> <span class="ow">or</span> <span class="n">select</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-66"><a href="#pushdown_projections-66"><span class="linenos">66</span></a> <span class="p">]</span>
</span><span id="pushdown_projections-67"><a href="#pushdown_projections-67"><span class="linenos">67</span></a>
</span><span id="pushdown_projections-68"><a href="#pushdown_projections-68"><span class="linenos">68</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">Select</span><span class="p">):</span>
</span><span id="pushdown_projections-69"><a href="#pushdown_projections-69"><span class="linenos">69</span></a> <span class="k">if</span> <span class="n">remove_unused_selections</span><span class="p">:</span>
</span><span id="pushdown_projections-70"><a href="#pushdown_projections-70"><span class="linenos">70</span></a> <span class="n">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</span><span class="p">)</span>
</span><span id="pushdown_projections-71"><a href="#pushdown_projections-71"><span class="linenos">71</span></a>
</span><span id="pushdown_projections-72"><a href="#pushdown_projections-72"><span class="linenos">72</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="pushdown_projections-73"><a href="#pushdown_projections-73"><span class="linenos">73</span></a> <span class="k">continue</span>
</span><span id="pushdown_projections-74"><a href="#pushdown_projections-74"><span class="linenos">74</span></a>
</span><span id="pushdown_projections-75"><a href="#pushdown_projections-75"><span class="linenos">75</span></a> <span class="c1"># Group columns by source name</span>
</span><span id="pushdown_projections-76"><a href="#pushdown_projections-76"><span class="linenos">76</span></a> <span class="n">selects</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="pushdown_projections-77"><a href="#pushdown_projections-77"><span class="linenos">77</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="pushdown_projections-78"><a href="#pushdown_projections-78"><span class="linenos">78</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">table</span>
</span><span id="pushdown_projections-79"><a href="#pushdown_projections-79"><span class="linenos">79</span></a> <span class="n">col_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span>
</span><span id="pushdown_projections-80"><a href="#pushdown_projections-80"><span class="linenos">80</span></a> <span class="n">selects</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">col_name</span><span class="p">)</span>
</span><span id="pushdown_projections-81"><a href="#pushdown_projections-81"><span class="linenos">81</span></a>
</span><span id="pushdown_projections-82"><a href="#pushdown_projections-82"><span class="linenos">82</span></a> <span class="c1"># Push the selected columns down to the next scope</span>
</span><span id="pushdown_projections-83"><a href="#pushdown_projections-83"><span class="linenos">83</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="pushdown_projections-84"><a href="#pushdown_projections-84"><span class="linenos">84</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">Scope</span><span class="p">):</span>
</span><span id="pushdown_projections-85"><a href="#pushdown_projections-85"><span class="linenos">85</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">pivots</span> <span class="k">else</span> <span class="n">selects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="pushdown_projections-86"><a href="#pushdown_projections-86"><span class="linenos">86</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">source</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</span><span id="pushdown_projections-87"><a href="#pushdown_projections-87"><span class="linenos">87</span></a>
</span><span id="pushdown_projections-88"><a href="#pushdown_projections-88"><span class="linenos">88</span></a> <span class="n">column_aliases</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">alias_column_names</span>
</span><span id="pushdown_projections-89"><a href="#pushdown_projections-89"><span class="linenos">89</span></a> <span class="k">if</span> <span class="n">column_aliases</span><span class="p">:</span>
</span><span id="pushdown_projections-90"><a href="#pushdown_projections-90"><span class="linenos">90</span></a> <span class="n">source_column_alias_count</span><span class="p">[</span><span class="n">source</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">column_aliases</span><span class="p">)</span>
</span><span id="pushdown_projections-91"><a href="#pushdown_projections-91"><span class="linenos">91</span></a>
</span><span id="pushdown_projections-92"><a href="#pushdown_projections-92"><span class="linenos">92</span></a> <span class="k">return</span> <span class="n">expression</span>
<div class="pdoc-code codehilite"><pre><span></span><span id="pushdown_projections-19"><a href="#pushdown_projections-19"><span class="linenos">19</span></a><span class="k">def</span><span class="w"> </span><span class="nf">pushdown_projections</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="kc">None</span><span class="p">,</span> <span class="n">remove_unused_selections</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span><span id="pushdown_projections-20"><a href="#pushdown_projections-20"><span class="linenos">20</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="pushdown_projections-21"><a href="#pushdown_projections-21"><span class="linenos">21</span></a><span class="sd"> Rewrite sqlglot AST to remove unused columns projections.</span>
</span><span id="pushdown_projections-22"><a href="#pushdown_projections-22"><span class="linenos">22</span></a>
</span><span id="pushdown_projections-23"><a href="#pushdown_projections-23"><span class="linenos">23</span></a><span class="sd"> Example:</span>
</span><span id="pushdown_projections-24"><a href="#pushdown_projections-24"><span class="linenos">24</span></a><span class="sd"> &gt;&gt;&gt; import sqlglot</span>
</span><span id="pushdown_projections-25"><a href="#pushdown_projections-25"><span class="linenos">25</span></a><span class="sd"> &gt;&gt;&gt; sql = &quot;SELECT y.a AS a FROM (SELECT x.a AS a, x.b AS b FROM x) AS y&quot;</span>
</span><span id="pushdown_projections-26"><a href="#pushdown_projections-26"><span class="linenos">26</span></a><span class="sd"> &gt;&gt;&gt; expression = sqlglot.parse_one(sql)</span>
</span><span id="pushdown_projections-27"><a href="#pushdown_projections-27"><span class="linenos">27</span></a><span class="sd"> &gt;&gt;&gt; pushdown_projections(expression).sql()</span>
</span><span id="pushdown_projections-28"><a href="#pushdown_projections-28"><span class="linenos">28</span></a><span class="sd"> &#39;SELECT y.a AS a FROM (SELECT x.a AS a FROM x) AS y&#39;</span>
</span><span id="pushdown_projections-29"><a href="#pushdown_projections-29"><span class="linenos">29</span></a>
</span><span id="pushdown_projections-30"><a href="#pushdown_projections-30"><span class="linenos">30</span></a><span class="sd"> Args:</span>
</span><span id="pushdown_projections-31"><a href="#pushdown_projections-31"><span class="linenos">31</span></a><span class="sd"> expression (sqlglot.Expression): expression to optimize</span>
</span><span id="pushdown_projections-32"><a href="#pushdown_projections-32"><span class="linenos">32</span></a><span class="sd"> remove_unused_selections (bool): remove selects that are unused</span>
</span><span id="pushdown_projections-33"><a href="#pushdown_projections-33"><span class="linenos">33</span></a><span class="sd"> Returns:</span>
</span><span id="pushdown_projections-34"><a href="#pushdown_projections-34"><span class="linenos">34</span></a><span class="sd"> sqlglot.Expression: optimized expression</span>
</span><span id="pushdown_projections-35"><a href="#pushdown_projections-35"><span class="linenos">35</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="pushdown_projections-36"><a href="#pushdown_projections-36"><span class="linenos">36</span></a> <span class="c1"># Map of Scope to all columns being selected by outer queries.</span>
</span><span id="pushdown_projections-37"><a href="#pushdown_projections-37"><span class="linenos">37</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><span id="pushdown_projections-38"><a href="#pushdown_projections-38"><span class="linenos">38</span></a> <span class="n">source_column_alias_count</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="pushdown_projections-39"><a href="#pushdown_projections-39"><span class="linenos">39</span></a> <span class="n">referenced_columns</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="pushdown_projections-40"><a href="#pushdown_projections-40"><span class="linenos">40</span></a>
</span><span id="pushdown_projections-41"><a href="#pushdown_projections-41"><span class="linenos">41</span></a> <span class="c1"># We build the scope tree (which is traversed in DFS postorder), then iterate</span>
</span><span id="pushdown_projections-42"><a href="#pushdown_projections-42"><span class="linenos">42</span></a> <span class="c1"># over the result in reverse order. This should ensure that the set of selected</span>
</span><span id="pushdown_projections-43"><a href="#pushdown_projections-43"><span class="linenos">43</span></a> <span class="c1"># columns for a particular scope are completely build by the time we get to it.</span>
</span><span id="pushdown_projections-44"><a href="#pushdown_projections-44"><span class="linenos">44</span></a> <span class="k">for</span> <span class="n">scope</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">traverse_scope</span><span class="p">(</span><span class="n">expression</span><span class="p">)):</span>
</span><span id="pushdown_projections-45"><a href="#pushdown_projections-45"><span class="linenos">45</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">})</span>
</span><span id="pushdown_projections-46"><a href="#pushdown_projections-46"><span class="linenos">46</span></a> <span class="n">alias_count</span> <span class="o">=</span> <span class="n">source_column_alias_count</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</span><span id="pushdown_projections-47"><a href="#pushdown_projections-47"><span class="linenos">47</span></a>
</span><span id="pushdown_projections-48"><a href="#pushdown_projections-48"><span class="linenos">48</span></a> <span class="c1"># We can&#39;t remove columns SELECT DISTINCT nor UNION DISTINCT.</span>
</span><span id="pushdown_projections-49"><a href="#pushdown_projections-49"><span class="linenos">49</span></a> <span class="k">if</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;distinct&quot;</span><span class="p">):</span>
</span><span id="pushdown_projections-50"><a href="#pushdown_projections-50"><span class="linenos">50</span></a> <span class="n">parent_selections</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span>
</span><span id="pushdown_projections-51"><a href="#pushdown_projections-51"><span class="linenos">51</span></a>
</span><span id="pushdown_projections-52"><a href="#pushdown_projections-52"><span class="linenos">52</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">SetOperation</span><span class="p">):</span>
</span><span id="pushdown_projections-53"><a href="#pushdown_projections-53"><span class="linenos">53</span></a> <span class="n">left</span><span class="p">,</span> <span class="n">right</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">union_scopes</span>
</span><span id="pushdown_projections-54"><a href="#pushdown_projections-54"><span class="linenos">54</span></a> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="pushdown_projections-55"><a href="#pushdown_projections-55"><span class="linenos">55</span></a> <span class="n">scope_sql</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">sql</span><span class="p">()</span>
</span><span id="pushdown_projections-56"><a href="#pushdown_projections-56"><span class="linenos">56</span></a> <span class="k">raise</span> <span class="n">OptimizeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Invalid set operation due to column mismatch: </span><span class="si">{</span><span class="n">scope_sql</span><span class="si">}</span><span class="s2">.&quot;</span><span class="p">)</span>
</span><span id="pushdown_projections-57"><a href="#pushdown_projections-57"><span class="linenos">57</span></a>
</span><span id="pushdown_projections-58"><a href="#pushdown_projections-58"><span class="linenos">58</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-59"><a href="#pushdown_projections-59"><span class="linenos">59</span></a>
</span><span id="pushdown_projections-60"><a href="#pushdown_projections-60"><span class="linenos">60</span></a> <span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="pushdown_projections-61"><a href="#pushdown_projections-61"><span class="linenos">61</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-62"><a href="#pushdown_projections-62"><span class="linenos">62</span></a> <span class="k">elif</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">select</span><span class="o">.</span><span class="n">is_star</span> <span class="k">for</span> <span class="n">select</span> <span class="ow">in</span> <span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">):</span>
</span><span id="pushdown_projections-63"><a href="#pushdown_projections-63"><span class="linenos">63</span></a> <span class="k">if</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;by_name&quot;</span><span class="p">):</span>
</span><span id="pushdown_projections-64"><a href="#pushdown_projections-64"><span class="linenos">64</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">left</span><span class="p">]</span>
</span><span id="pushdown_projections-65"><a href="#pushdown_projections-65"><span class="linenos">65</span></a> <span class="k">else</span><span class="p">:</span>
</span><span id="pushdown_projections-66"><a href="#pushdown_projections-66"><span class="linenos">66</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
</span><span id="pushdown_projections-67"><a href="#pushdown_projections-67"><span class="linenos">67</span></a> <span class="n">right</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">alias_or_name</span>
</span><span id="pushdown_projections-68"><a href="#pushdown_projections-68"><span class="linenos">68</span></a> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">select</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">left</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">selects</span><span class="p">)</span>
</span><span id="pushdown_projections-69"><a href="#pushdown_projections-69"><span class="linenos">69</span></a> <span class="k">if</span> <span class="n">SELECT_ALL</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-70"><a href="#pushdown_projections-70"><span class="linenos">70</span></a> <span class="ow">or</span> <span class="n">select</span><span class="o">.</span><span class="n">alias_or_name</span> <span class="ow">in</span> <span class="n">parent_selections</span>
</span><span id="pushdown_projections-71"><a href="#pushdown_projections-71"><span class="linenos">71</span></a> <span class="p">]</span>
</span><span id="pushdown_projections-72"><a href="#pushdown_projections-72"><span class="linenos">72</span></a>
</span><span id="pushdown_projections-73"><a href="#pushdown_projections-73"><span class="linenos">73</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">Select</span><span class="p">):</span>
</span><span id="pushdown_projections-74"><a href="#pushdown_projections-74"><span class="linenos">74</span></a> <span class="k">if</span> <span class="n">remove_unused_selections</span><span class="p">:</span>
</span><span id="pushdown_projections-75"><a href="#pushdown_projections-75"><span class="linenos">75</span></a> <span class="n">_remove_unused_selections</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">parent_selections</span><span class="p">,</span> <span class="n">schema</span><span class="p">,</span> <span class="n">alias_count</span><span class="p">)</span>
</span><span id="pushdown_projections-76"><a href="#pushdown_projections-76"><span class="linenos">76</span></a>
</span><span id="pushdown_projections-77"><a href="#pushdown_projections-77"><span class="linenos">77</span></a> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span><span class="o">.</span><span class="n">is_star</span><span class="p">:</span>
</span><span id="pushdown_projections-78"><a href="#pushdown_projections-78"><span class="linenos">78</span></a> <span class="k">continue</span>
</span><span id="pushdown_projections-79"><a href="#pushdown_projections-79"><span class="linenos">79</span></a>
</span><span id="pushdown_projections-80"><a href="#pushdown_projections-80"><span class="linenos">80</span></a> <span class="c1"># Group columns by source name</span>
</span><span id="pushdown_projections-81"><a href="#pushdown_projections-81"><span class="linenos">81</span></a> <span class="n">selects</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>
</span><span id="pushdown_projections-82"><a href="#pushdown_projections-82"><span class="linenos">82</span></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">columns</span><span class="p">:</span>
</span><span id="pushdown_projections-83"><a href="#pushdown_projections-83"><span class="linenos">83</span></a> <span class="n">table_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">table</span>
</span><span id="pushdown_projections-84"><a href="#pushdown_projections-84"><span class="linenos">84</span></a> <span class="n">col_name</span> <span class="o">=</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span>
</span><span id="pushdown_projections-85"><a href="#pushdown_projections-85"><span class="linenos">85</span></a> <span class="n">selects</span><span class="p">[</span><span class="n">table_name</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">col_name</span><span class="p">)</span>
</span><span id="pushdown_projections-86"><a href="#pushdown_projections-86"><span class="linenos">86</span></a>
</span><span id="pushdown_projections-87"><a href="#pushdown_projections-87"><span class="linenos">87</span></a> <span class="c1"># Push the selected columns down to the next scope</span>
</span><span id="pushdown_projections-88"><a href="#pushdown_projections-88"><span class="linenos">88</span></a> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span> <span class="ow">in</span> <span class="n">scope</span><span class="o">.</span><span class="n">selected_sources</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span><span id="pushdown_projections-89"><a href="#pushdown_projections-89"><span class="linenos">89</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">Scope</span><span class="p">):</span>
</span><span id="pushdown_projections-90"><a href="#pushdown_projections-90"><span class="linenos">90</span></a> <span class="n">columns</span> <span class="o">=</span> <span class="p">{</span><span class="n">SELECT_ALL</span><span class="p">}</span> <span class="k">if</span> <span class="n">scope</span><span class="o">.</span><span class="n">pivots</span> <span class="k">else</span> <span class="n">selects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">set</span><span class="p">()</span>
</span><span id="pushdown_projections-91"><a href="#pushdown_projections-91"><span class="linenos">91</span></a> <span class="n">referenced_columns</span><span class="p">[</span><span class="n">source</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</span><span id="pushdown_projections-92"><a href="#pushdown_projections-92"><span class="linenos">92</span></a>
</span><span id="pushdown_projections-93"><a href="#pushdown_projections-93"><span class="linenos">93</span></a> <span class="n">column_aliases</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">alias_column_names</span>
</span><span id="pushdown_projections-94"><a href="#pushdown_projections-94"><span class="linenos">94</span></a> <span class="k">if</span> <span class="n">column_aliases</span><span class="p">:</span>
</span><span id="pushdown_projections-95"><a href="#pushdown_projections-95"><span class="linenos">95</span></a> <span class="n">source_column_alias_count</span><span class="p">[</span><span class="n">source</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">column_aliases</span><span class="p">)</span>
</span><span id="pushdown_projections-96"><a href="#pushdown_projections-96"><span class="linenos">96</span></a>
</span><span id="pushdown_projections-97"><a href="#pushdown_projections-97"><span class="linenos">97</span></a> <span class="k">return</span> <span class="n">expression</span>
</span></pre></div>

View file

@ -366,7 +366,7 @@
</span><span id="L-272"><a href="#L-272"><span class="linenos">272</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-273"><a href="#L-273"><span class="linenos">273</span></a> <span class="n">expression</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">expression</span>
</span><span id="L-274"><a href="#L-274"><span class="linenos">274</span></a>
</span><span id="L-275"><a href="#L-275"><span class="linenos">275</span></a> <span class="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">Select</span><span class="p">):</span>
</span><span id="L-275"><a href="#L-275"><span class="linenos">275</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">Select</span><span class="p">)</span> <span class="ow">or</span> <span class="n">dialect</span> <span class="o">==</span> <span class="s2">&quot;oracle&quot;</span><span class="p">:</span>
</span><span id="L-276"><a href="#L-276"><span class="linenos">276</span></a> <span class="k">return</span>
</span><span id="L-277"><a href="#L-277"><span class="linenos">277</span></a>
</span><span id="L-278"><a href="#L-278"><span class="linenos">278</span></a> <span class="n">alias_to_expression</span><span class="p">:</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">Tuple</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">int</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{}</span>

View file

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

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

File diff suppressed because it is too large Load diff