U
    8ÄT_‘ß  ã                   @   s    d dl Z d dlmZ d dlmZmZmZmZmZ d dlm	Z	m
Z
 d dlmZmZ d dlmZmZ d dlmZ e  d¡Zd	d
„ Zdd„ Zdd„ ZG dd„ dƒZdS )é    N)Údatetime)ÚColumnsÚForeignKeyNameÚ	IndexNameÚ	StatementÚTable)Únames_digestÚsplit_identifier)Ú
DeferrableÚIndex)ÚTransactionManagementErrorÚatomic)Útimezonezdjango.db.backends.schemac                 C   s2   | j }|jrdS |jr&|jdgkr&dS |j|jkS )zz
    When altering the given field, must constraints on its model from the given
    relation be temporarily dropped?
    FNT)ÚfieldÚmany_to_manyÚprimary_keyZ	to_fieldsÚname)ZrelationZaltered_fieldr   © r   úB/tmp/pip-unpacked-wheel-dv63caxw/django/db/backends/base/schema.pyÚ_is_relevant_relation   s    r   c                 C   s   | j jdddd�S )NFT)ZforwardÚreverseZinclude_hidden)Ú_metaZ_get_fields©Úmodelr   r   r   Ú_all_related_fields   s    r   c                    s2   t ‡fdd„tˆjƒD ƒ‡ fdd„tˆ jƒD ƒƒS )Nc                 3   s   | ]}t |ˆ ƒr|V  qd S ©N©r   ©Ú.0Úobj)Ú	old_fieldr   r   Ú	<genexpr>'   s     
 z+_related_non_m2m_objects.<locals>.<genexpr>c                 3   s   | ]}t |ˆ ƒr|V  qd S r   r   r   )Ú	new_fieldr   r   r!   (   s     
 )Úzipr   r   )r    r"   r   )r"   r    r   Ú_related_non_m2m_objects#   s    þr$   c                	   @   s¦  e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZeZdZeZdZdZdZeZdZdZdZ dZ!eZ"dZ#dšdd „Z$d!d"„ Z%d#d$„ Z&d›d&d'„Z'd(d)„ Z(d*d+„ Z)dœd,d-„Z*d.d/„ Z+d0d1„ Z,d2d3„ Z-e.d4d5„ ƒZ/d6d7„ Z0d8d9„ Z1d:d;„ Z2d<d=„ Z3d>d?„ Z4d@dA„ Z5dBdC„ Z6dDdE„ Z7dFdG„ Z8dHdI„ Z9dJdK„ Z:dLdM„ Z;dNdO„ Z<dPdQ„ Z=dRdS„ Z>d�dTdU„Z?dždVdW„Z@dXdY„ ZAdŸdZd[„ZBd\d]„ ZCd^d_„ ZDd dadb„ZEd¡dcdd„ZFdedf„ ZGdd`d`dd%dd%ddgœdhdi„ZHd¢djdk„ZIdldm„ ZJdndo„ ZKdpdq„ ZLdrds„ ZMdtdu„ ZNdvdw„ ZOdxdy„ ZPdzd{„ ZQd|d}„ ZRd~d„ ZSd€d�„ ZTd£d‚dƒ„ZUd¤d„d…„ZVd¥d†d‡„ZWdˆd‰„ ZXdŠd‹„ ZYdŒd�„ ZZdŽd�„ Z[d¦d�d‘„Z\d§d’d“„Z]d”d•„ Z^d–d—„ Z_d¨d˜d™„Z`dS )©ÚBaseDatabaseSchemaEditorzÈ
    This class and its subclasses are responsible for emitting schema-changing
    statements to the databases - model creation/removal/alteration, field
    renaming, index fiddling, and so on.
    z'CREATE TABLE %(table)s (%(definition)s)z1ALTER TABLE %(old_table)s RENAME TO %(new_table)sz7ALTER TABLE %(table)s SET TABLESPACE %(new_tablespace)szDROP TABLE %(table)s CASCADEz:ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)sz!ALTER TABLE %(table)s %(changes)sz%ALTER COLUMN %(column)s TYPE %(type)sz%ALTER COLUMN %(column)s DROP NOT NULLz$ALTER COLUMN %(column)s SET NOT NULLz/ALTER COLUMN %(column)s SET DEFAULT %(default)sz$ALTER COLUMN %(column)s DROP DEFAULTz4ALTER TABLE %(table)s DROP COLUMN %(column)s CASCADEzDALTER TABLE %(table)s RENAME COLUMN %(old_column)s TO %(new_column)szFUPDATE %(table)s SET %(column)s = %(default)s WHERE %(column)s IS NULLz"UNIQUE (%(columns)s)%(deferrable)szCHECK (%(check)s)z.ALTER TABLE %(table)s DROP CONSTRAINT %(name)sz"CONSTRAINT %(name)s %(constraint)sz?ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)zPALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE (%(columns)s)%(deferrable)sz|ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) REFERENCES %(to_table)s (%(to_column)s)%(deferrable)sNzFCREATE INDEX %(name)s ON %(table)s (%(columns)s)%(extra)s%(condition)szDCREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)%(condition)szDROP INDEX %(name)szGALTER TABLE %(table)s ADD CONSTRAINT %(name)s PRIMARY KEY (%(columns)s)zDROP PROCEDURE %(procedure)sFTc                 C   s,   || _ || _| jrg | _| j jjo$|| _d S r   )Ú
connectionÚcollect_sqlÚcollected_sqlÚfeaturesÚcan_rollback_ddlÚatomic_migration)Úselfr&   r'   r   r   r   r   Ú__init__`   s
    z!BaseDatabaseSchemaEditor.__init__c                 C   s(   g | _ | jr$t| jjƒ| _| j ¡  | S r   )Údeferred_sqlr+   r   r&   ÚaliasÚ	__enter__©r,   r   r   r   r0   i   s
    
