U
    5ij                     @   s   d dl Z d dlmZ d dlmZ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 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ExpressionsForeignKeyName	IndexName	StatementTable)names_digestsplit_identifier)
DeferrableIndex)Query)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-gcyiijx6/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                 #   sb   t fddtjD  fddt jD }|D ]&\}}||fV  t|j|jE d H  q6d 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   _related_non_m2m_objectsremote_field)r"   r$   Zrelated_fieldsold_relnew_relr   )r$   r"   r   r&   $   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e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%dd d!Z&d"d# Z'd$d% Z(dd'd(Z)d)d* Z*d+d, Z+d-d. Z,dd/d0Z-d1d2 Z.d3d4 Z/d5d6 Z0d7d8 Z1e2d9d: Z3d;d< Z4d=d> Z5d?d@ Z6dAdB Z7dCdD Z8dEdF Z9dGdH Z:dIdJ Z;dKdL Z<dMdN Z=dOdP Z>dQdR Z?dSdT Z@dUdV ZAdWdX ZBddYdZZCdd[d\ZDd]d^ ZEdd_d`ZFdadb ZGdcdd ZHdedf ZIddhdiZJddjdkZKdldm ZLdndo ZMdddgdgdd&dd&ddddpdqdrZNddsdtZOdudv ZPdwdx ZQdydz ZRd{d| ZSd}d~ ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dddZ\dddZ]dddZ^dd Z_dd Z`dd Zadd ZbdddZcdddZddd Zedd Zfdd ZgdddZhd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 DEFAULTz2ALTER COLUMN %(column)s TYPE %(type)s%(collation)sz4ALTER 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)sNzQCREATE INDEX %(name)s ON %(table)s (%(columns)s)%(include)s%(extra)s%(condition)szOCREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)%(include)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__i   s
    z!BaseDatabaseSchemaEditor.__init__c                 C   s(   g | _ | jr$t| jj| _| j  | S r   )deferred_sqlr0   r   r+   alias	__enter__r1   r   r   r   r5   r   s
    
z"BaseDatabaseSchemaEditor.__enter__c                 C   s8   |d kr| j D ]}| | q| jr4| j||| d S r   )r3   executer0   r   __exit__)r1   exc_type	exc_value	tracebacksqlr   r   r   r8   y   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rXd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))paramsr<   )extra; N)r,   r+   Zin_atomic_blockr.   r/   r   strloggerdebugrstripendswithr-   appendtuplemapquote_valuecursorr7   )r1   r<   r=   ZendingrJ   r   r   r   r7      s    "z BaseDatabaseSchemaEditor.executec                 C   s   | j j|S r   )r+   ops
quote_name)r1   r   r   r   r   rL      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 |qS r   r   	get_fieldr    r   r   r   r   
<listcomp>   s     z6BaseDatabaseSchemaEditor.table_sql.<locals>.<listcomp>Nr+   check z %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   r1   r   r   rP      s     , c                 s   s   | ]}|r|V  qd S r   r   rW   r   r   r   r#      s      z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>)table
definition) r   Zunique_togetherr3   rF   _create_unique_sqllocal_fields
column_sqldb_parametersr+   sql_check_constraintZdb_type_suffixextendr'   db_constraintr   db_tablerN   
field_namecolumnsql_create_inline_fkrL   r.   supports_foreign_keys_create_fk_sqlget_internal_typerK   autoinc_sqlconstraintssql_create_tablejoindb_tablespacetablespace_sql)r1   r   field_namesfieldsZcolumn_sqlsr=   r   r\   Zextra_params	db_paramsZcol_type_suffixrT   rU   rk   rl   r<   rp   r   rY   r   	table_sql   sX    


