o
    b                     @   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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   ]/var/www/secure340b-portal/env/lib/python3.10/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reverseZinclude_hidden)_metaZ_get_fieldsmodelr   r   r   _all_related_fields       r   c                    s2   t fddtjD  fddt 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'   )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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+dd-d.Z,d/d0 Z-d1d2 Z.d3d4 Z/d5d6 Z0e1d7d8 Z2d9d: Z3d;d< Z4d=d> Z5d?d@ Z6dAdB Z7dCdD Z8dEdF Z9dGdH Z:dIdJ Z;dKdL Z<dMdN Z=dOdP Z>dQdR Z?dSdT Z@dUdV ZAddWdXZB	ddYdZZCd[d\ ZDdd]d^ZEd_d` ZFdadb ZGdcdd ZHddfdgZIddhdiZJdjdk ZKdldm ZLdddededd&dd&ddddndodpZMddqdrZNdsdt ZOdudv ZPdwdx ZQdydz ZRd{d| ZSd}d~ ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZ		dddZ[		dddZ\		dddZ]dd Z^dd Z_dd Z`dd Za			dddZbdddZcdd Zddd Zedd ZfdddZgd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__c   s
   z!BaseDatabaseSchemaEditor.__init__c                 C   s(   g | _ | jrt| jj| _| j  | S r    )deferred_sqlr1   r   r,   alias	__enter__r2   r   r   r   r6   l   s
   
z"BaseDatabaseSchemaEditor.__enter__c                 C   s<   |d u r| j D ]}| | q| jr| j||| d S d S r    )r4   executer1   r   __exit__)r2   exc_type	exc_value	tracebacksqlr   r   r   r9   s   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))paramsr=   )extra; N)r-   r,   Zin_atomic_blockr/   r0   r   strloggerdebugendswithr.   appendtuplemapquote_valuecursorr8   )r2   r=   r>   endingrJ   r   r   r   r8   |   s   $"z BaseDatabaseSchemaEditor.executec                 C   s   | j j|S r    )r,   ops
quote_name)r2   r   r   r   r   rM         z#BaseDatabaseSchemaEditor.quote_namec                    s   j jD ]} fdd|D }j | qg }g } j jD ]} |\}}|du r1q"|jjd}	|	d rE|dj	|	  7 }|j
jd}
|
rT|d|
 7 }|| |jr|jr|jjj j}|jjj |jjj}jr|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" 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 }||fS )z-Take a model and return its table definition.c                       g | ]	} j |jqS r   r   	get_fieldcolumnr#   r   r   r   r   
<listcomp>       z6BaseDatabaseSchemaEditor.table_sql.<locals>.<listcomp>Nr,   check  %s)to_table	to_column_fk_%(to_table)s_%(to_column)sz%s %s)Z	AutoFieldZBigAutoFieldZSmallAutoFieldc                    s   g | ]}|  qS r   )Zconstraint_sqlr#   
constraintr   r2   r   r   rT          , c                 s   s    | ]}|r|V  qd S r    r   r]   r   r   r   r&      s    z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>)table
definition) r   Zunique_togetherr4   rF   _create_unique_sqllocal_fields
column_sqldb_parametersr,   sql_check_constraintZdb_type_suffixextendremote_fielddb_constraintr   db_tablerQ   
field_namerR   sql_create_inline_fkrM   r/   supports_foreign_keys_create_fk_sqlget_internal_typerL   autoinc_sqlconstraintssql_create_tablejoindb_tablespacetablespace_sql)r2   r   fieldscolumnsZcolumn_sqlsr>   r   rc   Zextra_params	db_paramsZcol_type_suffixrZ   r[   rr   rs   r=   rw   r   r_   r   	table_sql   sZ   


z"BaseDatabaseSchemaEditor.table_sqlc                 C   s^  |j | jd}|d }g }|du rdS t|dd}|r"|| |7 }|j}|o4| | o4|o3| | }|r_| |}	d| | }
|	dur_| jj	j
rV||
| |	 7 }n	||
7 }||	g7 }|jrl|jsl| jj	jrld}|rx| jj	jsx|d7 }n|s~|d	7 }|jr|d
7 }n|jr|d7 }|jp|jj}|r| jj	jr|jr|d| jjj|dd 7 }||fS )z
        Take a field and return its column definition.
        The field must already have had set_attributes_from_name() called.
        rV   typeN)NNdb_collationz	 DEFAULT Tz NULLz	 NOT NULLz PRIMARY KEYz UNIQUErY   )inline)rg   r,   getattr_collate_sqlnullskip_defaultskip_default_on_altereffective_default_column_default_sqlr/   requires_literal_defaultsprepare_defaultempty_strings_allowedr   !interprets_empty_strings_as_nullsZimplied_column_nulluniquerv   r   Zsupports_tablespacesrL   rw   )r2   r   r   include_defaultrz   r=   r>   	collationr   default_valueZcolumn_defaultZ
