o
    [hA                    @   s   d dl Z d dlZd dlm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mZ d dlmZmZ d dl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)
FieldError)ColumnsExpressionsForeignKeyName	IndexName	StatementTable)names_digestsplit_identifiertruncate_name)
DeferrableIndex)CompositePrimaryKey)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   /home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/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reverseZinclude_hiddenZinclude_parentsr   )key)sorted_metaZ_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>:       
z+_related_non_m2m_objects.<locals>.<genexpr>c                 3   r&   r'   r(   r)   )	new_fieldr   r   r-   ?   r.   )zipr%   r$   _related_non_m2m_objectsremote_field)r,   r/   Zrelated_fieldsold_relnew_relr   )r/   r,   r   r1   6   s    


r1   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#dZ$eZ%dZ&dZ'd Z(dd#d$Z)d%d& Z*d'd( Z+dd*d+Z,d,d- Z-d.d/ Z.d0d1 Z/dd2d3Z0d4d5 Z1d6d7 Z2d8d9 Z3d:d; Z4d<d= Z5d>d? Z6e7d@dA Z8dBdC Z9dDdE Z:dFdG Z;dHdI Z<dJdK Z=dLdM Z>dNdO Z?dPdQ Z@dRdS ZAdTdU ZBdVdW ZCdXdY ZDdZd[ ZEd\d] ZFd^d_ ZGd`da ZHdbdc ZIddddeZJdfdg ZK	!ddhdiZLdjdk ZMddldmZN	!ddndoZOdpdq ZPdrds ZQdtdu ZRdvdw ZSddydzZTdd{d|ZUd}d~ ZVdd ZWdddxdxdd)dd)ddddddZXdddZYdd ZZdd Z[dd Z\dd Z]dddZ^dd Z_dd Z`dd Zadd Zbdd Zcdd Zddd Zedd Zfdd Zg					dddZh						dddZi							dddZjdddZk						dddZldd Zmdd Zndd Zodd Zp								dddZqdd ZrdddZsdd Ztdd ZudddZvdddZwd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)sz2ALTER COLUMN %(column)s TYPE %(type)s%(collation)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)%(deferrable)szCHECK (%(check)s)z.ALTER TABLE %(table)s DROP CONSTRAINT %(name)sz"CONSTRAINT %(name)s %(constraint)szPRIMARY KEY (%(columns)s)z?ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)zbALTER TABLE %(table)s ADD CONSTRAINT %(name)s UNIQUE%(nulls_distinct)s (%(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)szaCREATE UNIQUE INDEX %(name)s ON %(table)s (%(columns)s)%(include)s%(nulls_distinct)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)sz)COMMENT ON TABLE %(table)s IS %(comment)sz5COMMENT ON COLUMN %(table)s.%(column)s IS %(comment)sFTc                 C   s,   || _ || _| jrg | _| j jjo|| _d S r'   )
connectioncollect_sqlcollected_sqlfeaturescan_rollback_ddlatomic_migration)selfr6   r7   r   r   r   r   __init__   s
   z!BaseDatabaseSchemaEditor.__init__c                 C   s(   g | _ | jrt| jj| _| j  | S r'   )deferred_sqlr;   r   r6   alias	__enter__r<   r   r   r   r@      s
   
z"BaseDatabaseSchemaEditor.__enter__c                 C   s>   |d u r| j D ]}| |d  q| jr| j||| d S d S r'   )r>   executer;   r   __exit__)r<   exc_type	exc_value	tracebacksqlr   r   r   rC      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))paramsrG   )extra; N)r7   r6   Zin_atomic_blockr9   r:   r   strloggerdebugrstripendswithr8   appendtuplemapquote_valuecursorrB   )r<   rG   rH   endingrU   r   r   r   rB      s.   "z BaseDatabaseSchemaEditor.executec                 C   s   | j j|S r'   )r6   ops
quote_name)r<   r   r   r   r   rX         z#BaseDatabaseSchemaEditor.quote_namec                    sR   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"g }|rӈ j jD ]}j|  qn| fdd j jD   j j}t|tr| |j! 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r6   check z %s)to_table	to_column_fk_%(to_table)s_%(to_column)sz%s %s)Z	AutoFieldZBigAutoFieldZSmallAutoFieldc                 3   s    | ]	}|  V  qd S r'   )Zconstraint_sqlr*   
constraintr$   r<   r   r   r-     s
    

