U
    ?h                     @  sD  d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZ ddlmZ dd	lmZmZmZmZmZ dd
lmZ ddlmZm Z m!Z!m"Z" ddl#m#Z# ddl$m%Z%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 erddl1m2Z2 dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:G dd dZ;dS )z,Implements the MySQL Client/Server protocol.    )annotationsN)deque)DecimalDecimalException)	TYPE_CHECKINGAnyDequeDictListOptionalSequenceTupleUnion   )utils)PARAMETER_COUNT_AVAILABLE
ClientFlag	FieldFlag	FieldType	ServerCmd)MySQLConverter)DatabaseErrorInterfaceErrorProgrammingErrorget_exception)logger)MySQLAuthPluginget_auth_plugin)"MySQLCachingSHA2PasswordAuthPlugin)BinaryProtocolTypeDescriptionTypeEofPacketTypeHandShakeTypeOkPacketTypeStatsPacketType
StrOrBytes)MySQLSocket
            -   i   @c                   @  s  e Zd ZdZedddddZedddddZedddd	d
ZedddddZeddddddZ	ed~dddddddddd	ddZ
edededdddddf
ddddddddddddddd d!d"Zeedefddddd#d$d%Zeddd&dd'd(d)Zeddddd+d,d-Zeddd.d/d0Zedd1d.d2d3Zedd4d.d5d6Zedddd8d9d:d;Zdd<d.d=d>Zedddd@dAdBdCZddDdEddFdGdHdIZedd8dJdKdLdMZedd8dNdKdOdPZeddddRdSdTdUZedddVdWdXdYZeddZd.d[d\Zdd]ddd^d_d`daZddDd]dddbdcdddeZeddfd.dgdhZeddidjdkdlZ edmdJdjdndoZ!edpdJdjdqdrZ"edddddsdtduZ#dddwdxddyddzddd{	d|d}Z$dS )MySQLProtocolzRImplements MySQL client/server protocol

    Create and parses MySQL packets.
    bytes)pktreturnc                 C  s    | d t kstd| dd S )a  Parse a MySQL auth more data packet.

        Args:
            pkt: Packet representing an `auth more data` response.

        Returns:
            auth_data: Authentication method data (see [1]).

        Raises:
            InterfaceError: If packet's status tag doesn't
                            match `protocol.EXCHANGE_FURTHER_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_auth_more_data.html
           z"Failed parsing AuthMoreData packet   N)EXCHANGE_FURTHER_STATUSr   )r.    r3   </tmp/pip-unpacked-wheel-v4eb2wv5/mysql/connector/protocol.pyparse_auth_more_data\   s    z"MySQLProtocol.parse_auth_more_datazTuple[str, bytes]c                 C  sV   | d t krtdtj| dd dd\} }| rJ| d dkrJ| dd } | | fS )	a|  Parse a MySQL auth switch request packet.

        Args:
            pkt: Packet representing an `auth switch request` response.

        Returns:
            plugin_name: Name of the client authentication plugin to switch to.
            plugin_provided_data: Plugin provided data (see [1]).

        Raises:
            InterfaceError: If packet's status tag doesn't
                            match `protocol.AUTH_SWITCH_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/                latest/page_protocol_connection_phase_packets_protocol_
                auth_switch_request.html
        r0   z'Failed parsing AuthSwitchRequest packetr1   N    endr   )AUTH_SWITCH_STATUSr   r   read_stringdecode)r.   plugin_namer3   r3   r4   parse_auth_switch_requestr   s    z'MySQLProtocol.parse_auth_switch_requestc                 C  sF   t | dd d\} }|tkr(tdt j| dd\} }| | fS )a  Parse a MySQL auth next factor packet.

        Args:
            pkt: Packet representing an `auth next factor` response.

        Returns:
            plugin_name: Name of the client authentication plugin.
            plugin_provided_data: Initial authentication data for that
                                  client plugin (see [1]).

        Raises:
            InterfaceError: If packet's packet type doesn't
                            match `protocol.MFA_STATUS`.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_auth_                next_factor_request.html
        r0   Nr   z.Failed parsing AuthNextFactor packet (invalid)r6   r7   )r   read_int
