U
    fI                     @   s   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
 d dlmZ d dlmZ d dlmZ d d	lmZ G d
d deZdS )    N)settings)BaseDatabaseOperationssplit_tzname_delta)ExistsExpressionWrapperLookup)
OnConflict)timezone)	force_str)_lazy_re_compilec                       s  e Zd ZdZejddddZdddddd	dddd
d
d
ddZd	ZdZe	dZ
dd Zd]ddZdd Zdd Zdd Zdd Zdd Zdd Zd^dd Zd!d" Zd#d$ Zd%d& Zd_d'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d1d2d3d4Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z# fdCdDZ$ fdEdFZ%dGdH Z&dIdJ Z'dKdL Z(dMdN Z)dOdP Z*d` fdQdR	Z+dSdT Z,da fdUdV	Z-dbdWdXZ. fdYdZZ/ fd[d\Z0  Z1S )cDatabaseOperationsz!django.db.backends.mysql.compiler)r   i  )r   l    )r       )PositiveSmallIntegerFieldPositiveIntegerFieldPositiveBigIntegerFieldzsigned integerzchar(%(max_length)s)z+decimal(%(max_digits)s, %(decimal_places)s)charzunsigned integer)Z	AutoFieldZBigAutoFieldZSmallAutoFieldZ	CharFieldZDecimalFieldZ	TextFieldZIntegerFieldZBigIntegerFieldZSmallIntegerFieldr   r   r   ZDurationFieldZEXPLAINz[A-Z_]+c                 C   s   |dkrd| d|fS |dkr0d| d|fS |dkrHd| d	|fS |d
kr`d| d|fS |  }| j|std|d| d| d|fS d S )NZweek_dayz
DAYOFWEEK()Ziso_week_dayzWEEKDAY(z) + 1weekzWEEK(z, 3)Ziso_yearzTRUNCATE(YEARWEEK(z, 3), -2) / 100zInvalid loookup type: zEXTRACT(z FROM )upper_extract_format_re	fullmatch
ValueError)selflookup_typesqlparams r   G/tmp/pip-unpacked-wheel-_jot26k8/django/db/backends/mysql/operations.pydate_extract_sql,   s    z#DatabaseOperations.date_extract_sqlNc                 C   s   |  |||\}}ddd}||krB|| }d| d||ffS |dkrdd| d| d	||fS |d
krd| d| d||fS d| d|fS d S )Nz%Y-01-01z%Y-%m-01)yearmonthCAST(DATE_FORMAT(z, %s) AS DATE)quarterzMAKEDATE(YEAR(), 1) + INTERVAL QUARTER(z) QUARTER - INTERVAL 1 QUARTERr   z	DATE_SUB(, INTERVAL WEEKDAY(z) DAY)DATE(r   _convert_sql_to_tzr   r   r   r   tznamefields
format_strr   r   r   date_trunc_sqlD   s    z!DatabaseOperations.date_trunc_sqlc                 C   s"   t |\}}}|r| | S |S Nr   )r   r*   signoffsetr   r   r   _prepare_tzname_deltaX   s    z(DatabaseOperations._prepare_tzname_deltac                 C   s@   |r8t jr8| jj|kr8d| d|| jj| |ffS ||fS )NzCONVERT_TZ(z	, %s, %s))r   USE_TZ
connectionZtimezone_namer1   r   r   r   r*   r   r   r   r(   \   s    
z%DatabaseOperations._convert_sql_to_tzc                 C   s"   |  |||\}}d| d|fS )Nr&   r   r'   r4   r   r   r   datetime_cast_date_sqle   s    z)DatabaseOperations.datetime_cast_date_sqlc                 C   s"   |  |||\}}d| d|fS )NTIME(r   r'   r4   r   r   r   datetime_cast_time_sqli   s    z)DatabaseOperations.datetime_cast_time_sqlc                 C   s    |  |||\}}| |||S r.   )r(   r   )r   r   r   r   r*   r   r   r   datetime_extract_sqlm   s    z'DatabaseOperations.datetime_extract_sqlc           
      C   s   |  |||\}}ddddddg}d}d}|d	krNd
| d| d||dfS |dkrrd| d| d||dfS z||d }W n tk
r   Y n6X d|d | ||d   }	d| d||	ffS ||fS )Nr    r!   dayhourminutesecond)z%Y-z%mz-%dz %H:z%iz:%s)z0000-Z01z-01z 00:Z00z:00r#   zCAST(DATE_FORMAT(MAKEDATE(YEAR(r$   z0) QUARTER - INTERVAL 1 QUARTER, %s) AS DATETIME)%Y-%m-01 00:00:00r   zCAST(DATE_FORMAT(DATE_SUB(r%   z) DAY), %s) AS DATETIME)%Y-%m-%d 00:00:00    r"   z, %s) AS DATETIME))r=   )r>   )r(   indexr   join)
r   r   r   r   r*   r+   formatZ
format_defir,   r   r   r   datetime_trunc_sqlq   s&    z%DatabaseOperations.datetime_trunc_sqlc                 C   sX   |  |||\}}dddd}||krD|| }d| d||ffS d| d|fS d S )	Nz%H:00:00z%H:%i:00z%H:%i:%s)r:   r;   r<   r"   z, %s) AS TIME)r6   r   r'   r)   r   r   r   time_trunc_sql   s    z!DatabaseOperations.time_trunc_sqlc                 C   s   |  S )z
        Given a cursor object that has just performed an INSERT...RETURNING
        statement into a table, return the tuple of returned data.
        )Zfetchall)r   cursorr   r   r   fetch_returned_insert_rows   s    z-DatabaseOperations.fetch_returned_insert_rowsc                 C   s   d| S )NzINTERVAL %s MICROSECONDr   )r   r   r   r   r   format_for_duration_arithmetic   s    z1DatabaseOperations.format_for_duration_arithmeticc                 C   s   ddg dffgS )z
        "ORDER BY NULL" prevents MySQL from implicitly ordering by grouped
        columns. If no ordering would otherwise be applied, we don't want any
        implicit sorting going on.
        NNULLFr   r   r   r   r   force_no_ordering   s    z$DatabaseOperations.force_no_orderingc                 C   s   |S r.   r   )r   valueZ
max_digitsZdecimal_placesr   r   r   adapt_decimalfield_value   s    z+DatabaseOperations.adapt_decimalfield_valuec                 C   s   t t|dd ddS )NZ	_executedreplace)errors)r   getattr)r   rG   r   r   r   r   r   last_executed_query   s    z&DatabaseOperations.last_executed_queryc                 C   s   dS )Nr   r   rK   r   r   r   no_limit_value   s    z!DatabaseOperations.no_limit_valuec                 C   s    | dr|dr|S d| S )N`z`%s`)
startswithendswith)r   namer   r   r   
quote_name   s    zDatabaseOperations.quote_namec                    s,   |sdS  fdd|D }dd | dfS )N)r@   r   c                    s,   g | ]$}d   |jjj  |jf qS )z%s.%s)rX   modelZ_metaZdb_tablecolumn.0fieldrK   r   r   
<listcomp>   s   
z<DatabaseOperations.return_insert_columns.<locals>.<listcomp>zRETURNING %s, r   rB   )r   r+   columnsr   rK   r   return_insert_columns   s    
z(DatabaseOperations.return_insert_columnsF)reset_sequencesallow_cascadec                   sV   |sg S dg}|r.|  fdd|D  n|  fdd|D  |d |S )NzSET FOREIGN_KEY_CHECKS = 0;c                 3   s,   | ]$}d  d |f V  qdS )z%s %s;ZTRUNCATENZSQL_KEYWORDZ	SQL_FIELDrX   r\   Z
table_namer   styler   r   	<genexpr>   s   z/DatabaseOperations.sql_flush.<locals>.<genexpr>c              	   3   s4   | ],}d  d d |f V  qdS )z	%s %s %s;DELETEZFROMNre   rf   rg   r   r   ri      s   zSET FOREIGN_KEY_CHECKS = 1;)extendappend)r   rh   Ztablesrc   rd   r   r   rg   r   	sql_flush   s    
	