z5BaseDatabaseSchemaEditor.table_sql.<locals>.<genexpr>, c                 s   s    | ]	}|rt |V  qd S r'   )rL   )r*   	statementr   r   r   r-   &  s    
)table
definition)&r    Zunique_togetherr>   rQ   _create_unique_sqllocal_fields
column_sqldb_parametersr6   sql_check_constraintdb_type_suffixextendr2   db_constraintr$   db_tabler\   
field_namecolumnsql_create_inline_fkrX   r9   supports_foreign_keys_create_fk_sqlget_internal_typerW   autoinc_sqlconstraints
create_sqlpk
isinstancer   _pk_constraint_sqlcolumnssql_create_tablejoindb_tablespacetablespace_sql)r<   r$   field_namesfieldsZcolumn_sqlsrH   r   rl   Zextra_params	db_paramscol_type_suffixrc   rd   r|   Zconstraint_sqlsrg   r   rG   r   r   rh   r   	table_sql   s   



	



z"BaseDatabaseSchemaEditor.table_sqlc                 c   s   |V  | d }r| |V  | jjjr |jr | |jV  |j}| r;| 	|\}	}
d|	 V  |
|
 d}|oJ| | oJ|oI| | }|rs| |}|d ursd| | }| jjjrk|| | V  n|V  || |jr|js| jjjrd}|jr| |\}}|
| |V  n|sdV  n| jjjsdV  |jrdV  n|jrdV  |jp|jj}|r| jjjr|jr| jjj|dd	V  d S d S d S d S )
N	collationzDEFAULT FTzNOT NULLZNULLzPRIMARY KEYZUNIQUE)inline)get_collate_sqlr6   r9   supports_comments_inline
db_comment_comment_sqlnullhas_db_defaultdb_default_sqlrs   skip_defaultskip_default_on_altereffective_default_column_default_sqlrequires_literal_defaultsprepare_defaultrQ   empty_strings_allowedr   !interprets_empty_strings_as_nulls	generated_column_generated_sqlZimplied_column_nulluniquer   r    Zsupports_tablespacesrW   r   )r<   column_db_typerH   r$   r   field_db_paramsinclude_defaultr   r   default_sqlZdefault_paramsdefault_valueZcolumn_defaultgenerated_sqlZgenerated_paramsZ
tablespacer   r   r   _iter_column_sql6  sj   

	




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.
        r`   typeNNNrb   )rp   r6   r   r   )r<   r$   r   r   r   r   rH   r   r   r   ro   y  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        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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           	         s   ddl m} |j}t||r |nd}t|jd}|j jd}|	|\}} jj
jr=|t fdd|D ; }g }|| |fS )z;Return the sql and params for the field's database default.r   )Valuez(%s)r#   r`   c                 3       | ]}  |V  qd S r'   )r   r*   prA   r   r   r-         z:BaseDatabaseSchemaEditor.db_default_sql.<locals>.<genexpr>)Zdjango.db.models.expressionsr   Z_db_default_expressionr   r   r   r$   get_compilerr6   compiler9   r   rR   )	r<   r   r   
db_defaultrG   querycompilerr   rH   r   rA   r   r     s   
z'BaseDatabaseSchemaEditor.db_default_sqlc                    sZ   |  j\}}|jrdnd} jjjr#|t fdd|D  }d}d| d| |fS )z3Return the SQL to use in a GENERATED ALWAYS clause.ZSTOREDZVIRTUALc                 3   r   r'   rT   r   rA   r   r   r-     r   zABaseDatabaseSchemaEditor._column_generated_sql.<locals>.<genexpr>r   zGENERATED ALWAYS AS (z) )r   r6   
db_persistr9   r   rR   )r<   r   Zexpression_sqlrH   Zpersistency_sqlr   rA   r   r     s   
z.BaseDatabaseSchemaEditor._column_generated_sqlc                 C   s   |   r
|  }|S | jrd }|S | js(| jr(| jr(|  dkr$d}|S d}|S t| dds4t| ddrZ|  }|dkrBt	 }|S t
	 }|dkrP| }|S |d	krX| }|S d }|S )
