o
    ˷e:                    @   s   d dl Z d dlZd dlm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)settings)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_key	to_fieldsname)relationaltered_fieldr    r   U/var/www/ideatree/venv/lib/python3.10/site-packages/django/db/backends/base/schema.py_is_relevant_relation   s   r   c                 C   s"   t | jjdddddtddS )NFT)forwardreverseinclude_hiddeninclude_parentsr   )key)sorted_meta_get_fieldsoperator
attrgettermodelr   r   r   _all_related_fields'   s   r(   c                 #   sd    t fddtjD  fddt jD }|D ]\}}||fV  t|j|jE d H  qd S )Nc                 3       | ]
}t | r|V  qd S Nr   .0obj)	old_fieldr   r   	<genexpr>8       
z+_related_non_m2m_objects.<locals>.<genexpr>c                 3   r)   r*   r+   r,   )	new_fieldr   r   r0   =   r1   )zipr(   r'   _related_non_m2m_objectsremote_field)r/   r2   related_fieldsold_relnew_relr   )r2   r/   r   r4   4   s    


r4   c                   @   s4  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#dZ$eZ%dZ&dd!d"Z'd#d$ Z(d%d& Z)dd(d)Z*d*d+ Z+d,d- Z,d.d/ Z-dd0d1Z.d2d3 Z/d4d5 Z0d6d7 Z1d8d9 Z2e3d:d; Z4d<d= Z5d>d? Z6d@dA Z7dBdC Z8dDdE Z9dFdG Z:dHdI Z;dJdK Z<dLdM Z=dNdO Z>dPdQ Z?dRdS Z@dTdU ZAdVdW ZBdXdY ZCdZd[ ZDdd\d]ZE	dd^d_ZFd`da ZGddbdcZHddde ZIdfdg ZJdhdi ZKddkdlZLddmdnZMdodp ZNdqdr ZOdddjdjdd'dd'ddddsdtduZPddvdwZQdxdy ZRdzd{ ZSd|d} ZTd~d ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^					dddZ_						dddZ`dddZa					dddZbdd Zcdd Zddd Zedd Zf								dddZgdddZhdd Zidd Zjdd ZkdddZld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/ALTER INDEX %(old_name)s RENAME TO %(new_name)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   rD      s
   
z"BaseDatabaseSchemaEditor.__enter__c                 C   s<   |d u r| j D ]}| | q| jr| j||| d S d S r*   )rB   executer?   r   __exit__)r@   exc_type	exc_value	tracebacksqlr   r   r   rG      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 rN|	 
dr,dnd}|durD| j|tt| j| |  dS | j||  dS | j }||| W d   dS 1 sew   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))paramsrK   )extra; N)r;   r:   in_atomic_blockr=   r>   r   strloggerdebugrstripendswithr<   appendtuplemapquote_valuecursorrF   )r@   rK   rL   endingrZ   r   r   r   rF      s.   "z BaseDatabaseSchemaEditor.executec                 C   s   | j j|S r*   )r:   ops
quote_name)r@   r   r   r   r   r]         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 |qS r   r"   	get_fieldr-   r   r&   r   r   
<listcomp>       z6BaseDatabaseSchemaEditor.table_sql.<locals>.<listcomp>Nr:   check z %s)to_table	to_column_fk_%(to_table)s_%(to_column)sz%s %s)	AutoFieldBigAutoFieldSmallAutoFieldc                    s   g | ]}|  qS r   )constraint_sqlr-   
constraintr'   r@   r   r   rc   	  s    
, c                 s   s    | ]}|r|V  qd S r*   r   ro   r   r   r   r0     s    
z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>)table
definition) r"   unique_togetherrB   rV   _create_unique_sqllocal_fields
column_sqldb_parametersr:   sql_check_constraintdb_type_suffixextendr5   db_constraintr'   db_tablera   
field_namecolumnsql_create_inline_fkr]   r=   supports_foreign_keys_create_fk_sqlget_internal_typer\   autoinc_sqlconstraintssql_create_tablejoindb_tablespacetablespace_sql)r@   r'   field_namesfieldscolumn_sqlsrL   r   rt   extra_params	db_paramscol_type_suffixrh   ri   r   r   rK   r   r   rq   r   	table_sql   s   



	