MFA_STATUSr   r;   r<   )r.   statusr=   r3   r3   r4   parse_auth_next_factor   s
    z$MySQLProtocol.parse_auth_next_factorzDict[str, str])
conn_attrsr/   c              	     s    D ]} | dkrd |< qt  fdd D t   t   }td|g} D ]T}|tdt| ||  |tdt |  | |   q^d|S )az  Encode the connection attributes.

        Args:
            conn_attrs: Connection attributes.

        Returns:
            serialized_conn_attrs: Serialized connection attributes as per [1].

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html
        N c                 3  s"   | ]}t |t  |  V  qd S )N)len).0xrC   r3   r4   	<genexpr>   s     z0MySQLProtocol.make_conn_attrs.<locals>.<genexpr><B    )	sumrE   keysvaluesstructpackappendencodejoin)rC   	attr_nameZconn_attrs_lenZconn_attrs_packetr3   rH   r4   make_conn_attrs   s     


zMySQLProtocol.make_conn_attrsintzOptional[str])client_flagsdatabaser/   c                 C  s   | t j@ r|r| d S dS )a  Prepare database string for handshake response.

        Args:
            client_flags: Integer representing client capabilities flags.
            database: Initial database name for the connection.

        Returns:
            serialized_database: Serialized database name as per [1].

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html
        r6   )r   ZCONNECT_WITH_DBrR   )rW   rX   r3   r3   r4   connect_with_db   s    zMySQLProtocol.connect_with_dbNFstrboolzOptional[Dict[str, Any]]zTuple[bytes, MySQLAuthPlugin])		auth_datausernamepasswordrW   auth_pluginauth_plugin_classssl_enabledplugin_configr/   c              
   C  s   |sdt |||dfS |dkr"i }z&t|||||d}|j| f|}	W n6 ttfk
r~ }
 ztd|
 |
W 5 d}
~
X Y nX |	dkrtd|j |tj@ rt	t
|	|	 n|	d }	|	|fS )a  Prepare the first authentication response.

        Args:
            auth_data: Authorization data from initial handshake.
            username: Account's username.
            password: Account's password.
            client_flags: Integer representing client capabilities flags.
            auth_plugin: Authorization plugin name.
            auth_plugin_class: Authorization plugin class (has higher precedence
                               than the authorization plugin name).
            ssl_enabled: Whether SSL is enabled or not.
            plugin_config: Custom configuration to be passed to the auth plugin
                           when invoked. The parameters defined here will override
                           the ones defined in the auth plugin itself.

        Returns:
            auth_response: Authorization plugin response.
            auth_strategy: Authorization plugin instance created based
                           on the provided `auth_plugin` and `auth_plugin_class`
                           parameters.

        Raises:
            InterfaceError: If authentication fails or when got a NULL auth response.
        r6   )ra   NzFailed authentication: z8Got NULL auth response while authenticating with plugin )r   r   auth_response	TypeErrorr   namer   SECURE_CONNECTIONr   	int1storerE   )r\   r]   r^   rW   r_   r`   ra   rb   auth_strategyrc   errr3   r3   r4   auth_plugin_first_response   s4    #    "
z(MySQLProtocol.auth_plugin_first_responser   r"   zOptional[Dict[str, str]])	handshaker]   r^   rX   charsetrW   max_allowed_packetr_   r`   rC   is_change_user_requestra   rb   r/   c              
   C  s  |  }g }|
