U
    hr`                  
   @  s  d dl m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 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 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 ddlmZ ddlmZ ddlmZ ddlmZ erddlmZ ddlmZ ddlmZ G dd dZG dd dZ dZ!e	dd d!d"d#d$Z"e	dDdd%d&d"d'd$Z"dEdd(d)d"d*d$Z"dd+d,d-d.Z#d/d0d1d2d3Z$ddd4d5d6Z%d7d8d9d:d;d<d=d>d?d@	Z&e'dA(dBdC e&D Z)dS )F    )annotationsN)Any)Callable)Dict)List)Optional)overload)Sequence)Tuple)TYPE_CHECKING)Union   )ENUM)SET)DATETIME)TIME)	TIMESTAMP   )types)util)Literal)MySQLDialect)MySQLIdentifierPreparer)ReflectedColumnc                   @  s(   e Zd ZU dZded< ddddZdS )	ReflectedStatez;Stores raw information about a SHOW CREATE TABLE statement.Optional[str]charsetNonereturnc                 C  s(   g | _ i | _d | _g | _g | _g | _d S N)columnstable_options
table_namekeysfk_constraintsck_constraints)self r(   H/tmp/pip-unpacked-wheel-y9ln43lq/sqlalchemy/dialects/mysql/reflection.py__init__)   s    zReflectedState.__init__N)__name__
__module____qualname____doc____annotations__r*   r(   r(   r(   r)   r   $   s   
r   c                   @  s  e Zd ZdZdddddZddd	d
ddZdddddZdddddZdd	ddddZdd	ddddZ	dd	ddddZ
dd	ddddZdddd d!d"Zdd#d$d%d&Zdd'd(d)Zd*Zddd+d,d-Zddd+d.d/Zddd+d0d1Zdddd2d3d4Zd5S )6MySQLTableDefinitionParserz4Parses the results of a SHOW CREATE TABLE statement.r   r   )dialectpreparerc                 C  s   || _ || _|   d S r    )r1   r2   _prep_regexes)r'   r1   r2   r(   r(   r)   r*   5   s    z#MySQLTableDefinitionParser.__init__strr   r   )show_creater   r   c                 C  s   t  }||_td|D ]}|d| jj r<| || q|drT| || q|dkr^q|drv| 	|| qd|kr| 
|| q|sq| |\}}|d krtd|  q|dkr|j| q|d	kr|j| q|d
kr|j| qq|S )Nz\r?\nz  z) )zCREATE 	PARTITIONzUnknown schema content: %rkeyfk_constraintck_constraint)r   r   resplit
startswithr2   initial_quote_parse_column_parse_table_options_parse_table_name_parse_partition_options_parse_constraintsr   warnr$   appendr%   r&   )r'   r5   r   statelinetype_specr(   r(   r)   parse<   s4    

z MySQLTableDefinitionParser.parsebool)sqlr   c                 C  s   t | j|S r    )rK   _re_is_viewmatch)r'   rL   r(   r(   r)   _check_view`   s    z&MySQLTableDefinitionParser._check_viewzUnion[Tuple[None, str], Tuple[Literal['partition'], str], Tuple[Literal[('ck_constraint', 'fk_constraint', 'key')], Dict[str, str]]])rG   r   c                 C  s:  | j |}|r| }| |d |d< |d rb| j|d }|rb| d rb| d |d< |d r| j|d d |d< d|fS | j|}|r| }| j|d |d< dd | |d	 D |d	< d
d | |d D |d< d|fS | j|}|r| }d|fS | j	|}|r2d|fS d|fS )zaParse a KEY or CONSTRAINT line.

        :param line: A line of SHOW CREATE TABLE output
        r!   Zversion_sqlparserr   r8   tablec                 S  s   g | ]}|d  qS r   r(   .0cr(   r(   r)   
<listcomp>   s     zAMySQLTableDefinitionParser._parse_constraints.<locals>.<listcomp>localc                 S  s   g | ]}|d  qS rR   r(   rS   r(   r(   r)   rV      s    Zforeignr9   r:   	partitionN)
_re_keyrN   	groupdict_parse_keyexprs_re_key_version_sqlr2   Zunformat_identifiers_re_fk_constraint_re_ck_constraint_re_partition)r'   rG   mrI   m2r(   r(   r)   rC   c   s@    
z-MySQLTableDefinitionParser._parse_constraintsr   )rG   rF   r   c                 C  s,   | j \}}||}|r(||d|_dS )zZExtract the table name.

        :param line: The first line of SHOW CREATE TABLE
        nameN)_pr_namerN   groupr#   )r'   rG   rF   regexcleanupr`   r(   r(   r)   rA      s    