z"BaseDatabaseSchemaEditor.table_sqlc                 c   s.   |V  | d }r| |V  |j}|o#| | o#|o"| | }|rL| |}	|	d urLd| | }
| jjj	rD|
| 
|	 V  n|
V  ||	 |jrY|jsY| jjjrYd}|s_dV  n| jjjsgdV  |jrndV  n|jrtdV  |jpz|jj}|r| jjjr|jr| jjj|ddV  d S d S d S d S )	N	collationzDEFAULT TzNOT NULLNULLzPRIMARY KEYUNIQUE)inline)get_collate_sqlnullskip_defaultskip_default_on_altereffective_default_column_default_sqlr:   r=   requires_literal_defaultsprepare_defaultrV   empty_strings_allowedr   !interprets_empty_strings_as_nullsimplied_column_nulluniquer   r"   supports_tablespacesr\   r   )r@   column_db_typerL   r'   r   field_db_paramsinclude_defaultr   r   default_valuecolumn_default
tablespacer   r   r   _iter_column_sql  sT   
	



z)BaseDatabaseSchemaEditor._iter_column_sqlc              
   C   sD   |j | jd}|d }|du rdS g }d| |||||||fS )z
        Return the column definition for a field. The field must already have
        had set_attributes_from_name() called.
        re   typeN)NNrg   )ry   r:   r   r   )r@   r'   r   r   r   r   rL   r   r   r   rx   T  s"   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   r@   r   r   r   r   r   o     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   v  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r@   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rS|  }|dkr;t }|S t	 }|dkrI|
 }|S |d	krQ| }|S d }|S )
NBinaryField    rO   auto_nowFauto_now_addDateTimeField	DateField	TimeField)has_defaultget_defaultr   blankr   r   getattrr   nowr   datetime)r   defaultinternal_typer   r   r   _effective_default  s.   	z+BaseDatabaseSchemaEditor._effective_defaultc                 C   s   | | || jS )z2Return a field's effective database default value.)get_db_prep_saver   r:   r   r   r   r   r     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   rY     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   rF   rB   r|   _model_indexes_sqlr"   local_many_to_manyr5   throughauto_createdcreate_model)r@   r'   rK   rL   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.rs   N)r"   r   r5   r   r   delete_modelrF   sql_delete_tabler]   r~   listrB   
isinstancer   references_tableremove)r@   r'   r   rK   r   r   r   r     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rL   )contains_expressionsr:   r=   supports_expression_indexesrF   
create_sqlr@   r'   indexr   r   r   	add_index  s   z"BaseDatabaseSchemaEditor.add_indexc                 C   s*   |j r
| jjjs
dS | |||  dS )zRemove an index from a model.N)r   r:   r=   r   rF   
remove_sqlr   r   r   r   remove_index  s   z%BaseDatabaseSchemaEditor.remove_indexc                 C   sF   | j jjr| j| ||j|jd d d S | || | || d S )Nr   )r:   r=   can_rename_indexrF   _rename_index_sqlr   r   r   )r@   r'   	old_index	new_indexr   r   r   rename_index  s   

z%BaseDatabaseSchemaEditor.rename_indexc                 C   s&   | || }|r| j|dd dS dS )zAdd a constraint to a model.Nr   )r   rF   r@   r'   rp   rK   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   rF   r   r   r   r   remove_constraint  s   z*BaseDatabaseSchemaEditor.remove_constraintc                    s|   dd |D }dd |D }| |D ]}|  |ddd| 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   rW   r-   r   r   r   r   	<setcomp>      zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r     r   TF)r   r   c                    r_   r   r`   rb   r&   r   r   rc     rd   zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquerF   rv   )r@   r'   old_unique_togethernew_unique_togetheroldsnewsr   r   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                    r_   r   r`   rb   r&   r   r   rc   0  rd   zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>_idxr   suffixN)r   r   sql_delete_indexrF   _create_index_sql)r@   r'   old_index_togethernew_index_togetherr   r   r   r   r   r&   r   alter_index_together  s   z-BaseDatabaseSchemaEditor.alter_index_togetherc           
         s   dd  j jD }dd  j jD } fdd|D }| j |fd||B i|}|ddu rJ|rJ| jjjrJt| j	 j j
|d	d
}	|	|v rJ|	g}t|dkr`tdt| j j
d|f | | | |d  d S )Nc                 S      h | ]}|j qS r   r   ro   r   r   r   r   4      zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   r   r   r   ro   r   r   r   r   7      c                    s   g | ]	} j |jqS r   )r"   ra   r   rb   r&   r   r   rc   8  s    zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>excluder   TFquote   z1Found wrong number (%s) of constraints for %s(%s)rr   r   )r"   r   indexes_constraint_namesr   r:   r=   *allows_multiple_constraints_on_same_fieldsrQ   _unique_constraint_namer~   len
ValueErrorr   rF   _delete_constraint_sql)
r@   r'   r   constraint_kwargsrK   meta_constraint_namesmeta_index_namescolumnsconstraint_namesdefault_namer   r&   r   r   3  sB   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)	old_table	new_table)r:   r=   ignores_table_name_caselowerrF   sql_rename_tabler]   rB   r   r   rename_table_references)r@   r'   old_db_tablenew_db_tablerK   r   r   r   alter_db_tableU  s"   

