o
    DDiv=                     @  s  U d Z ddlmZ ddl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 ddlmZ dd	lmZmZ dd
lmZmZmZ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Z!dZ"G dd deZ#G dd dZ$ee%e&gdf Z'de(d< d0ddZ)ee)Z*G dd  d e$Z+ee%e&gd!f Z,de(d"< d1d#d$Z-ee-Z.e/d%Z0	'd2d3d+d,Z1ej2ej3ej4d-Z5G d.d/ d/e$Z6dS )4z&
Utility module to manipulate queries
    )annotationsN)TYPE_CHECKINGAny
NamedTuple	TypeAlias	TypeGuard)	lru_cache)CallableMappingSequence   )errors)pqsql)BufferParamsQueryQueryNoTemplate)PyFormat)Template)TemplateProcessor)Transformeri   2   c                   @  s&   e Zd ZU ded< ded< ded< dS )	QueryPartbytesprez	int | stritemr   formatN)__name__
__module____qualname____annotations__ r"   r"   I/var/www/Datamplify/venv/lib/python3.10/site-packages/psycopg/_queries.pyr      s   
 r   c                   @  sf   e Zd ZdZd Zd$ddZd%ddZd&ddZe	d'ddZ
e	d(ddZd)ddZd*d!d"Zd#S )+PostgresQueryzO
    Helper to convert a Python query and parameters into Postgres format.
    z^
        query params types formats
        _tx _want_formats _parts _encoding _order
        transformerr   c                 C  s2   || _ d | _d| _d | _d | _|  d| _d | _d S )Nr"       )_txparamstypes_want_formatsformatsquery_order)selfr%   r"   r"   r#   __init__,   s   
zPostgresQuery.__init__r,   r   varsParams | NonereturnNonec                 C  s   t |tr| ||S | |}|dur5t|tkr#t|tkr#t}nt}||| j	j
\| _| _| _| _n	|| _d | _| _| | dS z
        Set up the query and parameters to convert.

        The results of this function can be obtained accessing the object
        attributes (`query`, `params`, `types`, `formats`).
        N)
isinstancer   _convert_template_ensure_byteslenMAX_CACHED_STATEMENT_LENGTHMAX_CACHED_STATEMENT_PARAMS	_query2pg_query2pg_nocacher'   encodingr,   r*   r-   _partsdumpr.   r,   r0   fr"   r"   r#   convert;   s   

zPostgresQuery.convertc                 C  sl   |dur+|  | j|| j}| jdusJ | j|| j| _| jjp"d| _| jj| _dS d| _d| _d| _dS )
        Process a new set of variables on the query processed by `convert()`.

        This method updates `params` and `types`.
        Nr"   )	validate_and_reorder_paramsr>   r-   r*   r'   dump_sequencer(   r)   r+   r.   r0   r(   r"   r"   r#   r?   ^   s   
zPostgresQuery.dumpr   TypeGuard[Sequence[Any]]c                 C  sv   t | }|tu s|tu rd}|S |tu rd}|S t| tr(t| ttfs(d}|S t| tr1d}|S t	dt | j
 )NTFz8query parameters should be a sequence or a mapping, got )typelisttupledictr5   r   r   strr
   	TypeErrorr    )r0   tsequencer"   r"   r#   is_params_sequenceo   s$   

z PostgresQuery.is_params_sequencepartslist[QueryPart]orderlist[str] | NoneSequence[Any]c                   s   t  r1t t| d kr!tdt| d  dt  d r/t| d jts/td S  rFt| dkrFt| d d t	sFtdz|rS fdd	|D W S W d
S  t
yr   tddt fdd|pjd
D  w )zO
        Verify the compatibility between a query and a set of params.
        r   zthe query has z placeholders but z parameters were passedr   z2named placeholders require a mapping of parametersz=positional placeholders (%s) require a sequence of parametersc                   s   g | ]} | qS r"   r"   ).0r   r0   r"   r#   
