3
v^                 @   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 d dlmZmZ d dlmZ e j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)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_key	to_fieldsname)relationZaltered_fieldr    r   B/usr/lib/python3.6/site-packages/django/db/backends/base/schema.py_is_relevant_relation   s    r   c             C   s   | j jddddS )NFT)forwardreverseinclude_hidden)_meta_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 )N)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#ddd Z$d!d" Z%d#d$ Z&f fd%d&Z'd'd( Z(d)d* Z)dd+d,Z*d-d. Z+d/d0 Z,d1d2 Z-e.d3d4 Z/d5d6 Z0d7d8 Z1d9d: Z2d;d< Z3d=d> Z4d?d@ Z5dAdB Z6dCdD Z7dEdF Z8dGdH Z9dIdJ Z:dKdL Z;dMdN Z<dOdP Z=dQdR Z>ddSdTZ?ddUdVZ@dWdX ZAddYdZZBd[d\ ZCd]d^ ZDdd`daZEddbdcZFdd_d_df df ddddedfZGddgdhZHdidj ZIdkdl ZJdmdn ZKdodp ZLdqdr ZMdsdt ZNdudv ZOdwdx ZPdydz ZQd{d| ZRdd}d~ZSdddZTdddZUdd ZVdd ZWdd ZXdd ZYdddZZdddZ[dd Z\dd Z]f fdd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)z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)zBALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE (%(columns)s)z|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 )N)
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j  | S )N)deferred_sqlr+   r   r&   alias	__enter__)r,   r   r   r   r0   i   s
    
z"BaseDatabaseSchemaEditor.__enter__c             C   s<   |d kr"x| j D ]}| j| qW | jr8| jj||| d S )N)r.   executer+   r   __exit__)r,   exc_type	exc_value	tracebacksqlr   r   r   r2   p   s
    z!BaseDatabaseSchemaEditor.__exit__c          
   C   s   | j  r$| jjr$| jjj r$tdt|}tjd||||dd | j r|j	drXdnd}|dk	r| j
j|tt| j| |  q| j
j||  n"| jj }|j|| W d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))paramsr6   )extra; N)r'   r&   in_atomic_blockr)   r*   r   strloggerdebugendswithr(   appendtuplemapquote_valuecursorr1   )r,   r6   r7   endingrD   r   r   r   r1   y   s    "z BaseDatabaseSchemaEditor.executec             C   s   | j jj|S )N)r&   ops
quote_name)r,   r   r   r   r   rG      s    z#BaseDatabaseSchemaEditor.quote_namec                s  x6 j jD ]*} fdd|D }jjj | q
W g }g }xH j jD ]:}j |\}}|dkrlqL|jjd}	|	d r|dj	|	  7 }|j
jd}
|
r|d|
 7 }|j| |jo|jr<|jjj j}|jjj j|jjj}jr|djj|j|d  7 }n"jjjr<jjj |d	 |jd
j|j|f  |j dkrLjjj j j|j}|rLjj| qLW  fdd j jD }jj j jdjdd ||D d } j jr jjj j j}|r |d| 7 }||fS )z-Take a model and return its table definition.c                s   g | ]} j j|jqS r   )r   	get_fieldcolumn)r   r   )r   r   r   
<listcomp>   s    z6BaseDatabaseSchemaEditor.table_sql.<locals>.<listcomp>N)r&   check z %s)to_table	to_columnz_fk_%(to_table)s_%(to_column)sz%s %s	AutoFieldBigAutoFieldSmallAutoFieldc                s   g | ]}|j  qS r   )constraint_sql)r   
constraint)r   r,   r   r   rJ      s    z, c             s   s   | ]}|r|V  qd S )Nr   )r   rS   r   r   r   r!      s    z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>)table
definition)rO   rP   rQ   ) r   unique_togetherr.   r@   _create_unique_sqllocal_fields
column_sqldb_parametersr&   sql_check_constraintdb_type_suffixextendremote_fielddb_constraintr   db_tablerH   
field_namerI   sql_create_inline_fkrG   r)   supports_foreign_keys_create_fk_sqlget_internal_typerF   autoinc_sqlconstraintssql_create_tablejoindb_tablespacetablespace_sql)r,   r   fieldscolumnsZcolumn_sqlsr7   r   rU   extra_params	db_paramsZcol_type_suffixrM   rN   rf   rg   r6   rk   r   )r   r,   r   	table_sql   sR    