NZBinaryField    rK   Zauto_nowFZauto_now_addZDateTimeFieldZ	DateFieldZ	TimeField)has_defaultget_defaultr   r   blankr   r{   getattrr   nowr   datetime)r   defaultZinternal_typer   r   r   _effective_default  s4   	z+BaseDatabaseSchemaEditor._effective_defaultc                 C   s   | | || jS )z2Return a field's effective database default value.)Zget_db_prep_saver   r6   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   rT     s   z$BaseDatabaseSchemaEditor.quote_valuec                 C   s   |  |\}}| ||pd | jjjrG|jjr!| |d|jj | jjjsG|jj	D ]}|j
rF|j| jd}|d }| j| ||||j
  q*| j| | |jjD ]}|jjjjrc| |jj qTdS )zr
        Create a table and any accompanying indexes or unique constraints for
        the given `model`.
        Nr`   r   )r   rB   r6   r9   supports_commentsr    Zdb_table_commentalter_db_table_commentr   rn   r   rp   _alter_column_comment_sqlr>   rs   _model_indexes_sqllocal_many_to_manyr2   throughauto_createdcreate_model)r<   r$   rG   rH   r   r   
field_typer   r   r   r     s0   


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.rk   N)r    r   r2   r   r   delete_modelrB   sql_delete_tablerX   ru   listr>   r   r	   Zreferences_tableremove)r<   r$   r   rG   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rH   )contains_expressionsr6   r9   supports_expression_indexesrB   r~   r<   r$   indexr   r   r   	add_index0  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   r6   r9   r   rB   
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   )r6   r9   Zcan_rename_indexrB   _rename_index_sqlr   r   r   )r<   r$   Z	old_indexZ	new_indexr   r   r   rename_indexD  s   

z%BaseDatabaseSchemaEditor.rename_indexc                 C   s&   | || }|r| j|dd dS dS )zAdd a constraint to a model.Nr   )r~   rB   r<   r$   rg   rG   r   r   r   add_constraintN  s   z'BaseDatabaseSchemaEditor.add_constraintc                 C   s"   | || }|r| | dS dS )z!Remove a constraint from a model.N)r   rB   r   r   r   r   remove_constraintV  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   rR   r*   r   r   r   r   	<setcomp>b      zABaseDatabaseSchemaEditor.alter_unique_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r   c  r   TF)r   r   c                    rZ   r   r[   r]   r#   r   r   r^   n  r_   zBBaseDatabaseSchemaEditor.alter_unique_together.<locals>.<listcomp>N)
difference_delete_composed_indexsql_delete_uniquerB   rm   )r<   r$   Zold_unique_togetherZ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   w  r   z@BaseDatabaseSchemaEditor.alter_index_together.<locals>.<setcomp>c                 S   r   r   r   r   r   r   r   r   x  r   TF)r   r   c                    rZ   r   r[   r]   r#   r   r   r^     r_   zABaseDatabaseSchemaEditor.alter_index_together.<locals>.<listcomp>Z_idx)r   suffixN)r   r   sql_delete_indexrB   _create_index_sql)r<   r$   Zold_index_togetherZnew_index_togetherr   r   r   r   r   r#   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|}|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   rf   r   r   r   r         zBBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<setcomp>c                 S   r   r   r   rf   r   r   r   r         c                    s   g | ]	} j |jqS r   )r    r\   rw   r]   r#   r   r   r^     s    zCBaseDatabaseSchemaEditor._delete_composed_index.<locals>.<listcomp>excluder   TFquote   z1Found wrong number (%s) of constraints for %s(%s)ri   r   )r    r}   indexes_constraint_namesr   r6   r9   Z*allows_multiple_constraints_on_same_fieldsrL   _unique_constraint_nameru   len
ValueErrorr   rB   _delete_constraint_sql)
r<   r$   r   Zconstraint_kwargsrG   meta_constraint_namesmeta_index_namesr   constraint_namesdefault_namer   r#   r   r     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)Z	old_tableZ	new_table)r6   r9   Zignores_table_name_caselowerrB   sql_rename_tablerX   r>   r   r	   Zrename_table_references)r<   r$   Zold_db_tableZnew_db_tablerG   r   r   r   alter_db_table  s"   

z'BaseDatabaseSchemaEditor.alter_db_tablec                 C   sF   | j r| jjjr!| | j | |jj| |pdd  d S d S d S )NrK   )rk   comment)	sql_alter_table_commentr6   r9   r   rB   rX   r    ru   rT   )r<   r$   Zold_db_table_commentZnew_db_table_commentr   r   r   r     s   z/BaseDatabaseSchemaEditor.alter_db_table_commentc                 C   s2   |  | j| |jj| || |d  dS )z)Move a model's table between tablespaces.)rk   Zold_tablespaceZnew_tablespaceN)rB   sql_retablespace_tablerX   r    ru   )r<   r$   Zold_db_tablespaceZnew_db_tablespacer   r   r   alter_db_tablespace  s   z,BaseDatabaseSchemaEditor.alter_db_tablespacec              
   C   sL  |j r|jjjjr| |jjS | j||dd\}}|du r dS |j| jd }r0|d| 7 }|j	| jd}|d rD|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| ||||
rd| |
 nd	| |j| || |	| jj d
  7 }n| j| ||| | j| |jj| |j|d }| ||pd | s| |s|  |dur| j!|d|dd\}}| j"| |jj|d }| || |j#r| jjj$r| jjj%s|d }| j| &||||j#  | 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   Nr`   rb   ra   re   z%s.rK   )r   	namespacerw   rc   rd   
