î
ªÍ Xv  ã               @   s¡   d  Z  d d l m Z d d l m Z d d l m Z d Z d Z Gd d „  d e j	 ƒ Z
 Gd	 d
 „  d
 e ƒ Z Gd d „  d e ƒ Z Gd d „  d e ƒ Z d S)zG
Code to manage the creation and SQL rendering of 'where' constraints.
é    )ÚEmptyResultSet)Útree)Úcached_propertyÚANDÚORc               @   s‹   e  Z d  Z d Z e Z d 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 d S)Ú	WhereNodea½  
    Used to represent the 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.
    Fc             C   sa  |  j  s |  d f S| |  j A} | r5 |  j t k pH | oH |  j t k } | rd |  j  rd d |  f Sg  } g  } x– |  j D]‹ } t | d ƒ rß | j | ƒ \ } } | d k	 rÀ | j | ƒ n  | d k	 r| j | ƒ qqz | j  rø | j | ƒ qz | j | ƒ qz W| r*|  j	 | |  j |  j ƒ n d }	 | rQ|  j	 | |  j |  j ƒ n d }
 |
 |	 f S)zÖ
        Returns 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   ÚchildrenÚhasattrr   ÚappendÚ	__class__)Úselfr
   Z
in_negatedZmay_need_splitZwhere_partsZhaving_partsÚcZ
where_partZhaving_partZhaving_nodeZ
where_node© r   úH/home/ubuntu/projects/ifolica/build/django/django/db/models/sql/where.pyr      s,    	

	''zWhereNode.split_havingc             C   sz  g  } g  } |  j  t k r4 t |  j ƒ d } } n d t |  j ƒ } } xÉ |  j D]¾ } y | j | ƒ \ } }	 Wn t k
 r‘ | d 8} Yn. X| rµ | j | ƒ | j |	 ƒ n
 | d 8} | d k rç |  j rÞ d g  f St ‚ n  | d k rT |  j rt ‚ qd g  f SqT qT Wd |  j  }
 |
 j	 | ƒ } | rp|  j rNd | } qpt | ƒ d k rpd | } qpn  | | f S)a  
        Returns the SQL version of the where clause and the value to be
        substituted in. Returns '', [] if this node matches everything,
        None, [] if this node is empty, and raises EmptyResultSet if this
        node can't match anything.
        é   r   Ú z %s zNOT (%s)z(%s))
r   r   Úlenr   Úcompiler   r   Úextendr
   Újoin)r   ÚcompilerÚ
connectionÚresultZresult_paramsZfull_neededZempty_neededÚchildÚsqlÚparamsÚconnZ
sql_stringr   r   r   Úas_sql?   s<    
	
				zWhereNode.as_sqlc             C   s1   g  } x$ |  j  D] } | j | j ƒ  ƒ q W| S)N)r   r   Úget_group_by_cols)r   Úcolsr   r   r   r   r"   s   s    zWhereNode.get_group_by_colsc             C   sk   xd t  |  j ƒ D]S \ } } t | d ƒ r; | j | ƒ q t | d ƒ r | j | ƒ |  j | <q q Wd S)z—
        Relabels 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Úposr   r   r   r   r$   y   s
    zWhereNode.relabel_aliasesc             C   sw   |  j  j d g  d |  j d |  j ƒ } xI |  j D]> } t | d ƒ r_ | j j | j ƒ  ƒ q1 | j j | ƒ q1 W| S)zÝ
        Creates a clone of the tree. Must only be called on root nodes (nodes
        with empty subtree_parents). Childs must be either (Contraint, lookup,
        value) tuples, or objects supporting .clone().
        r   r   r
   Úclone)r   Z_new_instancer   r
   r   r   r   r)   )r   r)   r   r   r   r   r)   …   s    zWhereNode.clonec             C   s   |  j  ƒ  } | j | ƒ | S)N)r)   r$   )r   r'   r)   r   r   r   r%   ”   s    zWhereNode.relabeled_clonec                s9   t  | t j ƒ r2 t ‡  f d d †  | j Dƒ ƒ S| j S)Nc             3   s   |  ] } ˆ  j  | ƒ Vq d  S)N)Ú_contains_aggregate)Ú.0r   )Úclsr   r   ú	<genexpr>œ   s    z0WhereNode._contains_aggregate.<locals>.<genexpr>)Ú