z,MySQLTableDefinitionParser._parse_table_namec                 C  s   i }|rn|dkrn|}| j D ]R\}}||}|s2q|d|d }}	|rT||	}	|	|| < |d|}qdD ]}
||
d qr| D ]\}}||jd| jj	|f < qdS )zBuild a dictionary of all reflected table-level options.

        :param line: The final line of SHOW CREATE TABLE output.
        r6   	directiveval )auto_incrementzdata directoryzindex directoryN%s_%s)
_pr_optionssearchrd   lowersubpopitemsr"   r1   rb   )r'   rG   rF   optionsZrest_of_linere   rf   r`   rg   valueZnopeoptrh   r(   r(   r)   r@      s     
z/MySQLTableDefinitionParser._parse_table_optionsc                 C  s  i }|d d  }| ds$| dr2|dd  }q| jD ]\}}||}|r8d|jkr\q8|d}| }|dk}	|dks|	r
|dd	}|d
d	}|	r|dr|d d }| jj	dkr|drd|ksd|ksd|kr|d d }d| jj	|f }
|||
< n,|dd}|d}|r.||}|||<  q>q8|
 D ]~\}}d| jj	 }d| jj	 }||ksz||kr||jkr||j|< nd|j| |f |j|< n||jd| jj	|f < qFd S )N( r   r7   rg   ZsubpartitionrX   z) */ri   ,r6   ZmariadbZMAXVALUEZMINVALUEENGINEz%s_%s_definitions_rh   z%s_partition_definitionsz%s_subpartition_definitionsz%s, %srk   )r=   rl   rm   patternrd   rn   replaceendswithr1   rb   rq   r"   )r'   rG   rF   rr   new_linere   rf   r`   rg   Zis_subpartitionZdefsrs   rt   rh   Zpart_defZsubpart_defr(   r(   r)   rB      sV    



z3MySQLTableDefinitionParser._parse_partition_optionsc                 C  s  d}| j |}|r&| }d|d< n | j|}|rF| }d|d< |s\td|  dS |d srtd|  |d |d |d	   }}}z| jj| }W n, tk
r   td
||f  t	j
}Y nX |dks|dkrg }	n@|d dkr|d dkr| j|}	ndd | j|D }	i }
t|tttfrL|	rL|	d|
d< dD ]}||drPd|
|< qPdD ] }||drr|| |
|< qrt|ttfrt|	}	t|trd|	krd|
d< ||	|
}i }d|d< |dddkrd|d< |dddkrd|d< |ddr,d|d< nt|t	jrBd|d< |dd}|dkr\d}|dd}|dk	rzt|}|d}|dk	rt|d}|d }|dk	r|d!k|d"< ||d#< t||||d$}|| |j| dS )%zExtract column details.

        Falls back to a 'minimal support' variant if full parse fails.

        :param line: Any column-bearing line from SHOW CREATE TABLE
        NTfullFzUnknown column definition %rz-Incomplete reflection of column definition %rrb   Zcoltypeargz*Did not recognize type '%s' of column '%s'ri   r   'rx   c                 S  s   g | ]}t |qS r(   int)rT   vr(   r(   r)   rV   "  s     z<MySQLTableDefinitionParser._parse_column.<locals>.<listcomp>Zfsp)ZunsignedZzerofill)r   ZcollateZretrieve_as_bitwisenullableZnotnullNOT NULLZnotnull_generatedZautoincrZautoincrementdefaultNULLcomment	generated)sqltextZpersistenceZSTORED	persistedcomputed)rb   typer   r   )