deferrable)rk   rw   rl   droprk   changesr   )+r   r2   r   r    r   r   ro   rr   r6   rp   rq   r9   ry   rt   sql_create_column_inline_fkr$   ru   r\   rv   rw   r   _fk_constraint_namerX   rW   deferrable_sqlr>   rQ   rz   sql_create_columnrB   r   r   r   _alter_column_default_sqlsql_alter_columnr   r   r   r   rs   _field_indexes_sqlconnection_persists_old_columnsclose)r<   r$   r   rl   rH   r   r   Zconstraint_suffixrc   rd   r
  _rG   changes_sqlr   r   r   r   	add_field  s   





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.
        r`   r   NTforeign_key)rk   rw   )r   r2   r   r    r   r   rp   r6   r   rw   rB   _delete_fk_sqlsql_delete_columnrX   ru   r9   r  r  r   r>   r   r	   Zreferences_columnr   )r<   r$   r   fk_namesfk_namerG   r   r   r   remove_field(  s,   




z%BaseDatabaseSchemaEditor.remove_fieldc              
   C   s  |  ||sdS |j| jd}|d }|j| jd}|d }d}	|du r)|jdu s2|du r:|jdu r:t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 r||du r||jjr||jjr||jjjjs||jjjjs|dS |du s|du rtd||f |j	|j	ks|j	r|j
|j
krd}	n!|j	rz|| j}
W n ty   d}	Y nw || j}|
|k}	|	rtd| d	| |||||||| 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.
        Nr`   r   FzqCannot 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)Tz7Modifying GeneratedFields is not supported - the field z6 must be removed and re-added with the new definition.)_field_should_be_alteredrp   r6   r2   r   r   r    r   _alter_many_to_manyr   r   r   r   _alter_field)r<   r$   r,   r/   strictold_db_paramsold_typenew_db_paramsnew_typeZmodifying_generated_fieldZold_field_sqlZnew_field_sqlr   r   r   alter_fieldH  s   



	