tablespacer   r   r   rf      sL   





z#BaseDatabaseSchemaEditor.column_sqlc                 C      dS )z
        Some backends don't accept default values for certain columns types
        (i.e. MySQL longtext and longblob).
        Fr   r2   r   r   r   r   r        z%BaseDatabaseSchemaEditor.skip_defaultc                 C   r   )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     r   z.BaseDatabaseSchemaEditor.skip_default_on_alterc                 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r2   valuer   r   r   r     s   z(BaseDatabaseSchemaEditor.prepare_defaultc                 C   r   )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   $  r   z,BaseDatabaseSchemaEditor._column_default_sqlc                 C   s   |   r
|  }|S | js!| jr!| jr!|  dkrd}|S d}|S t| dds-t| ddrSt }|  }|dkr?|	 }|S |dkrI|
 }|S |d	krQt }|S d }|S )
NZBinaryField    rA   Zauto_nowFZauto_now_addZ	DateFieldZ	TimeFieldZDateTimeField)has_defaultget_defaultr   blankr   rq   r   r   nowdatetimer   )r   defaultZinternal_typer   r   r   _effective_default+  s.   z+BaseDatabaseSchemaEditor._effective_defaultc                 C   s   | | || jS )z2Return a field's effective database default value.)Zget_db_prep_saver   r,   r   r   r   r   r   B  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   rI   F  s   z$BaseDatabaseSchemaEditor.quote_valuec                 C   s\   |  |\}}| ||pd | 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`.
        N)r{   r8   r4   ri   _model_indexes_sqlr   local_many_to_manyrj   throughauto_createdcreate_model)r2   r   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r<||j j	r<| j| q(dS )z!Delete a model from the database.rb   N)r   r   rj   r   r   delete_modelr8   sql_delete_tablerM   rl   listr4   
