o
    ˷e(                     @   s   d Z ddlZddlmZ ddl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CaseWhen)Exact)tree)cached_propertyANDORXORc                   @   s   e Zd ZdZeZdZdZd-ddZdd Z	d.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d#d$ Zed%d& Zd'd( Zd)d* Zd+d, ZdS )/	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| dfS || jA }|r| jtkp| o| jtkp| jtk}|r)| j r)d| fS g }g }| jD ]/}t|drQ||\}}|durG|	| |durP|	| q0|j rZ|	| q0|	| q0|rk| 
|| j| jnd}	|rx| 
|| j| jnd}
|
|	fS )z
        Return two possibly None nodes: one for those parts of self that
        should be included in the WHERE clause and one for those parts of
        self that must be included in the HAVING clause.
        Nsplit_having)contains_aggregatenegated	connectorr   r   r   childrenhasattrr   append	__class__)selfr   
in_negatedmay_need_splitwhere_partshaving_partsc
where_parthaving_parthaving_node
where_node r!   Q/var/www/ideatree/venv/lib/python3.10/site-packages/django/db/models/sql/where.pyr   &   s@   





zWhereNode.split_havingc              	   C   sz  g }g }| j tkrt| jd}}ndt| j}}| j tkrI|jjsI| | jt}t	t
jdd | jD }td|}	| ||	gt| j||S | jD ]H}
z	||
\}}W n tyd   |d8 }Y nw |rr|| || n|d8 }|dkr| jrdg f  S t|dkr| jrtdg f  S qLd| j  }||}|r| jrd| }||fS 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#   )thenr   )defaultNr   .0r   r!   r!   r"   	<genexpr>g   s   " z#WhereNode.as_sql.<locals>.<genexpr>r    z %s zNOT (%s)(%s))r   r   lenr   r   featuressupports_logical_xorr   r   r   operatoraddr   r   as_sqlcompiler   r   extendjoinresolved)r   compiler
connectionresultresult_paramsfull_neededempty_neededlhsrhs_sumrhschildsqlparamsconn
sql_stringr!   r!   r"   r0   Q   sV   





zWhereNode.as_sqlNc                 C   s"   g }| j D ]	}||  q|S N)r   r2   get_group_by_cols)r   aliascolsr>   r!   r!   r"   rD      s   
zWhereNode.get_group_by_colsc                 C   s   | j d d  S rC   )r   r   r!   r!   r"   get_source_expressions   s   z WhereNode.get_source_expressionsc                 C   s    t |t | jksJ || _d S rC   )r+   r   )r   r   r!   r!   r"   set_source_expressions   s   
z WhereNode.set_source_expressionsc                 C   sH   t | jD ]\}}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   rJ   rK   )r   
change_mapposr>   r!   r!   r"   rJ      s   

zWhereNode.relabel_aliasesc                 C   sN   | j jd| j| jd}| jD ]}t|dr|j|  q|j| q|S )z
        Create a clone of the tree. Must only be called on root nodes (nodes
        with empty subtree_parents). Childs must be either (Constraint, lookup,
        value) tuples, or objects supporting .clone().
        N)r   r   r   clone)r   _new_instancer   r   r   r   r   rO   )r   rO   r>   r!   r!   r"   rO      s   

zWhereNode.clonec                 C   s   |   }|| |S rC   )rO   rJ   )r   rM   rO   r!   r!   r"   rK      s   
zWhereNode.relabeled_clonec                 C   s   |   S rC   )rO   rG   r!   r!   r"   copy   s   zWhereNode.copyc                    *   t |tjrt fdd|jD S |jS )Nc                 3       | ]}  |V  qd S rC   _contains_aggregater&   clsr!   r"   r(          z0WhereNode._contains_aggregate.<locals>.<genexpr>)
isinstancer	   Nodeanyr   r   rW   objr!   rV   r"   rU         zWhereNode._contains_aggregatec                 C   
   |  | S rC   rT   rG   r!   r!   r"   r         