_re_columnrN   rZ   _re_column_looser   rD   r1   Zischema_namesKeyErrorsqltypesZNullType_re_csv_strfindall_re_csv_int
issubclassr   r   r   rp   getr   r   _strip_valuesZIntegercleanup_textdictupdater!   rE   )r'   rG   rF   rI   r`   rb   rH   argscol_typeZ	type_argsZtype_kwkwZtype_instanceZcol_kwr   r   r   r   r   Zcol_dr(   r(   r)   r?      s    










   
z(MySQLTableDefinitionParser._parse_columnz-Sequence[Tuple[str, str, str, str, str, str]])r#   r!   r   c           
        s  g }|D ]  fdddD \}}}}}dg}	|	 | j| |	 | |sX|	 d |rd|krfnh|dr|dr|	 d	 |	 | n>|d
kr|	 d	 |	 | n |	 d	 |	 d|dd  |r|	 | | d|	 qdd| j| d|dgS )a  Re-format DESCRIBE output as a SHOW CREATE TABLE string.

        DESCRIBE is a much simpler reflection and is sufficient for
        reflecting views for runtime use.  This method formats DDL
        for columns only- keys are omitted.

        :param columns: A sequence of DESCRIBE or SHOW COLUMNS 6-tuples.
          SHOW FULL COLUMNS FROM rows must be rearranged for use with
          this function.
        c                 3  s   | ]} | V  qd S r    r(   )rT   irowr(   r)   	<genexpr>v  s    zAMySQLTableDefinitionParser._describe_to_create.<locals>.<genexpr>)r   r            rv   r   rj   	timestampCDEFAULTr   z'%s'r   ''ri   zCREATE TABLE %s (
z,
z
) )rE   r2   Zquote_identifierr=   r|   join)
r'   r#   r!   bufferrb   r   r   r   extrarG   r(   r   r)   _describe_to_created  sD    







z.MySQLTableDefinitionParser._describe_to_createz$List[Tuple[str, Optional[int], str]])identifiersr   c                 C  s   dd | j |D S )z8Unpack '"col"(2),"col" ASC'-ish strings into components.c                 S  s(   g | ] \}}}||rt |nd |fqS r    r   )rT   Zcolnamelength	modifiersr(   r(   r)   rV     s   z>MySQLTableDefinitionParser._parse_keyexprs.<locals>.<listcomp>)_re_keyexprsr   )r'   r   r(   r(   r)   r[     s
    z*MySQLTableDefinitionParser._parse_keyexprsr   c              	   C  sH  g | _ | jj}ttddd | jj|| j|fD }td| | jj| _	t