isinstancer   Zreferences_tableremove)r2   r   r   r=   r   r   r   r   c  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_indexesr8   
create_sqlr2   r   indexr   r   r   	add_indexs  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   r8   
remove_sqlr   r   r   r   remove_index~  s   z%BaseDatabaseSchemaEditor.remove_indexc                 C   s&   | || }|r| j|dd dS dS )zAdd a constraint to a model.Nr   )r   r8   r2   r   r^   r=   r   r   r   add_constraint  s   z'BaseDatabaseSchemaEditor.add_constraintc                 C   s"   | || }|r| | dS dS )z!Remove a constraint from a model.N)r   r8   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 }| |  | 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   rG   r#   rx   r   r   r   	<setcomp>      zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r     r   r   Tc                    rO   r   rP   rS   r   r   r   rT     rU   zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquer8   rd   )r2   r   Zold_unique_togetherZnew_unique_togetheroldsnewsrx   ry   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
 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     r   z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r     r   TF)r   r   c                       g | ]} j |qS r   r   rQ   rS   r   r   r   rT     r`   zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>_idxrx   suffixN)r   r   sql_delete_indexr8   _create_index_sql)r2   r   Zold_index_togetherZnew_index_togetherr   r   rx   field_namesr   r   r   alter_index_together  s   z-BaseDatabaseSchemaEditor.alter_index_togetherc           	         s   dd  j jD }dd  j jD } fdd|D }| j |fd||B i|}t|dkr?tdt| j jd	|f | | 	| |d
  d S )Nc                 S      h | ]}|j qS r   r   r]   r   r   r   r         zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   r   r   r   r]   r   r   r   r     r   c                    rO   r   rP   rS   r   r   r   rT     rU   zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>exclude   z1Found wrong number (%s) of constraints for %s(%s)ra   r   )
r   rs   indexes_constraint_nameslen
ValueErrorrl   ru   r8   _delete_constraint_sql)	r2   r   rx   Zconstraint_kwargsr=   meta_constraint_namesmeta_index_namesry   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	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lowerr8   sql_rename_tablerM   r4   r   r   Zrename_table_references)r2   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.)rb   Zold_tablespaceZnew_tablespaceN)r8   sql_retablespace_tablerM   r   rl   )r2   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u r dS |j| jd}|d r4|d| j	|  7 }|jr| jj
jr|jrd}| jr|jjjj}|jjj|jjj}t|jj\}	}
|d| j| ||||	rpd| |	 nd	| |j| || || jj d
  7 }n| j| ||| | j| |jj| |j|d }| || | |s| |dur| j|d|dd\}}| j | |jj|d }| || | j!| "|| | 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)r   NrV   rW   rX   r\   z%s.rA   )r   	namespacerR   rZ   r[   
deferrable)rb   rR   rc   droprb   changes)%r   rj   r   r   r   r   rf   rg   r,   rh   r/   ro   rk   sql_create_column_inline_fkr   rl   rQ   rm   rR   r
   _fk_constraint_namerM   rL   deferrable_sqlr4   rF   rp   sql_create_columnr8   r   r   _alter_column_default_sqlsql_alter_columnri   _field_indexes_sqlconnection_persists_old_columnsclose)r2   r   r   rc   r>   rz   Zconstraint_suffixrZ   r[   r   _r=   changes_sqlr   r   r   	add_field  sP   




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.
        rV   r|   NTforeign_key)rb   rR   )r   rj   r   r   r   r   rg   r,   r   rR   r8   _delete_fk_sqlsql_delete_columnrM   rl   r/   r   r   r   r4   r   r   Zreferences_columnr   )r2   r   r   fk_namesfk_namer=   r   r   r   remove_field  s(   



z%BaseDatabaseSchemaEditor.remove_fieldc           	   
   C   s0  |  ||sdS |j| jd}|d }|j| jd}|d }|du r'|jdu s0|du r8|jdu r8td||f |du r\|du r\|jjr\|jjr\|jjjjr\|jjjjr\| ||||S |du rz|du rz|jjrz|jjrz|jjjjsz|jjjjszdS |du s|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.
        NrV   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_alteredrg   r,   rj   r   r   r   r   _alter_many_to_many_alter_field)	r2   r   r%   r(   strictold_db_paramsold_typenew_db_paramsnew_typer   r   r   alter_field8  sZ   



z$BaseDatabaseSchemaEditor.alter_fieldc	           )      C   s  t  }	| jjjrC|jrC|jrC| j||jgdd}
|r.t|
dkr.t	dt|
|j
j|jf |
D ]}|	|jf | | || q0|jr|jrO| ||rdd |j
jD }| j||jgdd|d}|rzt|dkrzt	d	t||j
j|jf |D ]}| | || q|| jjjo|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r=|d r=dd |j
jD }| j||jgd|d}|r.t|dkr.t	dt||j
j|jf |D ]}| | || q0|j|jkri| | |j
j||| | jD ]}t|t rg|!|j
j|j|j qTg }g }g }t"|dd}t"|dd}||kr| #||||}|$| n||kr| %||||\}}|$| |&| d}|j'r|j's| (|}| (|} | )|s|| kr| durd}|$| *||| |j'|j'kr| +|||}|r|$| |, o|j'o|j' }!|s |ro|!s|| }| jjj-r#|r#t.t/| \}}"d0|t1|"g fg}|D ]\}}"| | j2| 3|j
j|d |" q%|!ro| | j4| 3|j
j| 3|jdd | g |D ]\}}"| | j2| 3|j
j|d |" qX|r|D ]\}}"| ||" qt|jr|js| 5|| | 6||r| | 7||jg |jr|jr|jr|js| | j8||gd g }#|r|#&t|| | ||r| | 9|| |#&t|| |#D ]B\}$}|jj:| jd}%|%d }&| %|j|$j|j|&\}}| | j2| 3|jj
j|d d |d  |D ]\}}"| ||" qq| jjjrH|jrH|	s:|jr:|jsH|jrH| | ;||d |rk|j<j
j=D ]}'t>|'|ri|'jjri| | ;|'j|'jd qP|d |d kr|d r| j?|j
j|jgdd}| | @|||d  |r| j*|||dd\}(}"| j2| 3|j
j|(d }| ||" | jjjAr| jB  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   r]   r   r   r   r   z  r   z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>F)r   r   r   z7Found wrong number (%s) of unique constraints for %s.%sc                 S   r   r   r   )r#   r   r   r   r   r     r   )r   type_r   rW   c                 S   r   r   r   r]   r   r   r   r     r   )rW   r   z6Found wrong number (%s) of check constraints for %s.%sr}   Nra   r   r   )rb   rR   r   rx   rV   r|   r   r\   Z_fk_checkr   r   )Csetr,   r/   ro   rj   rk   r   rR   r   r   r   rl   addr8   r   r   _field_became_primary_keyrs   _delete_unique_sqlr   r*   Zrelated_modelr   db_indexr   r   r   _delete_index_sql_delete_check_sql_rename_field_sqlr4   r   r   Zrename_column_referencesr   _alter_column_collation_sqlrF   _alter_column_type_sqlri   r   r   r   r   _alter_column_null_sqlr   Zsupports_combined_altersrG   r)   ru   sumr   rM   sql_update_with_default_delete_primary_key_unique_should_be_addedrd   r   _create_primary_key_sqlrg   rp   r   Zrelated_objectsr   _create_index_name_create_check_sqlr   r   ))r2   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_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_updateZold_relZrel_db_paramsZrel_typerelr   r   r   r   r   c  s  













 
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	TextFieldNrV   r|   rR   r|   )
r,   r/   r   rq   rg   r   sql_alter_column_nullsql_alter_column_not_nullrM   rR   )r2   r   r%   r(   r   r=   r   r   r   r  b  s   


z/BaseDatabaseSchemaEditor._alter_column_null_sqlc           
      C   s   |  |}| |}|g}|rg }n| jjjr| |}g }|j| jd}|r2|jr.| j}	n| 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.
        rV   r|   )rR   r|   r   )r   r   r,   r/   r   r   rg   r    sql_alter_column_no_default_nullsql_alter_column_no_defaultsql_alter_column_defaultrM   rR   )
r2   r   r%   r(   r   r  r   r>   r   r=   r   r   r   r   x  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_typerM   rR   )r2   r   r%   r(   r   r   r   r   r
    s   
z/BaseDatabaseSchemaEditor._alter_column_type_sqlc                 C   s,   | j | |j||r| |ndd g fS )NrA   )rR   r|   r   )sql_alter_column_collaterM   rR   r   )r2   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)	rj   r   r   rl   r   r   rQ   Zm2m_reverse_field_nameZm2m_field_name)r2   r   r%   r(   r   r   r   r   r     s   
z,BaseDatabaseSchemaEditor._alter_many_to_manyrA   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_%sr      N   r   r   zD%s)r
   r	   r,   rL   Zmax_name_lengthru   r   isdigit)	r2   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 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   rX   rA   )r   rv   r   r,   rL   rw   )r2   r   rx   rv   r   r   r   _get_index_tablespace_sql  s   z2BaseDatabaseSchemaEditor._get_index_tablespace_sqlc                 C   s   |rd| S dS )Nz WHERE rA   r   )r2   	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 )NrA   z INCLUDE (%(columns)s))ry   )r,   r/   supports_covering_indexesr   r   r   rl   rM   )r2   r   ry   r   r   r   _index_include_sql  s   z+BaseDatabaseSchemaEditor._index_include_sql)rx   r   r   usingrv   col_suffixesr=   	opclassesr,  includeexpressionsc                   s   |pg }|pg }t |ddjjd}j|||d}dd |D }|p&j}|jj} fdd}t|t|j	t
||||||rJ||||	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_colsrV   )rv   c                 S   s   g | ]}|j qS r   )rR   rS   r   r   r   rT     r   z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s"    d u rj | i |  S r    )r  rM   argskwargsr   r2   r   r   create_index_name  s   
zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)rb   r   r0  ry   r?   r,  r3  )r   Zget_compilerr,   r+  sql_create_indexr   rl   r   r   rM   r   _index_columnsr   rI   r-  r/  )r2   r   rx   r   r   r0  rv   r1  r=   r2  r,  r3  r4  compilerrw   ry   r:  rb   r9  r   r8  r   r     s,   


z*BaseDatabaseSchemaEditor._create_index_sqlc                 C   s&   t |p| jt|jj| j| |dS N)rb   r   )r   r   r   r   rl   rM   )r2   r   r   r=   r   r   r   r  ,  s
   z*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s   t ||| j|dS )N)r1  )r   rM   )r2   rb   ry   r1  r2  r   r   r   r;  3  r   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 ]}|jrI| jjjrR|| |  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   rS   r   r   r   rT   B  r`   z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   r   )r   ZmanagedproxyZswappedre   ri   r   Zindex_togetherrF   r   r   r   r,   r/   r   r   )r2   r   outputr   r   rx   r   r   r   r   r   6  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   )r2   r   r   r?  r   r   r   r   M  s   z+BaseDatabaseSchemaEditor._field_indexes_sqlc                 C   sv   |  \}}}}|  \}}}}	g d}
