U
    [+d_.                     @   s   d dl mZmZ d dlmZmZmZmZmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZ dgZG dd dZG d	d
 d
eZdS )    )names_digestsplit_identifier)ColExpressionListFFuncOrderByCollate)Q)Query)	partitionIndexc                   @   sz   e Zd ZdZdZdddddddddZe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dS )r   idx    N)fieldsnamedb_tablespace	opclasses	conditionincludec                G   st  |r|st dt|td tfs*t d|r:|s:t dt|ttfsPt dt|ttfsft d|sv|svt d|r|rt d|r|st d|r|rt d	|rt|t|krt d
|rtdd |D st d|r|st dt|td ttfst dt|| _dd | jD | _	|p2d| _
|| _|| _|| _|rVt|nd| _tdd |D | _d S )Nz(An index must be named to use opclasses.z%Index.condition must be a Q instance.z(An index must be named to use condition.z%Index.fields must be a list or tuple.z(Index.opclasses must be a list or tuple.z@At least one field or expression is required to define an index.z4Index.fields and expressions are mutually exclusive.z*An index must be named to use expressions.zgIndex.opclasses cannot be used with expressions. Use django.contrib.postgres.indexes.OpClass() instead.zGIndex.fields and Index.opclasses must have the same number of elements.c                 s   s   | ]}t |tV  qd S N)
isinstancestr).0fieldr   r   </tmp/pip-unpacked-wheel-n7e__lmp/django/db/models/indexes.py	<genexpr>9   s     z!Index.__init__.<locals>.<genexpr>z8Index.fields must contain only strings with field names.zA covering index must be named.z&Index.include must be a list or tuple.c                 S   s.   g | ]&}| d r"|dd dfn|dfqS )-   NZDESC )
startswithr   
field_namer   r   r   
<listcomp>A   s   z"Index.__init__.<locals>.<listcomp>r!   r   c                 s   s$   | ]}t |trt|n|V  qd S r   )r   r   r   )r   
expressionr   r   r   r   J   s   )
ValueErrorr   typer   listtuplelenallr   fields_ordersr   r   r   r   r   expressions)selfr   r   r   r   r   r   r.   r   r   r   __init__   s\    

zIndex.__init__c                 C   s
   t | jS r   )boolr.   r/   r   r   r   contains_expressionsO   s    zIndex.contains_expressionsc                    s`   | j d krd S t|dd}|| j }|j jd}|| j\}}|t fdd|D  S )NF)model
alias_cols)
connectionc                 3   s   | ]}  |V  qd S r   )Zquote_value)r   pschema_editorr   r   r   Z   s     z+Index._get_condition_sql.<locals>.<genexpr>)r   r   Zbuild_whereZget_compilerr6   as_sqlr*   )r/   r4   r9   querywherecompilerZsqlparamsr   r8   r   _get_condition_sqlS   s    
zIndex._get_condition_sqlr!   c                    s    fdd| j D }|  |}| jrtg }| jD ]"}t|}	|	|j ||	 q0t| t	 dd}
d }d }nD fdd| j
D }|jjjrdd | j
D }ndgt| j
 }d }
|j f|| j|| j|| j|||
d	|S )	Nc                    s   g | ]} j |jqS r   _meta	get_fieldcolumnr#   r4   r   r   r%   ]   s    z$Index.create_sql.<locals>.<listcomp>F)r5   c                    s   g | ]\}} j |qS r   )rA   rB   )r   r$   _rD   r   r   r%   m   s   c                 S   s   g | ]}|d  qS )r    r   )r   orderr   r   r   r%   r   s     r!   )	r   r   usingr   col_suffixesr   r   r   r.   )r   r?   r.   IndexExpressionset_wrapper_classesr6   appendr   resolve_expressionr   r-   featuresZsupports_index_column_orderingr+   Z_create_index_sqlr   r   r   )r/   r4   r9   rG   kwargsr   r   index_expressionsr&   Zindex_expressionr.   r   rH   r   rD   r   
create_sql\   sJ    




zIndex.create_sqlc                 K   s   |j || jf|S r   )Z_delete_index_sqlr   )r/   r4   r9   rN   r   r   r   
remove_sql   s    zIndex.remove_sqlc                 C   s   d| j j| j jf }|dd}d| ji}| jr:| j|d< | jd k	rN| j|d< | jr^| j|d< | jrn| j|d< | j	r~| j	|d	< || j
|fS )
Nz%s.%szdjango.db.models.indexeszdjango.db.modelsr   r   r   r   r   r   )	__class__
__module____name__replacer   r   r   r   r   r   r.   )r/   pathrN   r   r   r   deconstruct   s    






zIndex.deconstructc                 C   s   |   \}}}| j||S )zCreate a copy of this Index.)rW   rR   )r/   rE   argsrN   r   r   r   clone   s    zIndex.clonec                    s   t  jj\}} fdd| jD }dd t|| jD }|g| | jg }d|dd |d dd d	t|d
di| jf f | _t| j| j	krt
d| jd dks| jd  rd| jdd  | _dS )a  
        Generate a unique name for the index.

        The name is divided into 3 parts - table name (12 chars), field name
        (8 chars) and unique hash + suffix (10 chars). Each part is made to
        fit its size by truncating the excess length.
        c                    s   g | ]\}} j |jqS r   r@   )r   r$   rF   rD   r   r   r%      s   z-Index.set_name_with_model.<locals>.<listcomp>c                 S   s$   g | ]\}\}}|rd nd| qS )z-%sz%sr   )r   Zcolumn_namer$   rF   r   r   r   r%      s   
z%s_%s_%sN   r      z%s_%slength   zVIndex too long for multiple database support. Is self.suffix longer than 3 characters?rE   zD%sr    )r   rA   Zdb_tabler-   zipsuffixr   r   r+   max_name_lengthr'   isdigit)r/   r4   rE   Z
table_nameZcolumn_namesZcolumn_names_with_orderZ	hash_datar   rD   r   set_name_with_model   s,    
 
zIndex.set_name_with_modelc                 C   s   d| j j| jsdndt| j | js(dndt| j | js>dndt| j | jd krXdndt| j | jd krrdnd| j | jsdndt| j | j	sdnd	t| j	 f S )
Nz<%s:%s%s%s%s%s%s%s>r!   z
 fields=%sz expressions=%sz name=%sz db_tablespace=%sz condition=%sz include=%sz opclasses=%s)
rR   __qualname__r   reprr.   r   r   r   r   r   r2   r   r   r   __repr__   s    zIndex.__repr__c                 C   s    | j |j kr|  | kS tS r   )rR   rW   NotImplemented)r/   otherr   r   r   __eq__   s    zIndex.__eq__)r!   )rT   rS   rc   r_   r`   r0   propertyr3   r?   rP   rQ   rW   rY   rb   re   rh   r   r   r   r   r      s&   >
	