z"BaseDatabaseSchemaEditor.table_sqlc                 c   s(  |V  t |dd }|r"| |V  |j}|oF| | oF|oD| | }|r| |}|d k	rd| | }	| jjj	r|	| 
| V  n|	V  || |jr|js| jjjrd}|sdV  n| jjjsdV  |jrdV  n|jrdV  |jp|jj}
|
r$| jjjr$|jr$| jjj|
ddV  d S )	Ndb_collationzDEFAULT TzNOT NULLZNULLzPRIMARY KEYZUNIQUE)inline)getattr_collate_sqlnullskip_defaultskip_default_on_altereffective_default_column_default_sqlr+   r.   requires_literal_defaultsprepare_defaultrF   empty_strings_allowedr   !interprets_empty_strings_as_nullsZimplied_column_nulluniquero   r   Zsupports_tablespacesrK   rp   )r1   column_db_typer=   r   r   include_default	collationry   default_valueZcolumn_defaultZ
tablespacer   r   r   _iter_column_sql   sB    




z)BaseDatabaseSchemaEditor._iter_column_sqlc              	   C   sB   |j | jd}|d }|dkr"dS g }d| ||||||fS )z
        Return the column definition for a field. The field must already have
        had set_attributes_from_name() called.
        rQ   typeN)NNrS   )r`   r+   rn   r   )r1   r   r   r   rs   r   r=   r   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   r1   r   r   r   r   rz     s    z%BaseDatabaseSchemaEditor.skip_defaultc                 C   s   dS )z
        Some backends don't accept default values for certain columns types
        (i.e. MySQL longtext and longblob) in the ALTER COLUMN statement.
        Fr   r   r   r   r   r{     s    z.BaseDatabaseSchemaEditor.skip_default_on_alterc                 C   s   t ddS )zU
        Only used for backends which have requires_literal_defaults feature
        zsubclasses of BaseDatabaseSchemaEditor for backends which have requires_literal_defaults must provide a prepare_default() methodNNotImplementedErrorr1   valuer   r   r   r   $  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   r}   -  s    z,BaseDatabaseSchemaEditor._column_default_sqlc                 C   s   |   r|  }n| js<| jr<| jr<|  dkr6d}qd}nbt| ddsTt| ddr|  }|dkrnt }qt	 }|dkr|
 }q|d	kr| }nd }|S )
NZBinaryField    r@   Zauto_nowFZauto_now_addZDateTimeFieldZ	DateFieldZ	TimeField)has_defaultget_defaultry   blankr   rj   rw   r   nowr   datetime)r   defaultZinternal_typer   r   r   _effective_default4  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   r|   L  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   rI   P  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)rt   r7   r3   rb   _model_indexes_sqlr   local_many_to_manyr'   throughauto_createdcreate_model)r1   r   r<   r=   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.r[   N)r   r   r'   r   r   delete_modelr7   sql_delete_tablerL   rd   listr3   
isinstancer   Zreferences_tableremove)r1   r   r   r<   r   r   r   r   m  s     z%BaseDatabaseSchemaEditor.delete_modelc                 C   s.   |j r| jjjsdS | j||| dd dS )zAdd an index on a model.Nr=   )contains_expressionsr+   r.   supports_expression_indexesr7   
create_sqlr1   r   indexr   r   r   	add_index}  s    z"BaseDatabaseSchemaEditor.add_indexc                 C   s*   |j r| jjjsdS | |||  dS )zRemove an index from a model.N)r   r+   r.   r   r7   
remove_sqlr   r   r   r   remove_index  s    z%BaseDatabaseSchemaEditor.remove_indexc                 C   s"   | || }|r| j|dd dS )zAdd a constraint to a model.Nr   )r   r7   r1   r   rX   r<   r   r   r   add_constraint  s    z'BaseDatabaseSchemaEditor.add_constraintc                 C   s   | || }|r| | dS )z!Remove a constraint from a model.N)r   r7   r   r   r   r   remove_constraint  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   rG   r    rr   r   r   r   	<setcomp>  s     zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   s   h | ]}t |qS r   r   r   r   r   r   r     s     r   Tc                    s   g | ]} j |qS r   rM   rO   r   r   r   rP     s     zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquer7   r]   )r1   r   Zold_unique_togetherZnew_unique_togetheroldsnewsrr   rq   r   r   r   alter_unique_together  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   rM   rO   r   r   r   rP     s     zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>_idxrr   suffixN)r   r   sql_delete_indexr7   _create_index_sql)r1   r   Zold_index_togetherZnew_index_togetherr   r   rr   rq   r   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   rW   r   r   r   r     s     zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   s   h | ]
}|j qS r   r   rW   r   r   r   r     s     c                    s   g | ]} j |jqS r   )r   rN   rf   rO   r   r   r   rP     s     zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>exclude   z1Found wrong number (%s) of constraints for %s(%s)rZ   r   )
r   rl   indexes_constraint_nameslen
ValueErrorrd   rn   r7   _delete_constraint_sql)	r1   r   rr   Zconstraint_kwargsr<   meta_constraint_namesmeta_index_namescolumns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lowerr7   sql_rename_tablerL   r3   r   r   Zrename_table_references)r1   r   Zold_db_tableZnew_db_tabler<   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.)r[   Zold_tablespaceZnew_tablespaceN)r7   sql_retablespace_tablerL   r   rd   )r1   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| ||||	rd| |	 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   NrQ   rR   rS   rV   z%s.r@   )r   	namespacerf   rT   rU   
deferrable)r[   rf   r\   dropr[   changes)%r   r'   r   r   r   r   r_   r`   r+   ra   r.   rh   rc   sql_create_column_inline_fkr   rd   rN   re   rf   r
   _fk_constraint_namerL   rK   deferrable_sqlr3   rF   ri   sql_create_columnr7   r{   r|   _alter_column_default_sqlsql_alter_columnrb   _field_indexes_sqlconnection_persists_old_columnsclose)r1   r   r   r\   r=   rs   Zconstraint_suffixrT   rU   r   _r<   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| qdS )z
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        rQ   r   NTforeign_key)r[   rf   )r   r'   r   r   r   r   r`   r+   r   rf   r7   _delete_fk_sqlsql_delete_columnrL   rd   r.   r   r   r   r3   r   r   Zreferences_columnr   )r1   r   r   fk_namesfk_namer<   r   r   r   remove_field$  s$    