z"BaseDatabaseSchemaEditor.__enter__c                 C   s8   |d kr| j D ]}|  |¡ q| jr4| j |||¡ d S r   )r.   Úexecuter+   r   Ú__exit__)r,   Úexc_typeÚ	exc_valueÚ	tracebackÚsqlr   r   r   r3   p   s
    
z!BaseDatabaseSchemaEditor.__exit__r   c              	   C   sº   | j s | jjr | jjjs tdƒ‚t|ƒ}tjd||||dœd� | j r”| 	d¡rTdnd}|dk	r‚| j
 |tt| j|ƒƒ | ¡ q¶| j
 || ¡ n"| j ¡ �}| ||¡ W 5 Q R X dS )z:Execute the given SQL statement, with optional parameters.ziExecuting DDL statements while in a transaction on databases that can't perform a rollback is prohibited.z%s; (params %r))Úparamsr7   )Úextraú;Ú N)r'   r&   Zin_atomic_blockr)   r*   r   ÚstrÚloggerÚdebugÚendswithr(   ÚappendÚtupleÚmapÚquote_valueÚcursorr2   )r,   r7   r8   ZendingrD   r   r   r   r2   y   s    ÿ"z BaseDatabaseSchemaEditor.executec                 C   s   | j j |¡S r   )r&   ÚopsÚ
quote_name)r,   r   r   r   r   rF   �   s    z#BaseDatabaseSchemaEditor.quote_namec                    s   ˆ j jD ]*}‡ fdd„|D ƒ}ˆj ˆ ˆ |¡¡ qg }g }ˆ j jD �]<}ˆ ˆ |¡\}}|dkrdqD|jˆjd�}	|	d rŒ|dˆj	|	  7 }|j
ˆjd�}
|
rª|d|
 7 }| |¡ |j�r6|j�r6|jjj j}|jjj  |jj¡j}ˆj�r|dˆjˆ |¡ˆ |¡dœ  7 }n"ˆjjj�r6ˆj ˆ ˆ |d	¡¡ | d
ˆ |j¡|f ¡ | ¡ dkrDˆjj ˆ j j|j¡}|rDˆj |¡ qD‡ ‡fdd„ˆ j jD ƒ}ˆjˆ ˆ j j¡d dd„ ||˜D ƒ¡dœ }ˆ j j�røˆjj ˆ j j¡}|�rø|d| 7 }||fS )z-Take a model and return its table definition.c                    s   g | ]}ˆ j  |¡j‘qS r   ©r   Ú	get_fieldÚcolumn©r   r   r   r   r   Ú
<listcomp>˜   s     z6BaseDatabaseSchemaEditor.table_sql.<locals>.<listcomp>N©r&   Úcheckú ú %s)Úto_tableÚ	to_columnú_fk_%(to_table)s_%(to_column)sz%s %s)Z	AutoFieldZBigAutoFieldZSmallAutoFieldc                    s   g | ]}|  ˆ ˆ¡‘qS r   )Zconstraint_sql©r   Ú
constraint©r   r,   r   r   rK   Á   s     ú, c                 s   s   | ]}|r|V  qd S r   r   rS   r   r   r   r!   Ä   s      z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>)ÚtableÚ
definition) r   Zunique_togetherr.   r@   Ú_create_unique_sqlÚlocal_fieldsÚ
column_sqlÚdb_parametersr&   Úsql_check_constraintZdb_type_suffixÚextendÚremote_fieldÚdb_constraintr   Údb_tablerH   Ú
field_namerI   Úsql_create_inline_fkrF   r)   Úsupports_foreign_keysÚ_create_fk_sqlÚget_internal_typerE   Úautoinc_sqlÚconstraintsÚsql_create_tableÚjoinÚdb_tablespaceÚtablespace_sql)r,   r   ÚfieldsÚcolumnsZcolumn_sqlsr8   r   rX   Zextra_paramsÚ	db_paramsZcol_type_suffixrP   rQ   rg   rh   r7   rl   r   rU   r   Ú	table_sql“   sX    
þ
þþ
z"BaseDatabaseSchemaEditor.table_sqlc                 C   s6  |j | jd�}|d }g }|dkr&dS |j}|o:|  |¡ }|r�|  |¡}d|  |¡ }	|dk	r�| jjjr~||	|  |¡ 7 }n||	7 }||g7 }|j	rª|j
sª| jjjrªd}|rÂ| jjjsÂ|d7 }n|sÎ|d7 }|j
rÞ|d	7 }n|jrì|d
7 }|jpø|jj}
|
�r.| jjj�r.|j�r.|d| jjj|
dd� 7 }||fS )z‹
        Take a field and return its column definition.
        The field must already have had set_attributes_from_name() called.
        rL   ÚtypeN)NNz	 DEFAULT Tz NULLz	 NOT NULLz PRIMARY KEYz UNIQUErO   )Úinline)r\   r&   ÚnullÚskip_defaultÚeffective_defaultÚ_column_default_sqlr)   Úrequires_literal_defaultsÚprepare_defaultÚempty_strings_allowedr   Ú!interprets_empty_strings_as_nullsZimplied_column_nullÚuniquerk   r   Zsupports_tablespacesrE   rl   )r,   r   r   Úinclude_defaultro   r7   r8   rs   Údefault_valueZcolumn_defaultZ