z$BaseDatabaseSchemaEditor.alter_fieldc                 C   sD   | j j}|| j }d|d< z	||  | W S  ty!   Y d S w )NZ__column_name__rw   )r6   Zdata_type_check_constraintsZdb_type_parametersr{   KeyError)r<   r   r   Zcheck_constraintsdatar   r   r   _field_db_check  s   z(BaseDatabaseSchemaEditor._field_db_checkc	           2   	   C   sp  t  }	| jjjrL|jrL|jrL| j||dhdrL| j||jgdd}
|r7t	|
dkr7t
dt	|
|jj|jf |
D ]}|	|jf | | || q9|jr|jrX| ||rdd |jjD }| j||jgdd	|d
}|rt	|dkrt
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| ||}| ||}||kr^|r^dd |jjD }| j||jgd|d}|rOt	|dkrOt
dt	||jj|jf |D ]}| | || qQ|j|jkr| |  |jj||| | j!D ]}t"|t#r|$|jj|j|j qug }g }g }|j%| jd}|j%| jd}||ks||ks||ks| jjj&r|j'|j'kr| (||||||\} }!|)|  |*|! |+ r|+ r|j,|j,kr|)| -||| n|+ r|)| j-|||dd d	}"|j.r2|j.s2|+ s2| /|}#| /|}$| 0|s2|#|$kr2|$dur2d}"|)| 1||| |j.|j.krH| 2|||} | rH|)|  |3 pP|+ oY|j.oY|j. }%|s`|r|%sg||7 }| jjj4r|rt5t6| \}}&d7|t8|&g fg}|D ]\}}&| | j9| :|jj|d |& q|%r|+ sd}'|$g}&n| ;|\}'}&| | j<| :|jj| :|j|'d |& |D ]\}}&| | j9| :|jj|d |& q|r|D ]\}}&| ||& q|jr|js| =|| | >||r| | ?||g |jr|jr+|jr+|js+| | j@||gd g }(|r8|(*t|| | ||rP| | A|| |(*t|| |(D ]V\})}|jjB| jd}*|*d }+|*d},|)jjB| jd}-|-d}.| (|j|)j|j|+|.|,\} }!| | j9| :|jjj| d d | d  |!D ]\}}&| ||& qqR| jjjr|jr|	s|jr|js|jr| | C||d |r|(D ]\}/}0|0jjr| | C|0j|0jd q||kr|r| jD|jj|jgdd}| | E|||d   |"r)| j1|||dd\}1}&| j9| :|jj|1d }| ||& | jjjFr6| jG  dS dS )!z3Perform a "physical" (non-ManyToMany) field update.r   )ignoreTr  r   z<Found wrong number (%s) of foreign key constraints for %s.%sc                 S   r   r   r   rf   r   r   r   r     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   c                 S   r   r   r   rf   r   r   r   r     r   )ra   r   z6Found wrong number (%s) of check constraints for %s.%sr`   r  Nri   r  r   )rk   rw   r   r   r   r   re   Z_fk_checkr   ra   )Hsetr6   r9   ry   r2   rt   r#  r   rw   r   r   r    ru   addrB   r  r   _field_became_primary_keyr}   _delete_unique_sqlr   r   r1   Zrelated_modelr   db_indexr   r   r   _delete_index_sqlr.  _delete_check_sql_rename_field_sqlr>   r   r	   Zrename_column_referencesrr   r   r   _alter_column_type_sqlrQ   rs   r   r   "_alter_column_database_default_sqlr   r   r   r  _alter_column_null_sqlr   Zsupports_combined_altersrR   r0   r   sumr  rX   r   sql_update_with_default_delete_primary_key_unique_should_be_addedrm   r   _create_primary_key_sqlrp   rz   _create_index_name_create_check_sqlr  r  )2r<   r$   r,   r/   r(  r*  r'  r)  r&  Zfks_droppedr   r!  r   r  constraint_nameold_collationnew_collationZdrop_foreign_keysZ_old_relr4   Zrel_fk_namesr   Zindex_names
index_nameZold_db_checkZnew_db_checkrG   actionsZnull_actionsZpost_actionsZold_type_suffixZnew_type_suffixfragmentother_actionsZneeds_database_defaultZold_defaultnew_defaultZfour_way_default_alterationrH   r   Zrels_to_updater3   Zrel_db_paramsZrel_typeZrel_collationZold_rel_db_paramsZold_rel_collationr  relr  r   r   r   r%    sV  

























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.
        Nr`   r   )rw   r   )
r6   r9   r   r   rp   r   sql_alter_column_nullsql_alter_column_not_nullrX   rw   )r<   r$   r,   r/   r)  rG   r   r   r   r>    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.
        r`   r   rw   r   r   )r   r   r6   r9   r   r   rp   r    sql_alter_column_no_default_nullsql_alter_column_no_defaultsql_alter_column_defaultrX   rw   )
r<   r$   r,   r/   r  rM  r   rH   r)  rG   r   r   r   r  3  s,   