z%BaseDatabaseSchemaEditor.remove_fieldc           	   
   C   s6  |  ||sdS |j| jd}|d }|j| jd}|d }|dkrN|jdks`|dkrr|jdkrrt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sd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.
        NrQ   r   zqCannot alter field %s into %s - they do not properly define db_type (are you using a badly-written custom field?)zCannot 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))
_field_should_be_alteredr`   r+   r'   r   r   r   r   _alter_many_to_many_alter_field)	r1   r   r"   r$   strictold_db_paramsold_typenew_db_paramsnew_typer   r   r   alter_fieldB  s^    



  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}|rt|dkrt	d	t||j
j|jf |D ]}| | || q| jjjoF|jr0|js@|joF|joF||k}|rt||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 rd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 qg }g }g }t"|dd}t"|dd}||kr:| #||||}|$| n2||krl| %||||\}}|$| |&| d}|j'r|j's| (|}| (|} | )|s|| kr| dk	rd}|$| *||| |j'|j'kr| +|||}|r|$| |, o|j'o|j' }!|s|r|!s,|| }| jjj-rd|rdt.t/| \}}"d0|t1|"g fg}|D ],\}}"| | j2| 3|j
j|d |" qh|!r| | j4| 3|j
j| 3|jdd | g |D ],\}}"| | j2| 3|j
j|d |" q|r|D ]\}}"| ||" q|jr:|js:| 5|| | 6||r\| | 7||g |jrl|jr|jr|js| | j8||gd g }#|r|#&t|| | ||r| | 9|| |#&t|| |#D ]\}$}|jj:| jd}%|%d }&| %|j|$j|j|&\}}| | j2| 3|jj
j|d d |d  |D ]\}}"| ||" qJq| jjjr|jr|	s|jr|js|jr| | ;||d |r|#D ],\}'}(|(jjr| | ;|(j|(jd q|d |d kr0|d r0| j<|j
j|jgdd}| | =|||d  |rr| j*|||dd\})}"| j2| 3|j
j|)d }| ||" | jjj>r| 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   rW   r   r   r   r     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   rR   c                 S   s   h | ]
}|j qS r   r   rW   r   r   r   r     s     )rR   r   z6Found wrong number (%s) of check constraints for %s.%sru   NrZ   r   r   )r[   rf   r   rr   rQ   r   r   rV   Z_fk_checkr   r   )@setr+   r.   rh   r'   rc   r   rf   r   r   r   rd   addr7   r   r   _field_became_primary_keyrl   _delete_unique_sqlr   r&   Zrelated_modelr   db_indexr   r   r   _delete_index_sql_delete_check_sql_rename_field_sqlr3   r   r   Zrename_column_referencesrw   _alter_column_collation_sqlrF   _alter_column_type_sqlrb   ry   r|   r{   r   _alter_column_null_sqlr   Zsupports_combined_altersrG   r%   rn   sumr   rL   sql_update_with_default_delete_primary_key_unique_should_be_addedr]   r   _create_primary_key_sqlr`   ri   _create_index_name_create_check_sqlr   r   )*r1   r   r"   r$   r   r   r   r   r   Zfks_droppedr   r   r   r   constraint_nameZdrop_foreign_keysZ_old_relr)   Zrel_fk_namesr   Zindex_names
index_namer<   actionsZnull_actionsZpost_actionsZold_collationnew_collationfragmentZother_actionsZneeds_database_defaultZold_defaultnew_defaultZfour_way_default_alterationr=   Zrels_to_updater(   Zrel_db_paramsZrel_typer   relr   r   r   r   r   m  s              











    
z%BaseDatabaseSchemaEditor._alter_fieldc                 C   sV   | j jjr|jrdS |j| j d}|jr.| 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.
        NrQ   r   rf   r   )