z"BaseDatabaseSchemaEditor.table_sqlc             C   s<  |j | jd}|d }g }|dkr&dS |j}|o:| j| }|r| j|}d| j| }	|dk	r| jjjr~||	| j| 7 }n||	7 }||g7 }|j	r|j
 r| jjjrd}|r| jjj r|d7 }n|s|d7 }|j
r|d7 }n|jr|d	7 }|j p|jj}
|
r4| jjjr4|jr4|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.
        )r&   typeNz	 DEFAULT Tz NULLz	 NOT NULLz PRIMARY KEYz UNIQUEz %s)inline)NN)rZ   r&   nullskip_defaulteffective_default_column_default_sqlr)   requires_literal_defaultsprepare_defaultempty_strings_allowedr   !interprets_empty_strings_as_nullsimplied_column_nulluniquerj   r   supports_tablespacesrF   rk   )r,   r   r   include_defaultro   r6   r7   rs   default_valueZcolumn_default
tablespacer   r   r   rY      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
        zsubclasses 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.
        z%sr   )r,   r   r   r   r   rv     s    z,BaseDatabaseSchemaEditor._column_default_sqlc             C   s   | j  r| j }n| j rB| jrB| jrB| j dkr:t }qt }nbt| ddsZt| ddrt	j
 }| j }|dkr||j }q|dkr|j }q|dkrtj
 }nd }|S )NBinaryFieldauto_nowFauto_now_add	DateField	TimeFieldDateTimeField)has_defaultget_defaultrs   blankry   re   bytesr<   getattrr   nowdatetimer   )r   defaultinternal_typer   r   r   _effective_default  s"    