tablespacer   r   r   r[   Î   s>    


ÿ

z#BaseDatabaseSchemaEditor.column_sqlc                 C   s   dS )z�
        Some backends don't accept default values for certain columns types
        (i.e. MySQL longtext and longblob).
        Fr   ©r,   r   r   r   r   rt   ÿ   s    z%BaseDatabaseSchemaEditor.skip_defaultc                 C   s   t dƒ‚dS )zU
        Only used for backends which have requires_literal_defaults feature
        z€subclasses of BaseDatabaseSchemaEditor for backends which have requires_literal_defaults must provide a prepare_default() methodN©ÚNotImplementedError©r,   Úvaluer   r   r   rx     s    ÿz(BaseDatabaseSchemaEditor.prepare_defaultc                 C   s   dS )z�
        Return the SQL to use in a DEFAULT clause. The resulting string should
        contain a '%s' placeholder for a default value.
        ú%sr   r~   r   r   r   rv     s    z,BaseDatabaseSchemaEditor._column_default_sqlc                 C   s¢   |   ¡ r|  ¡ }nŒ| js<| jr<| jr<|  ¡ dkr6d}qžd}nbt| ddƒsTt| ddƒršt ¡ }|  ¡ }|dkrv| 	¡ }qž|dkrˆ| 
¡ }qž|d	kržt ¡ }nd }|S )
NZBinaryFieldó    r;   Zauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeField)Úhas_defaultÚget_defaultrs   Zblankry   rf   Úgetattrr   ÚnowÚdateÚtimer   )r   ÚdefaultZinternal_typer   r   r   Ú_effective_default  s"    



z+BaseDatabaseSchemaEditor._effective_defaultc                 C   s   |  |  |¡| j¡S )z2Return a field's effective database default value.)Zget_db_prep_saverŒ   r&   r~   r   r   r   ru   -  s    z*BaseDatabaseSchemaEditor.effective_defaultc                 C   s
   t ƒ ‚dS )aX  
        Return a quoted version of the value so it's safe to use in an SQL
        string. This is not safe against injection from user code; it is
        intended only for use in making SQL scripts or preparing default values
        for particularly tricky backends (defaults are not user-defined, though,
        so this is safe).
        Nr   r�   r   r   r   rC   1  s    z$BaseDatabaseSchemaEditor.quote_valuec                 C   s\   |   |¡\}}|  ||pd¡ | j |  |¡¡ |jjD ]}|jjjj	r8|  
|jj¡ q8dS )zr
        Create a table and any accompanying indexes or unique constraints for
        the given `model`.
        N)rp   r2   r.   r^   Ú_model_indexes_sqlr   Úlocal_many_to_manyr_   ÚthroughÚauto_createdÚcreate_model)r,   r   r7   r8   r   r   r   r   r‘   =  s    z%BaseDatabaseSchemaEditor.create_modelc                 C   s~   |j jD ]}|jjj jr|  |jj¡ q|  | jd|  |j j	¡i ¡ t
| jƒD ](}t|tƒrP| |j j	¡rP| j |¡ qPdS )z!Delete a model from the database.rW   N)r   rŽ   r_   r�   r�   Údelete_modelr2   Úsql_delete_tablerF   ra   Úlistr.   Ú
isinstancer   Zreferences_tableÚremove)r,   r   r   r7   r   r   r   r’   N  s     ÿz%BaseDatabaseSchemaEditor.delete_modelc                 C   s   | j | || ¡dd� dS )zAdd an index on a model.N)r8   )r2   Ú
create_sql©r,   r   Úindexr   r   r   Ú	add_index^  s    z"BaseDatabaseSchemaEditor.add_indexc                 C   s   |   | || ¡¡ dS )zRemove an index from a model.N)r2   Ú
remove_sqlr˜   r   r   r   Úremove_indexb  s    z%BaseDatabaseSchemaEditor.remove_indexc                 C   s   |  || ¡}|r|  |¡ dS )zAdd a constraint to a model.N)r—   r2   ©r,   r   rT   r7   r   r   r   Úadd_constraintf  s    z'BaseDatabaseSchemaEditor.add_constraintc                 C   s   |  || ¡}|r|  |¡ dS )z!Remove a constraint from a model.N)r›   r2   r�   r   r   r   Úremove_constraintl  s    z*BaseDatabaseSchemaEditor.remove_constraintc                    sz   dd„ |D ƒ}dd„ |D ƒ}|  |¡D ]}|  ˆ |ddi| j¡ q&|  |¡D ](}‡ fdd„|D ƒ}|  |  ˆ |¡¡ qLdS )	z°
        Deal with a model changing its unique_together. The input
        unique_togethers must be doubly-nested, not the single-nested
        ["foo", "bar"] format.
        c                 S   s   h | ]}t |ƒ’qS r   ©rA   ©r   rm   r   r   r   Ú	<setcomp>x  s     zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   s   h | ]}t |ƒ’qS r   r    r¡   r   r   r   r¢   y  s     r{   Tc                    s   g | ]}ˆ j  |¡j‘qS r   rG   rJ   r   r   r   rK     s     zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)Ú