r+   r.   r   r   r`   ry   sql_alter_column_nullsql_alter_column_not_nullrL   rf   )r1   r   r"   r$   r   r<   r   r   r   r   l  s    
z/BaseDatabaseSchemaEditor._alter_column_null_sqlc           
      C   s   |  |}| |}|g}|r$g }n| jjjr<| |}g }|j| jd}|rd|jr\| j}	qj| 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.
        rQ   r   )rf   r   r   )r|   r}   r+   r.   r~   r   r`   ry    sql_alter_column_no_default_nullsql_alter_column_no_defaultsql_alter_column_defaultrL   rf   )
r1   r   r"   r$   r   r  r   r=   r   r<   r   r   r   r     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_typerL   rf   )r1   r   r"   r$   r   r   r   r   r     s    
z/BaseDatabaseSchemaEditor._alter_column_type_sqlc                 C   s0   | j | |j||r"d| | ndd g fS )NrS   r@   )rf   r   r   )sql_alter_column_collaterL   rf   rx   )r1   r   r$   r   r	  r   r   r   r     s    
z4BaseDatabaseSchemaEditor._alter_column_collation_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   rd   r   r   rN   Zm2m_reverse_field_nameZm2m_field_name)r1   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  rd|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+   rK   Zmax_name_lengthrn   r   isdigit)	r1   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   rS   r@   )r   ro   r   r+   rK   rp   )r1   r   rr   ro   r   r   r   _get_index_tablespace_sql  s    z2BaseDatabaseSchemaEditor._get_index_tablespace_sqlc                 C   s   |rd| S dS )Nz WHERE r@   r   )r1   	conditionr   r   r   _index_condition_sql  s    z-BaseDatabaseSchemaEditor._index_condition_sqlc                 C   s,   |r| j jjsdS tdt|jj|| jdS )Nr@   z INCLUDE (%(columns)s))r   )r+   r.   supports_covering_indexesr   r   r   rd   rL   )r1   r   r   r   r   r   _index_include_sql	  s    z+BaseDatabaseSchemaEditor._index_include_sql)rr   r   r   usingro   col_suffixesr<   	opclassesr  includeexpressionsc                   s   |pg }|pg }t |ddjjd}j|||d}dd |D }|pLj}|jj} fdd}t|t|j	t
||||||r||||	nt|||j||
||d	S )
z
        Return the SQL statement to create the index for one or several fields
        or expressions. `sql` can be specified if the syntax differs from the
        standard (GIS indexes, ...).
        FZ
