o
    8Di                     @  s   d dl mZ d dlZd dlZd dlmZ d dlm	Z	 d dl
mZmZ ejr:ejejef Zejeejeejf f Zdd	d
ZdddZdddZdddZdddZdS )    )annotationsN)expressions)find_new_name)Scopebuild_scope
expressionexp.Expressionreturnc                 C  st  t | tjrt| j | S t| }|s| S i }|jD ]	}|||jjj	< q|
 D ]}|dd |j D  q(i }|jjd}d}|rW|jd}|jD ]}|j	||j< qNg }|jD ]"}	|	
 D ]}||	u riqbt|||}
|
rv||
 qb||	jj q\t|j|j|jD ]}|
 D ]}t|||}
|
r||
 qq|rt | tjr| jn| }|dtj||d | S )a  
    Rewrite derived tables as CTES, deduplicating if possible.

    Example:
        >>> import sqlglot
        >>> expression = sqlglot.parse_one("SELECT a FROM (SELECT * FROM x) AS y")
        >>> eliminate_subqueries(expression).sql()
        'WITH y AS (SELECT * FROM x) SELECT a FROM y AS y'

    This also deduplicates common subqueries:
        >>> expression = sqlglot.parse_one("SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z")
        >>> eliminate_subqueries(expression).sql()
        'WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z'

    Args:
        expression (sqlglot.Expression): expression
    Returns:
        sqlglot.Expression: expression
    c                 S  s$   i | ]\}}t |tjr|j|qS  )
isinstanceexpTablename).0_sourcer
   r
   _/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/optimizer/eliminate_subqueries.py
<dictcomp>9   s    
z(eliminate_subqueries.<locals>.<dictcomp>withF	recursive)r   r   )r   r   Subqueryeliminate_subqueriesthisr   
cte_scopesr   parentaliastraverseupdatesourcesitemsargsgetr   
_eliminateappend	itertoolschainunion_scopessubquery_scopestable_scopesDDLsetWith)r   roottakenscopeexisting_cteswith_r   ctenew_ctes	cte_scopenew_ctechild_scopequeryr
   r
   r   r      sV   






r   r.   r   r/   ExistingCTEsMappingr-   TakenNameMappingt.Optional[exp.Expression]c                 C  s(   | j r	t| ||S | jrt| ||S d S )N)is_derived_table_eliminate_derived_tableis_cte_eliminate_cte)r.   r/   r-   r
   r
   r   r"   i   s
   r"   c                 C  st   | j jst| j jtjrd S | jj  }t| ||\}}tjt	||j
p&|d}|d|jd || |S )N)r   joins)r   pivotsr   r   r   Lateralunwrap_new_ctealias_table_r   r*   r    r!   replace)r.   r/   r-   
to_replacer   r1   tabler
   r
   r   r;   u   s   
r;   c                 C  s   | j j}t| ||\}}|j}|  |js|  | j D ]!}|j D ]\}}	|	| u r?tj	t
||jdd}
||
 q&q|S )NF)r   copy)r   r   rB   popr   r   selected_sourcesvaluesr   rC   rD   alias_or_namerE   )r.   r/   r-   r   r   r1   r0   r5   rG   r   	new_tabler
   r
   r   r=      s   
r=   (t.Tuple[str, t.Optional[exp.Expression]]c                 C  s   | | j}| jj}|j}|st|dd}|r|}n| |r%t||d}| ||< |sC||| j< tj| jtjt|dd}||fS d}||fS )z
    Returns:
        tuple of (name, cte)
        where `name` is a new name for this CTE in the root scope and `cte` is a new CTE instance.
        If this CTE duplicates an existing CTE, `cte` will be None.
    r1   )r-   base)r   )r   r   N)	r!   r   r   r   r   r   CTE
TableAliasto_identifier)r.   r/   r-   duplicate_cte_aliasr   r   r1   r
   r
   r   rB      s&   	

rB   )r   r   r	   r   )r.   r   r/   r7   r-   r8   r	   r9   )r.   r   r/   r7   r-   r8   r	   rN   )
__future__r   r$   typingtsqlglotr   r   sqlglot.helperr   sqlglot.optimizer.scoper   r   TYPE_CHECKINGDict
Expressionstrr7   Unionr8   r   r"   r;   r=   rB   r
   r
   r
   r   <module>   s    

Z

