U
    5i>                     @   sX   d dl Z d dl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)timezone)	force_strc                       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dd Z	dXddZ
dd Zdd Zdd Zdd Zdd Zdd ZdYddZd d! Zd"d# Zd$d% ZdZd&d'Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d0d1d2d3Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Z d@dA Z! fdBdCZ" fdDdEZ#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(d[ fdPdQ	Z)dRdS Z*d\ fdTdU	Z+d]dVdWZ,  Z-S )^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EXPLAINc                 C   sT   |dkrd| S |dkr d| S |dkr0d| S |dkr@d| S d	|  |f S d S )
NZweek_dayzDAYOFWEEK(%s)Ziso_week_dayzWEEKDAY(%s) + 1weekzWEEK(%s, 3)Ziso_yearz#TRUNCATE(YEARWEEK(%s, 3), -2) / 100zEXTRACT(%s FROM %s))upper)selflookup_type
field_name r   G/tmp/pip-unpacked-wheel-gcyiijx6/django/db/backends/mysql/operations.pydate_extract_sql&   s    z#DatabaseOperations.date_extract_sqlNc                 C   sf   |  ||}ddd}||kr2|| }d||f S |dkrFd||f S |dkrZd||f S d	| S d S )
Nz	%%Y-01-01z
%%Y-%%m-01)yearmonthz#CAST(DATE_FORMAT(%s, '%s') AS DATE)quarterzIMAKEDATE(YEAR(%s), 1) + INTERVAL QUARTER(%s) QUARTER - INTERVAL 1 QUARTERr   z&DATE_SUB(%s, INTERVAL WEEKDAY(%s) DAY)DATE(%s)_convert_field_to_tzr   r   r   tznamefields
format_strr   r   r   date_trunc_sql;   s$      z!DatabaseOperations.date_trunc_sqlc                 C   s"   t |\}}}|r| | S |S Nr   )r   r   signoffsetr   r   r   _prepare_tzname_deltaO   s    z(DatabaseOperations._prepare_tzname_deltac                 C   s2   |r.t jr.| jj|kr.d|| jj| |f }|S )NzCONVERT_TZ(%s, '%s', '%s'))r   USE_TZ
connectionZtimezone_namer$   r   r   r   r   r   r   r   S   s    z'DatabaseOperations._convert_field_to_tzc                 C   s   |  ||}d| S )Nr   r   r'   r   r   r   datetime_cast_date_sql\   s    z)DatabaseOperations.datetime_cast_date_sqlc                 C   s   |  ||}d| S )NTIME(%s)r   r'   r   r   r   datetime_cast_time_sql`   s    z)DatabaseOperations.datetime_cast_time_sqlc                 C   s   |  ||}| ||S r!   )r   r   )r   r   r   r   r   r   r   datetime_extract_sqld   s    z'DatabaseOperations.datetime_extract_sqlc           
      C   s   |  ||}ddddddg}d}d}|d	kr8d
j|dS |dkrLdj|dS z||d }W n tk
rv   |}Y n,X d|d | ||d   }	d||	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   zCAST(DATE_FORMAT(MAKEDATE(YEAR({field_name}), 1) + INTERVAL QUARTER({field_name}) QUARTER - INTERVAL 1 QUARTER, '%%Y-%%m-01 00:00:00') AS DATETIME))r   r   zqCAST(DATE_FORMAT(DATE_SUB({field_name}, INTERVAL WEEKDAY({field_name}) DAY), '%%Y-%%m-%%d 00:00:00') AS DATETIME)    z'CAST(DATE_FORMAT(%s, '%s') AS DATETIME))r   formatindex
ValueErrorjoin)
r   r   r   r   r   r2   Z
format_defisqlr   r   r   r   datetime_trunc_sqlh   s*    
z%DatabaseOperations.datetime_trunc_sqlc                 C   s@   |  ||}dddd}||kr4|| }d||f S d| S d S )Nz	%%H:00:00z
%%H:%%i:00z%%H:%%i:%%s)r-   r.   r/   z#CAST(DATE_FORMAT(%s, '%s') AS TIME)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   r7   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   r:   r7   paramsr   r   r   last_executed_query   s    z&DatabaseOperations.last_executed_queryc                 C   s   dS )Nr	   r   r>   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)r1   r   c                    s,   g | ]$}d   |jjj  |jf qS )z%s.%s)rL   modelZ_metaZdb_tablecolumn).0fieldr>   r   r   
<listcomp>   s
   