rtd td | dkr6tdd| ddkrNtddz|pZ| d }W n8 ttfk
r } ztd| d	dW 5 d}~X Y nX td
| |
r|t	dt
| dtj| n,d}|t	d| t
| d|||| tj| d |||||||d\}}|| |t|| |
rN|t	d| |tj@ rl||  d  |tj@ r|	dk	r|t|	 d||fS )a  Make a MySQL Authentication packet.

        Args:
            handshake: Initial handshake.
            username: Account's username.
            password: Account's password.
            database: Initial database name for the connection
            charset: Client charset (see [2]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.
            auth_plugin: Authorization plugin name.
            auth_plugin_class: Authorization plugin class (has higher precedence
                               than the authorization plugin name).
            conn_attrs: Connection attributes.
            is_change_user_request: Whether is a `change user request` operation or not.
            ssl_enabled: Whether SSL is enabled or not.
            plugin_config: Custom configuration to be passed to the auth plugin
                           when invoked. The parameters defined here will override
                           the one defined in the auth plugin itself.

        Returns:
            handshake_response: Handshake response as per [1].
            auth_strategy: Authorization plugin instance created based
                           on the provided `auth_plugin` and `auth_plugin_class`.

        Raises:
            ProgrammingError: Handshake misses authentication info.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_handshake_response.html

            [2]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        zGot a `change user` requestzStarting authorization phaseNzGot a NULL handshaker\   z$Handshake misses authentication infor_   z-Handshake misses authentication plugin info ()z#The provided initial strategy is %srJ   ZsxZxxxxxxxxxxxxxxxxxxxxxxz<IIH)r\   r]   r^   rW   r_   r`   ra   rb   <Hr6   rK   )rR   r   debugr   getrd   KeyErrorrQ   rO   rP   rE   r   ZCHANGE_USERr,   rj   rY   r   PLUGIN_AUTHZCONNECT_ARGSrU   rS   )rk   r]   r^   rX   rl   rW   rm   r_   r`   rC   rn   ra   rb   Z
b_usernameZresponse_payloadri   Zfillerrc   rh   r3   r3   r4   	make_auth  sn    3







zMySQLProtocol.make_auth)rl   rW   rm   r/   c                 C  s$   d t|t|t| dgS )a  Make a SSL authentication packet (see [1]).

        Args:
            charset: Client charset (see [2]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.

        Returns:
            ssl_request_pkt: SSL connection request packet.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_connection_phase_packets_protocol_ssl_request.html

            [2]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        rK   s                         rS   r   	int4store	int2store)rl   rW   rm   r3   r3   r4   make_auth_ssl  s    zMySQLProtocol.make_auth_sslzOptional[bytes])commandargumentr/   c                 C  s   t | }|dkr|S || S )z(Make a MySQL packet containing a commandN)r   rg   )rz   r{   datar3   r3   r4   make_command  s    
zMySQLProtocol.make_commandr   )statement_idrowsr/   c                 C  s   t | t | S )z0Make a MySQL packet with Fetch Statement command)r   rw   )r~   r   r3   r3   r4   make_stmt_fetch  s    zMySQLProtocol.make_stmt_fetch)packetr/   c           	   	   C  s  i }t d| dd d |d< |d tkrDtd|d  dt tj| dd dd	\} |d
< t d| dd \|d< }}|d< |d< }}|d
  |d
< | dd } t|| }d}|tj	@ r|rt
d|d nd}| d| }| |d } |d dkr|dd }|tj@ rrd| krH|d
 drHd|  } |d< ntj| dd	\} |d< |d d|d< nd|d< || |d< ||d< |S )zParse a MySQL Handshake-packet.<xxxxBr   r1   protocolz$Protocol mismatch; server version = z, client version = Nr6   r7   Zserver_version_originalz<I8sx2sBH2sBxxxxxxxxxx   Zserver_threadidrl   Zserver_statusrK         r9   z5.5.8r_   utf-8Zmysql_native_passwordr\   capabilities)rO   unpackPROTOCOL_VERSIONr   r   r;   r<   Zintreadr   rf   minrt   
