o
    EDiF                  	   @   s  d dl Z d dlZd dlZd dlmZ d dl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 d dl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!m"Z" d dl#m$Z$m%Z% d dl&m'Z' e (e)Z*dZ+e,dej-Z.e,dej-Z/e,dej-Z0e,de+ d ej-Z1G dd de'Z2G dd deZ3e,dej4ej5B Z6de7de7fddZ8de9fddZ:d edefd!d"Z;d&d#e
e7 dee	e7 ee9ef f fd$d%Z<dS )'    N)IOBase)AnyTupleDictSequenceOptionalUnion	GeneratorBinaryIO)tzinfo)UnknownTimeZoneError)tzutil)
bind_query)	dict_copy	empty_genStreamContextget_rename_method)ExternalData)MatrixClosable)StreamClosedErrorProgrammingError)check_arrowpd_extended_dtypes)BaseQueryContextzfCREATE|ALTER|SYSTEM|GRANT|REVOKE|CHECK|DETACH|ATTACH|DROP|DELETE|KILL|OPTIMIZE|SET|RENAME|TRUNCATE|USEz\s+LIMIT($|\s)z(^|\s)SELECT\sz(^|\s)INSERT\s*INTOz(^\s*)(z)\sc                ,       s8  e Zd ZdZddddddejddddddddddddddfdeeef de	e
eef  de	e
eef  d	e	e
eef  d
e	e
eeee
eef f f  de	e dede	e de	e de	e de	e de	eeef  de	e
eeeef f  dede	e dededede	e de	e
eef  de	e f* fddZede	e fddZejd e	e fd!dZedefd"d#Zedefd$d%Zedefd&d'Zedefd(d)Zde
eef fd*d+Zd,ed-efd.d/Zd0efd1d2Zd3ef fd4d5Zd6e	e fd7d8Z																				d=de	eeef  de	e
eef  de	e
eef  d	e	e
eef  d
e	e
eeee
eef f f  de	e de	e de	e de	e de	e de	e de	eeef  de	e
eeeef f  de	e de	e dedede	e de	e
eef  de	e dd f*d9d:Zd;d< Z  ZS )>QueryContextzk
    Argument/parameter object for queries.  This context is used to set thread/query specific formats
     Nr   Fquery
parameterssettingsquery_formatscolumn_formatsencoding	server_tzuse_nonecolumn_oriented	use_numpymax_str_lenquery_tz
column_tzsutc_tz_awareuse_extended_dtypes	as_pandas	streamingapply_server_tzexternal_datatransport_settingsrename_response_columnc                    s  t  j|||||dur|nd|
dur|
nd|d || _|pi | _|du r'dn|| _|	du r0dn|	| _|
| _|du r<dn|| _|| _|| _	|| _
|| _t|trmzt|}W n tyl } z	td| d|d}~ww || _|dur| D ]*\}}t|trzt|}|||< W qx ty } z	td| d|d}~ww qx|| _d| _d| _d| _|| _|ot| _|| _|| _t|| _|   dS )	a#	  
        Initializes various configuration settings for the query context

        :param query:  Query string with Python style format value replacements
        :param parameters: Optional dictionary of substitution values
        :param settings: Optional ClickHouse settings for the query
        :param query_formats: Optional dictionary of query formats with the key of a ClickHouse type name
          (with * wildcards) and a value of valid query formats for those types.
          The value 'encoding' can be sent to change the expected encoding for this query, with a value of
          the desired encoding such as `latin-1`
        :param column_formats: Optional dictionary of column specific formats.  The key is the column name,
          The value is either the format for the data column (such as 'string' for a UUID column) or a
          second level "format" dictionary of a ClickHouse type name and a value of query formats.  This
          secondary dictionary can be used for nested column types such as Tuples or Maps
        :param encoding: Optional string encoding for this query, such as 'latin-1'
        :param column_formats: Optional dictionary
        :param use_none: Use a Python None for ClickHouse NULL values in nullable columns.  Otherwise the default
          value of the column (such as 0 for numbers) will be returned in the result_set
        :param max_str_len Limit returned ClickHouse String values to this length, which allows a Numpy
          structured array even with ClickHouse variable length String columns.  If 0, Numpy arrays for
          String columns will always be object arrays
        :param query_tz  Either a string or a pytz tzinfo object.  (Strings will be converted to tzinfo objects).
          Values for any DateTime or DateTime64 column in the query will be converted to Python datetime.datetime
          objects with the selected timezone
        :param column_tzs A dictionary of column names to tzinfo objects (or strings that will be converted to
          tzinfo objects).  The timezone will be applied to datetime objects returned in the query
        :param utc_tz_aware Force timezone-aware Python datetime objects even when the active timezone is UTC.
          Defaults to False to preserve the legacy behavior of returning naive UTC timestamps.
        NF)r0   Tr   z	query_tz z is not recognizedz