(#c                       sL   e Zd ZdZdZeefZdddZe	dd Z
d fd
d	Zdd Z  ZS )rI   z7Order and wrap expressions for CREATE INDEX statements.z%(expressions)sNc                 C   s&   |r"|j jr"tdd | jD | _d S )Nc                 S   s   g | ]}|t k	r|qS r   r	   r   Zwrapper_clsr   r   r   r%      s   z7IndexExpression.set_wrapper_classes.<locals>.<listcomp>)rM   Zcollate_as_index_expressionr*   wrapper_classes)r/   r6   r   r   r   rJ      s    z#IndexExpression.set_wrapper_classesc                 G   s
   || _ d S r   )rk   )clsrk   r   r   r   register_wrappers   s    z!IndexExpression.register_wrappersTFc                    sb  t   }t fdd|\}}dd |D }	t|	tt|	krbtdddd  jD  |dt|d  |krtd	dd
d  jD  |d }
|
|||||}t	|t
st|
dd}
|rBt| fddd}dd |D }t|d d D ]\}}|||d  g q |d |
g  |d g n |
g t |||||S )Nc                    s   t |  jS r   )r   rk   )er2   r   r   <lambda>       z4IndexExpression.resolve_expression.<locals>.<lambda>c                 S   s   g | ]}t |qS r   )r(   r   wrapperr   r   r   r%      s     z6IndexExpression.resolve_expression.<locals>.<listcomp>zAMultiple references to %s can't be used in an indexed expression.z, c                 S   s   g | ]
}|j qS r   rc   rj   r   r   r   r%      s     r    z8%s must be topmost expressions in an indexed expression.c                 S   s   g | ]
}|j qS r   rs   rj   r   r   r   r%     s     z(%(expressions)s))templatec                    s    j t| S r   )rk   indexr(   )wr2   r   r   ro     rp   )keyc                 S   s   g | ]}|  qS r   )copyrq   r   r   r   r%     s     r   )r)   flattenr   r+   setr'   joinrk   rL   r   r   r   sorted	enumerateZset_source_expressionssuper)r/   r;   Zallow_joinsZreuseZ	summarizeZfor_saver.   rO   wrappersZwrapper_typesZroot_expressionZresolve_root_expressionirr   rR   r2   r   rL      sd    


    z"IndexExpression.resolve_expressionc                 K   s   | j ||f|S r   )r:   )r/   r=   r6   Zextra_contextr   r   r   	as_sqlite%  s    zIndexExpression.as_sqlite)N)NTNFF)rT   rS   rc   __doc__rt   r   r
   rk   rJ   classmethodrm   rL   r   __classcell__r   r   r   r   rI      s   

     =rI   N)Zdjango.db.backends.utilsr   r   Zdjango.db.models.expressionsr   r   r   r   r   Zdjango.db.models.functionsr
   Zdjango.db.models.query_utilsr   Zdjango.db.models.sqlr   Zdjango.utils.functionalr   __all__r   rI   r   r   r   r   <module>   s    I