o
    بf                     @   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 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v 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   V/var/www/dscantool/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py_is_relevant_relation   s   r   c                    s2   t fddjjjD  fdd jjjD S )Nc                 3       | ]
}t | r|V  qd S Nr   .0obj)	old_fieldr   r   	<genexpr>#       z+_related_non_m2m_objects.<locals>.<genexpr>c                 3   r   r   r   r   )	new_fieldr   r   r   $   r   )zipmodel_metarelated_objects)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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'dd*d+Z(d,d- Z)d.d/ Z*e+d0d1 Z,d2d3 Z-d4d5 Z.d6d7 Z/d8d9 Z0d:d; Z1d<d= Z2d>d? Z3d@dA Z4dBdC Z5dDdE Z6dFdG Z7dHdI Z8dJdK Z9dLdM Z:dNdO Z;ddPdQZ<	ddRdSZ=dTdU Z>ddVdWZ?dXdY Z@dZd[ ZAdd]d^ZBdd_d`ZCdd\d\dd%dd%ddadbdcZDddde ZEdfdg ZFdhdi ZGdjdk ZHdldm ZIdndo ZJdpdq ZKdrds ZLdtdu ZMdvdw ZNddxdyZOddzd{ZPdd|d}ZQd~d ZRdd ZSdd ZTdd ZU			dddZVdddZWdd ZXdd ZYdddZZd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 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   r/   d   s
   
z"BaseDatabaseSchemaEditor.__enter__c                 C   s<   |d u r| j D ]}| | q| jr| j||| d S d S r   )r-   executer*   r   __exit__)r+   exc_type	exc_value	tracebacksqlr   r   r   r2   k   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 rL|	dr*dnd}|durB| j
|tt| j| |  dS | j
||  dS | j }||| W d   dS 1 scw   Y  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%   Zin_atomic_blockr(   r)   r   strloggerdebugendswithr'   appendtuplemapquote_valuecursorr1   )r+   r6   r7   endingrC   r   r   r   r1   t   s   $"z BaseDatabaseSchemaEditor.executec                 C   s   | j j|S r   )r%   ops
quote_name)r+   r   r   r   r   rF         z#BaseDatabaseSchemaEditor.quote_namec           
      C   s"  |j | jd}|d }g }|du rdS |j}|o| | }|rA| |}|durA| jjjr8|d| | 7 }n	|d7 }||g7 }|jrN|j	sN| jjj
