U
    5if                     @   sn   d dl mZ d dlmZmZ d dlmZmZmZ d dl	m
Z
 d dlmZ d dlmZ dgZG dd de
Zd	S )
    )NotSupportedError)	StatementTable)
DeferrableFQ)BaseConstraint)Col)QueryExclusionConstraintc                       s~   e Zd ZdZdddddd fdd
Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
 fddZ fddZdd Z  ZS )r   zdCONSTRAINT %(name)s EXCLUDE USING %(index_type)s (%(expressions)s)%(include)s%(where)s%(deferrable)sN )
index_type	condition
deferrableinclude	opclassesc                   s4  |r|  dkrtd|s$tdtdd |D s>tdt|td tfsXtd|rh|rhtdt|td tfstd	t|td ttfstd
|r|r|  dkrtdt|ttfstd|rt	|t	|krtd|| _
|pd| _|| _|| _|rt|nd| _|| _t j|d d S )N>   gistspgistz;Exclusion constraints only support GiST or SP-GiST indexes.zFAt least one expression is required to define an exclusion constraint.c                 s   s(   | ] }t |ttfot|d kV  qdS )   N)
isinstancelisttuplelen).0exprr   r   G/tmp/pip-unpacked-wheel-gcyiijx6/django/contrib/postgres/constraints.py	<genexpr>   s   z/ExclusionConstraint.__init__.<locals>.<genexpr>z+The expressions must be a list of 2-tuples.z3ExclusionConstraint.condition must be a Q instance.z7ExclusionConstraint with conditions cannot be deferred.z=ExclusionConstraint.deferrable must be a Deferrable instance.z4ExclusionConstraint.include must be a list or tuple.r   z9Covering exclusion constraints only support GiST indexes.z6ExclusionConstraint.opclasses must be a list or tuple.zhExclusionConstraint.expressions and ExclusionConstraint.opclasses must have the same number of elements.ZGISTr   )name)lower
ValueErrorallr   typer   r   r   r   r   expressionsr   r   r   r   r   super__init__)selfr   r"   r   r   r   r   r   	__class__r   r   r$      s^    
zExclusionConstraint.__init__c              	      s   g }t | jD ]\}\}}t|tr,t|}|j|d}||\}}	t|ts\d| d}z| j| }
|
rxd||
f }W n t	k
r   Y nX |t
 fdd|	D  }|d||f  q|S )N)query()z%s %sc                 3   s   | ]}  |V  qd S NZquote_valuer   pschema_editorr   r   r   U   s     z:ExclusionConstraint._get_expression_sql.<locals>.<genexpr>z
%s WITH %s)	enumerater"   r   strr   Zresolve_expressioncompiler	   r   
IndexErrorr   append)r%   compilerr0   r(   r"   idxZ
expressionoperatorsqlparamsZopclassr   r/   r   _get_expression_sqlF   s"    


z'ExclusionConstraint._get_expression_sqlc                    sF   | j d krd S || j }|| j\}}|t fdd|D  S )Nc                 3   s   | ]}  |V  qd S r+   r,   r-   r/   r   r   r   ^   s     z9ExclusionConstraint._get_condition_sql.<locals>.<genexpr>)r   Zbuild_whereZas_sql
connectionr   )r%   r6   r0   r(   wherer9   r:   r   r/   r   _get_condition_sqlY   s
    
z&ExclusionConstraint._get_condition_sqlc              	      s   t  dd}|j|jd}| |||}| |||} fdd| jD }| j|| j| j	d
|| ||rzd| nd|| jd	 S )
NF)Z
alias_cols)r<   c                    s   g | ]} j |jqS r   )_meta	get_fieldcolumn)r   
field_namemodelr   r   
<listcomp>e   s     z6ExclusionConstraint.constraint_sql.<locals>.<listcomp>z, z WHERE (%s) )r   r   r"   r   r=   r   )r
   Zget_compilerr<   r;   r>   r   template
quote_namer   r   joinZ_index_include_sqlZ_deferrable_constraint_sqlr   )r%   rD   r0   r(   r6   r"   r   r   r   rC   r   constraint_sql`   s    


z"ExclusionConstraint.constraint_sqlc                 C   s,   |  | tdt|jj|j| ||dS )Nz(ALTER TABLE %(table)s ADD %(constraint)s)table
constraint)check_supportedr   r   r?   Zdb_tablerH   rJ   r%   rD   r0   r   r   r   
create_sqlo   s    

zExclusionConstraint.create_sqlc                 C   s   | |j||| jS r+   )Z_delete_constraint_sqlZsql_delete_checkrH   r   rN   r   r   r   
remove_sqlw   s
    
zExclusionConstraint.remove_sqlc                 C   s   | j r|jjjstdd S )Nz7Covering exclusion constraints requires PostgreSQL 12+.)r   r<   featuresZsupports_covering_gist_indexesr   )r%   r0   r   r   r   rM   ~   s    z#ExclusionConstraint.check_supportedc                    s   t   \}}}| j|d< | jd k	r.| j|d< | j dkrF| j|d< | jrV| j|d< | jrf| j|d< | jrv| j|d< |||fS )Nr"   r   r   r   r   r   r   )	r#   deconstructr"   r   r   r   r   r   r   )r%   pathargskwargsr&   r   r   rR      s    






zExclusionConstraint.deconstructc                    sl   t || jr`| j|jko^| j|jko^| j|jko^| j|jko^| j|jko^| j|jko^| j|jkS t	 
|S r+   )r   r'   r   r   r"   r   r   r   r   r#   __eq__)r%   otherr&   r   r   rV      s    





	zExclusionConstraint.__eq__c                 C   s~   d| j jt| jt| jt| j| jd kr.dnd| j | jd krDdnd| j | jsVdndt| j | j	sldndt| j	 f S )Nz2<%s: index_type=%s expressions=%s name=%s%s%s%s%s>rF   z condition=%sz deferrable=%rz include=%sz opclasses=%s)
r'   __qualname__reprr   r"   r   r   r   r   r   )r%   r   r   r   __repr__   s    zExclusionConstraint.__repr__)__name__
__module__rX   rG   r$   r;   r>   rJ   rO   rP   rM   rR   rV   rZ   __classcell__r   r   r&   r   r      s       8N)Z	django.dbr   Z!django.db.backends.ddl_referencesr   r   Zdjango.db.modelsr   r   r   Zdjango.db.models.constraintsr   Zdjango.db.models.expressionsr	   Zdjango.db.models.sqlr
   __all__r   r   r   r   r   <module>   s   