|
D ]}||d  |	|d  q| |j| |jkp:|||f|||	fkS )N)r   Z	db_columneditableZerror_messages	help_textZlimit_choices_toZ	on_deleteZrelated_nameZrelated_query_nameZ
validatorsZverbose_name)ZdeconstructpoprM   rR   )r2   r%   r(   r   old_pathZold_argsZ
old_kwargsnew_pathnew_argsZ
new_kwargsZnon_database_attrsattrr   r   r   r   V  s   z1BaseDatabaseSchemaEditor._field_should_be_alteredc                 C   s   |j o|j S r    )r  r   r2   r   r   r   r   r   r@  s  rN   z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r    r   r2   r%   r(   r   r   r   r  v  rN   z2BaseDatabaseSchemaEditor._field_became_primary_keyc                 C   s"   |j  r|j p|jo|j o|j S r    )r   r   rJ  r   r   r   r  y  s   z0BaseDatabaseSchemaEditor._unique_should_be_addedc                 C   s*   | j | || |j| |j|d S )N)rb   Z
old_columnZ
new_columnr|   )sql_rename_columnrM   rR   )r2   rb   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)rb   r   rR   rZ   r[   r   )r   r   rl   rM   r   r   rR   target_fieldr   r,   rL   r   r   sql_create_fk)
r2   r   r   r   rb   r   rR   rZ   r[   r   r   r   r   rp     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                           j| i |S r    rM   r  r5  r7   r   r   create_fk_name     zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer   )r   r   rl   rR   r
   rL  r   )r2   r   r   r   rP  r   r7   r   r     s   z,BaseDatabaseSchemaEditor._fk_constraint_namec                 C      |  | j||S r    )r   sql_delete_fkr2   r   r   r   r   r   r        z'BaseDatabaseSchemaEditor._delete_fk_sqlc                 C   s,   |d u rdS |t jkrdS |t jkrdS d S )NrA   z DEFERRABLE INITIALLY DEFERREDz DEFERRABLE INITIALLY IMMEDIATE)r   ZDEFERREDZ	IMMEDIATE)r2   r   r   r   r   _deferrable_constraint_sql  s   