d| _t
d| | _t
d| _t
d| _t
d	| | _t
d
| | _t
d| | _t
d| _| }d|d< t
d| | _t
d| | _t
d| _tD ]}| | qdD ]}| | qdD ]}| | q| dd | dd | dd dS )z Pre-compile regular expressions.)ZiqZfqZesc_fqc                 S  s   g | ]}t |qS r(   r;   escape)rT   sr(   r(   r)   rV     s   z<MySQLTableDefinitionParser._prep_regexes.<locals>.<listcomp>zM^CREATE (?:\w+ +)?TABLE +%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +\($z^CREATE(?! TABLE)(\s.*)?\sVIEWzW(?:(?:%(iq)s((?:%(esc_fq)s|[^%(fq)s])+)%(fq)s)(?:\((\d+)\))?(?: +(ASC|DESC))?(?=\,|$))+z\x27(?:\x27\x27|[^\x27])*\x27z\d+a    %(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +(?P<coltype>\w+)(?:\((?P<arg>(?:\d+|\d+,\d+|(?:'(?:''|[^'])*',?)+))\))?(?: +(?P<unsigned>UNSIGNED))?(?: +(?P<zerofill>ZEROFILL))?(?: +CHARACTER SET +(?P<charset>[\w_]+))?(?: +COLLATE +(?P<collate>[\w_]+))?(?: +(?P<notnull>(?:NOT )?NULL))?(?: +DEFAULT +(?P<default>(?:NULL|'(?:''|[^'])*'|\(.+?\)|[\-\w\.\(\)]+(?: +ON UPDATE [\-\w\.\(\)]+)?)))?(?: +(?:GENERATED ALWAYS)? ?AS +(?P<generated>\(.*\))? ?(?P<persistence>VIRTUAL|STORED)?(?: +(?P<notnull_generated>(?:NOT )?NULL))?)?(?: +(?P<autoincr>AUTO_INCREMENT))?(?: +COMMENT +'(?P<comment>(?:''|[^'])*)')?(?: +COLUMN_FORMAT +(?P<colfmt>\w+))?(?: +STORAGE +(?P<storage>\w+))?(?: +(?P<extra>.*))?,?$z  %(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +(?P<coltype>\w+)(?:\((?P<arg>(?:\d+|\d+,\d+|\x27(?:\x27\x27|[^\x27])+\x27))\))?.*?(?P<notnull>(?:NOT )NULL)?aX    (?:(?P<type>\S+) )?KEY(?: +%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s)?(?: +USING +(?P<using_pre>\S+))? +\((?P<columns>.+?)\)(?: +USING +(?P<using_post>\S+))?(?: +KEY_BLOCK_SIZE *[ =]? *(?P<keyblock>\S+))?(?: +WITH PARSER +(?P<parser>\S+))?(?: +COMMENT +(?P<comment>(\x27\x27|\x27([^\x27])*?\x27)+))?(?: +/\*(?P<version_sql>.+)\*/ *)?,?$z+\!\d+ (?: *WITH PARSER +(?P<parser>\S+) *)?z/RESTRICT|CASCADE|SET NULL|NO ACTION|SET DEFAULTonaJ    CONSTRAINT +%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +FOREIGN KEY +\((?P<local>[^\)]+?)\) REFERENCES +(?P<table>%(iq)s[^%(fq)s]+%(fq)s(?:\.%(iq)s[^%(fq)s]+%(fq)s)?) +\((?P<foreign>(?:%(iq)s[^%(fq)s]+%(fq)s(?: *, *)?)+)\)(?: +(?P<match>MATCH \w+))?(?: +ON DELETE (?P<ondelete>%(on)s))?(?: +ON UPDATE (?P<onupdate>%(on)s))?z[  CONSTRAINT +%(iq)s(?P<name>(?:%(esc_fq)s|[^%(fq)s])+)%(fq)s +CHECK +\((?P<sqltext>.+)\),?z(?:.*)(?:SUB)?PARTITION(?:.*))ry   ZTYPEZAUTO_INCREMENTZAVG_ROW_LENGTHzCHARACTER SETzDEFAULT CHARSETZCHECKSUMZCOLLATEZDELAY_KEY_WRITEZINSERT_METHODZMAX_ROWSZMIN_ROWSZ	PACK_KEYSZ
ROW_FORMATZKEY_BLOCK_SIZEZSTATS_SAMPLE_PAGES)PARTITION BYSUBPARTITION BY
PARTITIONSSUBPARTITIONSr7   ZSUBPARTITIONZUNIONz
\([^\)]+\)Z
TABLESPACEz.*? STORAGE DISKZ	RAID_TYPEz4\w+\s+RAID_CHUNKS\s*\=\s*\w+RAID_CHUNKSIZE\s*=\s*\w+N)rl   r2   Zfinal_quoter   zipr>   Z_escape_identifier_pr_compileZ_unescape_identifierrc   _re_compilerM   r   r   r   r   r   rY   r\   copyr]   r^   r_   _options_of_type_string_add_option_string_add_option_word_add_partition_option_word_add_option_regex)r'   Z_finalquotesr   optionr(   r(   r)   r3     s    