z'BaseDatabaseSchemaEditor.alter_db_tablec                 C   s2   |  | j| |jj| || |d  dS )z)Move a model's table between tablespaces.)rs   old_tablespacenew_tablespaceN)rF   sql_retablespace_tabler]   r"   r~   )r@   r'   old_db_tablespacenew_db_tablespacer   r   r   alter_db_tablespaceh  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   Nre   rf   rg   rj   z%s.rO   )r   	namespacer   rh   ri   
deferrable)rs   r   rt   droprs   changes)%r   r5   r   r"   r   r   rx   ry   r:   rz   r=   r   r}   sql_create_column_inline_fkr'   r~   ra   r   r   r   _fk_constraint_namer]   r\   deferrable_sqlrB   rV   r   sql_create_columnrF   r   r   _alter_column_default_sqlsql_alter_columnr|   _field_indexes_sqlconnection_persists_old_columnsclose)r@   r'   r   rt   rL   r   constraint_suffixrh   ri   r  _rK   changes_sqlr   r   r   	add_fields  sr   





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.
        re   r   NTforeign_key)rs   r   )r   r5   r   r"   r   r   ry   r:   r   r   rF   _delete_fk_sqlsql_delete_columnr]   r~   r=   r(  r)  r   rB   r   r   references_columnr   )r@   r'   r   fk_namesfk_namerK   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.
        Nre   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_alteredry   r:   r5   r  r   r"   r   _alter_many_to_many_alter_field)	r@   r'   r/   r2   strictold_db_paramsold_typenew_db_paramsnew_typer   r   r   alter_field  sf   



	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||d
}|d
}| jjjo|jr|jp|jo|jo||kp||k}|rt||D ]\}}| j|j|jjgdd}|D ]}| | |j| qq|jr|js|jr|jrdd |j
jD }| j||jgdtj|d}|D ]}| | || q|d |d krN|d rNdd |j
jD }| j||jgd|d}|r?t|dkr?t	dt||j
j|jf |D ]}| | || qA|j|jkrz| | |j
j||| | jD ]}t |t!rx|"|j
j|j|j qeg }g }g }|j#| jd}|j#| jd}||kr| $||||}|%| n||f||fkr| &||||\}}|%| |'| d} |j(r|j(s| )|}!| )|}"| *|s|!|"kr|"durd} |%| +||| |j(|j(kr| ,|||}|r|%| |- o|j(o|j( }#|s|r|#s|| }| jjj.r:|r:t/t0| \}}$d1|t2|$g fg}|D ]\}}$| | j3| 4|j
j|d |$ q<|#r| | j5| 4|j
j| 4|jdd |"g |D ]\}}$| | j3| 4|j
j|d |$ qo|r|D ]\}}$| ||$ q|jr|js| 6|| | 7||r| | 8||g |jr|jr|jr|js| | j9||gd g }%|r|%'t|| | ||r| | :|| |%'t|| |%D ]f\}&}|jj;| jd}'|'d }(|'d
})|&jj;| jd}*|*d
}+|+|)kr,| $|j|j|(|)}g }n| &|j|&j|j|(\}}| | j3| 4|jj
j|d d |d  |D ]\}}$| ||$ qQq| jjjr|jr|	st|jrt|js|jr| | <||d |r|%D ]\},}-|-jjr| | <|-j|-jd q|d |d kr|d r| j=|j
j|jgdd}| | >|||d  | r| j+|||dd\}.}$| j3| 4|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   ro   r   r   r   r   B  r   z8BaseDatabaseSchemaEditor._alter_field.<locals>.<setcomp>F)r   r   r   z7Found wrong number (%s) of unique constraints for %s.%sr   c                 S   r   r   r   )r-   r   r   r   r   r   |  r   )r   type_r   rf   c                 S   r   r   r   ro   r   r   r   r     r   )rf   r   z6Found wrong number (%s) of check constraints for %s.%sre   Nrr   r  r   )rs   r   r   r   r   r   rj   _fk_checkr   r  )Asetr:   r=   r   r5   r}   r   r   r  r  r"   r~   addrF   r0  r   _field_became_primary_keyr   _delete_unique_sqlr   r   r4   related_modelr   db_indexr   r   r   _delete_index_sql_delete_check_sql_rename_field_sqlrB   r   r   rename_column_referencesr{   _alter_column_collation_sqlrV   _alter_column_type_sqlr|   r   r   r   r%  _alter_column_null_sqlr   supports_combined_altersrW   r3   r   sumr&  r]   sql_update_with_default_delete_primary_key_unique_should_be_addedrv   r   _create_primary_key_sqlry   r   _create_index_name_create_check_sqlr(  r)  )/r@   r'   r/   r2   r;  r=  r:  r<  r9  fks_droppedr3  r4  r  r
  constraint_nameold_collationnew_collationdrop_foreign_keys_old_relr8   rel_fk_namesr  index_names