rNd}|rZ| jjjsZ|d7 }n|s`|d7 }|j	rh|d	7 }n|jro|d
7 }|jpu|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.
        r%   typeNNNz DEFAULT %sTz NULLz	 NOT NULLz PRIMARY KEYz UNIQUE %s)inline)db_parametersr%   nullskip_defaulteffective_defaultr(   requires_literal_defaultsprepare_defaultempty_strings_allowedr   !interprets_empty_strings_as_nullsZimplied_column_nulluniquedb_tablespacer!   Zsupports_tablespacesrE   tablespace_sql)
r+   r    r   include_default	db_paramsr6   r7   rN   default_valueZ
tablespacer   r   r   
column_sql   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   rO      s   z%BaseDatabaseSchemaEditor.skip_defaultc                 C   s   t d)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() methodNotImplementedErrorr+   valuer   r   r   rR      s   z(BaseDatabaseSchemaEditor.prepare_defaultc                 C   s   |   r
|  }|S | js#| jr#| jr#|  dkrt }|S t }|S t| dds/t| ddrUt	
 }|  }|dkrA| }|S |dkrK| }|S |dkrSt
 }|S d }|S )NZBinaryFieldZauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeField)has_defaultget_defaultrN   blankrS   get_internal_typebytesr;   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_saverk   r%   r\   r   r   r   rP      s   z*BaseDatabaseSchemaEditor.effective_defaultc                 C   s   t  )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).
        r]   r_   r   r   r   rB      s   z$BaseDatabaseSchemaEditor.quote_valuec                    sB  g }g } j jD ]} |\}}|du rq|jjd}|d r+|dj|  7 }|jjd}|r:|d| 7 }|| |jr||j	r||jj
j j}	|jj
j |jjj}
jrl|dj|	|
d  7 }njjjr|j |d |d|j|f  | d	v rjj j j|j}|rj| q j jD ]} fd
d|D }j | q fdd j jD }j j jddd g ||R D d } j jrjj j j}|r|d| 7 } ||pd j!   j j"D ]}|jj#j j$r%|jj# qdS )zr
        Create a table and any accompanying indexes or unique constraints for
        the given `model`.
        NrH   check rK   )to_table	to_column_fk_%(to_table)s_%(to_column)sz%s %s)Z	AutoFieldZBigAutoFieldc                       g | ]	} j |jqS r   r!   	get_fieldcolumnr   r   r    r   r   
<listcomp>&      z9BaseDatabaseSchemaEditor.create_model.<locals>.<listcomp>c                    s   g | ]}|  qS r   )Zconstraint_sqlr   
constraintr    r+   r   r   rw   (      , c                 s   s    | ]}|r|V  qd S r   r   ry   r   r   r   r   ,  s    z8BaseDatabaseSchemaEditor.create_model.<locals>.<genexpr>)table
definition)&r!   local_fieldsr[   rM   r%   sql_check_constraintZdb_type_suffixextendremote_fielddb_constraintr    db_tablers   
field_namert   sql_create_inline_fkrF   r(   supports_foreign_keysr-   r?   _create_fk_sqlrd   rE   autoinc_sqlZunique_together_create_unique_sqlconstraintssql_create_tablejoinrV   rW   r1   _model_indexes_sqllocal_many_to_manythroughauto_createdcreate_model)r+   r    Zcolumn_sqlsr7   r   r   Zextra_paramsrY   Zcol_type_suffixrn   ro   r   fieldscolumnsr   r6   rW   r   r{   r   r      sf   


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r<||j j	r<| j| q(dS )z!Delete a model from the database.r~   N)r!   r   r   r   r   delete_modelr1   sql_delete_tablerF   r   listr-   
isinstancer   Zreferences_tableremove)r+   r    r   r6   r   r   r   r   =  s   z%BaseDatabaseSchemaEditor.delete_modelc                 C   s   | j ||| dd dS )zAdd an index on a model.N)r7   )r1   
create_sqlr+   r    indexr   r   r   	add_indexM  s   z"BaseDatabaseSchemaEditor.add_indexc                 C   s   |  |||  dS )zRemove an index from a model.N)r1   
remove_sqlr   r   r   r   remove_indexQ  s   z%BaseDatabaseSchemaEditor.remove_indexc                 C   "   | || }|r| | dS dS )z"Add a check constraint to a model.N)r   r1   r+   r    rz   r6   r   r   r   add_constraintU     z'BaseDatabaseSchemaEditor.add_constraintc                 C   r   )z'Remove a check constraint from a model.N)r   r1   r   r   r   r   remove_constraint[  r   z*BaseDatabaseSchemaEditor.remove_constraintc                    sz   dd |D }dd |D }| |D ]}|  |ddi| j q| |D ]} fdd|D }| |  | q&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      h | ]}t |qS r   r@   r   r   r   r   r   	<setcomp>g      zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r   h  r   rU   Tc                    rq   r   rr   ru   rv   r   r   rw   n  rx   zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquer1   r   )r+   r    Zold_unique_togetherZnew_unique_togetheroldsnewsr   r   r   rv   r   alter_unique_togethera  s   z.BaseDatabaseSchemaEditor.alter_unique_togetherc                    s~   dd |D }dd |D }| |D ]}|  |ddi| j q| |D ]} fdd|D }| | j |dd	 q&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   r   r   r   r   r   r   r   r   w  r   z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r   x  r   r   Tc                       g | ]} j |qS r   r!   rs   ru   rv   r   r   rw   ~  r|   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   r   field_namesr   rv   r   alter_index_togetherq  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      h | ]}|j qS r   r   ry   r   r   r   r         zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   r   r   r   ry   r   r   r   r     r   c                    rq   r   rr   ru   rv   r   r   rw     rx   zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>exclude   z1Found wrong number (%s) of constraints for %s(%s)r}   r   )
r!   r   indexes_constraint_nameslen
ValueErrorr   r   r1   _delete_constraint_sql)	r+   r    r   Zconstraint_kwargsr6   meta_constraint_namesmeta_index_namesr   constraint_namesr   rv   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	r4|
|| q'dS )z#Rename the table a model points to.N)Z	old_tableZ	new_table)r%   r(   Zignores_table_name_caselowerr1   sql_rename_tablerF   r-   r   r   Zrename_table_references)r+   r    Zold_db_tableZnew_db_tabler6   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)r1   sql_retablespace_tablerF   r!   r   )r+   r    Zold_db_tablespaceZnew_db_tablespacer   r   r   alter_db_tablespace  s
   z,BaseDatabaseSchemaEditor.alter_db_tablespacec                 C   sH  |j r|jjjjr| |jjS | j||dd\}}|du r dS |j| jd}|d r4|d| j	|  7 }| j
| |jj| |j|d }| || | |sv| |durv| j|d|dd\}}| j| |jj|d	 }| || | j| || |jr| jjjr|jr| j| ||d
 | jjjr| j  dS 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)rX   NrH   rl   rm   )r~   rt   r   dropr~   changesrp   )r   r   r   r!   r   r   r[   rM   r%   r   sql_create_columnrF   r   rt   r1   rO   rP   _alter_column_default_sqlsql_alter_columnr-   r   _field_indexes_sqlr(   r   r   r?   r   connection_persists_old_columnsclose)r+   r    r   r   r7   rY   r6   changes_sqlr   r   r   	add_field  s6   

z"BaseDatabaseSchemaEditor.add_fieldc                 C   s   |j r|jjjjr| |jjS |j| jdd du rdS |jr8| j||j	gdd}|D ]}| 
| || q,| j| |jj| |j	d }| 
| | jjjrX| j  t| jD ]}t|trs||jj|j	rs| j| q]dS )z
        Remove a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
        rH   rI   NTforeign_key)r~   rt   )r   r   r   r!   r   r   rM   r%   r   rt   r1   _delete_fk_sqlsql_delete_columnrF   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u r|jdu s(|du r0|jdu r0td||f |du rT|du rT|jjrT|jjrT|jjjjrT|jjjjrT| ||||S |du rr|du rr|jjrr|jjrr|jjjjsr|jjjjsrdS |du sz|du rt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.
        rH   rI   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))	rM   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  sP   	



z$BaseDatabaseSchemaEditor.alter_fieldc	           '      C   s6  t  }	|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rJ| ||rdd |jjD }| j||jgdd|d}|rut|dkrutd	t||jj|jf |D ]}| 
| || qw|jr|jp|jo|jo||k}|rt||D ]\}}| j|j|jjgdd}|D ]}| 
| |j| qq|jr|js|jr|jrd
d |jjD }| j||jgdtj|d}|D ]}| 
| || q|d |d kr3|d r3dd |jjD }| j||jgd|d}|r$t|dkr$tdt||jj|jf |D ]}| 
| || q&|j|jkr_| 
| |jj||| | jD ]}t|tr]||jj|j|j qJg }g }g }||kr~| ||||\}}| | |!| | "|}| "|}|j#o|j# o||ko|duo| $| }|r| | %||| |j#|j#kr| &|||}|r| | |' o|j#o|j# }|s|rF|s|| }| j(j)j*r|rt+t,| \}} d-|t.| g fg}|D ]\}} | 
| j/| 0|jj|d |  q|rF| 
| j1| 0|jj| 0|jdd |g |D ]\}} | 
| j/| 0|jj|d |  q/|rW|D ]\}} | 
||  qK|jre|jse| 2|| | 3||rw| 
| 4||jg |jr|jr|jr|js| 
| 5||g g }!|jr|jr||kr|!!t|| | ||r| 
| 6|| |!!t|| |!D ]B\}"}|jj7| j(d}#|#d }$| |j|"j|j|$\}}| 
| j/| 0|jjj|d d |d  |D ]\}} | 
||  qq|jr"|	s|jr|js"|jr"| 
| 8||d |rE|j9jj:D ]}%t;|%|rC|%jjrC| 
| 8|%j|%jd q*|d |d krk|d rk| j<|jj|jgdd}| 
| =|||d  |r| j%|||dd\}&} | j/| 0|jj|&d }| 
||  | j(j)j>r| j(?  dS dS )z3Perform a "physical" (non-ManyToMany) field update.Tr   r   z<Found wrong number (%s) of foreign key constraints for %s.%sc                 S   r   r   r   ry   r   r   r   r   ,  r   z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>F)rU   r   r   z7Found wrong number (%s) of unique constraints for %s.%sc                 S   r   r   r   )r   r   r   r   r   r   V  r   )r   type_r   rl   c                 S   r   r   r   ry   r   r   r   r   d  r   )rl   r   z6Found wrong number (%s) of check constraints for %s.%sNr}   r   %s)r~   rt   rj   rH   rI   r   rp   Z_fk_checkr   r   )@setr   r   r   rt   r   r   r!   r   addr1   r   rU   _field_became_primary_keyr   _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   rP   rN   rO   r   _alter_column_null_sqlra   r%   r(   Zsupports_combined_altersr@   r   r   sumr   rF   sql_update_with_default_delete_primary_key_unique_should_be_addedr   r   _create_primary_key_sqlrM   r   r    r"   r   _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     sp  












 
z%BaseDatabaseSchemaEditor._alter_fieldc                 C   sX   | j jjr| dv rdS |j| j d}|jr| jn| j}|| |j	|d d g f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	TextFieldNrH   rI   rt   rI   )
r%   r(   rT   rd   rM   rN   sql_alter_column_nullsql_alter_column_not_nullrF   rt   )r+   r    r   r   r   r6   r   r   r   r     s   

z/BaseDatabaseSchemaEditor._alter_column_null_sqlc           
      C   st   |  |}d}|g}|rg }n| jjjr| |}g }|j| jd}|r'| 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.
        r   rH   rI   )rt   rI   rj   )
rP   r%   r(   rQ   rR   rM   sql_alter_column_no_defaultsql_alter_column_defaultrF   rt   )
r+   r    r   r   r   r   rj   r7   r   r6   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_typerF   rt   )r+   r    r   r   r   r   r   r   r   B  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!   r   r   r   rs   Zm2m_reverse_field_nameZm2m_field_name)r+   r    r   r   r   r   r   r   r   W  s   
z,BaseDatabaseSchemaEditor._alter_many_to_manyr:   c           	      C   s   t |\}}dt|g|R ddi|f }| jj pd}d|d||f }t||kr/|S t||d kr?|d|d  }|t| d	 d
 }d|d| d|d| |f }|d dksg|d  rod|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%   rE   Zmax_name_lengthr   r   isdigit)	r+   Z
table_namecolumn_namesr   r
  Zhash_suffix_part
max_lengthr   Zother_lengthr   r   r   r   l  s"   
z+BaseDatabaseSchemaEditor._create_index_namec                 C   sX   |d u rt |dkr|d jr|d j}n|jjr|jj}|d ur*d| jj| S dS )Nr   r   rm   r:   )r   rV   r!   r%   rE   rW   )r+   r    r   rV   r   r   r   _get_index_tablespace_sql  s   z2BaseDatabaseSchemaEditor._get_index_tablespace_sql)r   r   usingrV   col_suffixesr6   	opclasses	conditionc                   s   j |||d}dd |D }|pj}|jj} fdd}t|t|jt|||||||||	||
r=d|
 dS 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, ...).
        )rV   c                 S   s   g | ]}|j qS r   )rt   ru   r   r   r   rw     r   z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s"    d u rj | i |  S r   )r   rF   argskwargsr   r+   r   r   create_index_name  s   
zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name WHERE r:   )r~   r   r  r   r8   r  )	r  sql_create_indexr!   r   r   r   rF   r   _index_columns)r+   r    r   r   r   r  rV   r  r6   r  r  rW   r   r  r~   r  r   r  r   r     s    


z*BaseDatabaseSchemaEditor._create_index_sqlc                 C   s"   t | jt|jj| j| |dS N)r~   r   )r   r   r   r!   r   rF   r+   r    r   r   r   r   r     s
   z*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s   t ||| j|dS )N)r  )r   rF   )r+   r~   r   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 q$ 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                    r   r   r   ru   rv   r   r   rw     r|   z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   r   )r!   ZmanagedproxyZswappedr   r   r   Zindex_togetherr?   r   r   r   )r+   r    outputr   r   r   r   r   rv   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   rU   r+   r    r   r   r   r   r"    rG   z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r   r   r+   r   r   r   r   r   r     rG   z2BaseDatabaseSchemaEditor._field_became_primary_keyc                 C   s"   |j  r|j p|jo|j o|j S r   )rU   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_columnrI   )sql_rename_columnrF   rt   )r+   r~   r   r   r   r   r   r   r     s   

z*BaseDatabaseSchemaEditor._rename_field_sqlc              	      s    fdd}t |jj j}t|jj|jgt|jjjjd |jjg||}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 )Nc                           j| i |S r   rF   r   r  r0   r   r   create_fk_name     z?BaseDatabaseSchemaEditor._create_fk_sql.<locals>.create_fk_namer   )r~   r   rt   rn   ro   
deferrable)r   r!   r   rF   r   rt   r	   Ztarget_fieldr    r   r%   rE   Zdeferrable_sqlr   sql_create_fk)r+   r    r   r   r)  r~   r   rt   rn   ro   r+  r   r0   r   r     s.   z'BaseDatabaseSchemaEditor._create_fk_sqlc                 C      |  | j||S r   )r   sql_delete_fkr  r   r   r   r        z'BaseDatabaseSchemaEditor._delete_fk_sqlc                 C   s\   |r| j ||||d}|r| j| d S | jddt| j|i }| j| ||d S )N)r   r  r   r}   r   rz   )r   r-   r?   sql_unique_constraintr   rA   rF   sql_constraint)r+   r    r   r   r  r6   rz   r   r   r   _unique_sql  s   z$BaseDatabaseSchemaEditor._unique_sqlc                    s    fdd}t |jj j}|d u rt|jj|d|}n |}t|| j}|r= jjjr;t	 j
|||d| dS d S t	 j|||dS )Nc                     r'  r   r(  r  r0   r   r   create_unique_name  r*  zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_name_uniqr  )r~   r   r   r  r~   r   r   )r   r!   r   rF   r   r   r%   r(   supports_partial_indexesr   sql_create_unique_indexsql_create_unique)r+   r    r   r   r  r4  r~   r   r0   r   r     s.   
z+BaseDatabaseSchemaEditor._create_unique_sqlc                 C   s2   |r| j jjr| | j||S d S | | j||S r   )r%   r(   r7  r   r   r   )r+   r    r   r  r   r   r   r   1  s   z+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j | || jd|i d S )Nrl   r0  )r2  rF   r   )r+   r   rl   r   r   r   
_check_sql9  s   z#BaseDatabaseSchemaEditor._check_sqlc                 C   s$   t | jt|jj| j| ||dS )N)r~   r   rl   )r   sql_create_checkr   r!   r   rF   )r+   r    r   rl   r   r   r   r   ?  s   z*BaseDatabaseSchemaEditor._create_check_sqlc                 C   r-  r   )r   sql_delete_checkr  r   r   r   r   G  r/  z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| j| |dS r  )r   r   r!   r   rF   )r+   templater    r   r   r   r   r   J  s
   z/BaseDatabaseSchemaEditor._delete_constraint_sqlc
                    s  |dur fdd|D } j  }
 j j|
|jj}W d   n1 s'w   Y  g }| D ]Y\}}|du s@||d kr|durK|d |krKq2|durV|d |krVq2|dura|d |kraq2|durl|d |krlq2|duru|d	 suq2|dur|d
 |krq2|	r||	vr|| q2|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   r0   r   r   rw   V  s    z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r   rU   r   r   rl   r   rI   )r%   rC   r>  Zget_constraintsr!   r   itemsr?   )r+   r    r  rU   r   r   r   rl   r   r   rC   r   resultr   Zinfodictr   r0   r   r   Q  s4   

z*BaseDatabaseSchemaEditor._constraint_namesc                 C   sV   | j |dd}|rt|dkrtdt||jjf |D ]}| | || qd S )NTr$  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   o  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   r6  )	r   sql_create_pkr   r!   r   rF   r   rt   r   r#  r   r   r   r   y  s   z0BaseDatabaseSchemaEditor._create_primary_key_sqlc                 C   r-  r   )r   sql_delete_pkr  r   r   r   rA    r/  z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc                 C   s*   | j | |d|d }| | d S )N,)Z	procedureparam_types)sql_delete_procedurerF   r   r1   )r+   Zprocedure_namerE  r6   r   r   r   remove_procedure  s
   z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)r:   r   rJ   )NNNNNNNN)[__name__
__module____qualname____doc__r   r   r   r   r   r   r  r  r  r  r  r   r&  r   r1  r   Zsql_delete_constraintr2  r;  r<  r9  r   r,  r   r.  r  r8  r   rB  rC  rF  r,   r/   r2   r1   rF   r[   rO   rR   staticmethodrk   rP   rB   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   r   r3  r   r   r:  r   r   r   r   r   r   rA  rG  r   r   r   r   r$   (   s    
	
	
0	
F*
*
 u



	




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