3
v^-                 @   s^   d Z ddlmZ ddlmZmZ G dd deZG dd dZG dd	 d	Z	G d
d dZ
dS )z]
Useful auxiliary data structures for query construction. Not useful outside
the SQL domain.
    )EmptyResultSet)INNERLOUTERc               @   s   e Zd ZdZdd ZdS )	MultiJoinz
    Used by join construction code to indicate the point at which a
    multi-valued join was attempted (if the caller wants to treat that
    exceptionally).
    c             C   s   || _ || _d S )N)levelnames_with_path)selfZ	names_posZpath_with_names r	   G/usr/lib/python3.6/site-packages/django/db/models/sql/datastructures.py__init__   s    zMultiJoin.__init__N)__name__
__module____qualname____doc__r   r	   r	   r	   r
   r   
   s   r   c               @   s   e Zd ZdS )EmptyN)r   r   r   r	   r	   r	   r
   r      s   r   c               @   sJ   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )Joina  
    Used by sql.Query and sql.SQLCompiler to generate JOIN clauses into the
    FROM entry. For example, the SQL generated could be
        LEFT OUTER JOIN "sometable" T1 ON ("othertable"."sometable_id" = "sometable"."id")

    This class is primarily used in Query.alias_map. All entries in alias_map
    must be Join compatible by providing the following attributes and methods:
        - table_name (string)
        - table_alias (possible alias for the table, can be None)
        - join_type (can be None for those entries that aren't joined from
          anything)
        - parent_alias (which table is this join's parent, can be None similarly
          to join_type)
        - as_sql()
        - relabeled_clone()
    Nc             C   s8   || _ || _|| _|| _|j | _|| _|| _|| _d S )N)	
table_nameparent_aliastable_alias	join_typeZget_joining_columns	join_cols
join_fieldnullablefiltered_relation)r   r   r   r   r   r   r   r   r	   r	   r
   r   +   s    
zJoin.__init__c             C   s0  g }g }|j }|jj}x<| jD ]2\}}|jd|| j|||| j||f  qW | jj|j	j
| j| j}	|	r|j|	\}
}|jd|
  |j| | jr|j| j\}
}|
r|jd|
  |j| |st| jd| j}td|j dj|}| j| jkrdnd| j }d| j|| j||f }||fS )	z
        Generate the full
           LEFT OUTER JOIN sometable ON sometable.somecol = othertable.othercol, params
        clause for this join.
        z%s.%s = %s.%sz(%s)fieldzaJoin generated an empty ON clause. %s did not yield either joining columns or extra restrictions.z AND  z %sz%s %s%s ON (%s))quote_name_unless_aliasops
quote_namer   appendr   r   r   get_extra_restrictionquerywhere_classcompileextendr   getattr
ValueError	__class__joinr   r   )r   compiler
connectionZjoin_conditionsparamsqnZqn2Zlhs_colZrhs_colZ
extra_condZ	extra_sqlZextra_paramsZdeclared_fieldZon_clause_sql	alias_strsqlr	   r	   r
   as_sql=   s<    



zJoin.as_sqlc          	      sr    j | j| j} j | j| j}| jd k	rN| jj } fdd| jjD |_nd }| j| j||| j| j	| j
|dS )Nc                s   g | ]} j ||qS r	   )get).0p)
change_mapr	   r
   
<listcomp>o   s    z(Join.relabeled_clone.<locals>.<listcomp>)r   )r0   r   r   r   clonepathr'   r   r   r   r   )r   r3   Znew_parent_aliasZnew_table_aliasr   r	   )r3   r
   relabeled_clonej   s    

zJoin.relabeled_clonec             C   sB   t || jo@| j|jko@| j|jko@| j|jko@| p@| j|jkS )N)
isinstancer'   r   r   r   r   )r   otherwith_filtered_relationr	   r	   r
   equalsw   s
    zJoin.equalsc             C   s   | j |ddS )NT)r:   )r;   )r   r9   r	   r	   r
   __eq__   s    zJoin.__eq__c             C   s   | j i }t|_|S )N)r7   r   r   )r   newr	   r	   r
   demote   s    
zJoin.demotec             C   s   | j i }t|_|S )N)r7   r   r   )r   r=   r	   r	   r
   promote   s    
zJoin.promote)N)r   r   r   r   r   r/   r7   r;   r<   r>   r?   r	   r	   r	   r
   r      s   
-	r   c               @   s<   e Zd ZdZdZdZdZdd Zdd Zdd Z	d	d
 Z
dS )	BaseTablez
    The BaseTable class is used for base table references in FROM clause. For
    example, the SQL "foo" in
        SELECT * FROM "foo" WHERE somecond
    could be generated by this class.
    Nc             C   s   || _ || _d S )N)r   r   )r   r   aliasr	   r	   r
   r      s    zBaseTable.__init__c             C   s2   | j | jkrdnd| j  }|j| j}|| g fS )Nr   z %s)r   r   r   )r   r)   r*   r-   Zbase_sqlr	   r	   r
   r/      s    zBaseTable.as_sqlc             C   s   | j | j|j| j| jS )N)r'   r   r0   r   )r   r3   r	   r	   r
   r7      s    zBaseTable.relabeled_clonec             C   s$   t | |jo"| j|jko"| j|jkS )N)r8   r'   r   r   )r   r9   r:   r	   r	   r
   r;      s    zBaseTable.equals)r   r   r   r   r   r   r   r   r/   r7   r;   r	   r	   r	   r
   r@      s   r@   N)r   django.core.exceptionsr   django.db.models.sql.constantsr   r   	Exceptionr   r   r   r@   r	   r	   r	   r
   <module>   s   t