index_namerK   actionsnull_actionspost_actionsold_type_suffixnew_type_suffixfragmentother_actionsneeds_database_defaultold_defaultnew_defaultfour_way_default_alterationrL   rels_to_updater7   rel_db_paramsrel_typerel_collationold_rel_db_paramsold_rel_collationr+  relr,  r   r   r   r8    s&  





















z%BaseDatabaseSchemaEditor._alter_fieldc                 C   sR   | j jjr
|j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.
        Nre   r   r   r   )
r:   r=   r   r   ry   r   sql_alter_column_nullsql_alter_column_not_nullr]   r   )r@   r'   r/   r2   r<  rK   r   r   r   rP  t  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.
        re   r   )r   r   r   )r   r   r:   r=   r   r   ry   r    sql_alter_column_no_default_nullsql_alter_column_no_defaultsql_alter_column_defaultr]   r   )
r@   r'   r/   r2   r  rk  r   rL   r<  rK   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.
        rt  )sql_alter_column_typer]   r   )r@   r'   r/   r2   r=  r   r   r   rO    s   
z/BaseDatabaseSchemaEditor._alter_column_type_sqlc                 C   s0   | j | |j||rd| | ndd g fS )Nrg   rO   )r   r   r   )sql_alter_column_collater]   r   r   )r@   r'   r2   r=  r\  r   r   r   rN    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)	r5   r   r"   r~   r  r>  ra   m2m_reverse_field_namem2m_field_name)r@   r'   r/   r2   r9  r   r   r   r7    s,   





z,BaseDatabaseSchemaEditor._alter_many_to_manyrO   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:   r\   max_name_lengthr   r  isdigit)	r@   
table_namecolumn_namesr   r+  hash_suffix_part
max_lengthra  other_lengthr   r   r   rW    s(   
z+BaseDatabaseSchemaEditor._create_index_namec                 C   sf   |d u r$t |dkr|d jr|d j}ntjrtj}n|jjr$|jj}|d ur1d| jj| S dS )Nr   r   rg   rO   )r  r   r   DEFAULT_INDEX_TABLESPACEr"   r:   r\   r   )r@   r'   r   r   r   r   r   _get_index_tablespace_sql  s   z2BaseDatabaseSchemaEditor._get_index_tablespace_sqlc                 C   s   |rd| S dS )Nz WHERE rO   r   )r@   	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 )NrO   z INCLUDE (%(columns)s))r	  )r:   r=   supports_covering_indexesr   r   r"   r~   r]   )r@   r'   r	  r   r   r   _index_include_sql+  s   z+BaseDatabaseSchemaEditor._index_include_sql)r   r   r   usingr   col_suffixesrK   	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
alias_colsre   )r   c                 S      g | ]}|j qS r   r   rb   r   r   r   rc   P  r   z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s"    d u rj | i |  S r*   )rW  r]   argskwargsr   r@   r   r   create_index_nameT  s   
zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)rs   r   r  r	  rM   r  r  )r   get_compilerr:   r  sql_create_indexr"   r~   r   r	   r]   r   _index_columnsr   rY   r  r  )r@   r'   r   r   r   r  r   r  rK   r  r  r  r  compilerr   r	  r  rs   r  r   r  r   r   3  s0   


