U
    e1                     @   s   d Z ddlZddlmZ ddlmZmZ ddlmZm	Z	 ddl
mZ ddlmZ ddlmZ d	Zd
ZdZG dd dejZG dd dZG dd dZG dd dZdS )zG
Code to manage the creation and SQL rendering of 'where' constraints.
    N)reduce)EmptyResultSetFullResultSetCaseWhen)Exact)tree)cached_propertyANDORXORc                   @   s  e Zd ZdZeZdZdZd5dd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d Zedd Zedd Zedd Zedd Zed d! Zed"d# Zed$d% Zd&d' Zed(d) Zed*d+ Zd,d- Z d.d/ Z!d0d1 Z"d2d3 Z#d4S )6	WhereNodea  
    An SQL WHERE clause.

    The class is tied to the Query class that created it (in order to create
    the correct SQL).

    A child is usually an expression producing boolean values. Most likely the
    expression is a Lookup instance.

    However, a child could also be any class with as_sql() and either
    relabeled_clone() method or relabel_aliases() and clone() methods and
    contains_aggregate attribute.
    FTc                 C   s  | j s| js| ddfS || jA }|r.| jtkpF| r>| jtkpF| jtk}|rb| j rb| jsbd| dfS g }g }g }| jD ]}t|dr|	||\}	}
}|	dk	r|
|	 |
dk	r|
|
 |dk	r|
| qt|jr|
| qt|j r|
| qt|
| qt|r2|r2|r|r$|s$dd| fS |r2td|rJ| || j| jnd}|rf| || j| jnd}|r| || j| jnd}|||fS )a  
        Return three possibly None nodes: one for those parts of self that
        should be included in the WHERE clause, one for those parts of self
        that must be included in the HAVING clause, and one for those parts
        that refer to window functions.
        Nsplit_having_qualifyzzHeterogeneous disjunctive predicates against window functions are not implemented when performing conditional aggregation.)contains_aggregatecontains_over_clausenegated	connectorr   r   r   childrenhasattrr   appendNotImplementedErrorcreate)selfr   Zmust_group_byZ
in_negatedZmust_remain_connectedZwhere_partsZhaving_partsZqualify_partscZ
where_partZhaving_partZqualify_partZ
where_nodeZhaving_nodeZqualify_node r   >/tmp/pip-unpacked-wheel-lctamlir/django/db/models/sql/where.pyr   &   sn    




 



zWhereNode.split_having_qualifyc              	   C   s  g }g }| j tkr$t| jd }}ndt| j }}| j tkr|jjs| | jt}t	t
jdd | jD }td|}	| ||	gt| j||S | jD ]}
z||
\}}W n6 tk
r   |d8 }Y n@ tk
r   |d8 }Y n&X |r|| || n|d8 }|dkr&| jr"tnt|dkr| jr<tqtqd| j  }||}|s`t| jrrd| }nt|dks| jrd| }||fS )a  
        Return the SQL version of the where clause and the value to be
        substituted in. Return '', [] if this node matches everything,
        None, [] if this node is empty, and raise EmptyResultSet if this
        node can't match anything.
           c                 s   s"   | ]}t t|d dddV  qdS )r   )Zthenr   )defaultNr   .0r   r   r   r   	<genexpr>   s     z#WhereNode.as_sql.<locals>.<genexpr>r   z %s zNOT (%s)(%s))r   r   lenr   r   featuresZsupports_logical_xor	__class__r   r   operatoraddr   r   as_sqlcompiler   r   r   extendjoinresolved)r   compiler
connectionresultZresult_paramsZfull_neededZempty_neededlhsZrhs_sumrhschildsqlparamsconnZ
sql_stringr   r   r   r(   r   sX    

 





zWhereNode.as_sqlc                 C   s"   g }| j D ]}||  q
|S N)r   r*   get_group_by_cols)r   colsr2   r   r   r   r7      s    
zWhereNode.get_group_by_colsc                 C   s   | j d d  S r6   )r   r   r   r   r   get_source_expressions   s    z WhereNode.get_source_expressionsc                 C   s    t |t | jkst|| _d S r6   )r#   r   AssertionError)r   r   r   r   r   set_source_expressions   s    z WhereNode.set_source_expressionsc                 C   sH   t | jD ]8\}}t|dr(|| q
t|dr
||| j|< q
dS )z
        Relabel the alias values of any children. 'change_map' is a dictionary
        mapping old (current) alias values to the new values.
        relabel_aliasesrelabeled_cloneN)	enumerater   r   r=   r>   )r   
change_mapposr2   r   r   r   r=      s
    

zWhereNode.relabel_aliasesc                 C   s@   | j | j| jd}| jD ]"}t|dr.| }|j| q|S )Nr   r   clone)r   r   r   r   r   rC   r   )r   rC   r2   r   r   r   rC      s    