startswith)	r   resZ
auth_data1Zcapabilities1Zcapabilities2Zauth_data_lengthr   Z
auth_data2sizer3   r3   r4   parse_handshake  sP    
 zMySQLProtocol.parse_handshaker#   c              
   C  s   | d dkst di }ztd| dd d |d< t| dd \} |d< t| \} |d	< td
| dd \|d< |d< | dd } | rt| \} |d< |d d|d< W n, tk
r } zt d|W 5 d}~X Y nX |S )zParse a MySQL OK-packetr0   r   z#Failed parsing OK packet (invalid).r   r1   Zfield_countNZaffected_rowsZ	insert_idz<HHstatus_flagwarning_countZinfo_msgr   zFailed parsing OK packet.)r   rO   r   r   read_lc_intread_lc_stringr<   
ValueError)r   Z	ok_packetri   r3   r3   r4   parse_ok  s$    zMySQLProtocol.parse_okzOptional[int]c              
   C  sT   zt | dd d }|W S  tjtfk
rN } ztd|W 5 d}~X Y nX dS )z=Parse a MySQL packet with the number of columns in result setr0   Nr   zFailed parsing column count)r   r   rO   errorr   r   )r   countri   r3   r3   r4   parse_column_count  s
    z MySQLProtocol.parse_column_countr   r    )r   encodingr/   c              	   C  s   t | dd \} }t | \} }t | \} }t | \} }t | \} }t | \} }ztd| \}}}}}W n  tjk
r   tddY nX |||dddd| tj@ ||f	S )zParse a MySQL column-packet.r0   Nz	<xHIBHBxxz!Failed parsing column information)	r   r   rO   r   r   r   r<   r   ZNOT_NULL)r   r   _re   rl   Zcolumn_typeflagsr3   r3   r4   parse_column  s6    

zMySQLProtocol.parse_columnr!   c              
   C  s   |d dkr|  |S d}i }ztd|}W n. tjk
r\ } zt||W 5 d}~X Y nX |d dkrvt|dks~t||d	 |d
< |d |d< |S )zParse a MySQL EOF-packetr0   r   zFailed parsing EOF packet.z<xxxBBHHNr   r(   	   r)   r      r   )r   rO   r   r   r   rE   )selfr   err_msgr   unpackedri   r3   r3   r4   	parse_eof:  s    
zMySQLProtocol.parse_eofTr$   )r   with_headerr/   c           	      C  s   d}i }dg}d}|r*| dd  d}n
|  d}|D ]}zdd | dd	D \}}W n, tk
r } zt||W 5 d}~X Y nX |d
}zt|||< W q8 ttfk
r   zt|d
||< W nD tk
r } z$t| d| dt| d|W 5 d}~X Y nX Y q8X q8|S )zParse the statistics packetz)Failed getting COM_STATISTICS informationrK   r0   Ns     c                 S  s   g | ]}|  qS r3   )strip)rF   vr3   r3   r4   
<listcomp>\  s     z2MySQLProtocol.parse_statistics.<locals>.<listcomp>   :r)   r   z (:ro   )	splitr   r   r<   rV   rs   r   r   repr)	r   r   errmsgr   pairsZlblpairvalri   r3   r3   r4   parse_statisticsN  s*    

:zMySQLProtocol.parse_statisticsr&   zTuple[int, ...]zATuple[List[Tuple[Optional[bytes], ...]], Optional[EofPacketType]])sockversionr   r/   c                 C  s"  |}g }d}d}d}|s ||kr$q|  }	|	dr|	dd g}
|  }	|	drr|
|	dd  |  }	qL|
|	dd  td|
}nB|	d dkr|	d dk r| |	}d}nd}tt|	dd }|dkr|dk	r|| n|dkr|dkrt|	|d7 }q||fS )	zRead MySQL text result

        Reads all or given number of rows from the socket.

        Returns a tuple with 2 elements: a list with all rows and
        the EOF packet.
        Nr   s   r0   rK   r(      r   )	recvr   rQ   r   Zread_lc_string_listrS   r   r-   r   )r   r   r   r   r   r   eofZrowdatair   Zdatasr3   r3   r4   read_text_resultk  s6    




