o
    8Di                     @  sV   d dl mZ d dlZd dlmZ d dlmZ dZdd Z	dd	 Z
d
d ZdddZdS )    )annotationsN)exp)tsort)onsidekindusingmethodc              	   C  s&  |  tjD ]}i }g }|jdg D ]!}t|}|r,|D ]}||g |g ||< qq||j|f q|D ]P\}}||g D ]E}|jd }	t|	tj	rt
t|dk rWqAt|	}
|	 D ]&}|t|v r|t  tj|jd|g|
dd}|j|ddd q_qAq7qt| } t| } | S )aM  
    Removes cross joins if possible and reorder joins based on predicate dependencies.

    Example:
        >>> from sqlglot import parse_one
        >>> optimize_joins(parse_one("SELECT * FROM x CROSS JOIN y JOIN z ON x.a = z.a AND y.a = z.a")).sql()
        'SELECT * FROM x JOIN z ON x.a = z.a AND TRUE JOIN y ON y.a = z.a'
    joinsr      F)copy)appendr   )find_allr   Selectargsgetother_table_namesr   alias_or_name
isinstance	Connectorlentypeflattencolumn_table_namesreplacetrue_combiner   reorder_joins	normalize)
expressionselect
referencescross_joinsjointablestablenamedepr   operator	predicate r*   Y/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/optimizer/optimize_joins.pyoptimize_joins   s<   

r,   c                   sf   |  tjD ]*  j}dd |jdg D dd  D }|d fddt|D  q| S )zP
    Reorder joins by topological sort order based on predicate references.
    c                 S  s   i | ]}|j |qS r*   r   ).0r#   r*   r*   r+   
<dictcomp>>   s    z!reorder_joins.<locals>.<dictcomp>r
   c                 S  s   i | ]	\}}|t |qS r*   )r   )r.   r&   r#   r*   r*   r+   r/   ?   s    c                   s&   g | ]}| j kr|v r| qS r*   r-   )r.   r&   from_r
   r*   r+   
<listcomp>B   s   & z!reorder_joins.<locals>.<listcomp>)	r   r   Fromparentr   r   itemssetr   )r   r4   dagr*   r0   r+   r   8   s   r   c                   s   |  tjD ]9 t fddtD s dd  jdkr% dd q dd  jds? jds? dt	  q| S )zA
    Remove INNER and OUTER from joins as they are optional.
    c                 3  s    | ]	} j |V  qd S )N)r   r   )r.   kr#   r*   r+   	<genexpr>L   s    znormalize.<locals>.<genexpr>r   CROSSr   Nr   )
r   r   Joinany
JOIN_ATTRSr6   r   r   r   r   )r   r*   r9   r+   r   G   s   
r   r#   exp.Joinreturn
t.Set[str]c                 C  s$   | j d}|rt|| jS t S )Nr   )r   r   r   r   r   r6   )r#   r   r*   r*   r+   r   Y   s   r   )r#   r?   r@   rA   )
__future__r   typingtsqlglotr   sqlglot.helperr   r>   r,   r   r   r   r*   r*   r*   r+   <module>   s    -