z+BaseDatabaseSchemaEditor._effective_defaultc             C   s   |j | j|| jS )z2Return a field's effective database default value.)get_db_prep_saver   r&   )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).
        N)r   )r,   r   r   r   r   rC   1  s    z$BaseDatabaseSchemaEditor.quote_valuec             C   s`   | j |\}}| j||pd | jj| j| x*|jjD ]}|jjjj	r:| j
|jj q:W dS )zr
        Create a table and any accompanying indexes or unique constraints for
        the given `model`.
        N)rp   r1   r.   r]   _model_indexes_sqlr   local_many_to_manyr^   throughauto_createdcreate_model)r,   r   r6   r7   r   r   r   r   r   =  s    z%BaseDatabaseSchemaEditor.create_modelc             C   s   x*|j jD ]}|jjj jr
| j|jj q
W | j| jd| j|j j	i  x6t
| jD ](}t|trV|j|j j	rV| jj| qVW dS )z!Delete a model from the database.rT   N)r   r   r^   r   r   delete_modelr1   sql_delete_tablerG   r`   listr.   
isinstancer   references_tableremove)r,   r   r   r6   r   r   r   r   N  s    z%BaseDatabaseSchemaEditor.delete_modelc             C   s   | j |j|| dd dS )zAdd an index on a model.N)r7   )r1   
create_sql)r,   r   indexr   r   r   	add_index^  s    z"BaseDatabaseSchemaEditor.add_indexc             C   s   | j |j||  dS )zRemove an index from a model.N)r1   
remove_sql)r,   r   r   r   r   r   remove_indexb  s    z%BaseDatabaseSchemaEditor.remove_indexc             C   s   |j || }|r| j| dS )zAdd a constraint to a model.N)r   r1   )r,   r   rS   r6   r   r   r   add_constraintf  s    z'BaseDatabaseSchemaEditor.add_constraintc             C   s   |j || }|r| j| dS )z!Remove a constraint from a model.N)r   r1   )r,   r   rS   r6   r   r   r   remove_constraintl  s    z*BaseDatabaseSchemaEditor.remove_constraintc                s   dd |D }dd |D }x(|j |D ]}| j |ddi| j q(W x6|j |D ](} fdd|D }| j| j | qRW d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   rl   r   r   r   	<setcomp>x  s    zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c             S   s   h | ]}t |qS r   )rA   )r   rl   r   r   r   r   y  s    r|   Tc                s   g | ]} j j|jqS r   )r   rH   rI   )r   r   )r   r   r   rJ     s    zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquer1   rW   )r,   r   Zold_unique_togetherZnew_unique_togetheroldsnewsrl   rm   r   )r   r   alter_unique_togetherr  s    z.BaseDatabaseSchemaEditor.alter_unique_togetherc                s   dd |D }dd |D }x(|j |D ]}| j |ddi| j q(W x:|j |D ],} fdd|D }| j| j |dd	 qRW d
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   )rA   )r   rl   r   r   r   r     s    z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c             S   s   h | ]}t |qS r   )rA   )r   rl   r   r   r   r     s    r   Tc                s   g | ]} j j|qS r   )r   rH   )r   r   )r   r   r   rJ     s    zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>_idx)suffixN)r   r   sql_delete_indexr1   _create_index_sql)r,   r   Zold_index_togetherZnew_index_togetherr   r   rl   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	j|f | j| j	| |d
  d S )Nc             S   s   h | ]
}|j qS r   )r   )r   rS   r   r   r   r     s    zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c             S   s   h | ]
}|j qS r   )r   )r   rS   r   r   r   r     s    c                s   g | ]} j j|jqS r   )r   rH   rI   )r   r   )r   r   r   rJ     s    zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>exclude   z1Found wrong number (%s) of constraints for %s(%s)z, r   )
r   rg   indexes_constraint_nameslen
ValueErrorr`   ri   r1   _delete_constraint_sql)	r,   r   rl   Zconstraint_kwargsr6   meta_constraint_namesmeta_index_namesrm   constraint_namesr   )r   r   r     s    z/BaseDatabaseSchemaEditor._delete_composed_indexc             C   sr   ||ks"| j jjr&|j |j kr&dS | j| j| j|| j|d  x$| jD ]}t|t	rP|j
|| qPW dS )z#Rename the table a model points to.N)Z	old_tableZ	new_table)r&   r)   ignores_table_name_caselowerr1   sql_rename_tablerG   r.   r   r   Zrename_table_references)r,   r   old_db_tablenew_db_tabler6   r   r   r   alter_db_table  s    

z'BaseDatabaseSchemaEditor.alter_db_tablec             C   s2   | j | j| j|jj| j|| j|d  dS )z)Move a model's table between tablespaces.)rT   Zold_tablespaceZnew_tablespaceN)r1   sql_retablespace_tablerG   r   r`   )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jS | j||dd\}}|dkr@dS |j| jd}|d rh|d| j	|  7 }|jo|| jj
jo||jrd}| jr|jjjj}|jjjj|jjj}|d| j| j|||| j|j| j|| j|| jjj d  7 }n| jj| j||| | j| j|jj| j|j|d	 }	| j|	| | j| r| j|dk	r| j|d|dd
\}
}| j| j|jj|
d }	| j|	| | jj | j!|| | jj
j"r| j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~   N)r&   rK   rL   z_fk_%(to_table)s_%(to_column)s)r   rI   rM   rN   
deferrable)rT   rI   rU   )drop)rT   changes)$r   r^   r   r   r   r   rY   rZ   r&   r[   r)   rc   r_   sql_create_column_inline_fkr   r`   rH   ra   rI   _fk_constraint_namerG   rF   deferrable_sqlr.   r@   rd   sql_create_columnr1   rt   ru   _alter_column_default_sqlsql_alter_columnr]   _field_indexes_sqlconnection_persists_old_columnsclose)r,   r   r   rU   r7   ro   Zconstraint_suffixrM   rN   r6   changes_sqlr   r   r   	add_field  sD    



z"BaseDatabaseSchemaEditor.add_fieldc             C   s   |j r |jjjjr | j|jjS |j| jdd dkr:dS |jrt| j||j	gdd}x|D ]}| j
| j|| qZW | j| j|jj| j|j	d }| j
| | jjjr| jj  x:t| jD ],}t|tr|j|jj|j	r| jj| qW dS )z
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        )r&   rq   NT)foreign_key)rT   rI   )r   r^   r   r   r   r   rZ   r&   r   rI   r1   _delete_fk_sqlsql_delete_columnrG   r`   r)   r   r   r   r.   r   r   Zreferences_columnr   )r,   r   r   fk_namesfk_namer6   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| j||||S |dkr|dkr|jjr|jjr|jjjj r|jjjj rdS |dkp|dkrtd||f | j|||||||| 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.
        )r&   rq   NzqCannot 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))	rZ   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  s2    	z$BaseDatabaseSchemaEditor.alter_fieldc	       '      C   s|  t  }	|jr|jr| j||jgdd}