column_tz ) super__init__r   r   r$   r%   r&   r'   r#   r.   r/   r*   
isinstancestrpytztimezoner   r   r(   itemsr)   	column_tzresponse_tz
block_infor,   r   use_pandas_nar-   _rename_response_columnr   column_renamer_update_query)selfr   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   excol_namer7   	__class__ X/var/www/Datamplify/venv/lib/python3.10/site-packages/clickhouse_connect/driver/query.pyr3   %   s^   3





zQueryContext.__init__returnc                 C   s   | j S N)r=   r@   rE   rE   rF   r1      s   z#QueryContext.rename_response_columnmethodc                 C   s   || _ t|| _d S rH   )r=   r   r>   )r@   rJ   rE   rE   rF   r1      s   c                 C      t | jd uS rH   )	select_researchuncommented_queryrI   rE   rE   rF   	is_select      zQueryContext.is_selectc                 C   rK   rH   )limit_rerM   rN   rI   rE   rE   rF   	has_limit   rP   zQueryContext.has_limitc                 C   rK   rH   )	insert_rerM   rN   rI   rE   rE   rF   	is_insert   rP   zQueryContext.is_insertc                 C   rK   rH   )
command_rerM   rN   rI   rE   rE   rF   
is_command   rP   zQueryContext.is_commandc                 C   s   || _ |   d S rH   r   r?   )r@   r   rE   rE   rF   set_parameters   s   zQueryContext.set_parameterskeyvaluec                 C   s"   | j si | _ || j |< |   d S rH   rW   )r@   rY   rZ   rE   rE   rF   set_parameter   s   
zQueryContext.set_parameterr:   c                 C   s
   || _ d S rH   )r:   )r@   r:   rE   rE   rF   set_response_tz   s   