zMySQLProtocol.read_text_resultzTuple[bytes, int])r   fieldr/   c                 C  s   |d t jkrd}d}nV|d t jkr0d}d}n>|d t jt jfkrNd}d}n |d t jkrfd}d}ntd	|d
 tj@ r|	 }| |d t
|| d| d fS )z%Parse an integer from a binary packetr   <b<hr)   <ir0   <qr   zUnknown integer typer   Nr   )r   TINYSHORTINT24LONGLONGLONGr   r   ZUNSIGNEDupperrO   r   )r   r   format_lengthr3   r3   r4   _parse_binary_integer  s     z#MySQLProtocol._parse_binary_integerzTuple[bytes, float]c                 C  sD   |d t jkrd}d}nd}d}| |d t|| d| d fS )z)Parse a float/double from a binary packetr   r   <dr0   z<fNr   )r   DOUBLErO   r   )r   r   r   r   r3   r3   r4   _parse_binary_float  s    z!MySQLProtocol._parse_binary_floatutf8zTuple[bytes, Decimal])r   rl   r/   c                 C  s    t | \} }| t||fS )z(Parse a New Decimal from a binary packet)r   r   r   r<   )r   rl   valuer3   r3   r4   _parse_binary_new_decimal  s    z'MySQLProtocol._parse_binary_new_decimalz?Tuple[bytes, Optional[Union[datetime.date, datetime.datetime]]])r   
field_typer/   c              	   C  s   | d }d}|dkrpt d| dd d }| d }| d }|tjtjfkr^tj|||d}qtj|||d}np|dkrd}|d	krt d
| d|d  d }tjt d| dd d | d | d | d | d | d |d}| |d d |fS )z&Parse a timestamp from a binary packetr   Nr0   rp   r   r   )yearmonthdayr      <Ir   r1      )r   r   r   hourminutesecondmicrosecond)rO   r   r   DATETIME	TIMESTAMPdatetimedate)r   r   r   r   r   r   r   mcsr3   r3   r4   _parse_binary_timestamp  s.    
z%MySQLProtocol._parse_binary_timestampz Tuple[bytes, datetime.timedelta]c                 C  s   | d }|s | dd t  fS | d|d  }d}|dkrTtd|dd d }td|dd d }|d dkr|d9 }t j||d ||d	 |d d
}| |d d |fS )z'Parse a time value from a binary packetr   r   Nr   r   r1   r9   r   r   )dayssecondsmicrosecondsminuteshours)r   	timedeltarO   r   )r   r   r|   r   r   tmpr3   r3   r4   _parse_binary_time  s$    z MySQLProtocol._parse_binary_timezList[DescriptionType]zTuple[BinaryProtocolType, ...])fieldsr   rl   r/   c           
   	   C  s8  t |d d d }dd |d| D }||d }g }d}t|D ]\}}	|t|d d  d|d d > @ r|d qF|	d tjtjtjtjtj	fkr| 