z2BaseDatabaseSchemaEditor._alter_column_default_sqlc           	      C   sV   |r
| j }d}g }n
| j}| |\}}|j| jd}|| |j|d |d |fS )z
        Hook to specialize column database default alteration.

        Return a (sql, params) fragment to add or drop (depending on the drop
        argument) a default to new_field's column.
        rK   r`   r   rQ  )rS  rT  r   rp   r6   rX   rw   )	r<   r$   r,   r/   r  rG   r   rH   r)  r   r   r   r=  Y  s   	
z;BaseDatabaseSchemaEditor._alter_column_database_default_sqlc                 C   s   g }|  |||jj }rd| }nd}d}	| jjjrB|jsB|j|jkr9| ||||j\}
}|
r9|	|
|f |jrB| 
|j}	| j| |j|||	d g f|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 2-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.
        rb   rK   )rw   r   r   r  )r   r    ru   r6   r9   r   r   r   r   rQ   r   sql_alter_column_typerX   rw   )r<   r$   r,   r/   r*  rG  rH  rL  Zcollate_sqlZcomment_sqlrG   rH   r   r   r   r<  u  s6   



z/BaseDatabaseSchemaEditor._alter_column_type_sqlc                 C   s.   | j | |jj| |j| |d g fS )N)rk   rw   r  )sql_alter_column_commentrX   r    ru   rw   r   )r<   r$   r/   r*  Znew_db_commentr   r   r   r     s   
z2BaseDatabaseSchemaEditor._alter_column_comment_sqlc                 C   s   |  |pdS )NrK   r   )r<   r  r   r   r   r     rY   z%BaseDatabaseSchemaEditor._comment_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)	r2   r   r    ru   r  r+  r\   Zm2m_reverse_field_nameZm2m_field_name)r<   r$   r,   r/   r&  r   r   r   r$    s,   





z,BaseDatabaseSchemaEditor._alter_many_to_manyrK   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   r6   rW   max_name_lengthr   r   isdigit)	r<   
table_namecolumn_namesr   r  Zhash_suffix_part
max_lengthrI  Zother_lengthr   r   r   rD    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   rb   rK   )r   r   r   ZDEFAULT_INDEX_TABLESPACEr    r6   rW   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 rK   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 )NrK   z INCLUDE (%(columns)s))r   )r6   r9   supports_covering_indexesr	   r   r    ru   rX   )r<   r$   r   r   r   r   _index_include_sql  s   z+BaseDatabaseSchemaEditor._index_include_sql)r   r   r   usingr   col_suffixesrG   	opclassesrc  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_colsr`   )r   c                 S      g | ]}|j qS r   rw   r]   r   r   r   r^   '  r   z>BaseDatabaseSchemaEditor._create_index_sql.<locals>.<listcomp>c                     s"    d u rj | i |  S r'   )rD  rX   argskwargsr   r<   r   r   create_index_name+  s   
zEBaseDatabaseSchemaEditor._create_index_sql.<locals>.create_index_name)rk   r   rg  r   rI   rc  rj  )r   r   r6   rb  sql_create_indexr    ru   r	   r
   rX   r   _index_columnsr   rT   rd  rf  )r<   r$   r   r   r   rg  r   rh  rG   ri  rc  rj  rk  r   r   r   rt  rk   rs  r   rr  r   r   
  s0   


z*BaseDatabaseSchemaEditor._create_index_sqlc                 C   sr   t |p| jt|jj| j| |d}|jd j}|jd }t| j	D ]}t
|t r6|||r6| j	| q#|S )Nrk   r   rk   r   )r	   r   r
   r    ru   rX   partsrk   r   r>   r   Zreferences_indexr   )r<   r$   r   rG   rj   r_  rI  r   r   r   r9  @  s   
z*BaseDatabaseSchemaEditor._delete_index_sqlc                 C   s*   t | jt|jj| j| || |dS )N)rk   old_namenew_name)r	   sql_rename_indexr
   r    ru   rX   )r<   r$   rx  ry  r   r   r   r   R  s   z*BaseDatabaseSchemaEditor._rename_index_sqlc                 C   s   t ||| j|dS )N)rh  )r   rX   )r<   rk   r   rh  ri  r   r   r   ru  Z  s   z'BaseDatabaseSchemaEditor._index_columnsc                 C   st   |j jr|j js|j jrg S g }|j jD ]}|| || q|j jD ]}|jr.| j	j
jr7||||  q$|S )zz
        Return a list of all index SQL statements (field indexes, Meta.indexes)
        for the specified model.
        )r    ZmanagedproxyZswappedrn   rs   r  r   r   r6   r9   r   rQ   r~   )r<   r$   outputr   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.
        r1  )_field_should_be_indexedrQ   r   )r<   r$   r   r|  r   r   r   r  p  s   z+BaseDatabaseSchemaEditor._field_indexes_sqlc                 C   s   |j s|j sdS |pt }| \}}}}| \}}}	}
||jD ]}||d  q#||jD ]}|
|d  q2|js\|jr\|jr\|jjj	j
|jjj	j
kr\|dd  |
dd  |drz|
drz| || |krz|d |
d | |j| |jkp|||f||	|
fkS )NFtor   )Zconcreter4  ZdeconstructunionZnon_db_attrspopr   r2   r$   r    ru   r   r   rX   rw   )r<   r,   r/   r/  r  old_pathZold_argsZ
old_kwargsnew_pathnew_argsZ
new_kwargsattrr   r   r   r#  y  s@   