zDatabaseOperations.sql_flushc                    s    fdd|D S )Nc                    s>   g | ]6}d  d d |d df qS )z%s %s %s %s = 1;ZALTERZTABLEtableZAUTO_INCREMENTre   )r\   Zsequence_inforg   r   r   r^      s   zADatabaseOperations.sequence_reset_by_name_sql.<locals>.<listcomp>r   )r   rh   	sequencesr   rg   r   sequence_reset_by_name_sql   s    z-DatabaseOperations.sequence_reset_by_name_sqlc                 C   s   |dkr| j jjstd|S )Nr   z@The database backend does not accept 0 as a value for AutoField.)r3   featuresZallows_auto_pk_0r   r   rM   r   r   r   validate_autopk_value   s
    z(DatabaseOperations.validate_autopk_valuec                 C   sL   |d krd S t |dr|S t|rDtjr<t|| jj}ntdt|S )Nresolve_expressionzMMySQL backend does not support timezone-aware datetimes when USE_TZ is False.)	hasattrr
   is_awarer   r2   Z
make_naiver3   r   strrr   r   r   r   adapt_datetimefield_value   s    

z,DatabaseOperations.adapt_datetimefield_valuec                 C   s8   |d krd S t |dr|S t|r,td|jddS )Nrt   z4MySQL backend does not support timezone-aware times.microseconds)Ztimespec)ru   r
   rv   r   	isoformatrr   r   r   r   adapt_timefield_value  s    