||	\}}|| qF|	d tjtjfkr| ||	\}}|| qF|	d tjtjfkr| ||\}}|| qF|	d tjtjtjfkrX| ||	d \}}|| qF|	d tjkr| |\}}|| qF|	d tjkrt|\}}|t| qF|	d tjks|	d d	krt|\}}|| qFt|\}}z||| W qF tk
r,   || Y qFX qFt |S )
z(Parse values from a binary result packetr   r)   r   c                 S  s   g | ]}t |qS r3   )rV   )rF   r   r3   r3   r4   r     s     z6MySQLProtocol._parse_binary_values.<locals>.<listcomp>r   Nr   ?   )!rE   	enumeraterV   rQ   r   r   r   r   r   r   r   r   FLOATr   DECIMALZ
NEWDECIMALr   r   DATEr   r   TIMEr   ZVECTORr   r   r   Z_vector_to_pythonr   ZBINARYr<   UnicodeDecodeErrortuple)
r   r   r   rl   Znull_bitmap_lengthnull_bitmaprN   r   posr   r3   r3   r4   _parse_binary_values  s\    $
z"MySQLProtocol._parse_binary_valueszDTuple[List[Tuple[BinaryProtocolType, ...]], Optional[EofPacketType]])r   columnsr   rl   r/   c           
      C  s   g }d}d}d}|dk	rq||kr$qt | }	|	d dkrL| |	}d}n&|	d dkrrd}| ||	dd |}|dkr|dk	r|| n|dkr|dkrt|	|d7 }q||fS )zwRead MySQL binary protocol result

        Reads all or given number of binary resultset rows from the socket.
        Nr   r0   r(   r1   r   )r-   r   r   r   rQ   r   )
r   r   r   r   rl   r   r   rN   r   r   r3   r3   r4   read_binary_result8  s*    

z MySQLProtocol.read_binary_resultzDict[str, int]c              
   C  s   | d dkst di }zht| dd d\} |d< t| d\} |d< t| d\} |d	< | d
d } t| d\} |d< W n, tk
r } zt d|W 5 d}~X Y nX |S )z(Parse a MySQL Binary Protocol OK packet.r0   r   zFailed parsing Binary OK packetr1   Nr~   r)   Znum_columnsZ
num_paramsr   r   )r   r   r?   r   )r   Zok_pktri   r3   r3   r4   parse_binary_prepare_ok]  s    z%MySQLProtocol.parse_binary_prepare_okzTuple[bytes, int, int])r   r/   c                 C  s   d}d}| dk rX| dkr$d}t j}q| dkr8d}t j}q| dkrLd}t j}qd	}t j}nJd
}| dkrpd}t j}n2| dkrd}t j}n| dkrd}t j}n
t j}d}t|| ||fS )z0Prepare an integer for the MySQL binary protocolNr   ir   i r   i   r   r      r*   rJ   i  rp   l    r   z<Q)r   r   r   r   r   rO   rP   )r   r   r   r   r3   r3   r4   prepare_binary_integero  s6    z$MySQLProtocol.prepare_binary_integerz'Union[datetime.date, datetime.datetime]c                 C  s   t | tjrtj}nt | tjr(tj}ntdt| j	t
| jt
| jg}t | tjr|t
| jt
| jt
| jg | jdkr|t| j d|}t
t|| |fS )a  Prepare a timestamp object for the MySQL binary protocol

        This method prepares a timestamp of type datetime.datetime or
        datetime.date for sending over the MySQL binary protocol.
        A tuple is returned with the prepared value and field type
        as elements.

        Raises ValueError when the argument value is of invalid type.

        Returns a tuple.
        z2Argument must a datetime.datetime or datetime.dater   rK   )
isinstancer   r   r   r   r   r   r   rx   r   rg   r   r   extendr   r   r   r   rQ   rw   rS   rE   )r   r   chunkspackedr3   r3   r4   prepare_binary_timestamp  s(    







z&MySQLProtocol.prepare_binary_timestampz(Union[datetime.timedelta, datetime.time]c           
      C  s  t | tjtjfstdtj}d}d}tg }t | tjr| jdk rJd}t	| j
d\}}t	|d\}}|tt| jt|t|t|g | j}n6|tdt| jt| jt| jg | j}|r|t| |t| d|}	tt|	|	 |fS )a  Prepare a time object for the MySQL binary protocol

        This method prepares a time object of type datetime.timedelta or
        datetime.time for sending over the MySQL binary protocol.
        A tuple is returned with the prepared value and field type
        as elements.

        Raises ValueError when the argument value is of invalid type.

        Returns a tuple.
        z3Argument must a datetime.timedelta or datetime.timer   Nr   i  <   rK   )r   r   r   timer   r   r   r   r   divmodr   r   r   rw   absrg   r   r   r   r   r   rQ   