|rRt|
dkrRtdt|
|jj|jf x,|
D ]$}|	j	|jf | j
| j|| qXW |jo|j s| j||rdd |jjD }| j||jgdd|d}|rt|dkrtd	t||jj|jf x|D ]}| j
| j|| qW |jr"|js2|jo8|jo8||k}|rxTt||D ]F\}}| j|j|jjgdd}x"|D ]}| j
| j|j| qrW qLW |jr|j r|j s|jrd
d |jjD }| j||jgdtj|d}x |D ]}| j
| j|| qW |d |d kr|d rdd |jjD }| j||jgd|d}|r|t|dkr|tdt||jj|jf x |D ]}| j
| j|| qW |j|jkr| j
| j|jj||| x2| jD ](}t|tr|j|jj|j|j qW g }g }g }||kr8| j||||\}}|j | |j!| | j"|}| j"|}|j#o||j# o|||ko||dk	o|| j$| }|r|j | j%||| |j#|j#kr| j&|||}|r|j | |j' o|j#o|j# }|s|r|s|| }| j(j)j*r0|r0t+t,| \}} dj-|t.| g fg}x4|D ],\}} | j
| j/| j0|jj|d |  q6W |r| j
| j1| j0|jj| j0|jdd |g x4|D ],\}} | j
| j/| j0|jj|d |  qW |rx|D ]\}} | j
||  qW |jr|j r| j2|| | j3||r8| j
| j4||jg |j sJ|jrp|jrp|j rp| j
| j5||g g }!|r|!j!t|| | j||r| j
| j6|| |!j!t|| x|!D ]\}"}|jj7| j(d}#|#d }$| j|j|"j|j|$\}}| j
| j/| j0|jjj|d d |d  x|D ]\}} | j
||  q,W qW |jr|	sn|j sn|j r|jr| j
| j8||d |rxB|j9jj:D ]4}%t;|%|r|%jjr| j
| j8|%j|%jd qW |d |d kr |d r | j<|jj|jgdd}| j
| j=|||d  |rb| j%|||dd\}&} | j/| j0|jj|&d }| j
||  | j(j)j>rx| j(j?  dS )z3Perform a "physical" (non-ManyToMany) field update.T)r   r   z<Found wrong number (%s) of foreign key constraints for %s.%sc             S   s   h | ]
}|j qS r   )r   )r   rS   r   r   r   r   J  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   t  s    )r   type_r   rK   c             S   s   h | ]
}|j qS r   )r   )r   rS   r   r   r   r     s    )rK   r   z6Found wrong number (%s) of check constraints for %s.%sNz, )rT   r   z%s)rT   rI   r   )r&   rq   r   z_fk_%(to_table)s_%(to_column)sZ_fk_check)r   )r   )@setr^   r_   r   rI   r   r   r   r`   addr1   r   r|   _field_became_primary_keyrg   _delete_unique_sqlr   r$   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]   ru   rs   rt   r   _alter_column_null_sqlr   r&   r)   supports_combined_altersrA   r#   ri   sumr   rG   sql_update_with_default_delete_primary_key_unique_should_be_addedrW   r   _create_primary_key_sqlrZ   rd   r   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_namer6   actionsZnull_actionsZpost_actionsfragmentZother_actionsZold_defaultnew_defaultZneeds_database_defaultZfour_way_default_alterationr7   Zrels_to_updateZold_relZrel_db_paramsZrel_typerelr   r   r   r   r   7  s*   


 $














$

z%BaseDatabaseSchemaEditor._alter_fieldc             C   s\   | j jjr|j dkrdS |j| j d}|jr4| jn| j}|| 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.
        	CharField	TextFieldN)r&   rq   )rI   rq   )r   r   )
r&   r)   rz   re   rZ   rs   sql_alter_column_nullsql_alter_column_not_nullrG   rI   )r,   r   r    r"   r   r6   r   r   r   r   +  s    

z/BaseDatabaseSchemaEditor._alter_column_null_sqlc       
      C   sz   | j |}| j|}|g}|r$g }n| jjjr<| j|}g }|j| jd}|rT| jn| j}	|	| 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.
        )r&   rq   )rI   rq   r   )ru   rv   r&   r)   rw   rx   rZ   sql_alter_column_no_defaultsql_alter_column_defaultrG   rI   )
r,   r   r    r"   r   r   r   r7   r   r6   r   r   r   r   A  s    




z2BaseDatabaseSchemaEditor._alter_column_default_sqlc             C   s    | j | 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.
        )rI   rq   )sql_alter_column_typerG   rI   )r,   r   r    r"   r   r   r   r   r   `  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 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   r`   r   r   rH   m2m_reverse_field_namem2m_field_name)r,   r   r    r"   r   r   r   r   r   u  s    z,BaseDatabaseSchemaEditor._alter_many_to_manyr:   c       	      C   s   t |\}}dt|f|ddi|f }| jjj p6d}d|dj||f }t||kr\|S t||d kr||d|d  }|t| d	 d
 }d|d| dj|d| |f }|d dks|d j 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_%s_   N   r   r   zD%s)r	   r   r&   rF   max_name_lengthri   r   isdigit)	r,   
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j| S dS )Nr   r   rL   r:   )r   rj   r   r&   rF   rk   )r,   r   rl   rj   r   r   r   _get_index_tablespace_sql  s    z2BaseDatabaseSchemaEditor._get_index_tablespace_sql)r   r   usingrj   col_suffixesr6   	opclasses	conditionc         
      s~   j |||d}dd |D }|p&j}|jj} fdd}t|t|jt|||||j||||	||
rvd|
 nd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, ...).
        )rj   c             S   s   g | ]
}|j qS r   )rI   )r   r   r   r   r   rJ     s    z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                 s    d krj | | j S )N)r   rG   )argskwargs)r   r,   r   r   create_index_name  s    zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_namez WHERE r:   )rT   r   r  rm   r8   r  )	r  sql_create_indexr   r`   r   r   rG   r   _index_columns)r,   r   rl   r   r   r  rj   r  r6   r  r  rk   rm   r  rT   r  r   )r   r,   r   r     s    

