o
    8Di*                     @   sX   d dl mZ d dlmZ d dlmZmZmZ dd Zdd Z	dd	 Z
d
d Zdd ZdS )    )exp)name_sequence)	ScopeTypefind_in_scopetraverse_scopec                 C   s\   t d}t| D ]#}|j}|j}|sq|jrt|||j| q|jtjkr+t	||| q| S )a  
    Rewrite sqlglot AST to convert some predicates with subqueries into joins.

    Convert scalar subqueries into cross joins.
    Convert correlated or vectorized subqueries into a group by so it is not a many to many left join.

    Example:
        >>> import sqlglot
        >>> expression = sqlglot.parse_one("SELECT * FROM x AS x WHERE (SELECT y.a AS a FROM y AS y WHERE x.a = y.a) = 1 ")
        >>> unnest_subqueries(expression).sql()
        'SELECT * FROM x AS x LEFT JOIN (SELECT y.a AS a FROM y AS y WHERE TRUE GROUP BY y.a) AS _u_0 ON x.a = _u_0.a WHERE _u_0.a = 1'

    Args:
        expression (sqlglot.Expression): expression to unnest
    Returns:
        sqlglot.Expression: unnested expression
    _u_)
r   r   
expressionparent_selectexternal_columnsdecorrelate
scope_typer   SUBQUERYunnest)r   next_alias_namescopeselectparent r   \/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/optimizer/unnest_subqueries.pyunnest_subqueries   s   r   c                 C   s  t | jdkr	d S | tj}|r||jus|jdsd S t| tj	r1tj
| j | | } | }|tjtjtj}t|tjtjfst| jd j|}|rV|jnd }t|tjrb||u sx|rh||ur|jdsxtdd |jD rtj|d}n	t| jtjsd S t| j| |j| d|d	d
 d S | tjtjrd S t|tjr|tj}|r||jurd S t|}| jd }t|j|}	|	 t! " }
t|tjrt|t#  |j$|
d	d nt||
 | jd}|r"|j%ht&|j'kr!t
t(t|jd|jj| jdd	dd	dj)t|jdd	d} nt*|j%tj+s2| j)|j%d	d} |j| |,|	d|d	d d S )N   fromr   groupc                 s   s    | ]	}t |tjV  qd S N)r   r   AggFunc).0r   r   r   r   	<genexpr>C   s    zunnest.<locals>.<genexpr>thisCROSSF)	join_type
join_aliascopyr"   _qLEFTonr    r!   r"   )-lenselectsfind_ancestorr   	Conditionr	   argsget
isinstanceSetOperationr   from_subqueryHavingWhereJoinInAnycolumnalias_or_nameanyMaxr   Subquery_replacejoinfindLimitOffsetEQ_other_operandaliasis_nullnot_truewherer   setexpressionsalias_group_byr   r   eq)r   r	   r   	predicaterC   clauser7   clause_parent_selectvaluejoin_keyjoin_key_not_nullr   r   r   r   r   '   s~   





r   c              
      s&  j d}|r|tjstjtjrd S | }g }|D ]F  tj|ur, d S  tj	}|r<|tj|ur? d S t
|tjrZt fdd|j D rV|jn|j}n d S || |f qtdd |D sqd S tfddtdd |jD }	jd }
i }g }|D ]-\}}}||
jkr|
j||< || q||vr| ||< t
|tjr||vr|| qtj	}|	rtjntj}|
tjs|
j|vrjtj||
jd	|
jd
dd
d
d t
|tjrg j d< | D ]5\}}||v rt
|tjs||
jkrj| d| d
d qjtj|| d	|d
dd
d qt|
j|}t|}|r?t |j!nd }t
|tjr^tt"|# d |}t$|d| d}nt
|tj%rt&|tjsnJ ||tdd}t$|j!d| d| d}nt
|tj'rt&|tjsJ |
j|v r|||d}t$|j!|}ni||tdd}t$|d| d| d}nSt
|tj(r|
j|v rt$|| d| }n;t$|d| d|j d}n-|	rj!jrt|j!j}|
tj)rdd }tj*||
j+|gd}j!,| |D ]h\} }|,t-  t|| |}|	r?|,| t
|tjs=|j.|d
d q||v rK|,| qt
|tjrct$|d| d| d  d }q|,t/d t$|d| d!| d| d }q|j0j1|d"d
id#d$ |D d%|d
d& d S )'NrH   c                 3   s    | ]}| u V  qd S r   r   r   node)r7   r   r   r      s    zdecorrelate.<locals>.<genexpr>c                 s   s"    | ]^ }}t |tjV  qd S r   r.   r   rA   r   _rN   r   r   r   r      s     c                 3   s&    | ]}t |tjr| ju V  qd S r   )r.   r   r;   r   rT   )r   r   r   r      s    

c                 S   s   |   S r   )unalias)sr   r   r   <lambda>   s    zdecorrelate.<locals>.<lambda>r   r   F)quoted)appendr"   rJ   z AS r#   zNOT z IS NULL_x)r   r   z
ARRAY_ALL(z, _x -> )z
ARRAY_ANY(z = z, _x -> _x = c                 S   s0   t | tjrtjdS t | tjrt S | S )Nr   )r.   r   CountLiteralnumberr   rE   )rU   r   r   r   remove_aggs   s
   z decorrelate.<locals>.remove_aggs)r   rJ   (z AND ARRAY_CONTAINS(z, z))z AND ARRAY_ANY(r"   c                 S   s"   g | ]^ }}t |tjr|qS r   rV   rW   r   r   r   
<listcomp>  s   " zdecorrelate.<locals>.<listcomp>r%   r&   )2r,   r-   r>   r   Orr?   r@   r*   r3   	Predicater.   Binaryr9   leftwalkrightr]   mapr)   r   rC   rA   r:   ArrayAggr   r   rK   Existsitemsr"   r7   rB   typer   listvaluesr<   All
issubclassr6   r5   r`   Coalesce	transformreplacerG   rH   to_identifierr=   rL   )r   r	   r
   r   rH   table_aliaskeysrN   keyis_subquery_projectionrQ   key_aliasesrL   rX   parent_predicateagg_funcrC   otherop_typerc   nestedr   )r7   r   r   r   x   s    






&


r   c                 C   s   |  t|S r   )rw   r   	condition)r   r   r   r   r   r<     s   r<   c                 C   sf   t | tjr	| jS t | tjtjfrt| jS t | tjr1t | j	tj
tjtjtjfr.| jS | j	S d S r   )r.   r   r5   r   r6   rs   rB   r   rh   ri   r;   rn   rk   )r   r   r   r   rB      s   
rB   N)sqlglotr   sqlglot.helperr   sqlglot.optimizer.scoper   r   r   r   r   r   r<   rB   r   r   r   r   <module>   s    !Q %