appendleftrS   rE   )
r   r   negativer   r   r   	remainderZminsZsecsr   r3   r3   r4   prepare_binary_time  s@    




z!MySQLProtocol.prepare_binary_time)	statementparamr|   r/   c                 C  s   d t| t||gS )zMPrepare long data for prepared statements

        Returns a string.
        rK   rv   )r  r  r|   r3   r3   r4   prepare_stmt_send_long_data  s    z)MySQLProtocol.prepare_stmt_send_long_datar3   zSequence[BinaryProtocolType]r   z Optional[Dict[int, Tuple[bool]]]z.Optional[List[Tuple[str, BinaryProtocolType]]])	r~   r|   
parametersr   long_data_usedrl   query_attrsconverter_str_fallbackr/   c	              	   C  s  d}	dgt |d d  }
g }g }d}t |}g }|s:|n|t }|dkrNd}|dkrZi }|rt|}|D ]\}}|| qjdgt |d d  }
|s|r*|t |krtd	t|D ]l\}}d}|dkr|
|d   d|d > O  < |ttj	t|  q||kr6|| d r,tj
}ntj}nt|tr`| |\}}}|| npt|tr||}|tt ||  tj}n8t|tr|tt ||  tj}n
t|tr|tt t||t||  tj}nt|tr,|td
| tj}nt|tjtjfrZ| |\}}|| nvt|tjtjfr| |\}}|| nH|rt||}|tt ||  tj}ntd|j j! d|t|t|  |r|d |kr|||  d |}|tt ||  qt"|t|t"|	g}|dk	r^|t | }n|}|r|dk	r|t| |#dd |
D  |td d}|D ]N}|| |dk	r|d |kr||||   n
|d |d7 }q|D ]}|| qd$|S )z6Make a MySQL packet with the Statement Execute commandr   r   r   r   rK   Zutf8mb4r   NzTFailed executing prepared statement: data values does not match number of parametersr   z&MySQL binary protocol can not handle 'z	' objectsc                 S  s   g | ]}t d |qS )B)rO   rP   )rF   bitr3   r3   r4   r   m  s     z3MySQLProtocol.make_stmt_execute.<locals>.<listcomp>r6   )%rE   r   listrQ   r   r   r   rg   r   ZNULLZBLOBSTRINGr   rV   r   rZ   rR   Zlc_intr-   r   r   floatrO   rP   r   r   r   r   r   r   r  r   	__class____name__rw   r   rS   )r   r~   r|   r  r   r  rl   r  r  Ziteration_countr   rN   typesr   Zdata_lenZquery_attr_namesr   Zattr_valr   r   _flagsr   re   r   Zparameter_countr   Za_typeZa_valuer3   r3   r4   make_stmt_execute  s    











zMySQLProtocol.make_stmt_execute)NFN)N)r   )r   )T)r   )r   )r   )r   r   )r3   r3   r   Nr   NF)%r  
__module____qualname____doc__staticmethodr5   r>   rB   rU   rY   rj   DEFAULT_CHARSET_IDDEFAULT_MAX_ALLOWED_PACKETru   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r3   r3   r3   r4   r,   V   s      "A,z 3  ,  >  %!*7
       r,   )<r  
__future__r   r   rO   collectionsr   decimalr   r   typingr   r   r   r	   r
   r   r   r   r   rD   r   	constantsr   r   r   r   r   
conversionr   errorsr   r   r   r   r   Zpluginsr   r   Zplugins.caching_sha2_passwordr   r  r   r    r!   r"   r#   r$   r%   networkr&   r   r:   r2   Z	OK_STATUSr@   Z
ERR_STATUSr  r  r,   r3   r3   r3   r4   <module>   s2   ,$