z3BaseDatabaseSchemaEditor._deferrable_constraint_sqlc           
      C   s   |r	| j jjs	d S |s|s|r$| j||||||d}|r"| j| d S | jdt| j	|| 
|d }	| j| 	||	d S )N)r   r,  r3  r2  ra   )ry   r   r   r^   )r,   r/   &supports_deferrable_unique_constraintsrd   r4   rF   sql_unique_constraintru   rH   rM   rV  sql_constraint)
r2   r   rx   r   r,  r   r3  r2  r=   r^   r   r   r   _unique_sql  s2   z$BaseDatabaseSchemaEditor._unique_sqlc                    s   |r j jjr|r j jjr|r j jjsd S  fdd}t|jj j}	|d u r3t	|jj|d|}n |} j
|	|d|d}|sG|sG|rK j}
n j}
t|
|	|| | | ||dS )Nc                     rN  r    rO  r5  r7   r   r   create_unique_name  rQ  zGBaseDatabaseSchemaEditor._create_unique_sql.<locals>.create_unique_name_uniqr   )r1  r2  )rb   r   ry   r,  r   r3  )r,   r/   rX  supports_partial_indexesr.  r   r   rl   rM   r   r;  sql_create_unique_indexsql_create_uniquer   r-  rV  r/  )r2   r   ry   r   r,  r   r3  r2  r\  rb   r=   r   r7   r   rd     s>   