isinstancer   ÚNodeÚanyr   r	   )r,   Úobjr   )r,   r   r*   ™   s     zWhereNode._contains_aggregatec             C   s   |  j  |  ƒ S)N)r*   )r   r   r   r   r	   Ÿ   s    zWhereNode.contains_aggregateN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Údefaultr   r!   r"   r$   r)   r%   Úclassmethodr*   r   r	   r   r   r   r   r      s   !4r   c               @   s.   e  Z d  Z d Z d Z d d d d „ Z d S)ÚNothingNodez&
    A node that matches nothing.
    FNc             C   s
   t  ‚ d  S)N)r   )r   r   r   r   r   r   r!   ª   s    zNothingNode.as_sql)r2   r3   r4   r5   r	   r!   r   r   r   r   r8   ¤   s   r8   c               @   s4   e  Z d  Z d Z d d „  Z d d d d „ Z d S)Ú
ExtraWhereFc             C   s   | |  _  | |  _ d  S)N)Úsqlsr   )r   r:   r   r   r   r   Ú__init__²   s    	zExtraWhere.__init__Nc             C   s8   d d „  |  j  Dƒ } d j | ƒ t |  j p1 f  ƒ f S)Nc             S   s   g  |  ] } d  | ‘ q S)z(%s)r   )r+   r   r   r   r   ú
<listcomp>·   s   	 z%ExtraWhere.as_sql.<locals>.<listcomp>z AND )r:   r   Úlistr   )r   r   r   r:   r   r   r   r!   ¶   s    zExtraWhere.as_sql)r2   r3   r4   r	   r;   r!   r   r   r   r   r9   ®   s   r9   c               @   sF   e  Z d  Z d Z d d „  Z d d „  Z d d „  Z d d	 „  Z d
 S)ÚSubqueryConstraintFc             C   s(   | |  _  | |  _ | |  _ | |  _ d  S)N)ÚaliasÚcolumnsÚtargetsÚquery_object)r   r?   r@   rA   rB   r   r   r   r;   À   s    			zSubqueryConstraint.__init__c             C   sÅ   |  j  } t | d ƒ rš | j rB | j | j k rB t d ƒ ‚ n  | j d  k rf | j |  j Œ  } n | j ƒ  } | j	 } | j
 ƒ  rš | j d ƒ qš n  | j d | ƒ } | j |  j |  j | ƒ S)NÚvaluesz2Can't do subqueries with queries on different DBs.Tr   )rB   r   Ú_dbr?   Ú
ValueErrorÚ_fieldsrC   rA   Z_cloneÚqueryZ
can_filterZclear_orderingZget_compilerZas_subquery_conditionr@   )r   r   r   rG   Zquery_compilerr   r   r   r!   Æ   s    		zSubqueryConstraint.as_sqlc             C   s   | j  |  j |  j ƒ |  _ d  S)N)Úgetr?   )r   r'   r   r   r   r$   Ú   s    z"SubqueryConstraint.relabel_aliasesc             C   s"   |  j  |  j |  j |  j |  j ƒ S)N)r   r?   r@   rA   rB   )r   r   r   r   r)   Ý   s    zSubqueryConstraint.cloneN)r2   r3   r4   r	   r;   r!   r$   r)   r   r   r   r   r>   »   s
   r>   N)r5   Z#django.db.models.sql.datastructuresr   Zdjango.utilsr   Zdjango.utils.functionalr   r   r   r/   r   Úobjectr8   r9   r>   r   r   r   r   Ú<module>   s   –