differenceÚ_delete_composed_indexÚsql_delete_uniquer2   rY   )r,   r   Zold_unique_togetherZnew_unique_togetherÚoldsÚnewsrm   rn   r   r   r   Úalter_unique_togetherr  s    z.BaseDatabaseSchemaEditor.alter_unique_togetherc                    s€   dd„ |D ƒ}dd„ |D ƒ}|  |¡D ]}|  ˆ |dddœ| j¡ q&|  |¡D ],}‡ fdd„|D ƒ}|  | jˆ |d	d
�¡ qNdS )z®
        Deal with a model changing its index_together. The input
        index_togethers must be doubly-nested, not the single-nested
        ["foo", "bar"] format.
        c                 S   s   h | ]}t |ƒ’qS r   r    r¡   r   r   r   r¢   ˆ  s     z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c                 S   s   h | ]}t |ƒ’qS r   r    r¡   r   r   r   r¢   ‰  s     TF)r™   r{   c                    s   g | ]}ˆ j  |¡‘qS r   ©r   rH   rJ   r   r   r   rK   ”  s     zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>Ú_idx©ÚsuffixN)r£   r¤   Úsql_delete_indexr2   Ú_create_index_sql)r,   r   Zold_index_togetherZnew_index_togetherr¦   r§   rm   Úfield_namesr   r   r   Úalter_index_together‚  s    üz-BaseDatabaseSchemaEditor.alter_index_togetherc           	         sš   dd„ ˆ j jD ƒ}dd„ ˆ j jD ƒ}‡ fdd„|D ƒ}| jˆ |fd||B i|—Ž}t|ƒdkr~tdt|ƒˆ j jd	 |¡f ƒ‚|  |  	|ˆ |d
 ¡¡ d S )Nc                 S   s   h | ]
}|j ’qS r   ©r   rS   r   r   r   r¢   ˜  s     zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   s   h | ]
}|j ’qS r   r±   rS   r   r   r   r¢   ™  s     c                    s   g | ]}ˆ j  |¡j‘qS r   rG   rJ   r   r   r   rK   š  s     zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>Úexcludeé   z1Found wrong number (%s) of constraints for %s(%s)rV   r   )
r   rh   ÚindexesÚ_constraint_namesÚlenÚ
ValueErrorra   rj   r2   Ú_delete_constraint_sql)	r,   r   rm   Zconstraint_kwargsr7   Úmeta_constraint_namesÚmeta_index_namesrn   Úconstraint_namesr   r   r   r¤   —  s$     ÿÿþýz/BaseDatabaseSchemaEditor._delete_composed_indexc                 C   sn   ||ks"| j jjr&| ¡ | ¡ kr&dS |  | j|  |¡|  |¡dœ ¡ | jD ]}t|t	ƒrN| 
||¡ qNdS )z#Rename the table a model points to.N)Z	old_tableZ	new_table)r&   r)   Zignores_table_name_caseÚlowerr2   Úsql_rename_tablerF   r.   r•   r   Zrename_table_references)r,   r   Zold_db_tableZnew_db_tabler7   r   r   r   Úalter_db_table§  s    ÿþþ


z'BaseDatabaseSchemaEditor.alter_db_tablec                 C   s2   |   | j|  |jj¡|  |¡|  |¡dœ ¡ dS )z)Move a model's table between tablespaces.)rW   Zold_tablespaceZnew_tablespaceN)r2   Úsql_retablespace_tablerF   r   ra   )r,   r   Zold_db_tablespaceZnew_db_tablespacer   r   r   Úalter_db_tablespace¶  s
    ýz,BaseDatabaseSchemaEditor.alter_db_tablespacec              
   C   sè  |j r |jjjjr |  |jj¡S | j||dd�\}}|dkr@dS |j| jd�}|d rh|d| j	|  7 }|j�r2| jj
j�r2|j�r2d}| j�r|jjjj}|jjj |jj¡j}t|jjƒ\}	}
|d| j|  |||¡|	rèd|  |	¡ nd	|  |j¡|  |¡|  |¡| jj ¡ d
œ  7 }n| j |  |||¡¡ | j|  |jj¡|  |j¡|dœ }|  ||¡ |  |¡�sº|  |¡dk	�rº| j|d|dd�\}}| j |  |jj¡|dœ }|  ||¡ | j !|  "||¡¡ | jj
j#�rä| j $¡  dS )z�
        Create a field on a model. Usually involves adding a column, but may
        involve adding a table instead (for M2M fields).
        T)r|   NrL   rM   rN   rR   z%s.r;   )r   Ú	namespacerI   rP   rQ   Ú