z+BaseDatabaseSchemaEditor._create_unique_sqlc                 C   sV   |r| j jjr|r| j jjr|r| j jjsd S |s|s|r!| j}n| j}| |||S r    )r,   r/   rX  r^  r.  r   r   r   )r2   r   r   r,  r   r3  r2  r=   r   r   r   r    s"   z+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j | || jd|i d S )NrW   rW  )rZ  rM   rh   )r2   r   rW   r   r   r   
_check_sql  s   z#BaseDatabaseSchemaEditor._check_sqlc                 C   s$   t | jt|jj| j| ||dS )N)rb   r   rW   )r   sql_create_checkr   r   rl   rM   )r2   r   r   rW   r   r   r   r    s   z*BaseDatabaseSchemaEditor._create_check_sqlc                 C   rR  r    )r   sql_delete_checkrT  r   r   r   r    rU  z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| j| |dS r=  )r   r   r   rl   rM   )r2   templater   r   r   r   r   r     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   r7   r   r   rT   $  s    z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>ry   r   r   r   rW   r   r|   )r,   rJ   re  Zget_constraintsr   rl   itemsrF   )r2   r   r)  r   r   r   r   rW   r   r   rJ   rs   resultr   Zinfodictr   r7   r   r     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 )NTrI  r   z0Found wrong number (%s) of PK constraints for %s)r   r   r   r   rl   r8   _delete_primary_key_sql)r2   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   )rb   r   ry   )	r   sql_create_pkr   r   rl   rM   r  rR   r   rH  r   r   r   r  G  s   z0BaseDatabaseSchemaEditor._create_primary_key_sqlc                 C   rR  r    )r   sql_delete_pkrT  r   r   r   rh  Q  rU  z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc                 C   s   d|  | S )Nz	 COLLATE )rM   )r2   r   r   r   r   r   T  rN   z%BaseDatabaseSchemaEditor._collate_sqlc                 C   s*   | j | |d|d }| | d S )N,)Z	procedureparam_types)sql_delete_procedurerM   ru   r8   )r2   Zprocedure_namerl  r=   r   r   r   remove_procedureW  s
   z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)rA   r    )NNNN)NNNNN)NNNNNNNN)h__name__
__module____qualname____doc__rt   r   r   r   r   r   r   r  r  r  r  r  r!  r   rK  r  rY  rh   Zsql_delete_constraintrZ  rb  rc  r`  r   rM  rn   r   rS  r:  r_  r   ri  rj  rm  r3   r6   r9   r8   rM   r{   rf   r   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  r;  r   r   r   r@  r  r  r  rp   r   r   rV  r[  rd   r  ra  r  r  r   r   r  r  rh  r   rn  r   r   r   r   r+   -   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   	getLoggerrC   r   r   r*   r+   r   r   r   r   <module>   s     
	