<listcomp>   s    z=PostgresQuery.validate_and_reorder_params.<locals>.<listcomp>r"   zquery parameter missing: z, c                 3  s    | ]	}| vr|V  qd S Nr"   )rV   irW   r"   r#   	<genexpr>   s    z<PostgresQuery.validate_and_reorder_params.<locals>.<genexpr>)r$   rP   r8   eProgrammingErrorr5   r   intrM   rL   KeyErrorjoinsorted)rQ   r0   rS   r"   rW   r#   rD      s2   
"z)PostgresQuery.validate_and_reorder_paramsr   r   c                 C  s4   t |tr|| jjS t |tjr|| jS |S rY   )r5   rL   encoder'   r=   r   
Composableas_bytes)r.   r,   r"   r"   r#   r7      s
   
zPostgresQuery._ensure_bytesr   c                 C  s|   |d urt dt|d| jd}|  |j| _|jr3| j|j|j| _| jjp*d| _| jj| _d S d | _d| _d | _d S )NA'execute()' with string template query doesn't support parametersTserver_paramstxr"   )	rM   r   r'   processr,   r(   rE   r+   r)   r.   r,   r0   tpr"   r"   r#   r6      s   
zPostgresQuery._convert_templateN)r%   r   r,   r   r0   r1   r2   r3   r0   r1   r2   r3   )r0   r   r2   rG   )rQ   rR   r0   r   rS   rT   r2   rU   )r,   r   r2   r   r,   r   r0   r1   r2   r3   )r   r   r    __doc__split	__slots__r/   rB   r?   staticmethodrP   rD   r7   r6   r"   r"   r"   r#   r$   "   s    


#
"r$   ?tuple[bytes, list[PyFormat], list[str] | None, list[QueryPart]]r   	_Query2Pgr,   r   r=   rL   r2   c           	      C  sh  t | |}d}g }g }t|d jtr;|dd D ] }t|jts#J ||j |d|jd   ||j qnht|d jtri }g }|dd D ]U}t|jtsWJ ||j |j|vrdt|d  }||jf||j< ||j || ||j qM||j d |jkrt	
d|j d|||j d  qM||d j d||||fS )	a  
    Convert Python query and params into something Postgres understands.

    - Convert Python placeholders (``%s``, ``%(name)s``) into Postgres
      format (``$1``, ``$2``)
    - placeholders can be %s, %t, or %b (auto, text or binary)
    - return ``query`` (bytes), ``formats`` (list of formats) ``order``
      (sequence of names used in the query, in the position they appear)
      ``parts`` (splits of queries and placeholders).
    Nr   s   $%dr   zplaceholder 'z' cannot have different formatsr&   )_split_queryr5   r   r^   appendr   r   rL   r8   r\   r]   r`   )	r,   r=   rQ   rS   chunksr+   partseenphr"   r"   r#   r<      s<   


r<   c                   @  s2   e Zd ZdZdZdd	d
ZdddZdddZdS )PostgresClientQueryzI
    PostgresQuery subclass merging query and arguments client-side.
    )templater,   r   r0   r1   r2   r3   c                 C  s   t |tr| ||S | |}|dur3t|tkr#t|tkr#t}nt}||| j	j
\| _| _| _n|| _d| _| | dS r4   )r5   r   r6   r7   r8   r9   r:   _query2pg_client_query2pg_client_nocacher'   r=   r}   r-   r>   r,   r?   r@   r"   r"   r#   rB     s   

zPostgresClientQuery.convertc                   sN   |dur"   j| j}t fdd|D  _ j j  _dS d _dS )rC   Nc                 3  s(    | ]}|d ur j |ndV  qd S )Ns   NULL)r'   
as_literal)rV   pr.   r"   r#   r[   +  s    
z+PostgresClientQuery.dump.<locals>.<genexpr>)rD   r>   r-   rJ   r(   r}   r,   rF   r"   r   r#   r?   #  s   

zPostgresClientQuery.dumpr   c                 C  s<   |d urt dt|d| jd}|  |j| _|j| _d S )Nre   Frf   )rM   r   r'   ri   r,   r(   rj   r"   r"   r#   r6   2  s   z%PostgresClientQuery._convert_templateNrl   rm   rn   )r   r   r    ro   rq   rB   r?   r6   r"   r"   r"   r#   r|      s    

r|   /tuple[bytes, list[str] | None, list[QueryPart]]_Query2PgClientc                 C  s  t | |dd}d}g }t|d jtr0|dd D ]}t|jts#J ||j |d qnNt|d jtr~i }g }|dd D ];}t|jtsLJ ||j |j|vrmd}||jf||j< ||j || qB|||j d  ||j qB||d j d|||fS )zX
    Convert Python query and params into a template to perform client-side binding
    F)collapse_double_percentNr   ru   s   %sr&   )	rv   r5   r   r^   rw   r   rL   r   r`   )r,   r=   rQ   rS   rx   ry   rz   r{   r"   r"   r#   r   C  s0   
r   s"  (?x)
        %                       # a literal %
        (?:
            (?:
                \( ([^)]+) \)   # or a name in (braces)
                .               # followed by a format
            )
            |
            (?:.)               # or any char, really
        )
        asciiTr   boolrR   c                 C  s  g }d}d }t | D ]}| ||dd  }|||f |dd }q|r5|| |d  d f n|| d f g }d}d }	|t|k r|| \}}|d u r_|t|dtj 	 |S |d }