deferrable)rW   rI   rX   ©Údrop©rW   Úchanges)%r   r_   r�   r   r�   r‘   r[   r\   r&   r]   r)   rd   r`   Úsql_create_column_inline_fkr   ra   rH   rb   rI   r	   Ú_fk_constraint_namerF   rE   Údeferrable_sqlr.   r@   re   Úsql_create_columnr2   rt   ru   Ú_alter_column_default_sqlÚsql_alter_columnr^   Ú_field_indexes_sqlÚconnection_persists_old_columnsÚclose)r,   r   r   rX   r8   ro   Zconstraint_suffixrP   rQ   rÁ   Ú_r7   Úchanges_sqlr   r   r   Ú	add_field¾  sN    

ú

ýþz"BaseDatabaseSchemaEditor.add_fieldc                 C   sì   |j r |jjjjr |  |jj¡S |j| jd�d dkr:dS |jrp| j||j	gdd�}|D ]}|  
|  ||¡¡ qX| j|  |jj¡|  |j	¡dœ }|  
|¡ | jjjr°| j ¡  t| jƒD ],}t|tƒrº| |jj|j	¡rº| j |¡ qºdS )z…
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        rL   rq   NT©Úforeign_key)rW   rI   )r   r_   r�   r   r�   r’   r\   r&   rµ   rI   r2   Ú_delete_fk_sqlÚsql_delete_columnrF   ra   r)   rÎ   rÏ   r”   r.   r•   r   Zreferences_columnr–   )r,   r   r   Úfk_namesÚfk_namer7   r   r   r   Úremove_field÷  s$    
þ


z%BaseDatabaseSchemaEditor.remove_fieldc           	   
   C   s$  |j | jd�}|d }|j | jd�}|d }|dkr>|jdksP|dkrb|jdkrbtd||f ƒ‚n¦|dkrª|dkrª|jjrª|jjrª|jjjjrª|jjjjrª|  ||||¡S |dkræ|dkræ|jjræ|jjræ|jjjjsæ|jjjjsædS |dksø|dk�rtd||f ƒ‚|  ||||||||¡ dS )a'  
        Allow a field's type, uniqueness, nullability, default, column,
        constraints, etc. to be modified.
        `old_field` is required to compute the necessary changes.
        If `strict` is True, raise errors if the old column does not match
        `old_field` precisely.
        rL   rq   NzqCannot alter field %s into %s - they do not properly define db_type (are you using a badly-written custom field?)z�Cannot alter field %s into %s - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields))	r\   r&   r_   r·   r�   r   r�   Ú_alter_many_to_manyÚ_alter_field)	r,   r   r    r"   ÚstrictÚold_db_paramsÚold_typeÚnew_db_paramsÚnew_typer   r   r   Úalter_field  sZ    	ÿÿþÿÿÿ
þ
ýÿÿ
þ
ýþÿ  ÿz$BaseDatabaseSchemaEditor.alter_fieldc	           '      C   s\  t ƒ }	| jjjr†|jr†|jr†| j||jgdd�}
|r\t|
ƒdkr\t	dt|
ƒ|j
j|jf ƒ‚|
D ]$}|	 |jf¡ |  |  ||¡¡ q`|j�r|jr¢|  ||¡�rdd„ |j
jD ƒ}| j||jgdd|d�}|røt|ƒdkrøt	d	t|ƒ|j
j|jf ƒ‚|D ]}|  |  ||¡¡ qü| jjj�oF|j�r0|j�s@|j�oF|j�oF||k}|�rœt||ƒD ]B\}}| j|j|jjgdd�}|D ]}|  |  |j|¡¡ �q|�qX|j�r|j�s|j�r¼|j�rd
d„ |j
jD ƒ}| j||jgdtj|d�}|D ]}|  |  ||¡¡ �qì|d |d k�r˜|d �r˜dd„ |j
jD ƒ}| j||jgd|d�}|�rzt|ƒdk�rzt	dt|ƒ|j
j|jf ƒ‚|D ]}|  |  ||¡¡ �q~|j|jk�rð|  |  |j
j|||¡¡ | jD ](}t|t ƒ�rÆ| !|j
j|j|j¡ �qÆg }g }g }||k�r.|  "||||¡\}}| #|¡ | $|¡ d}|j%�rŽ|j%�sŽ|  &|¡}|  &|¡}|  '|¡�sŽ||k�rŽ|dk	�rŽd}| #|  (|||¡¡ |j%|j%k�rº|  )|||¡}|�rº| #|¡ | *¡ �oÒ|j%�oÒ|j% }|�sà|�r¾|�sî|| }| jjj+�r&|�r&t,t-|Ž ƒ\}} d .|¡t/| g ƒfg}|D ],\}} |  | j0|  1|j
j¡|dœ | ¡ �q*|�r¾|  | j2|  1|j
j¡|  1|j¡ddœ |g¡ |D ],\}} |  | j0|  1|j
j¡|dœ | ¡ �q�|�rà|D ]\}} |  || ¡ �qÈ|j�rü|j�sü|  3||¡ |  4||¡�r |  |  5||jg¡¡ |j�r0|j�rT|j�rT|j�sT|  |  6||g¡¡ g }!|�rn|! $t||ƒ¡ |  ||¡�rž|  |  7||¡¡ |! $t||ƒ¡ |!D ]„\}"}|jj8| jd�}#|#d }$|  "|j|"j|j|$¡\}}|  | j0|  1|jj
j¡|d dœ |d ¡ |D ]\}} |  || ¡ �q�q¢| jjj�rn|j�rn|	�sR|j�rR|j�sn|j�rn|  |  9||d¡¡ |�r´|j:j
j;D ]4}%t<|%|ƒ�r~|%jj�r~|  |  9|%j|%jd¡¡ �q~|d |d k�r |d �r | j=|j
j|jgdd�}|  |  >|||d ¡¡ |�rB| j(|||dd�\}&} | j0|  1|j
j¡|&dœ }|  || ¡ | jjj?�rX| j @¡  dS )z3Perform a "physical" (non-ManyToMany) field update.TrÓ   r³   z<Found wrong number (%s) of foreign key constraints for %s.%sc                 S   s   h | ]
}|j ’qS r   r±   rS   r   r   r   r¢   U  s     z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>F)r{   r   r²   z7Found wrong number (%s) of unique constraints for %s.%sc                 S   s   h | ]
}|j ’qS r   r±   )r   r™   r   r   r   r¢     s     )r™   Útype_r²   rM   c                 S   s   h | ]
}|j ’qS r   r±   rS   r   r   r   r¢   �  s     )rM   r²   z6Found wrong number (%s) of check constraints for %s.%sNrV   rÅ   rƒ   )rW   rI   r‹   rL   rq   r   rR   Z_fkÚ_checkr«   rÃ   )AÚsetr&   r)   rd   r_   r`   rµ   rI   r¶   r·   r   ra   Úaddr2   rÕ   r{   Ú_field_became_primary_keyrh   Ú_delete_unique_sqlr   r$   Zrelated_modelr   Údb_indexr´   r   r¬   Ú_delete_index_sqlÚ_delete_check_sqlÚ_rename_field_sqlr.   r•   r   Zrename_column_referencesÚ_alter_column_type_sqlr@   r^   rs   ru   rt   rË   Ú_alter_column_null_sqlr…   Zsupports_combined_altersrA   r#   rj   ÚsumrÌ   rF   Úsql_update_with_defaultÚ_delete_primary_keyÚ_unique_should_be_addedrY   r®   Ú_create_primary_key_sqlr\   re   r   Zrelated_objectsr   Ú_create_index_nameÚ_create_check_sqlrÎ   rÏ   )'r,   r   r    r"   rÞ   rà   rÝ   rß   rÜ   Zfks_droppedr×   rØ   r¹   r»   Úconstraint_nameZdrop_foreign_keysZ_old_relZnew_relZrel_fk_namesrº   Zindex_namesÚ
index_namer7   ÚactionsZnull_actionsZpost_actionsÚfragmentZother_actionsZneeds_database_defaultZold_defaultÚnew_defaultZfour_way_default_alterationr8   Zrels_to_updateZold_relZrel_db_paramsZrel_typeÚrelrÑ   r   r   r   rÛ   >  sŠ   ÿþýý   þýþü  ÿ    þ  þý





ÿþý

þþû
ýú
þû
    ÿþûÿÿÿþþz%BaseDatabaseSchemaEditor._alter_fieldc                 C   s\   | j jjr| ¡ dkrdS |j| j d�}|jr4| jn| j}||  |j	¡|d dœ g fS dS )zÏ
        Hook to specialize column null alteration.

        Return a (sql, params) fragment to set a column to null or non-null
        as required by new_field, or None if no changes are required.
        )Z	CharFieldZ	TextFieldNrL   rq   ©rI   rq   )
r&   r)   rz   rf   r\   rs   Úsql_alter_column_nullÚsql_alter_column_not_nullrF   rI   )r,   r   r    r"   rß   r7   r   r   r   rí   6  s    

ÿ
þûz/BaseDatabaseSchemaEditor._alter_column_null_sqlc           
      C   sz   |   |¡}|  |¡}|g}|r$g }n| jjjr<|  |¡}g }|j| jd�}|rT| jn| j}	|	|  	|j
¡|d |dœ |fS )zÁ
        Hook to specialize column default alteration.

        Return a (sql, params) fragment to add or drop (depending on the drop
        argument) a default to new_field's column.
        rL   rq   )rI   rq   r‹   )ru   rv   r&   r)   rw   rx   r\   Úsql_alter_column_no_defaultÚsql_alter_column_defaultrF   rI   )
r,   r   r    r"   rÄ   rù   r‹   r8   rß   r7   r   r   r   rË   L  s"    




ýúz2BaseDatabaseSchemaEditor._alter_column_default_sqlc                 C   s    | j |  |j¡|dœ g fg fS )a–  
        Hook to specialize column type alteration for different backends,
        for cases when a creation type is different to an alteration type
        (e.g. SERIAL in PostgreSQL, PostGIS fields).

        Return a two-tuple of: an SQL fragment of (sql, params) to insert into
        an ALTER TABLE statement and a list of extra (sql, params) tuples to
        run once the field is altered.
        rû   )Úsql_alter_column_typerF   rI   )r,   r   r    r"   rà   r   r   r   rì   k  s    
þûøz/BaseDatabaseSchemaEditor._alter_column_type_sqlc                 C   s¢   |j jjj|j jjjkr:|  |j j|j jjj|j jjj¡ |  |j j|j jj | ¡ ¡|j jj | ¡ ¡¡ |  |j j|j jj | ¡ ¡|j jj | ¡ ¡¡ dS )z*Alter M2Ms to repoint their to= endpoints.N)	r_   r�   r   ra   r¾   rá   rH   Zm2m_reverse_field_nameZm2m_field_name)r,   r   r    r"   rÜ   r   r   r   rÚ   €  s    
ÿûüz,BaseDatabaseSchemaEditor._alter_many_to_manyr;   c           	      C   sà   t |ƒ\}}dt|f|žddiŽ|f }| jj ¡ p6d}d|d |¡|f }t|ƒ|kr\|S t|ƒ|d kr||d|d … }|t|ƒ d	 d
 }d|d|… d |¡d|… |f }|d dksÌ|d  ¡ rÜd|dd…  }|S )z½
        Generate a unique name for an index/unique constraint.

        The name is divided into 3 parts: the table name, the column names,
        and a unique digest and suffix.
        z%s%sÚlengthé   éÈ   z%s_%s_%srÐ   é   Né   r³   r   zD%séÿÿÿÿ)r	   r   r&   rE   Zmax_name_lengthrj   r¶   Úisdigit)	r,   Z
table_nameÚcolumn_namesr¬   rÐ   Zhash_suffix_partÚ
max_lengthrö   Zother_lengthr   r   r   ró   •  s"    
ýz+BaseDatabaseSchemaEditor._create_index_namec                 C   sX   |d kr:t |ƒdkr*|d jr*|d j}n|jjr:|jj}|d k	rTd| jj |¡ S dS )Nr³   r   rN   r;   )r¶   rk   r   r&   rE   rl   )r,   r   rm   rk   r   r   r   Ú_get_index_tablespace_sql²  s    z2BaseDatabaseSchemaEditor._get_index_tablespace_sqlc                 C   s   |rd| S dS )Nz WHERE r;   r   )r,   Ú	conditionr   r   r   Ú_index_condition_sql¼  s    z-BaseDatabaseSchemaEditor._index_condition_sql)r   r¬   Úusingrk   Úcol_suffixesr7   Ú	opclassesr  c                   sx   ˆj |||d�}dd„ |D ƒ}|p&ˆj}|jj}‡ ‡fdd„}t|t|ˆjƒt||||ƒ|ˆ ||||	¡|ˆ 	|
¡d�S )z¼
        Return the SQL statement to create the index for one or several fields.
        `sql` can be specified if the syntax differs from the standard (GIS
        indexes, ...).
        )rk   c                 S   s   g | ]
}|j ‘qS r   )rI   rJ   r   r   r   rK   Ê  s     z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s   ˆ d krˆj | |Ž‰ ˆ ˆ ¡S r   )ró   rF   ©ÚargsÚkwargs©r   r,   r   r   Úcreate_index_nameÎ  s    zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)rW   r   r  rn   r9   r  )
r
  Úsql_create_indexr   ra   r   r   rF   r   Ú_index_columnsr  )r,   r   rm   r   r¬   r  rk   r  r7   r  r  rl   rn   r  rW   r  r   r  r   r®   Á  s    

ùz*BaseDatabaseSchemaEditor._create_index_sqlc                 C   s&   t |p
| jt|jj| jƒ|  |¡d�S ©N)rW   r   )r   r­   r   r   ra   rF   )r,   r   r   r7   r   r   r   ré   Þ  s
    ýz*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s   t ||| j|d�S )N)r  )r   rF   )r,   rW   rn   r  r  r   r   r   r  å  s    z'BaseDatabaseSchemaEditor._index_columnsc                    sš   ˆ j jrˆ j jsˆ j jrg S g }ˆ j jD ]}| |  ˆ |¡¡ q(ˆ j jD ],}‡ fdd„|D ƒ}| | j	ˆ |dd�¡ qHˆ j j
D ]}| | ˆ | ¡¡ q~|S )zŠ
        Return a list of all index SQL statements (field indexes,
        index_together, Meta.indexes) for the specified model.
        c                    s   g | ]}ˆ j  |¡‘qS r   r©   rJ   r   r   r   rK   ô  s     z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>rª   r«   )r   ZmanagedÚproxyZswappedrZ   r^   rÍ   Zindex_togetherr@   r®   r´   r—   )r,   r   Úoutputr   r¯   rm   r™   r   r   r   r�   è  s    z+BaseDatabaseSchemaEditor._model_indexes_sqlc                 C   s(   g }|   ||¡r$| |  ||g¡¡ |S )zT
        Return a list of all index SQL statements for the specified field.
        )Ú_field_should_be_indexedr@   r®   )r,   r   r   r  r   r   r   rÍ   û  s    z+BaseDatabaseSchemaEditor._field_indexes_sqlc                 C   s   |j o|j S r   )rè   r{   ©r,   r   r   r   r   r   r    s    z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r   ©r   ©r,   r    r"   r   r   r   ræ     s    z2BaseDatabaseSchemaEditor._field_became_primary_keyc                 C   s"   |j  r|j p |jo |j o |j S r   )r{   r   r  r   r   r   rñ   
  s    ÿz0BaseDatabaseSchemaEditor._unique_should_be_addedc                 C   s*   | j |  |¡|  |j¡|  |j¡|dœ S )N)rW   Z
old_columnZ
new_columnrq   )Úsql_rename_columnrF   rI   )r,   rW   r    r"   rà   r   r   r   rë     s    

üz*BaseDatabaseSchemaEditor._rename_field_sqlc           
   	   C   sˆ   t |jj| jƒ}|  |||¡}t|jj|jg| jƒ}t |jjjj| jƒ}t|jjjj|jjg| jƒ}| j	j
 ¡ }	t| j||||||	d�S )N)rW   r   rI   rP   rQ   rÂ   )r   r   ra   rF   rÈ   r   rI   Útarget_fieldr   r&   rE   rÉ   r   Úsql_create_fk)
r,   r   r   r¬   rW   r   rI   rP   rQ   rÂ   r   r   r   re     s    ùz'BaseDatabaseSchemaEditor._create_fk_sqlc                    s<   ‡ fdd„}t |jj|jgt|jjjjƒd |jjg||ƒS )Nc                     s   ˆ   ˆ j| |Ž¡S r   ©rF   ró   r  r1   r   r   Úcreate_fk_name)  s    zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer³   )r   r   ra   rI   r	   r  r   )r,   r   r   r¬   r"  r   r1   r   rÈ   (  s    úz,BaseDatabaseSchemaEditor._fk_constraint_namec                 C   s   |   | j||¡S r   )r¸   Úsql_delete_fk©r,   r   r   r   r   r   rÕ   5  s    z'BaseDatabaseSchemaEditor._delete_fk_sqlc                 C   s,   |d krdS |t jkrdS |t jkr(dS d S )Nr;   z DEFERRABLE INITIALLY DEFERREDz DEFERRABLE INITIALLY IMMEDIATE)r
   ZDEFERREDZ	IMMEDIATE)r,   rÂ   r   r   r   Ú_deferrable_constraint_sql8  s    

z3BaseDatabaseSchemaEditor._deferrable_constraint_sqlc                 C   sv   |r| j jjsd S |r<| j||||d�}|r8| j |¡ d S | jd t| j	|ƒ¡|  
|¡dœ }| j|  	|¡|dœ S )N)r   r  rV   )rn   rÂ   ©r   rT   )r&   r)   Ú&supports_deferrable_unique_constraintsrY   r.   r@   Úsql_unique_constraintrj   rB   rF   r%  Úsql_constraint)r,   r   rm   r   r  rÂ   r7   rT   r   r   r   Ú_unique_sql@  s$    ÿþþþz$BaseDatabaseSchemaEditor._unique_sqlc           	   	      s¢   |rˆ j jjsd S ‡ fdd„}t|jjˆ jƒ}|d krJt|jj|d|ƒ}n
ˆ  |¡}t||ˆ jƒ}|r|ˆ j jj	std S ˆ j
}nˆ j}t||||ˆ  |¡ˆ  |¡d�S )Nc                     s   ˆ   ˆ j| |Ž¡S r   r!  r  r1   r   r   Úcreate_unique_name]  s    zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_nameÚ_uniq)rW   r   rn   r  rÂ   )r&   r)   r'  r   r   ra   rF   r   r   Úsupports_partial_indexesÚsql_create_unique_indexÚsql_create_uniquer   r  r%  )	r,   r   rn   r   r  rÂ   r+  rW   r7   r   r1   r   rY   V  s0    ÿþ

úz+BaseDatabaseSchemaEditor._create_unique_sqlc                 C   sD   |r| j jjsd S |r4| j jjr0|  | j||¡S d S |  | j||¡S r   )r&   r)   r'  r-  r¸   r­   r¥   )r,   r   r   r  rÂ   r   r   r   rç   u  s    ÿþÿþz+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j |  |¡| jd|i dœ S )NrM   r&  )r)  rF   r]   )r,   r   rM   r   r   r   Ú
_check_sql‚  s    þz#BaseDatabaseSchemaEditor._check_sqlc                 C   s$   t | jt|jj| jƒ|  |¡|d�S )N)rW   r   rM   )r   Úsql_create_checkr   r   ra   rF   )r,   r   r   rM   r   r   r   rô   ˆ  s    üz*BaseDatabaseSchemaEditor._create_check_sqlc                 C   s   |   | j||¡S r   )r¸   Úsql_delete_checkr$  r   r   r   rê   �  s    z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| jƒ|  |¡d�S r  )r   r   r   ra   rF   )r,   Útemplater   r   r   r   r   r¸   “  s
    ýz/BaseDatabaseSchemaEditor._delete_constraint_sqlc
              	      s  |dk	r‡ fdd„|D ƒ}ˆ j  ¡ �}
ˆ j j |
|jj¡}W 5 Q R X g }| ¡ D ]²\}}|dksl||d krP|dk	r‚|d |kr‚qP|dk	r˜|d |kr˜qP|dk	r®|d |kr®qP|dk	rÄ|d |krÄqP|dk	rÖ|d	 sÖqP|dk	rì|d
 |krìqP|	rø||	krP| |¡ qP|S )z@Return all constraint names matching the columns and conditions.Nc                    s   g | ]}ˆ j j |¡‘qS r   )r&   ÚintrospectionZidentifier_converter)r   r   r1   r   r   rK   Ÿ  s   ÿz>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>rn   r{   r   r™   rM   rÔ   rq   )r&   rD   r4  Zget_constraintsr   ra   Úitemsr@   )r,   r   r  r{   r   r™   rÔ   rM   râ   r²   rD   rh   Úresultr   Zinfodictr   r1   r   rµ   š  s0    
þz*BaseDatabaseSchemaEditor._constraint_namesc                 C   sV   | j |dd�}|r6t|ƒdkr6tdt|ƒ|jjf ƒ‚|D ]}|  |  ||¡¡ q:d S )NTr  r³   z0Found wrong number (%s) of PK constraints for %s)rµ   r¶   r·   r   ra   r2   Ú_delete_primary_key_sql)r,   r   rÜ   r»   rõ   r   r   r   rð   ¸  s    þz,BaseDatabaseSchemaEditor._delete_primary_keyc              
   C   sJ   t | jt|jj| jƒ|  | j|jj|jgdd�¡t|jj|jg| jƒd�S )NZ_pkr«   )rW   r   rn   )	r   Úsql_create_pkr   r   ra   rF   ró   rI   r   r  r   r   r   rò   Â  s    ÿúz0BaseDatabaseSchemaEditor._create_primary_key_sqlc                 C   s   |   | j||¡S r   )r¸   Úsql_delete_pkr$  r   r   r   r7  Ì  s    z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc                 C   s*   | j |  |¡d |¡dœ }|  |¡ d S )Nú,)Z	procedureÚparam_types)Úsql_delete_procedurerF   rj   r2   )r,   Zprocedure_namer;  r7   r   r   r   Úremove_procedureÏ  s
    þz)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)F)F)F)r;   )N)N)NN)NNN)NN)NNNNNNNN)F)r   )aÚ__name__Ú
__module__Ú__qualname__Ú__doc__ri   r½   r¿   r“   rÊ   rÌ   r   rü   rý   rÿ   rþ   rÖ   r  rï   r(  r]   Zsql_delete_constraintr)  r1  r2  r/  r¥   r   rc   rÇ   r#  r  r.  r­   r8  r9  r<  r-   r0   r3   r2   rF   rp   r[   rt   rx   rv   ÚstaticmethodrŒ   ru   rC   r‘   r’   rš   rœ   rž   rŸ   r¨   r°   r¤   r¾   rÀ   rÒ   rÙ   rá   rÛ   rí   rË   rì   rÚ   ró   r
  r  r®   ré   r  r�   rÍ   r  ræ   rñ   rë   re   rÈ   rÕ   r%  r*  rY   rç   r0  rô   rê   r¸   rµ   rð   rò   r7  r=  r   r   r   r   r%   ,   sÜ   ÿ
		
;
1	
9
* ÿ
 y



   þ
	


           þ



r%   )Úloggingr   Z!django.db.backends.ddl_referencesr   r   r   r   r   Zdjango.db.backends.utilsr   r	   Zdjango.db.modelsr
   r   Zdjango.db.transactionr   r   Zdjango.utilsr   Ú	getLoggerr=   r   r   r$   r%   r   r   r   r   Ú<module>   s   
	