z(DatabaseOperations.adapt_timefield_valuec                 C   s   dS )N@   r   rK   r   r   r   max_name_length   s    z"DatabaseOperations.max_name_lengthc                 C   s   dS )NrJ   r   rK   r   r   r   pk_default_value#  s    z#DatabaseOperations.pk_default_valuec                 C   s*   dd |D }d dd |D }d| S )Nc                 s   s   | ]}d  |V  qdS )r_   Nr`   )r\   rowr   r   r   ri   '  s     z5DatabaseOperations.bulk_insert_sql.<locals>.<genexpr>r_   c                 s   s   | ]}d | V  qdS )z(%s)Nr   )r\   r   r   r   r   ri   (  s     zVALUES r`   )r   r+   Zplaceholder_rowsZplaceholder_rows_sqlZ
values_sqlr   r   r   bulk_insert_sql&  s    z"DatabaseOperations.bulk_insert_sqlc                    sh   |dkrdd | S |dkr<|dkr*dn|}d| | S |dkrZ|\}}d||d	 S t ||S )
N^zPOW(%s),)&|z<<#r   zCONVERT(%s, SIGNED)z>>z FLOOR(%(lhs)s / POW(2, %(rhs)s))lhsrhs)rB   supercombine_expression)r   Z	connectorZsub_expressionsr   r   	__class__r   r   r   +  s    z%DatabaseOperations.combine_expressionc                    s`   t  |}|j }|dkr,|| j n0|dkrHtjr\|| j n|dkr\|| j	 |S )NZBooleanFieldZDateTimeFieldZ	UUIDField)
r   get_db_convertersZoutput_fieldZget_internal_typerl   convert_booleanfield_valuer   r2   convert_datetimefield_valueconvert_uuidfield_value)r   
expression
convertersinternal_typer   r   r   r   8  s    
z$DatabaseOperations.get_db_convertersc                 C   s   |dkrt |}|S )N)r   r?   )boolr   rM   r   r3   r   r   r   r   D  s    z-DatabaseOperations.convert_booleanfield_valuec                 C   s   |d k	rt || jj }|S r.   )r
   Z