z*BaseDatabaseSchemaEditor._create_index_sqlc                 C   s&   t |p| jt|jj| j| |dS N)rs   r   )r   r   r	   r"   r~   r]   )r@   r'   r   rK   r   r   r   rJ  i  s
   z*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s*   t | jt|jj| j| || |dS )N)rs   old_namenew_name)r   sql_rename_indexr	   r"   r~   r]   )r@   r'   r  r  r   r   r   r   p  s   z*BaseDatabaseSchemaEditor._rename_index_sqlc                 C   s   t ||| j|dS )N)r  )r   r]   )r@   rs   r	  r  r  r   r   r   r  x  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 ]}|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`   rb   r&   r   r   rc     rd   z?BaseDatabaseSchemaEditor._model_indexes_sql.<locals>.<listcomp>r   r   )r"   managedproxyswappedrw   r|   r'  index_togetherrV   r   r   r   r:   r=   r   r   )r@   r'   outputr   r   r   r   r   r&   r   r   {  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_indexedrV   r   )r@   r'   r   r  r   r   r   r'    s   z+BaseDatabaseSchemaEditor._field_indexes_sqlc                 C   s|   |  \}}}}|  \}}}}	|jD ]}
||
d  q|jD ]}
|	|
d  q| |j| |jkp=|||f|||	fkS r*   )deconstructnon_db_attrspopr]   r   )r@   r/   r2   r+  old_pathold_args
old_kwargsnew_pathnew_args
new_kwargsattrr   r   r   r6    s   

z1BaseDatabaseSchemaEditor._field_should_be_alteredc                 C   s   |j o|j S r*   )rI  r   r@   r'   r   r   r   r   r    r^   z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r*   r   r@   r/   r2   r   r   r   rF    r^   z2BaseDatabaseSchemaEditor._field_became_primary_keyc                 C   s   |j  o|jo|j p|j S r*   )r   r   r  r   r   r   rU    s
   z0BaseDatabaseSchemaEditor._unique_should_be_addedc                 C   s*   | j | || |j| |j|d S )N)rs   
old_column
new_columnr   )sql_rename_columnr]   r   )r@   rs   r/   r2   r=  r   r   r   rL    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)rs   r   r   rh   ri   r  )r	   r"   r~   r]   r"  r   r   target_fieldr'   r:   r\   r#  r   sql_create_fk)
r@   r'   r   r   rs   r   r   rh   ri   r  r   r   r   r     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*   r]   rW  r  rE   r   r   create_fk_name     zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer   )r   r"   r~   r   r   r  r'   )r@   r'   r   r   r  r   rE   r   r"    s   z,BaseDatabaseSchemaEditor._fk_constraint_namec                 C      |  | j||S r*   )r  sql_delete_fkr@   r'   r   r   r   r   r0       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 )NrO   z DEFERRABLE INITIALLY DEFERREDz DEFERRABLE INITIALLY IMMEDIATE)r   DEFERRED	IMMEDIATE)r@   r  r   r   r   _deferrable_constraint_sql  s   

z3BaseDatabaseSchemaEditor._deferrable_constraint_sqlc	              	      s   |r	 j jjs	d S |s|s|s|r' j|||||||d}	|	r% j|	 d S  jd fdd|D  |d }
 j	 
||
d S )N)r   r  r  r  r  rr   c                    s   g | ]}  |jqS r   )r]   r   rb   rE   r   r   rc     rd   z8BaseDatabaseSchemaEditor._unique_sql.<locals>.<listcomp>)r	  r  r   rp   )r:   r=   &supports_deferrable_unique_constraintsrv   rB   rV   sql_unique_constraintr   r  sql_constraintr]   )r@   r'   r   r   r  r  r  r  r  rK   rp   r   rE   r   _unique_sql  s4   	z$BaseDatabaseSchemaEditor._unique_sqlc	                 C   s  |r| j jjr|r| j jjr|r| j jjr|r| j jjsd S t|ddj| j d}	|jj	}
dd |D }|d u rA| j
|
|dd}n| |}|sN|sN|sN|rR| j}n| j}|ra| j|
|d|d	}nt|
||	| j}t|t|
| j||| || || ||d
S )NFr  re   c                 S   r  r   r  rb   r   r   r   rc   0  r   z?BaseDatabaseSchemaEditor._create_unique_sql.<locals>.<listcomp>Tr   r   )r  r  )rs   r   r	  r  r  r  )r:   r=   r  supports_partial_indexesr  r   r   r  r"   r~   r  r]   sql_create_unique_indexsql_create_uniquer  r   rY   r   r	   r  r  r  )r@   r'   r   r   r  r  r  r  r  r  rs   r	  rK   r   r   r   rv     sT   