z1BaseDatabaseSchemaEditor._field_should_be_alteredc                 C   s   |j o|j S r'   )r8  r   r<   r$   r   r   r   r   r}    rY   z1BaseDatabaseSchemaEditor._field_should_be_indexedc                 C   s   |j  o|j S r'   r   r<   r,   r/   r   r   r   r6    rY   z2BaseDatabaseSchemaEditor._field_became_primary_keyc                 C   s   |j  o|jo|j p|j S r'   )r   r   r  r   r   r   rB    s
   z0BaseDatabaseSchemaEditor._unique_should_be_addedc                 C   s*   | j | || |j| |j|d S )N)rk   Z
old_columnZ
new_columnr   )sql_rename_columnrX   rw   )r<   rk   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)rk   r   rw   rc   rd   r  )r
   r    ru   rX   r  r   rw   target_fieldr$   r6   rW   r  r	   sql_create_fk)
r<   r$   r   r   rk   r   rw   rc   rd   r  r   r   r   rz     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'   rX   rD  ro  rA   r   r   create_fk_name     zDBaseDatabaseSchemaEditor._fk_constraint_name.<locals>.create_fk_namer   )r   r    ru   rw   r   r  r$   )r<   r$   r   r   r  r   rA   r   r    s   z,BaseDatabaseSchemaEditor._fk_constraint_namec                 C      |  | j||S r'   )r   sql_delete_fkr<   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 )NrK   z DEFERRABLE INITIALLY DEFERREDz DEFERRABLE INITIALLY IMMEDIATE)r   ZDEFERREDZ	IMMEDIATE)r<   r  r   r   r   _deferrable_constraint_sql  s   

z3BaseDatabaseSchemaEditor._deferrable_constraint_sqlc                 C   s   |du rdS |du rdS dS )NFz NULLS NOT DISTINCTTz NULLS DISTINCTrK   r   )r<   nulls_distinctr   r   r    _unique_index_nulls_distinct_sql  s
   z9BaseDatabaseSchemaEditor._unique_index_nulls_distinct_sqlc                 C   sR   | s| j jjo(| p| j jjo(| p| j jjo(| p| j jjo(|d u p(| j jjS r'   )r6   r9   Zsupports_partial_indexesZ&supports_deferrable_unique_constraintsre  r   Z*supports_nulls_distinct_unique_constraints)r<   rc  r  rj  rk  r  r   r   r   _unique_supported  s   	
z*BaseDatabaseSchemaEditor._unique_supportedc
              
      s    j |||||	dsd S |s|s|s|s|	d ur/ j||||||||	d}
|
r- j|
 d S  jd fdd|D  |d } j ||d S )Nrc  r  rj  rk  r  )r   rc  rj  ri  rk  r  ri   c                    s   g | ]}  |jqS r   )rX   rw   r]   rA   r   r   r^   +  r_   z8BaseDatabaseSchemaEditor._unique_sql.<locals>.<listcomp>)r   r  r   rg   )	r  rm   r>   rQ   sql_unique_constraintr   r  sql_constraintrX   )r<   r$   r   r   rc  r  rj  ri  rk  r  rG   rg   r   rA   r   _unique_sql  sL   
z$BaseDatabaseSchemaEditor._unique_sqlc
                 C   s   | j |||||	dsd S t|ddj| jd}