make_awarer3   r   r   r   r   r   I  s    z.DatabaseOperations.convert_datetimefield_valuec                 C   s   |d k	rt |}|S r.   )uuidUUIDr   r   r   r   r   N  s    
z*DatabaseOperations.convert_uuidfield_valuec                 C   s   |d k	rt |dsdS dS )NZas_sqlz
_binary %s%s)ru   rr   r   r   r   binary_placeholder_sqlS  s    z)DatabaseOperations.binary_placeholder_sqlc           	      C   st   |\}}|\}}|dkr\| j jr6d||d ||fS d||d t|d t|d  fS ||}d||f |fS )NZ	TimeFieldzGCAST((TIME_TO_SEC(%(lhs)s) - TIME_TO_SEC(%(rhs)s)) * 1000000 AS SIGNED)r   zs((TIME_TO_SEC(%(lhs)s) * 1000000 + MICROSECOND(%(lhs)s)) - (TIME_TO_SEC(%(rhs)s) * 1000000 + MICROSECOND(%(rhs)s)))   z"TIMESTAMPDIFF(MICROSECOND, %s, %s))r3   mysql_is_mariadbtuple)	r   r   r   r   Zlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_paramsr   r   r   r   subtract_temporalsX  s0    z%DatabaseOperations.subtract_temporalsc                    s   |r|  dkrd}n|s,d| jjjkr,d}|dd}t j|f|}|rj| jjjrj| jjrbdn|d }|r|rz| jjr|d| 7 }|S )	NZTEXTZTRADITIONALZTREEanalyzeFZANALYZEz ANALYZEz
 FORMAT=%s)	r   r3   rq   Zsupported_explain_formatspopr   explain_query_prefixZsupports_explain_analyzer   )r   rC   optionsr   prefixr   r   r   r   r  s    z'DatabaseOperations.explain_query_prefixc                 C   s0   | j jr|dkrdS dS |dkr$dnd}d| S )Nregexz%s REGEXP BINARY %sz%s REGEXP %scrD   zREGEXP_LIKE(%%s, %%s, '%s')r3   r   )r   r   Zmatch_optionr   r   r   regex_lookup  s    zDatabaseOperations.regex_lookupc                    s   |t jkrdS t j|dS )NzINSERT IGNORE INTO)on_conflict)r	   ZIGNOREr   insert_statement)r   r   r   r   r   r     s    
z#DatabaseOperations.insert_statementc                 C   s$   d}|dkr | j js|dkr d}|S )Nr   Z	JSONField)	ZiexactcontainsZ	icontainsrU   ZistartswithrV   Z	iendswithr   ZiregexzJSON_UNQUOTE(%s)r   )r   r   r   lookupr   r   r   lookup_cast  s
    zDatabaseOperations.lookup_castc                    sJ   t |ttfrdS t |tr.|jr.| |jS t|ddr>dS t |S )NTconditionalF)	
isinstancer   r   r   r   0conditional_expression_supported_in_where_clauser   rQ   r   )r   r   r   r   r   r     s    zCDatabaseOperations.conditional_expression_supported_in_where_clausec                    sz   |t jkrhd}| jjs8| jjdkr2d| }d q<d nd d fdd	t| j|D }|d
|i S t 	||||S )Nz"ON DUPLICATE KEY UPDATE %(fields)s)   r      zAS new z%(field)s = new.%(field)sz%(field)s = VALUES(%(field)s)z%(field)s = VALUE(%(field)s)r_   c                    s   g | ]} d |i qS )r]   r   r[   Z	field_sqlr   r   r^     s   z=DatabaseOperations.on_conflict_suffix_sql.<locals>.<listcomp>r+   )
r	   ZUPDATEr3   r   Zmysql_versionrB   maprX   r   on_conflict_suffix_sql)r   r+   r   Zupdate_fieldsZunique_fieldsZconflict_suffix_sqlr   r   r   r     s(    



z)DatabaseOperations.on_conflict_suffix_sql)N)N)NN)N)N)N)2__name__
__module____qualname__Zcompiler_moduler   Zinteger_field_rangesZcast_data_typesZ"cast_char_field_without_max_lengthZexplain_prefixr   r   r   r-   r1   r(   r5   r7   r8   rE   rF   rH   rI   rL   rN   rR   rS   rX   rb   rm   rp   rs   rx   r{   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r      sz   
	

	

r   )r   Zdjango.confr   Z"django.db.backends.base.operationsr   Zdjango.db.backends.utilsr   Zdjango.db.modelsr   r   r   Zdjango.db.models.constantsr	   Zdjango.utilsr
   Zdjango.utils.encodingr   Zdjango.utils.regex_helperr   r   r   r   r   r   <module>   s   