zWhereNode.clonec                 C   s   |   }|| |S r6   )rC   r=   )r   r@   rC   r   r   r   r>      s    
zWhereNode.relabeled_clonec                 C   sF   | |  }r|S | j| j| jd}| jD ]}|j|| q*|S )NrB   )getr   r   r   r   r   replace_expressions)r   replacementsreplacementrC   r2   r   r   r   rE      s    
zWhereNode.replace_expressionsc                 C   s"   t  }| jD ]}|| O }q|S r6   )setr   get_refs)r   refsr2   r   r   r   rI      s    
zWhereNode.get_refsc                    s*   t |tjr$t fdd|jD S |jS )Nc                 3   s   | ]}  |V  qd S r6   _contains_aggregater   clsr   r   r!      s     z0WhereNode._contains_aggregate.<locals>.<genexpr>)
isinstancer	   Nodeanyr   r   rN   objr   rM   r   rL      s    zWhereNode._contains_aggregatec                 C   s
   |  | S r6   rK   r9   r   r   r   r      s    zWhereNode.contains_aggregatec                    s*   t |tjr$t fdd|jD S |jS )Nc                 3   s   | ]}  |V  qd S r6   _contains_over_clauser   rM   r   r   r!      s     z2WhereNode._contains_over_clause.<locals>.<genexpr>)rO   r	   rP   rQ   r   r   rR   r   rM   r   rU      s    zWhereNode._contains_over_clausec                 C   s
   |  | S r6   rT   r9   r   r   r   r      s    zWhereNode.contains_over_clausec                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r6   )
is_summary)r    r2   r   r   r   r!     s     z'WhereNode.is_summary.<locals>.<genexpr>)rQ   r   r9   r   r   r   rV      s    zWhereNode.is_summaryc                 O   s    t | dr| j|f||} | S )Nresolve_expression)r   rW   )exprqueryargskwargsr   r   r   _resolve_leaf  s    
zWhereNode._resolve_leafc                 O   sr   t |dr*|jD ]}| j||f|| qt |drL| j|j|f|||_t |drn| j|j|f|||_d S )Nr   r0   r1   )r   r   _resolve_noder\   r0   r1   )rN   noderY   rZ   r[   r2   r   r   r   r]   
  s    



zWhereNode._resolve_nodec                 O   s$   |   }|j|f|| d|_|S )NT)rC   r]   r,   )r   rZ   r[   rC   r   r   r   rW     s    zWhereNode.resolve_expressionc                 C   s   ddl m} | S )Nr   )BooleanField)Zdjango.db.modelsr_   )r   r_   r   r   r   output_field  s    zWhereNode.output_fieldc                 C   s   | j S r6   )r`   r9   r   r   r   _output_field_or_none   s    zWhereNode._output_field_or_nonec                 C   s   |j jjsd| d}||fS )Nz
CASE WHEN z THEN 1 ELSE 0 END)r.   r$   Z&supports_boolean_expr_in_select_clause)r   r-   r3   r4   r   r   r   select_format$  s    
zWhereNode.select_formatc                 C   s   | j |S r6   )r`   get_db_converters)r   r.   r   r   r   rc   ,  s    zWhereNode.get_db_convertersc                 C   s   | j |S r6   )r`   
get_lookup)r   lookupr   r   r   rd   /  s    zWhereNode.get_lookupc                 c   s0   | j D ]$}t|tr$| E d H  q|V  qd S r6   )r   rO   r   leaves)r   r2   r   r   r   rf   2  s    

zWhereNode.leavesN)FF)$__name__
__module____qualname____doc__r   r   r,   Zconditionalr   r(   r7   r:   r<   r=   rC   r>   rE   rI   classmethodrL   r
   r   rU   r   propertyrV   staticmethodr\   r]   rW   r`   ra   rb   rc   rd   rf   r   r   r   r   r      sJ   
LF






	

r   c                   @   s"   e Zd ZdZdZdZdddZdS )NothingNodezA node that matches nothing.FNc                 C   s   t d S r6   )r   )r   r-   r.   r   r   r   r(   @  s    zNothingNode.as_sql)NN)rg   rh   ri   rj   r   r   r(   r   r   r   r   rn   :  s   rn   c                   @   s&   e Zd ZdZdZdd ZdddZdS )
ExtraWhereFc                 C   s   || _ || _d S r6   )sqlsr4   )r   rp   r4   r   r   r   __init__I  s    zExtraWhere.__init__Nc                 C   s(   dd | j D }d|t| jp"dfS )Nc                 S   s   g | ]}d | qS )r"   r   )r    r3   r   r   r   
<listcomp>N  s     z%ExtraWhere.as_sql.<locals>.<listcomp>z AND r   )rp   r+   listr4   )r   r-   r.   rp   r   r   r   r(   M  s    zExtraWhere.as_sql)NNrg   rh   ri   r   r   rq   r(   r   r   r   r   ro   D  s   ro   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )SubqueryConstraintFc                 C   s(   || _ || _|| _|jdd || _d S )NT)Zclear_default)aliascolumnstargetsZclear_orderingquery_object)r   rv   rw   rx   ry   r   r   r   rq   X  s
    zSubqueryConstraint.__init__c                 C   s0   | j }|| j |j|d}|| j| j|S )N)r.   )ry   Z
set_valuesrx   Zget_compilerZas_subquery_conditionrv   rw   )r   r-   r.   rY   Zquery_compilerr   r   r   r(   _  s    zSubqueryConstraint.as_sqlNrt   r   r   r   r   ru   R  s   ru   )rj   r&   	functoolsr   Zdjango.core.exceptionsr   r   Zdjango.db.models.expressionsr   r   Zdjango.db.models.lookupsr   Zdjango.utilsr	   Zdjango.utils.functionalr
   r   r   r   rP   r   rn   ro   ru   r   r   r   r   <module>   s      )