|jj}dd |D }|d u r/| j||dd}n| |}|s<|s<|s<|r@| j}n| j	}|rO| j
||d	|d
}nt|||
| j}t|t|| j||| || || ||| |	dS )Nr  Frl  r`   c                 S   rm  r   rn  r]   r   r   r   r^   L  r   z?BaseDatabaseSchemaEditor._create_unique_sql.<locals>.<listcomp>Tr   r   )rh  ri  )rk   r   r   rc  r  rj  r  )r  r   r   r6   r    ru   r   rX   sql_create_unique_indexsql_create_uniqueru  r   rT   r	   r
   rd  r  rf  r  )r<   r$   r   r   rc  r  rj  ri  rk  r  r   rk   r   rG   r   r   r   rm   3  sD   


z+BaseDatabaseSchemaEditor._create_unique_sqlc                    s&   |r	 fdd}n j }t||d|S )Nc                     r  r'   r  ro  rA   r   r   create_unique_namei  r  zLBaseDatabaseSchemaEditor._unique_constraint_name.<locals>.create_unique_name_uniq)rD  r   )r<   rk   r   r   r  r   rA   r   r   f  s   z0BaseDatabaseSchemaEditor._unique_constraint_namec	           
      C   sD   | j |||||dsd S |s|s|s|r| j}	n| j}	| |	||S )Nr  )r  r   r   r   )
r<   r$   r   rc  r  rj  ri  rk  r  rG   r   r   r   r7  q  s   z+BaseDatabaseSchemaEditor._delete_unique_sqlc                 C   s    | j | || jd|i d S )Nra   r  )r  rX   rq   )r<   r   ra   r   r   r   
_check_sql  s   z#BaseDatabaseSchemaEditor._check_sqlc                 C   s2   | j jjsd S t| jt|jj| j| ||dS )N)rk   r   ra   )	r6   r9    supports_table_check_constraintsr	   sql_create_checkr
   r    ru   rX   )r<   r$   r   ra   r   r   r   rE    s   
z*BaseDatabaseSchemaEditor._create_check_sqlc                 C   s   | j jjsd S | | j||S r'   )r6   r9   r  r   sql_delete_checkr  r   r   r   r:    s   
z*BaseDatabaseSchemaEditor._delete_check_sqlc                 C   s    t |t|jj| j| |dS )Nrv  )r	   r
   r    ru   rX   )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jr j jt| j j n j j|qS r   )r6   r9   Ztruncates_namesintrospectionZidentifier_converterr   rW   r]  )r*   r   rA   r   r   r^     s    
z>BaseDatabaseSchemaEditor._constraint_names.<locals>.<listcomp>r   r   r   r   ra   r  r   )r6   rU   r  Zget_constraintsr    ru   itemsrQ   )r<   r$   r`  r   r   r   r  ra   r0  r   rU   r}   resultr   Zinfodictr   rA   r   r     s8   


z*BaseDatabaseSchemaEditor._constraint_namesc                    s"    j dd fdd|D i S )Nr   ri   c                 3   r   r'   rX   )r*   rw   rA   r   r   r-     r   z>BaseDatabaseSchemaEditor._pk_constraint_sql.<locals>.<genexpr>)sql_pk_constraintr   )r<   r   r   rA   r   r     s   z+BaseDatabaseSchemaEditor._pk_constraint_sqlc                 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    ru   rB   _delete_primary_key_sql)r<   r$   r&  r  rF  r   r   r   rA    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_pkr3  )rk   r   r   )	r	   sql_create_pkr
   r    ru   rX   rD  rw   r   r  r   r   r   rC    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   |r	d|  | S dS )NzCOLLATE rK   r  )r<   r   rG  r_  r   r   r   r     r  z%BaseDatabaseSchemaEditor._collate_sqlc                 C   s*   | j | |d|d }| | d S )N,)Z	procedureparam_types)sql_delete_procedurerX   r   rB   )r<   Zprocedure_namer  rG   r   r   r   remove_procedure  s
   z)BaseDatabaseSchemaEditor.remove_procedure)FT)r   )F)rK   r'   )NNNNN)NNNNNN)NNNNNNN)T)NNNNNNNNr   )x__name__
__module____qualname____doc__r   r  r  r   r  r  rU  rO  rP  rT  rS  rR  r  r  r@  r  rq   Zsql_delete_constraintr  r  r  r  r  r   r  rx   r  r  rt  r  rz  r   r  r  r  r  rV  r=   r@   rC   rB   rX   r   r   ro   r   r   r   r   r   r   staticmethodr   r   rT   r   r   r   r   r   r   r   r   r   r   r  r   r	  r  r"  r+  r.  r%  r>  r  r=  r<  r   r   r$  rD  rb  rd  rf  r   r9  r   ru  r   r  r#  r}  r6  rB  r;  rz   r  r  r  r  r  r  rm   r   r7  r  rE  r:  r   r   r   rA  rC  r  r   r  r   r   r   r   r5   M   sX   
	
	e
C		
#	
"
X
 S
  r
'
.
 
 
6
	%	

8

3



/

r5   )$loggingr!   r   Zdjango.confr   Zdjango.core.exceptionsr   Z!django.db.backends.ddl_referencesr   r   r   r   r	   r
   Zdjango.db.backends.utilsr   r   r   Zdjango.db.modelsr   r   Z!django.db.models.fields.compositer   Zdjango.db.models.sqlr   Zdjango.db.transactionr   r   Zdjango.utilsr   	getLoggerrM   r   r%   r1   r5   r   r   r   r   <module>   s"     