dkr|rld}
||d  \}}||
 | |f||d < ||= qB|
dkrt	
d| |dd d   d | d|
dkrt	
d	|
d
d  dvrt	
d|d| d|dr|d|n|}|	st|}	n|	t|urt	
dt|
d
d   }|t||| |d7 }|t|k sH|S )Nr   r   s   %%   %s   %(zincomplete placeholder: ''s   % zfincomplete placeholder: '%'; if you want to use '%' as an operator you can double it up, i.e. use '%%'ru   s   sbtz8only '%s', '%b', '%t' are allowed as placeholders, got 'z1positional and named placeholders cannot be mixed)_re_placeholderfinditerspanrw   r8   r   r   AUTOgroupr\   r]   rp   decoderH   
_ph_to_fmt)r,   r=   r   rQ   curmr   rvrZ   phtyper{   pre1m1r   r   r"   r"   r#   rv   z  sl   +"
0rv   )   s   t   bc                   @  s*   e Zd ZdddZdd	d
ZdddZdS )PostgresRawQueryr,   r   r0   r1   r2   r3   c                 C  s<   t |tr| ||S | || _d  | _| _| | d S rY   )r5   r   r6   r7   r,   r*   r-   r?   r.   r,   r0   r"   r"   r#   rB     s
   
zPostgresRawQuery.convertc                 C  sp   |d ur-t |stdtjgt| | _| j|| j| _	| jj
p$d| _
| jj| _d S d | _	d| _
d | _d S )Nz,raw queries require a sequence of parametersr"   )r$   rP   rM   r   r   r8   r*   r'   rE   r(   r)   r+   )r.   r0   r"   r"   r#   r?     s   

zPostgresRawQuery.dumpr   c                 C  s   t t| j d)Nz! doesn't support template strings)r\   NotSupportedErrorrH   r   r   r"   r"   r#   r6     s   z"PostgresRawQuery._convert_templateNrl   rm   rn   )r   r   r    rB   r?   r6   r"   r"   r"   r#   r     s    

r   )r,   r   r=   rL   r2   rs   )r,   r   r=   rL   r2   r   )r   T)r,   r   r=   rL   r   r   r2   rR   )7ro   
__future__r   retypingr   r   r   r   r   	functoolsr   collections.abcr	   r
   r    r   r\   r   r   abcr   r   r   r   _enumsr   _compatr   	_tstringsr   r   r9   r:   r   r$   r   rL   rt   r!   r<   r;   r|   r   r   r~   compiler   rv   r   TEXTBINARYr   r   r"   r"   r"   r#   <module>   sP      

7>

%J