z<DatabaseOperations.return_insert_columns.<locals>.<listcomp>zRETURNING %s, r   r5   )r   r   columnsr   r>   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_FIELDrL   rO   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FROMNrX   rY   rZ   r   r   r\      s   zSET FOREIGN_KEY_CHECKS = 1;)extendappend)r   r[   ZtablesrV   rW   r7   r   rZ   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_INCREMENTrX   )rO   Zsequence_inforZ   r   r   rQ      s   zADatabaseOperations.sequence_reset_by_name_sql.<locals>.<listcomp>r   )r   r[   	sequencesr   rZ   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.)r&   featuresZallows_auto_pk_0r4   r   r@   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   r%   Z
make_naiver&   r4   strre   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 )Nrg   z4MySQL backend does not support timezone-aware times.microseconds)Ztimespec)rh   r   ri   r4   	isoformatre   r   r   r   adapt_timefield_value   s    

z(DatabaseOperations.adapt_timefield_valuec                 C   s   dS )N@   r   r>   r   r   r   max_name_length  s    z"DatabaseOperations.max_name_lengthc                 C   s   dS )Nr=   r   r>   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 )rR   NrS   )rO   rowr   r   r   r\     s     z5DatabaseOperations.bulk_insert_sql.<locals>.<genexpr>rR   c                 s   s   | ]}d | V  qdS )z(%s)Nr   )rO   r7   r   r   r   r\     s     zVALUES rS   )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<<#rx   zCONVERT(%s, SIGNED)z>>z FLOOR(%(lhs)s / POW(2, %(rhs)s))lhsrhs)r5   supercombine_expression)r   Z	connectorZsub_expressionsrz   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_typer_   convert_booleanfield_valuer   r%   convert_datetimefield_valueconvert_uuidfield_value)r   
expression
convertersinternal_typer~   r   r   r   $  s    
z$DatabaseOperations.get_db_convertersc                 C   s   |dkrt |}|S )N)r   r0   )boolr   r@   r   r&   r   r   r   r   0  s    z-DatabaseOperations.convert_booleanfield_valuec                 C   s   |d k	rt || jj }|S r!   )r   Z
make_awarer&   r   r   r   r   r   5  s    z.DatabaseOperations.convert_datetimefield_valuec                 C   s   |d k	rt |}|S r!   )uuidUUIDr   r   r   r   r   :  s    
z*DatabaseOperations.convert_uuidfield_valuec                 C   s   |d k	rt |dsdS dS )NZas_sqlz
_binary %s%s)rh   re   r   r   r   binary_placeholder_sql?  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)ry   zs((TIME_TO_SEC(%(lhs)s) * 1000000 + MICROSECOND(%(lhs)s)) - (TIME_TO_SEC(%(rhs)s) * 1000000 + MICROSECOND(%(rhs)s)))   z"TIMESTAMPDIFF(MICROSECOND, %s, %s))r&   mysql_is_mariadbtuple)	r   r   rz   r{   Zlhs_sqlZ
lhs_paramsZrhs_sqlZ
rhs_paramsrE   r   r   r   subtract_temporalsB  s"     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   r&   rd   Zsupported_explain_formatspopr|   explain_query_prefixZsupports_explain_analyzer   )r   r2   optionsr   prefixr~   r   r   r   S  s    z'DatabaseOperations.explain_query_prefixc                 C   s<   | j jdk s| j jr$|dkr dS dS |dkr0dnd}d| S )N)   r   r   regexz%s REGEXP BINARY %sz%s REGEXP %scr6   zREGEXP_LIKE(%%s, %%s, '%s'))r&   Zmysql_versionr   )r   r   Zmatch_optionr   r   r   regex_lookupd  s    zDatabaseOperations.regex_lookupc                    s   |rdS t  |S )NzINSERT IGNORE INTO)r|   insert_statement)r   Zignore_conflictsr~   r   r   r   o  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	icontainsrI   ZistartswithrJ   Z	iendswithr   ZiregexzJSON_UNQUOTE(%s))r&   r   )r   r   r   lookupr   r   r   lookup_castr  s
    zDatabaseOperations.lookup_cast)N)N)NN)N)F)N).__name__
__module____qualname__Zcompiler_moduler   Zinteger_field_rangesZcast_data_typesZ"cast_char_field_without_max_lengthZexplain_prefixr   r    r$   r   r(   r*   r+   r8   r9   r;   r<   r?   rA   rF   rG   rL   rU   r`   rc   rf   rk   rn   rp   rq   rs   r}   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r~   r   r   
   st   
	


r   )r   Zdjango.confr   Z"django.db.backends.base.operationsr   Zdjango.db.backends.utilsr   Zdjango.utilsr   Zdjango.utils.encodingr   r   r   r   r   r   <module>   s   