o
    8Di                     @   sl   d dl mZ d dlmZ d dlmZmZ dd Zdd Z	dd	 Z
d
d Zdd Zdd Zdd Zdd ZdS )    )expressions)
normalized)Scopetraverse_scopec                 C   s\   t | D ]'}|jr
q|jjdg }t|D ]}|j}t|||r*|  |	| qq| S )a  
    Remove unused joins from an expression.

    This only removes joins when we know that the join condition doesn't produce duplicate rows.

    Example:
        >>> import sqlglot
        >>> sql = "SELECT x.a FROM x LEFT JOIN (SELECT DISTINCT y.b FROM y) AS y ON x.b = y.b"
        >>> expression = sqlglot.parse_one(sql)
        >>> eliminate_joins(expression).sql()
        'SELECT x.a FROM x'

    Args:
        expression (sqlglot.Expression): expression to optimize
    Returns:
        sqlglot.Expression: optimized expression
    joins)
r   unqualified_columns
expressionargsgetreversedalias_or_name_should_eliminate_joinpopremove_source)r   scoper   joinalias r   Z/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/optimizer/eliminate_joins.pyeliminate_joins   s   
r   c                 C   sN   | j |}t|to&t| || o&|jdkrt||p&|jd o&t|S )NLEFTon)	sourcesr
   
isinstancer   _join_is_usedside _is_joined_on_all_unique_outputsr	   _has_single_output_row)r   r   r   inner_sourcer   r   r   r   *   s   
r   c                    sJ   |j d}|rdd |tjD  nt  t fdd| |D S )Nr   c                 S   s   h | ]}t |qS r   id.0columnr   r   r   	<setcomp>;   s    z _join_is_used.<locals>.<setcomp>c                 3   s     | ]}t | vr|V  qd S Nr   r!   on_clause_columnsr   r   	<genexpr>>   s    z _join_is_used.<locals>.<genexpr>)r	   r
   find_allexpColumnsetanysource_columns)r   r   r   r   r   r&   r   r   6   s   r   c                 C   s6   t | }|sdS t|\}}}|dd |D  }| S )NFc                 S   s   h | ]}|j qS r   )namer"   cr   r   r   r$   I   s    z3_is_joined_on_all_unique_outputs.<locals>.<setcomp>)_unique_outputsjoin_condition)r   r   unique_outputs_	join_keysremaining_unique_outputsr   r   r   r   C   s   r   c                 C   s   | j jdrt| j jS | j jd}|rEt|j}t }t }| j jD ]}| }||v r:|| ||j	 q%|
|sB|S t S t| rOt| j jS t S )zODetermine output columns of `scope` that must have a unique combination per rowdistinctgroup)r   r	   r
   r,   named_selectsr   selectsunaliasaddr   
differencer   )r   r9   grouped_expressionsgrouped_outputsr4   selectoutputr   r   r   r2   M   s&   


r2   c                 C   s<   t | jtjotdd | jjD pt| p| jjd S )Nc                 s   s     | ]}t | tjV  qd S r%   )r   r<   r*   AggFunc)r"   er   r   r   r(   l   s    z)_has_single_output_row.<locals>.<genexpr>from)	r   r   r*   Selectallr;   _is_limit_1r	   r
   )r   r   r   r   r   j   s   r   c                 C   s   | j jd}|o|j jdkS )Nlimit1)r   r	   r
   this)r   rI   r   r   r   rH   r   s   rH   c                    s  | j | jdpt  }g g   fdd}t|rCt|tjr'|n	tj	|t dd}|
 D ]}t|tjrA|| q5nFt|ddrd}|
 D ]0}d	d
 |
 D }|du ra|}qOg }|D ]fdd
|D }|r|| || qe|}qO|D ]}|| q |fS )z
    Extract the join condition from a join expression.

    Args:
        join (exp.Join)
    Returns:
        tuple[list[str], list[str], exp.Expression]:
            Tuple of (source key, join key, remaining predicate)
    r   c                    s   |   \}}t|}t|}|v r+|vr+ | | | t  d S |v rF|vrH | | | t  d S d S d S r%   )unnest_operandsr*   column_table_namesappendreplacetrue)	conditionleftrightleft_tablesright_tables)join_keyr/   
source_keyr   r   extract_condition   s   





z)join_condition.<locals>.extract_conditionF)copyT)dnfNc                 S   s   g | ]
}t |tjr|qS r   )r   r*   EQ)r"   partr   r   r   
<listcomp>   s    z"join_condition.<locals>.<listcomp>c                    s   g | ]} |kr|qS r   r   r0   )pr   r   r]      s    )r   r	   r
   r*   rP   rY   r   r   Andand_flattenr[   rN   extend)r   r   rX   rQ   
conditionspartstempcsr   )rV   r/   r^   rW   r   r3   w   s:   
$



r3   N)sqlglotr   r*   sqlglot.optimizer.normalizer   sqlglot.optimizer.scoper   r   r   r   r   r   r2   r   rH   r3   r   r   r   r   <module>   s    $