z+BaseDatabaseSchemaEditor._create_unique_sqlc                    s&   |r	 fdd}n j }t||d|S )Nc                     r  r*   r  r  rE   r   r   create_unique_nameL  r  zLBaseDatabaseSchemaEditor._unique_constraint_name.<locals>.create_unique_name_uniq)rW  r   )r@   rs   r	  r   r  r   rE   r   r  I  s   z0BaseDatabaseSchemaEditor._unique_constraint_namec           	      C   sh   |r| j jjr|r| j jjr|r| j jjr|r| j jjsd S |s&|s&|s&|r*| j}n| j}| |||S r*   )	r:   r=   r  r  r  r   r   r   r  )	r@   r'   r   r  r  r  r  r  rK   r   r   r   rG  T  s*   z+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j | || jd|i d S )Nrf   r  )r  r]   rz   )r@   r   rf   r   r   r   
_check_sqlp  s   z#BaseDatabaseSchemaEditor._check_sqlc                 C   s$   t | jt|jj| j| ||dS )N)rs   r   rf   )r   sql_create_checkr	   r"   r~   r]   )r@   r'   r   rf   r   r   r   rX  v  s   z*BaseDatabaseSchemaEditor._create_check_sqlc                 C   r  r*   )r  sql_delete_checkr  r   r   r   rK  ~  r  z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| j| |dS r  )r   r	   r"   r~   r]   )r@   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:   introspectionidentifier_converter)r-   r   rE   r   r   rc     s    z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r	  r   r   r   rf   r/  r   )r:   rZ   r  get_constraintsr"   r~   itemsrV   )r@   r'   r  r   r   r   r/  rf   r?  r   rZ   r   resultr   infodictr   rE   r   r     s8   

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~   rF   _delete_primary_key_sql)r@   r'   r9  r
  rZ  r   r   r   rT    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 )N_pkrC  )rs   r   r	  )	r   sql_create_pkr	   r"   r~   r]   rW  r   r   r  r   r   r   rV    s   z0BaseDatabaseSchemaEditor._create_primary_key_sqlc                 C   r  r*   )r  sql_delete_pkr  r   r   r   r    r  z0BaseDatabaseSchemaEditor._delete_primary_key_sqlc                 C   s   d|  | S )NzCOLLATE )r]   )r@   r   r   r   r   r     r^   z%BaseDatabaseSchemaEditor._collate_sqlc                 C   s*   | j | |d|d }| | d S )N,)	procedureparam_types)sql_delete_procedurer]   r   rF   )r@   procedure_namer  rK   r   r   r   remove_procedure  s
   z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)rO   r*   )NNNNN)NNNNNN)T)NNNNNNNN)m__name__
__module____qualname____doc__r   r  r  r   r$  r&  rz  ru  rv  ry  rx  rw  r{  r1  r  rS  r  rz   sql_delete_constraintr  r  r  r  r   r  r   r!  r  r  r  r  r   r  r  r  rA   rD   rG   rF   r]   r   r   rx   r   r   r   r   staticmethodr   r   rY   r   r   r   r   r   r   r   r   r   r   r  r  r-  r5  r>  r8  rP  r%  rO  rN  r7  rW  r  r  r  r   rJ  r   r  r   r'  r6  r  rF  rU  rL  r   r"  r0  r  r  rv   r  rG  r  rX  rK  r  r   rT  rV  r  r   r  r   r   r   r   r9   K   s0   
	
	Q
7	
	
"H
 I
  [
&
 
 
6	
,

5



)r9   )loggingr$   r   django.confr   !django.db.backends.ddl_referencesr   r   r   r   r   r	   django.db.backends.utilsr
   r   django.db.modelsr   r   django.db.models.sqlr   django.db.transactionr   r   django.utilsr   	getLoggerrR   r   r(   r4   r9   r   r   r   r   <module>   s     