alias_colsrQ   )ro   c                 S   s   g | ]
}|j qS r   rf   rO   r   r   r   rP     s     z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s    d krj | |  S r   )r  rL   argskwargsr   r1   r   r   create_index_name#  s    zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)r[   r   r#  r   r>   r  r&  )r   get_compilerr+   r  sql_create_indexr   rd   r   r   rL   r   _index_columnsr   rI   r   r"  )r1   r   rr   r   r   r#  ro   r$  r<   r%  r  r&  r'  compilerrp   r   r0  r[   r.  r   r-  r   r     s,    


z*BaseDatabaseSchemaEditor._create_index_sqlc                 C   s&   t |p
| jt|jj| j| |dS N)r[   r   )r   r   r   r   rd   rL   )r1   r   r   r<   r   r   r   r   8  s
    z*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s   t ||| j|dS )N)r$  )r   rL   )r1   r[   r   r$  r%  r   r   r   r1  ?  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 ]&}|jr| jjjr~|| |  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   rM   rO   r   r   r   rP   N  s     z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   r   )r   ZmanagedproxyZswappedr^   rb   r   Zindex_togetherrF   r   r   r   r+   r.   r   r   )r1   r   outputr   rq   rr   r   r   r   r   r   B  s    z+BaseDatabaseSchemaEditor._model_indexes_sqlc                 C   s*   g }|  ||r&|| j||gd |S )zT
        Return a list of all index SQL statements for the specified field.
        r   )_field_should_be_indexedrF   r   )r1   r   r   r5  r   r   r   r   Y  s    z+BaseDatabaseSchemaEditor._field_indexes_sqlc                 C   s   |  \}}}}|  \}}}}	ddddddddd	d
dg}
|
D ]}||d  |	|d  q>| |j| |jkp|||f|||	fkS )Nr   Z	db_columneditableZerror_messages	help_textZlimit_choices_toZ	on_deleteZrelated_nameZrelated_query_nameZ
validatorsZverbose_name)ZdeconstructpoprL   rf   )r1   r"   r$   r   old_pathZold_argsZ
old_kwargsnew_pathnew_argsZ
new_kwargsZnon_database_attrsattrr   r   r   r   b  s(    z1BaseDatabaseSchemaEditor._field_should_be_alteredc                 C   s   |j o|j S r   )r   r   r1   r   r   r   r   r   r6    s    z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r   r   r1   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)r[   Z
old_columnZ
new_columnr   )sql_rename_columnrL   rf   )r1   r[   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)r[   r   rf   rT   rU   r   )r   r   rd   rL   r   r   rf   target_fieldr   r+   rK   r   r   sql_create_fk)
r1   r   r   r   r[   r   rf   rT   rU   r   r   r   r   ri     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   rL   r  r*  r6   r   r   create_fk_name  s    zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer   )r   r   rd   rf   r
   rB  r   )r1   r   r   r   rE  r   r6   r   r     s    z,BaseDatabaseSchemaEditor._fk_constraint_namec                 C   s   |  | j||S r   )r   sql_delete_fkr1   r   r   r   r   r   r     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)r1   r   r   r   r   _deferrable_constraint_sql  s    

z3BaseDatabaseSchemaEditor._deferrable_constraint_sqlc	              	      s   |r j jjsd S |s"|s"|s"|rN j|||||||d}	|	rJ j|	 d S  jd fdd|D  |d }
 j	 
||
d S )N)r   r  r&  r%  r'  rZ   c                    s   g | ]}  |jqS r   )rL   rf   rO   r6   r   r   rP     s     z8BaseDatabaseSchemaEditor._unique_sql.<locals>.<listcomp>)r   r   r   rX   )r+   r.   &supports_deferrable_unique_constraintsr]   r3   rF   sql_unique_constraintrn   rH  sql_constraintrL   )r1   r   rr   r   r  r   r&  r%  r'  r<   rX   r   r6   r   _unique_sql  s4    	z$BaseDatabaseSchemaEditor._unique_sqlc	                    s  |r j jjr8|r j jjr8|r* j jjr8|r< j jjs<d S  fdd}	t|ddj j d}
|jj	}dd |D }|d krt
||d|	}n
 |}|s|s|s|r j}n j}|r̈ j||d	|d
}nt|||
 j}t|t| j|| | | ||dS )Nc                     s      j| |S r   rD  r*  r6   r   r   create_unique_name  s    zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_nameFr(  rQ   c                 S   s   g | ]
}|j qS r   r)  rO   r   r   r   rP     s     z?BaseDatabaseSchemaEditor._create_unique_sql.<locals>.<listcomp>_uniqr   )r$  r%  )r[   r   r   r  r   r&  )r+   r.   rJ  supports_partial_indexesr!  r   r   r/  r   rd   r   rL   sql_create_unique_indexsql_create_uniquer1  r   rI   r   r   r   rH  r"  )r1   r   rr   r   r  r   r&  r%  r'  rN  r2  r[   r   r<   r   r6   r   r]     sN    	