zWhereNode.contains_aggregatec                    rR   )Nc                 3   rS   rC   _contains_over_clauser&   rV   r!   r"   r(      rX   z2WhereNode._contains_over_clause.<locals>.<genexpr>)rY   r	   rZ   r[   r   contains_over_clauser\   r!   rV   r"   rb      r^   zWhereNode._contains_over_clausec                 C   r_   rC   ra   rG   r!   r!   r"   rc      r`   zWhereNode.contains_over_clausec                 O   s&   t | dr| j|g|R i |} | S )Nresolve_expression)r   rd   )exprqueryargskwargsr!   r!   r"   _resolve_leaf   s   
zWhereNode._resolve_leafc                 O   s   t |dr|jD ]}| j||g|R i | qt |dr,| j|j|g|R i ||_t |drB| j|j|g|R i ||_d S d S )Nr   r;   r=   )r   r   _resolve_noderi   r;   r=   )rW   noderf   rg   rh   r>   r!   r!   r"   rj      s   



"zWhereNode._resolve_nodec                 O   s*   |   }|j|g|R i | d|_|S )NT)rO   rj   r4   )r   rg   rh   rO   r!   r!   r"   rd      s   zWhereNode.resolve_expressionc                 C   s   ddl m} | S )Nr   )BooleanField)django.db.modelsrl   )r   rl   r!   r!   r"   output_field   s   zWhereNode.output_fieldc                 C   s   |j jjsd| d}||fS )Nz
CASE WHEN z THEN 1 ELSE 0 END)r6   r,   &supports_boolean_expr_in_select_clause)r   r5   r?   r@   r!   r!   r"   select_format   s   
zWhereNode.select_formatc                 C      | j |S rC   )rn   get_db_converters)r   r6   r!   r!   r"   rr         zWhereNode.get_db_convertersc                 C   rq   rC   )rn   
get_lookup)r   lookupr!   r!   r"   rt     rs   zWhereNode.get_lookup)FrC   )__name__
__module____qualname____doc__r   r%   r4   conditionalr   r0   rD   rH   rI   rJ   rO   rK   rQ   classmethodrU   r
   r   rb   rc   staticmethodri   rj   rd   rn   rp   rr   rt   r!   r!   r!   r"   r      s@    
+
C





	
r   c                   @   s   e Zd ZdZdZdddZdS )NothingNodezA node that matches nothing.FNc                 C   s   t rC   r   )r   r5   r6   r!   r!   r"   r0     s   zNothingNode.as_sqlNN)rv   rw   rx   ry   r   r0   r!   r!   r!   r"   r}     s    r}   c                   @   s"   e Zd ZdZdd ZdddZdS )
ExtraWhereFc                 C   s   || _ || _d S rC   )sqlsr@   )r   r   r@   r!   r!   r"   __init__  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'   r?   r!   r!   r"   
<listcomp>  s    z%ExtraWhere.as_sql.<locals>.<listcomp>z AND r!   )r   r3   listr@   )r   r5   r6   r   r!   r!   r"   r0     s   zExtraWhere.as_sqlr~   rv   rw   rx   r   r   r0   r!   r!   r!   r"   r     s    r   c                   @   s    e Zd ZdZdd Zdd ZdS )SubqueryConstraintFc                 C   s(   || _ || _|| _|jdd || _d S )NT)clear_default)rE   columnstargetsclear_orderingquery_object)r   rE   r   r   r   r!   r!   r"   r   !  s
   
zSubqueryConstraint.__init__c                 C   s0   | j }|| j |j|d}|| j| j|S )N)r6   )r   
set_valuesr   get_compileras_subquery_conditionrE   r   )r   r5   r6   rf   query_compilerr!   r!   r"   r0   (  s   zSubqueryConstraint.as_sqlNr   r!   r!   r!   r"   r     s    r   )ry   r.   	functoolsr   django.core.exceptionsr   django.db.models.expressionsr   r   django.db.models.lookupsr   django.utilsr	   django.utils.functionalr
   r   r   r   rZ   r   r}   r   r   r!   r!   r!   r"   <module>   s      t	