z*BaseDatabaseSchemaEditor._create_index_sqlc             C   s&   t |p
| jt|jj| j| j|dS )N)rT   r   )r   r   r   r   r`   rG   )r,   r   r   r6   r   r   r   r     s    z*BaseDatabaseSchemaEditor._delete_index_sqlc             C   s   t ||| j|dS )N)r  )r   rG   )r,   rT   rm   r  r  r   r   r   r    s    z'BaseDatabaseSchemaEditor._index_columnsc                s    j j s j js j jrg S g }x" j jD ]}|j| j | q,W x8 j jD ],} fdd|D }|j| j	 |dd qPW x" j j
D ]}|j|j |  qW |S )z
        Return a list of all index SQL statements (field indexes,
        index_together, Meta.indexes) for the specified model.
        c                s   g | ]} j j|qS r   )r   rH   )r   r   )r   r   r   rJ     s    z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   )r   )r   managedproxyswappedrX   r]   r   index_togetherr@   r   r   r   )r,   r   outputr   r   rl   r   r   )r   r   r     s    z+BaseDatabaseSchemaEditor._model_indexes_sqlc             C   s(   g }| j ||r$|j| j||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 )N)r   r|   )r,   r   r   r   r   r   r"    s    z1BaseDatabaseSchemaEditor._field_should_be_indexedc             C   s   |j  o|j S )N)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 )N)r|   r   )r,   r    r"   r   r   r   r     s    z0BaseDatabaseSchemaEditor._unique_should_be_addedc             C   s*   | j | j|| j|j| j|j|d S )N)rT   Z
old_columnZ
new_columnrq   )sql_rename_columnrG   rI   )r,   rT   r    r"   r   r   r   r   r     s
    

z*BaseDatabaseSchemaEditor._rename_field_sqlc       
   	   C   s   t |j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
j }	t| j||||||	dS )N)rT   r   rI   rM   rN   r   )r   r   r`   rG   r   r   rI   target_fieldr   r&   rF   r   r   sql_create_fk)
r,   r   r   r   rT   r   rI   rM   rN   r   r   r   r   rd     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  j| |S )N)rG   r   )r  r  )r,   r   r   create_fk_name  s    zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer   )r   r   r`   rI   r	   r$  r   )r,   r   r   r   r&  r   )r,   r   r     s    z,BaseDatabaseSchemaEditor._fk_constraint_namec             C   s   | j | j||S )N)r   sql_delete_fk)r,   r   r   r   r   r   r   %  s    z'BaseDatabaseSchemaEditor._delete_fk_sqlc             C   s\   |r*| j ||||d}|r&| jj| d S | jddjt| j|i }| j| j||d S )N)r   r  rm   z, )r   rS   )rW   r.   r@   sql_unique_constraintri   rB   rG   sql_constraint)r,   r   rl   r   r  r6   rS   r   r   r   _unique_sql(  s    z$BaseDatabaseSchemaEditor._unique_sqlc                s    fdd}t |jj j}|d kr8t|jj|d|}n
 j|}t|| j}|rz jjjrvt	 j
|||d| dS d S t	 j|||dS d S )Nc                 s    j  j| |S )N)rG   r   )r  r  )r,   r   r   create_unique_name9  s    zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_nameZ_uniqz WHERE )rT   r   rm   r  )rT   r   rm   )r   r   r`   rG   r   r   r&   r)   supports_partial_indexesr   sql_create_unique_indexsql_create_unique)r,   r   rm   r   r  r+  rT   r   )r,   r   rW   8  s    
&z+BaseDatabaseSchemaEditor._create_unique_sqlc             C   s2   |r"| j jjr| j| j||S d S | j| j||S )N)r&   r)   r,  r   r   r   )r,   r   r   r  r   r   r   r   R  s    z+BaseDatabaseSchemaEditor._delete_unique_sqlc             C   s    | j | j|| jd|i d S )NrK   )r   rS   )r)  rG   r[   )r,   r   rK   r   r   r   
_check_sqlZ  s    z#BaseDatabaseSchemaEditor._check_sqlc             C   s$   t | jt|jj| j| j||dS )N)rT   r   rK   )r   sql_create_checkr   r   r`   rG   )r,   r   r   rK   r   r   r   r   `  s
    z*BaseDatabaseSchemaEditor._create_check_sqlc             C   s   | j | j||S )N)r   sql_delete_check)r,   r   r   r   r   r   r   h  s    z*BaseDatabaseSchemaEditor._delete_check_sqlc             C   s    t |t|jj| j| j|dS )N)rT   r   )r   r   r   r`   rG   )r,   templater   r   r   r   r   r   k  s    z/BaseDatabaseSchemaEditor._delete_constraint_sqlc
                s  |dk	r fdd|D } j j }
 j jj|
|jj}W dQ R X g }x|j D ]\}}|dksn||d krR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d |krqR|dk	r|d	  rqR|dk	r|d
 |krqR|	 p||	krR|j| qRW |S )z@Return all constraint names matching the columns and conditions.Nc                s   g | ]} j jj|qS r   )r&   introspectionidentifier_converter)r   r   )r,   r   r   rJ   x  s   z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>rm   r|   r   r   rK   r   rq   )r&   rD   r3  get_constraintsr   r`   itemsr@   )r,   r   r  r|   r   r   r   rK   r   r   rD   rg   resultr   Zinfodictr   )r,   r   r   r  s.    