z(MySQLTableDefinitionParser._prep_regexesz(?:\s*(?:=\s*)|\s+))rg   r   c                 C  s*   dt || jf }| jt|t d S )Nz0(?P<directive>%s)%s'(?P<val>(?:[^']|'')*?)'(?!'))r;   r   _optional_equalsrl   rE   r   r   r'   rg   re   r(   r(   r)   r   k  s
    z-MySQLTableDefinitionParser._add_option_stringc                 C  s(   dt || jf }| jt| d S )Nz(?P<directive>%s)%s(?P<val>\w+)r;   r   r   rl   rE   r   r   r(   r(   r)   r   r  s
    z+MySQLTableDefinitionParser._add_option_wordc                 C  sp   |dks|dkr&dt || jf }n6|dks6|dkrLdt || jf }ndt |f }| jt| d S )Nr   r   z((?<!\S)(?P<directive>%s)%s(?P<val>\w+.*)r   r   z&(?<!\S)(?P<directive>%s)%s(?P<val>\d+)z(?<!\S)(?P<directive>%s)(?!\S)r   r   r(   r(   r)   r   y  s    z5MySQLTableDefinitionParser._add_partition_option_word)rg   re   r   c                 C  s*   dt || j|f }| jt| d S )Nz(?P<directive>%s)%s(?P<val>%s)r   r   r(   r(   r)   r     s    z,MySQLTableDefinitionParser._add_option_regexN)r+   r,   r-   r.   r*   rJ   rO   rC   rA   r@   rB   r?   r   r[   r3   r   r   r   r   r   r(   r(   r(   r)   r0   2   s$   $8:j9 Ar0   )COMMENTzDATA DIRECTORYzINDEX DIRECTORYZPASSWORDZ
CONNECTIONr4   zCallable[[str], str]z,Tuple[re.Pattern[Any], Callable[[str], str]])re   rf   r   c                 C  s   d S r    r(   re   rf   r(   r(   r)   r     s    r   r   zTuple[re.Pattern[Any], None]c                 C  s   d S r    r(   r   r(   r(   r)   r     s    zOptional[Callable[[str], str]]z6Tuple[re.Pattern[Any], Optional[Callable[[str], str]]]c                 C  s   t | |fS )z1Prepare a 2-tuple of compiled regex and callable.)r   r   r(   r(   r)   r     s    zre.Pattern[Any])re   r   c                 C  s   t | t jt jB S )z)Compile a string to regex, I and UNICODE.)r;   compileIUNICODE)re   r(   r(   r)   r     s    r   zSequence[str]z	List[str])valuesr   c                 C  s\   g }| D ]N}|dd dks,|dd dkrL|dd  |d d |d }|| q|S )zStrip reflected values quotesr   r   "r   rx   r   )r|   rE   )r   Zstrip_valuesar(   r(   r)   r     s      r   )raw_textr   c                 C  s&   d| krt tdd | } | ddS )N\c                 S  s   t | d  S )Nr   )_control_char_map)r   r(   r(   r)   <lambda>      zcleanup_text.<locals>.<lambda>r   r   )r;   ro   _control_char_regexpr|   )r   r(   r(   r)   r     s    r   r    	
)	z\\z\0z\az\bz\tz\nz\vz\fz\r|c                 c  s   | ]}t |V  qd S r    r   )rT   kr(   r(   r)   r     s     r   )N)N)*
__future__r   r;   typingr   r   r   r   r   r   r	   r
   r   r   Z
enumeratedr   r   r   r   r   r   ri   r   r   Zutil.typingr   baser   r   Zengine.interfacesr   r   r0   r   r   r   r   r   r   r   r   r   r(   r(   r(   r)   <module>   sj       c	  