zQueryContext.set_response_tznamec                    s6   t  | | jr|| jv r| j| | _d S d | _d S rH   )r2   start_columnr)   r9   )r@   r]   rC   rE   rF   r^      s   
zQueryContext.start_columndatatype_tzc                 C   s`   | j r| j }n|r|}n| jr| j}n| jr| j}n
| jr!| j}ntj}|tjkr.| j	s.d S |S rH   )
r9   r(   r:   r.   r#   r   local_tzr6   UTCr*   )r@   r_   	active_tzrE   rE   rF   rb      s   zQueryContext.active_tzc                 C   s  t |p| jt| j|t| j|t| j|t| j||r|n| j|r#|n| j|du r,| j	n||	du r4| j
n|	|
du r<| jn|
|du rD| jn||du rL| jn||du rT| jn||du r\| jn||du rd| jn|||| j|du rp| jn||du rx| jn||du r| jS |S )z_
        Creates Query context copy with parameters overridden/updated as appropriate.
        N)r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r.   r/   r0   r1   )r@   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r/   r0   r1   rE   rE   rF   updated_copy   s0   




zQueryContext.updated_copyc                 C   sF   t | j| j| j\| _| _t| jtrt| j| _	d S t| j| _	d S rH   )
r   r   r   r#   final_querybind_paramsr4   bytesremove_sql_commentsrN   rI   rE   rE   rF   r?      s   zQueryContext._update_query)NNNNNNNNNNNNNNNFFNNN) __name__
__module____qualname____doc__r6   ra   r   r5   rf   r   r   r   r   boolintr   r3   propertyr1   setterrO   rR   rT   rV   rX   r[   r\   r^   rb   rc   r?   __classcell__rE   rE   rC   rF   r      s&   
	
]	

.r   c                   @   s0  e Zd ZdZ								d,dedeeddf deded	ed
ede	de
e	ef fddZedefddZedefddZedefddZede	fddZdd Zdd ZedefddZedd Zedefd d!Zdeeddf fd"d#Zedefd$d%Zed&d' Zed(d) Zd*d+ ZdS )-QueryResultz<
    Wrapper class for query return values and metadata
    NrE   F
result_set	block_gencolumn_namescolumn_typesr%   sourcequery_idsummaryc	           	      C   sX   || _ d | _|p
t | _d| _|| _|| _|| _|| _|| _	|d u r'i | _
d S || _
d S )NF)_result_rows_result_columnsr   
_block_gen_in_context	_query_idrt   ru   r%   rv   rx   )	r@   rr   rs   rt   ru   r%   rv   rw   rx   rE   rE   rF   r3      s   	zQueryResult.__init__rG   c                 C   s   | j r| jS | jS rH   )r%   result_columnsresult_rowsrI   rE   rE   rF   rr     s   zQueryResult.result_setc                 C   s|   | j d u r;dd tt| jD }| j}|D ]}t||D ]	\}}|| qqW d    n1 s3w   Y  || _ | j S )Nc                 S   s   g | ]}g qS rE   rE   ).0_rE   rE   rF   
<listcomp>  s    z.QueryResult.result_columns.<locals>.<listcomp>)rz   rangelenrt   column_block_streamzipextend)r@   resultstreamblockbaseaddedrE   rE   rF   r~     s   
zQueryResult.result_columnsc                 C   sT   | j d u r'g }| j}|D ]}|| qW d    n1 sw   Y  || _ | j S rH   )ry   row_block_streamr   )r@   r   r   r   rE   rE   rF   r   #  s   
zQueryResult.result_rowsc                 C   s   | j d}|r
|S | jS )Nrw   )rx   getr}   )r@   rw   rE   rE   rF   rw   -  s   zQueryResult.query_idc                 C   s   | j d u rt| j }d | _ |S rH   )r{   r   )r@   block_streamrE   rE   rF   _column_block_stream4  s
   
z QueryResult._column_block_streamc                 c   s"    |   D ]	}tt| V  qd S rH   )r   listr   )r@   r   rE   rE   rF   _row_block_stream;  s   zQueryResult._row_block_streamc                 C      t | |  S rH   )r   r   rI   rE   rE   rF   r   ?     zQueryResult.column_block_streamc                 C   r   rH   )r   r   rI   rE   rE   rF   r   C  r   zQueryResult.row_block_streamc                    s    fdd}t  | S )Nc                  3   s       D ]} | E d H  qd S rH   )r   )r   rI   rE   rF   r   I  s   z'QueryResult.rows_stream.<locals>.stream)r   )r@   r   rE   rI   rF   rows_streamG  s   zQueryResult.rows_streamc                 c   s4    | j r	t| j n| jD ]}tt| j|V  qd S rH   )r%   r   rr   dictrt   )r@   rowrE   rE   rF   named_resultsO  s   zQueryResult.named_resultsc                 C   s0   | j rt| jdkrdS t| jd S t| jS )Nr   )r%   r   rr   rI   rE   rE   rF   	row_countS  s    
zQueryResult.row_countc                 C   s4   | j rdd t| j| jD S tt| j| jd S )Nc                 S   s   i | ]	\}}||d  qS r   rE   )r   r]   colrE   rE   rF   
<dictcomp>\  s    z*QueryResult.first_item.<locals>.<dictcomp>r   )r%   r   rt   rr   r   rI   rE   rE   rF   
first_itemY  s   zQueryResult.first_itemc                 C   s    | j rdd | jD S | jd S )Nc                 S   s   g | ]}|d  qS r   rE   )r   r   rE   rE   rF   r   b  s    z)QueryResult.first_row.<locals>.<listcomp>r   )r%   rr   rI   rE   rE   rF   	first_row_  s   
zQueryResult.first_rowc                 C   s8   | j r| j   d | _ | jd ur| j  d | _d S d S rH   )rv   closer{   rI   rE   rE   rF   r   e  s   



zQueryResult.close)NNrE   rE   FNNN)rh   ri   rj   rk   r   r	   r   rl   r   r5   r   r   r3   rn   rr   r~   r   rw   r   r   r   r   r   r   r   r   rm   r   r   r   r   rE   rE   rE   rF   rq      sf    


	


rq   z+(\".*?\"|\'.*?\')|(/\*.*?\*/|(--\s)[^\n]*$)sqlrG   c                 C   s   dd }t || S )av  
    Remove SQL comments.  This is useful to determine the type of SQL query, such as SELECT or INSERT, but we
    don't fully trust it to correctly ignore weird quoted strings, and other edge cases, so we always pass the
    original SQL to ClickHouse (which uses a full-fledged AST/ token parser)
    :param sql:  SQL query
    :return: SQL Query without SQL comments
    c                 S   s   |  drdS |  dS )N   r      )group)matchrE   rE   rF   replacerz  s   

z%remove_sql_comments.<locals>.replacer)
comment_resub)r   r   rE   rE   rF   rg   q  s   	rg   contentc                 C   s   t  }|j| }| S rH   )r   ipcRecordBatchFileReaderread_all)r   pyarrowreaderrE   rE   rF   to_arrow  s   r   bufferc                 C   s   t  }|j| }t| |S rH   )r   r   open_streamr   )r   r   r   rE   rE   rF   to_arrow_batches  s   
r   compressionc                 C   s|   t  }d }|dv r|jj|j|dd}| }|j|| j|d}||  W d    n1 s1w   Y  | jj|	 fS )N)zstdlz4)r   )options)
r   r   IpcWriteOptionsCodecBufferOutputStreamRecordBatchFileWriterschemawritenamesgetvalue)tabler   r   r   sinkwriterrE   rE   rF   arrow_buffer  s   r   rH   )=loggingrer6   ior   typingr   r   r   r   r   r   r	   r
   datetimer   pytz.exceptionsr   clickhouse_connect.driverr   !clickhouse_connect.driver.bindingr    clickhouse_connect.driver.commonr   r   r   r   "clickhouse_connect.driver.externalr   clickhouse_connect.driver.typesr   r   $clickhouse_connect.driver.exceptionsr   r   !clickhouse_connect.driver.optionsr   r   !clickhouse_connect.driver.contextr   	getLoggerrh   loggercommandscompile
IGNORECASErQ   rL   rS   rU   r   rq   	MULTILINEDOTALLr   r5   rg   rf   r   r   r   rE   rE   rE   rF   <module>   s:    (
 Zv0