z*BaseDatabaseSchemaEditor._constraint_namesc             C   sZ   | j |dd}|r6t|dkr6tdt||jjf x|D ]}| j| j|| q<W d S )NT)r   r   z0Found wrong number (%s) of PK constraints for %s)r   r   r   r   r`   r1   _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|jgddt|jj|jg| jdS )NZ_pk)r   )rT   r   rm   )	r   sql_create_pkr   r   r`   rG   r   rI   r   )r,   r   r   r   r   r   r     s    z0BaseDatabaseSchemaEditor._create_primary_key_sqlc             C   s   | j | j||S )N)r   sql_delete_pk)r,   r   r   r   r   r   r8    s    z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc             C   s*   | j | j|dj|d }| j| d S )N,)Z	procedureparam_types)sql_delete_procedurerG   ri   r1   )r,   Zprocedure_namer<  r6   r   r   r   remove_procedure  s    z)BaseDatabaseSchemaEditor.remove_procedure)FT)F)F)F)F)r:   )N)N)N)NN)N)NNNNNNNN)F)___name__
__module____qualname____doc__rh   r   r   r   r   r   r  r   r  r  r  r   r#  r   r(  r[   Zsql_delete_constraintr)  r0  r1  r.  r   r%  rb   r   r'  r  r-  r   r9  r:  r=  r-   r0   r2   r1   rG   rp   rY   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   rd   r   r   r*  rW   r   r/  r   r   r   r   r   r   r8  r>  r   r   r   r   r%   ,   s   
		;
1	7
*
 t




	


  


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