z+BaseDatabaseSchemaEditor._create_unique_sqlc           	      C   sh   |r| j jjr8|r| j jjr8|r*| j jjr8|r<| j jjs<d S |sL|sL|sL|rT| j}n| j}| |||S r   )	r+   r.   rJ  rP  r!  r   r   r   r   )	r1   r   r   r  r   r&  r%  r'  r<   r   r   r   r     s*    
z+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j | || jd|i d S )NrR   rI  )rL  rL   ra   )r1   r   rR   r   r   r   
_check_sql  s    z#BaseDatabaseSchemaEditor._check_sqlc                 C   s$   t | jt|jj| j| ||dS )N)r[   r   rR   )r   sql_create_checkr   r   rd   rL   )r1   r   r   rR   r   r   r   r  "  s    z*BaseDatabaseSchemaEditor._create_check_sqlc                 C   s   |  | j||S r   )r   sql_delete_checkrG  r   r   r   r   *  s    z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| j| |dS r3  )r   r   r   rd   rL   )r1   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rqP|dk	r|d |krqP|dk	r|d |krqP|dk	r|d |krqP|dk	r|d	 sqP|dk	r|d
 |krqP|	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   r6   r   r   rP   9  s   z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r   r   r   r   rR   r   r   )r+   rJ   rW  Zget_constraintsr   rd   itemsrF   )r1   r   r  r   r   r   r   rR   r   r   rJ   rl   resultr   Zinfodictr   r6   r   r   4  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   rd   r7   _delete_primary_key_sql)r1   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   )r[   r   r   )	r   sql_create_pkr   r   rd   rL   r  rf   r   r>  r   r   r   r  \  s    z0BaseDatabaseSchemaEditor._create_primary_key_sqlc                 C   s   |  | j||S r   )r   sql_delete_pkrG  r   r   r   rZ  f  s    z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc                 C   s   d|  | S )NzCOLLATE )rL   )r1   r   r   r   r   rx   i  s    z%BaseDatabaseSchemaEditor._collate_sqlc                 C   s*   | j | |d|d }| | d S )N,)Z	procedureparam_types)sql_delete_procedurerL   rn   r7   )r1   Zprocedure_namer^  r<   r   r   r   remove_procedurel  s
    z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)F)F)F)r@   )N)N)NNNNN)NNNNNN)NNNNN)NNNNNNNN)F)r   )i__name__
__module____qualname____doc__rm   r   r   r   r   r   r  r  r  r  r  r  r  r   rA  r   rK  ra   Zsql_delete_constraintrL  rT  rU  rR  r   rC  rg   r   rF  r0  rQ  r   r[  r\  r_  r2   r5   r8   r7   rL   rt   r   r_   rz   r{   r   r}   staticmethodr   r|   rI   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   r1  r   r   r   r6  r   r  r   ri   r   r   rH  rM  r]   r   rS  r  r   r   r   r  r  rZ  rx   r`  r   r   r   r   r*   3   s  
		
;.
	
	9
, 
  
%



     '
		        
"          
,        
           



r*   )loggingr   Z!django.db.backends.ddl_referencesr   r   r   r   r   r   Zdjango.db.backends.utilsr	   r
   Zdjango.db.modelsr   r   Zdjango.db.models.sqlr   Zdjango.db.transactionr   r   Zdjango.utilsr   	getLoggerrB   r   r   r&   r*   r   r   r   r   <module>   s    
