o
    ٭hL                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	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 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$m%Z% ddl&m'Z'm(Z(m)Z)m*Z*m+Z+ erddl,m-Z-m.Z.m/Z/ ej0dkrd dlm1Z1 nd dl2m1Z1 edZ3edddZ4G dd dZ5G dd de5Z6G dd de6Z7G dd dZ8G dd de6Z9G dd de6Z:G dd de6Z;G d d! d!e6Z<G d"d# d#e6Z=G d$d% d%e=Z>G d&d' d'e=Z?G d(d) d)e6Z@G d*d+ d+ZAG d,d- d-e@e;ZBG d.d/ d/e6ZCG d0d1 d1eBZDG d2d3 d3e@ZEG d4d5 d5eEZFG d6d7 d7eEZGG d8d9 d9e@ZHG d:d; d;e@ZIG d<d= d=e@ZJG d>d? d?e@ZKG d@dA dAe@ZLG dBdC dCeLZMG dDdE dEeLZNG dFdG dGe@ZOG dHdI dIe@ZPG dJdK dKeIZQG dLdM dMe6ZRG dNdO dOe6ZSG dPdQ dQe@ZTG dRdS dSe@ZUG dTdU dUZVG dVdW dWe@ZWG dXdY dYeWZXG dZd[ d[eXZYed\d]dZZG d^d_ d_eYZ[G d`da daeYZ\G dbdc dce6Z]G ddde deeWZ^G dfdg dgeWZ_G dhdi dieWZ`G djdk dke6ZaG dldm dme6ZbdS )n    )annotationsN)IterableIteratorSequence)datetime)Enum)TYPE_CHECKINGAnyCallableTypeVarcast   )DEFAULT_SQL_CONTEXT
SqlContext)	
ArithmeticBoolean
ComparatorDatePartDialectsEqualityJSONOperatorsMatchingOrder)CaseExceptionFunctionException)builderformat_alias_sqlformat_quotesignore_copyresolve_is_aggregate)QueryBuilder
SelectableTable)      )SelfTNodeTNode)boundc                   @  s.   e Zd ZU dZded< dddZdddZdS )r)   Nbool | Noneis_aggregatereturnIterator[NodeT]c                 c  s    | V  d S N selfr0   r0   Z/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/pypika_tortoise/terms.pynodes_+   s   
zNode.nodes_typetype[NodeT]list[NodeT]c                   s    fdd|   D S )Nc                   s   g | ]	}t | r|qS r0   )
isinstance).0noder5   r0   r3   
<listcomp>/   s
    
zNode.find_.<locals>.<listcomp>)r4   )r2   r5   r0   r;   r3   find_.   s   
z
Node.find_r-   r.   )r5   r6   r-   r7   )__name__
__module____qualname__r,   __annotations__r4   r=   r0   r0   r0   r3   r)   (   s   
 
c                   @  sP  e Zd ZU dZded< ddd	d
ZedddZedddZ	dddZ
e	ddddZe	dddd Zdd$d%Zdd(d)Zdd+d,Zdd.d/Zdd3d4Zdd5d6Zdd7d8Zdd9d:Zdd;d<Zdd=d>Zdd@dAZddBdCZddDdEZddFdGZddHdIZddJdKZddMdNZddRdSZddWdXZ ddYdZZ!dd\d]Z"ddadbZ#ddcddZ$ddedfZ%ddgdhZ&ddidjZ'ddkdlZ(ddndoZ)ddqdrZ*ddsdtZ+ddudvZ,ddwdxZ-ddzd{Z.dd}d~Z/dddZ0dddZ1dddZ2dddZ3dddZ4dddZ5dddZ6dddZ7dddZ8dddZ9dddZ:dddZ;dddZ<dddZ=dS )TermFr+   r,   Nalias
str | Noner-   Nonec                 C  
   || _ d S r/   rD   r2   rD   r0   r0   r3   __init__7      
zTerm.__init__strr&   c                 C  rG   r/   rH   rI   r0   r0   r3   as_:      
zTerm.as_
set[Table]c                 C  s   ddl m} t| |S )Nr   )r#   ) r#   setr=   )r2   r#   r0   r0   r3   tables_>   s   zTerm.tables_
set[Field]c                 C  s   t | tS r/   )rQ   r=   Fieldr1   r0   r0   r3   fields_D      zTerm.fields_valr
   wrapper_clstype[Term] | None3NodeT | LiteralValue | Array | Tuple | ValueWrapperc                 C  sV   t | tr
tt| S | du rt S t | trt|  S t | tr#t|  S |p&t	}|| S )a,  
        Used for wrapping raw inputs such as numbers in Criterions and Operator.

        For example, the expression F('abc')+1 stores the integer part in a ValueWrapper object.

        :param val:
            Any value.
        :param wrapper_cls:
            A pypika class which wraps a constant value so it can be handled as a component of the query.
        :return:
            Raw string, number, or decimal values will be returned in a ValueWrapper.  Fields and other parts of the
            querybuilder will be returned as inputted.

        N)
r8   r)   r   r(   	NullValuelistArraytupleTupleValueWrapper)rW   rX   r0   r0   r3   wrap_constantG   s   



zTerm.wrap_constant-Term | QueryBuilder | str | int | bool | Nonetype[ValueWrapper] | None5Term | QueryBuilder | NullValue | ValueWrapper | JSONc                 C  sT   ddl m} t| t|fr| S | d u rt S t| tttfr&|p!t}|| S t	| S )Nr   )r!   )
queriesr!   r8   rC   r[   rL   intboolr`   JSON)rW   rX   r!   r0   r0   r3   	wrap_jsong   s   zTerm.wrap_jsoncurrent_tableTable | None	new_tablec                 C     | S )a  
        Replaces all occurrences of the specified table with the new table. Useful when reusing fields across queries.
        The base implementation returns self because not all terms have a table property.

        :param current_table:
            The table to be replaced.
        :param new_table:
            The table to replace with.
        :return:
            Self.
        r0   r2   rj   rl   r0   r0   r3   replace_tablex   s   zTerm.replace_tableotherBasicCriterionc                 C  s   | |kS r/   r0   r2   rp   r0   r0   r3   eq      zTerm.eqNullCriterionc                 C     t | S r/   )ru   r1   r0   r0   r3   isnull   rt   zTerm.isnullNotc                 C  s   |    S r/   )rw   negater1   r0   r0   r3   notnull   s   zTerm.notnullvaluerf   BitwiseAndCriterionc                 C  s   t | | |S r/   )r|   ra   r2   r{   r0   r0   r3   
bitwiseand      zTerm.bitwiseandc                 C  s   | |kS r/   r0   rr   r0   r0   r3   gt   rt   zTerm.gtc                 C  s   | |kS r/   r0   rr   r0   r0   r3   gte   rt   zTerm.gtec                 C  s   | |k S r/   r0   rr   r0   r0   r3   lt   rt   zTerm.ltc                 C  s   | |kS r/   r0   rr   r0   r0   r3   lte   rt   zTerm.ltec                 C  s   | |kS r/   r0   rr   r0   r0   r3   ne   rt   zTerm.neexprc                 C     t tj| | |S r/   )rq   r   globra   r2   r   r0   r0   r3   r         z	Term.globc                 C  r   r/   )rq   r   likera   r   r0   r0   r3   r      r   z	Term.likec                 C  r   r/   )rq   r   not_likera   r   r0   r0   r3   r      r   zTerm.not_likec                 C  r   r/   )rq   r   ilikera   r   r0   r0   r3   r      r   z
Term.ilikec                 C  r   r/   )rq   r   	not_ilikera   r   r0   r0   r3   r      r   zTerm.not_ilikec                 C  r   r/   )rq   r   rlikera   r   r0   r0   r3   r      r   z
Term.rlikepatternc                 C  r   r/   )rq   r   regexra   r2   r   r0   r0   r3   r      r   z
Term.regexlowerupperBetweenCriterionc                 C     t | | || |S r/   )r   ra   r2   r   r   r0   r0   r3   between      zTerm.betweenstartendPeriodCriterionc                 C  r   r/   )r   ra   )r2   r   r   r0   r0   r3   from_to   r   zTerm.from_toc                 C  r   r/   )rq   r   as_ofra   r   r0   r0   r3   r      r   z
Term.as_ofAllc                 C  rv   r/   )r   r1   r0   r0   r3   all_   rt   z	Term.all_arglist | tuple | set | TermContainsCriterionc                 C  s(   t |tttfrt| t| S t| |S r/   )r8   r\   r^   rQ   r   r_   r2   r   r0   r0   r3   isin   s   
z	Term.isinc                 C  s   |  | S r/   )r   ry   r   r0   r0   r3   notin   rV   z
Term.notinc                 C  r   r/   )rq   r   	bin_regexra   r   r0   r0   r3   r      r   zTerm.bin_regexc                 C  rv   r/   rx   r1   r0   r0   r3   ry      rt   zTerm.negatec                 C  rv   r/   r   r1   r0   r0   r3   
__invert__   rt   zTerm.__invert__c                 C  rm   r/   r0   r1   r0   r0   r3   __pos__      zTerm.__pos__Negativec                 C  rv   r/   )r   r1   r0   r0   r3   __neg__   rt   zTerm.__neg__ArithmeticExpressionc                 C  r   r/   r   r   addra   rr   r0   r0   r3   __add__   r   zTerm.__add__c                 C  r   r/   r   r   subra   rr   r0   r0   r3   __sub__   r   zTerm.__sub__c                 C  r   r/   r   r   mulra   rr   r0   r0   r3   __mul__   r   zTerm.__mul__c                 C  r   r/   r   r   divra   rr   r0   r0   r3   __truediv__   r   zTerm.__truediv__Powc                 C  
   t | |S r/   )r   rr   r0   r0   r3   __pow__   rK   zTerm.__pow__Modc                 C  r   r/   )r   rr   r0   r0   r3   __mod__   rK   zTerm.__mod__c                 C     t tj| || S r/   r   rr   r0   r0   r3   __radd__   r   zTerm.__radd__c                 C  r   r/   r   rr   r0   r0   r3   __rsub__   r   zTerm.__rsub__c                 C  r   r/   r   rr   r0   r0   r3   __rmul__   r   zTerm.__rmul__c                 C  r   r/   r   rr   r0   r0   r3   __rtruediv__   r   zTerm.__rtruediv__c                 C  r   r/   )rq   r   rs   ra   rr   r0   r0   r3   __eq__   r   zTerm.__eq__c                 C  r   r/   )rq   r   r   ra   rr   r0   r0   r3   __ne__   r   zTerm.__ne__c                 C  r   r/   )rq   r   r   ra   rr   r0   r0   r3   __gt__   r   zTerm.__gt__c                 C  r   r/   )rq   r   r   ra   rr   r0   r0   r3   __ge__   r   zTerm.__ge__c                 C  r   r/   )rq   r   r   ra   rr   r0   r0   r3   __lt__  r   zTerm.__lt__c                 C  r   r/   )rq   r   r   ra   rr   r0   r0   r3   __le__  r   zTerm.__le__itemslicec                 C  s"   t |ts	td| |j|jS )Nz"Field' object is not subscriptable)r8   r   	TypeErrorr   r   stop)r2   r   r0   r0   r3   __getitem__	  s   
zTerm.__getitem__c                 C  
   |  tS r/   get_sqlr   r1   r0   r0   r3   __str__  rK   zTerm.__str__c                 C  s   t jdd}t| |S )NT
with_alias)r   copyhashr   r2   ctxr0   r0   r3   __hash__     zTerm.__hash__r   r   c                 C     t  r/   NotImplementedErrorr   r0   r0   r3   r        zTerm.get_sqlr/   rD   rE   r-   rF   )rD   rL   r-   r&   )r-   rO   r-   rS   )rW   r
   rX   rY   r-   rZ   )rW   rb   rX   rc   r-   rd   rj   rk   rl   rk   r-   r&   rp   r
   r-   rq   )r-   ru   )r-   rx   )r{   rf   r-   r|   )r   rL   r-   rq   )r   rL   r-   rq   )r   r
   r   r
   r-   r   )r   r
   r   r
   r-   r   )r-   r   )r   r   r-   r   r-   r&   )r-   r   )rp   r
   r-   r   )rp   r
   r-   r   )rp   r
   r-   r   )r   r   r-   r   r-   rL   )r-   rf   r   r   r-   rL   )>r?   r@   rA   r,   rB   rJ   r   rM   propertyrR   rU   staticmethodra   ri   ro   rs   rw   rz   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r0   r0   r0   r3   rC   4   s|   
 















































rC   c                   @  sd   e Zd ZdZejdd ejdd ejdd ejdd ej	dd iZ
dZd	ZddddZdddZd	S )	Parameterz
    Represents a parameter in a query. The placeholder can be specified with the `placeholder` argument or
    will be determined based on the dialect if not provided.
    c                 C     dS N?r0   _r0   r0   r3   <lambda>       zParameter.<lambda>c                 C  r   r   r0   r   r0   r0   r3   r   !  r   c                 C  r   )Nz%sr0   r   r0   r0   r3   r   "  r   c                 C  s
   d|  S )N$r0   idxr0   r0   r3   r   #  s   
 c                 C  r   r   r0   r   r0   r0   r3   r   $  r   r   NplaceholderrE   r   
int | Noner-   rF   c                 C  sL   |s
|d u r
t d|d ur|dk rt d|r|rt d|| _|| _d S )Nz+Must provide either a placeholder or an idxr   zidx must start at 1z,Cannot provide both a placeholder and an idx)
ValueError_placeholder_idx)r2   r   r   r0   r0   r3   rJ   )  s   
zParameter.__init__r   r   rL   c                   s*    j r j S  j|j fdd jS )Nc                   s    j S r/   )DEFAULT_PLACEHOLDERr   r1   r0   r3   r   :  s    z#Parameter.get_sql.<locals>.<lambda>)r   IDX_PLACEHOLDERSgetdialectr   r   r0   r1   r3   r   6  s   zParameter.get_sqlNN)r   rE   r   r   r-   rF   r   )r?   r@   rA   __doc__r   ORACLEMSSQLMYSQL
POSTGRESQLSQLITEr   r   r,   rJ   r   r0   r0   r0   r3   r     s    




r   c                   @  s0   e Zd ZdZddddZdddZdddZdS )Parameterizera  
    Parameterizer can be used to replace values with parameters in a query:
>>>>>>> 94fab2d (Replace ListParameter with Parameterizer)

        >>> parameterizer = Parameterizer()
        >>> customers = Table("customers")
        >>> sql = Query.from_(customers).select(customers.id)        ...             .where(customers.lname == "Mustermann")        ...             .get_sql(parameterizer=parameterizer, dialect=Dialects.SQLITE)
        >>> sql, parameterizer.values
        ('SELECT "id" FROM "customers" WHERE "lname"=?', ['Mustermann'])

    Parameterizer remembers the values it has seen and replaces them with parameters. The values can
    be accessed via the `values` attribute.
    Nplaceholder_factoryCallable[[int], str] | Noner-   rF   c                 C  s   || _ g | _d S r/   )r  values)r2   r  r0   r0   r3   rJ   N     
zParameterizer.__init__r{   r
   rg   c                 C  s(   t |trdS t |tr|dkrdS dS )NF*T)r8   r   rL   r}   r0   r0   r3   should_parameterizeR  s
   
z!Parameterizer.should_parameterizer   c                 C  s6   | j | | jrt| t| j S tt| j dS )Nr   )r  appendr  r   lenr}   r0   r0   r3   create_paramZ  s   zParameterizer.create_paramr/   )r  r  r-   rF   )r{   r
   r-   rg   )r{   r
   r-   r   )r?   r@   rA   r   rJ   r	  r  r0   r0   r0   r3   r  =  s
    
r  c                      s6   e Zd Zd fddZeddd	ZdddZ  ZS )r   termrC   r-   rF   c                   s   t    || _d S r/   superrJ   r  r2   r  	__class__r0   r3   rJ   c  s   

zNegative.__init__r+   c                 C     | j jS r/   r  r,   r1   r0   r0   r3   r,   g     zNegative.is_aggregater   r   rL   c                 C     dj | j|dS )Nz-{term}r  )formatr  r   r   r0   r0   r3   r   k  r   zNegative.get_sql)r  rC   r-   rF   r-   r+   r   )r?   r@   rA   rJ   r   r,   r   __classcell__r0   r0   r  r3   r   b  
    r   c                      sH   e Zd ZdZ	dd fddZdddZedddZdddZ  Z	S )r`   NTr{   r
   rD   rE   allow_parametrizerg   r-   rF   c                   s   t  | || _|| _dS )ab  
        A wrapper for a constant value such as a string or number.

        :param value:
            The value to be wrapped.
        :param alias:
            An optional alias for the value.
        :param allow_parametrize:
            Whether the value should be replaced with a parameter in the query if parameterizer
            is used.
        N)r  rJ   r{   r  )r2   r{   rD   r  r  r0   r3   rJ   r  s   
zValueWrapper.__init__r   r   rL   c                 C  s   |  | j|S r/   )get_formatted_valuer{   r   r0   r0   r3   get_value_sql  rV   zValueWrapper.get_value_sqlc                 C  s   |j pd}t|tr||S t|tr#t|tr|jS | |j|S t|tt	fr2| |
 |S t|trD|||d }t||S t|trOt| S t|tjr]| t||S t|ttfrltt||S |d u rrdS t|S )NrP      null)secondary_quote_charr8   rC   r   r   r   r{   r  r   r   	isoformatrL   replacer   rg   r   uuidUUIDdictr\   jsondumps)clsr{   r   
quote_charr0   r0   r3   r    s*   







z ValueWrapper.get_formatted_valuec                 C  sX   |j d u s|j | jr| js| |}t|| j|S |j | j}t||| j|S r/   )	parameterizerr	  r{   r  r  r   rD   r  r   )r2   r   sqlparamr0   r0   r3   r     s   
zValueWrapper.get_sqlNT)r{   r
   rD   rE   r  rg   r-   rF   r   )r{   r
   r   r   r-   rL   )
r?   r@   rA   r,   rJ   r  classmethodr  r   r  r0   r0   r  r3   r`   o  s    
r`   c                      s   e Zd ZU dZded< d6d7 fd
dZd8ddZd9ddZd:ddZe	d;d<ddZ
d=ddZd>d!d"Zd>d#d$Zd?d&d'Zd?d(d)Zd@d+d,Zd@d-d.Zd@d/d0ZdAd2d3ZdAd4d5Z  ZS )Brh   Nrk   tabler{   r
   rD   rE   r-   rF   c                      t  | || _d S r/   )r  rJ   r{   r2   r{   rD   r  r0   r3   rJ        
zJSON.__init__kwargsrL   c                 K  s\   t |tr| j|fi |S t |tr| j|fi |S t |tr*| j|fi |S t|S r/   )r8   r&  _get_dict_sqlr\   _get_list_sqlrL   _get_str_sql)r2   r{   r4  r0   r0   r3   _recursive_get_sql  s   


zJSON._recursive_get_sqlr&  c                   s.    fdd|  D }ddd|dgS )Nc                   s:   g | ]\}}d j j|fi  j|fi  dqS )z{key}:{value})keyr{   )r  r8  )r9   kvr4  r2   r0   r3   r<     s    z&JSON._get_dict_sql.<locals>.<listcomp>rP   {,})itemsjoinr2   r{   r4  pairsr0   r<  r3   r5    s   zJSON._get_dict_sqlr\   c                   s*    fdd|D }d dd |dgS )Nc                   s   g | ]}j |fi  qS r0   )r8  )r9   r;  r<  r0   r3   r<     s    z&JSON._get_list_sql.<locals>.<listcomp>rP   [r>  ])rA  rB  r0   r<  r3   r6    s   zJSON._get_list_sql"r*  c                 K  r   r/   )r   )r{   r*  r4  r0   r0   r3   r7    rN   zJSON._get_str_sqlr   r   c                 C  s"   t | | j|j}t|| j|S r/   )r   r8  r{   r!  r   rD   r2   r   r,  r0   r0   r3   r        zJSON.get_sqlkey_or_index	str | intrq   c                 C  r   r/   )rq   r   GET_JSON_VALUEra   r2   rI  r0   r0   r3   get_json_value  
   zJSON.get_json_valuec                 C  r   r/   )rq   r   GET_TEXT_VALUEra   rL  r0   r0   r3   get_text_value  rN  zJSON.get_text_value	path_jsonc                 C  r   r/   )rq   r   GET_PATH_JSON_VALUEri   r2   rQ  r0   r0   r3   get_path_json_value  rN  zJSON.get_path_json_valuec                 C  r   r/   )rq   r   GET_PATH_TEXT_VALUEri   rS  r0   r0   r3   get_path_text_value  rN  zJSON.get_path_text_valuerp   c                 C  r   r/   )rq   r   HAS_KEYri   rr   r0   r0   r3   has_key  rN  zJSON.has_keyc                 C  r   r/   )rq   r   CONTAINSri   rr   r0   r0   r3   contains  rN  zJSON.containsc                 C  r   r/   )rq   r   CONTAINED_BYri   rr   r0   r0   r3   contained_by  rN  zJSON.contained_byr   c                 C     t tj| t| S r/   )rq   r   HAS_KEYSr]   rr   r0   r0   r3   has_keys     zJSON.has_keysc                 C  r]  r/   )rq   r   HAS_ANY_KEYSr]   rr   r0   r0   r3   has_any_keys  r`  zJSON.has_any_keysr   )r{   r
   rD   rE   r-   rF   )r{   r
   r4  r
   r-   rL   )r{   r&  r4  r
   r-   rL   )r{   r\   r4  r
   r-   rL   )rF  )r{   rL   r*  rL   r4  r
   r-   rL   r   )rI  rJ  r-   rq   )rQ  rL   r-   rq   r   )rp   r   r-   rq   )r?   r@   rA   r0  rB   rJ   r8  r5  r6  r   r7  r   rM  rP  rT  rV  rX  rZ  r\  r_  rb  r  r0   r0   r  r3   rh     s$   
 

	










rh   c                      (   e Zd Zd fddZdd
dZ  ZS )Valuesfieldstr | Fieldr-   rF   c                   s.   t  d  t|tst|| _d S || _d S r/   )r  rJ   r8   rT   re  )r2   re  r  r0   r3   rJ     s   "zValues.__init__r   r   rL   c                 C  r  )NzVALUES({value})r{   )r  re  r   r   r0   r0   r3   r     r   zValues.get_sql)re  rf  r-   rF   r   r?   r@   rA   rJ   r   r  r0   r0   r  r3   rd        rd  c                      s*   e Zd Zdd fddZdddZ  ZS )LiteralValueNrD   rE   r-   rF   c                   r1  r/   )r  rJ   _valuer2  r  r0   r3   rJ     r3  zLiteralValue.__init__r   r   rL   c                 C  s   t | j| j|S r/   )r   rk  rD   r   r0   r0   r3   r     r   zLiteralValue.get_sqlr/   r   r   rh  r0   r0   r  r3   rj        rj  c                          e Zd Zdd	 fddZ  ZS )
r[   NrD   rE   r-   rF   c                      t  d| d S )NNULLr  rJ   rI   r  r0   r3   rJ   "  r`  zNullValue.__init__r/   r   r?   r@   rA   rJ   r  r0   r0   r  r3   r[   !      r[   c                      rm  )
SystemTimeValueNrD   rE   r-   rF   c                   rn  )NSYSTEM_TIMErp  rI   r  r0   r3   rJ   '  r`  zSystemTimeValue.__init__r/   r   rq  r0   r0   r  r3   rs  &  rr  rs  c                   @  sT   e Zd ZdddZdddZdd	d
ZeddddZeddddZdddZ	dS )	Criterionrp   r
   r-   ComplexCriterionc                 C     t tj| |S r/   )rv  r   and_rr   r0   r0   r3   __and__,  rV   zCriterion.__and__c                 C  rw  r/   )rv  r   or_rr   r0   r0   r3   __or__/  rV   zCriterion.__or__c                 C  rw  r/   )rv  r   xor_rr   r0   r0   r3   __xor__2  rV   zCriterion.__xor__r0   termsIterable[Term]EmptyCriterionc                 C  s   t  }| D ]}||O }q|S r/   r  r~  critr  r0   r0   r3   any5     
zCriterion.anyIterable[Any]c                 C  s   t  }| D ]}||M }q|S r/   r  r  r0   r0   r3   all>  r  zCriterion.allr   r   rL   c                 C  r   r/   r   r   r0   r0   r3   r   G  r   zCriterion.get_sqlN)rp   r
   r-   rv  )r0   )r~  r  r-   r  )r~  r  r-   r  r   )
r?   r@   rA   ry  r{  r}  r   r  r  r   r0   r0   r0   r3   ru  +  s    


ru  c                   @  sP   e Zd ZU dZded< e Zded< ddd	ZdddZdddZ	dddZ
dS )r  Nr+   r,   rO   rR   r-   rS   c                 C  s   t  S r/   )rQ   r1   r0   r0   r3   rU   O  r   zEmptyCriterion.fields_rp   r'   c                 C     |S r/   r0   rr   r0   r0   r3   ry  R  r   zEmptyCriterion.__and__c                 C  r  r/   r0   rr   r0   r0   r3   r{  U  r   zEmptyCriterion.__or__c                 C  r  r/   r0   rr   r0   r0   r3   r}  X  r   zEmptyCriterion.__xor__r   )rp   r'   r-   r'   )r?   r@   rA   r,   rB   rQ   rR   rU   ry  r{  r}  r0   r0   r0   r3   r  K  s   
 


r  c                      sF   e Zd Z		dd fd
dZdddZedddZdddZ  ZS )rT   NnamerL   rD   rE   r0  str | Selectable | Noner-   rF   c                   s   t  j|d || _|| _d S NrH   )r  rJ   r  r0  )r2   r  rD   r0  r  r0   r3   rJ   ]  s   
zField.__init__r.   c                 c  *    | V  | j d ur| j  E d H  d S d S r/   r0  r4   r1   r0   r0   r3   r4   g  
   
zField.nodes_rj   rk   rl   r&   c                 C  s   | j |kr
|| _ dS dS )Q  
        Replaces all occurrences of the specified table with the new table. Useful when reusing fields across queries.

        :param current_table:
            The table to be replaced.
        :param new_table:
            The table to replace with.
        :return:
            A copy of the field with the tables replaced.
        Nr0  rn   r0   r0   r3   ro   l  s   

zField.replace_tabler   r   c                 C  sd   t | j|j}| jr!|js| jjr!| j }djt ||j|d}t| dd }|j	r0t
|||S |S )Nz{namespace}.{name})	namespacer  rD   )r   r  r*  r0  with_namespacerD   get_table_namer  getattrr   r   )r2   r   	field_sql
table_namefield_aliasr0   r0   r3   r   }  s   

zField.get_sqlr   )r  rL   rD   rE   r0  r  r-   rF   r>   r   r   	r?   r@   rA   rJ   r4   r   ro   r   r  r0   r0   r  r3   rT   \  s    

rT   c                      s*   e Zd Zdd fdd	ZdddZ  ZS )IndexNr  rL   rD   rE   r-   rF   c                   r1  r/   r  rJ   r  )r2   r  rD   r  r0   r3   rJ     r3  zIndex.__init__r   r   c                 C  s   t | j|jS r/   )r   r  r*  r   r0   r0   r3   r     rV   zIndex.get_sqlr/   )r  rL   rD   rE   r-   rF   r   rh  r0   r0   r  r3   r    rl  r  c                      s4   e Zd Zdd fddZdd	d
ZdddZ  ZS )StarNr0  r  r-   rF   c                   s   t  jd|d d S )Nr  r  rp  )r2   r0  r  r0   r3   rJ     r   zStar.__init__r.   c                 c  r  r/   r  r1   r0   r0   r3   r4     r  zStar.nodes_r   r   rL   c                 C  s>   | j r|js
| j jr| j jpt| j d}dt||jS dS )N_table_namez{}.*r  )r0  r  rD   r  r  r   r*  )r2   r   r  r0   r0   r3   r     s   zStar.get_sqlr/   )r0  r  r-   rF   r>   r   r?   r@   rA   rJ   r4   r   r  r0   r0   r  r3   r    s    
r  c                      sN   e Zd Zd fddZddd	ZdddZedddZedddZ	  Z
S )r_   r  r
   r-   rF   c                   s"   t     fdd|D  _d S )Nc                      g | ]}  |qS r0   ra   r9   r{   r1   r0   r3   r<         z"Tuple.__init__.<locals>.<listcomp>)r  rJ   r  r2   r  r  r1   r3   rJ     s   
zTuple.__init__r.   c                 c  &    | V  | j D ]	}| E d H  qd S r/   )r  r4   r}   r0   r0   r3   r4     
   
zTuple.nodes_r   r   rL   c                   s.   d d fdd| jD }t|| j S )N({})r>  c                 3      | ]}|  V  qd S r/   r   r9   r  r   r0   r3   	<genexpr>      z Tuple.get_sql.<locals>.<genexpr>)r  rA  r  r   rD   rG  r0   r  r3   r     s    zTuple.get_sqlr+   c                 C     t dd | jD S )Nc                 S     g | ]}|j qS r0   r,   )r9   rW   r0   r0   r3   r<         z&Tuple.is_aggregate.<locals>.<listcomp>)r    r  r1   r0   r0   r3   r,     s   zTuple.is_aggregaterj   rk   rl   r&   c                       fdd| j D | _ dS )r  c                      g | ]}|  qS r0   ro   r  rj   rl   r0   r3   r<         z'Tuple.replace_table.<locals>.<listcomp>N)r  rn   r0   r  r3   ro        zTuple.replace_tabler  r
   r-   rF   r>   r   r  r   )r?   r@   rA   rJ   r4   r   r   r,   r   ro   r  r0   r0   r  r3   r_     s    

r_   c                      rc  )r]   r  r
   r-   rF   c                   s   t  j|  t|| _d S r/   )r  rJ   r\   original_valuer  r  r0   r3   rJ     r   zArray.__init__r   r   rL   c                   s    j d u s j | js;d fdd| jD }d|} jtjtj	fv r4t
|dkr2d|nd}t|| j S  j | j}| S )Nr>  c                 3  r  r/   r  r  r  r0   r3   r    r  z Array.get_sql.<locals>.<genexpr>z[{}]r   z	ARRAY[{}]z'{}')r+  r	  r  rA  r  r  r   r   r  REDSHIFTr  r   rD   r  r   )r2   r   r  r,  r-  r0   r  r3   r     s   

zArray.get_sqlr  r   rh  r0   r0   r  r3   r]     ri  r]   c                         e Zd Zd fddZ  ZS )Bracketr  r
   r-   rF   c                   s   t  | d S r/   rp  r  r  r0   r3   rJ     r   zBracket.__init__)r  r
   r-   rF   rq  r0   r0   r  r3   r        r  c                      sR   e Zd Z	d!d" fddZd#ddZed$ddZed%ddZd&dd Z	  Z
S )'NestedCriterionN
comparatorr   nested_comparatorrv  leftr
   rightnestedrD   rE   r-   rF   c                   s.   t  | || _|| _|| _|| _|| _d S r/   )r  rJ   r  r  r  r  r  )r2   r  r  r  r  r  rD   r  r0   r3   rJ     s   	
zNestedCriterion.__init__r.   c                 c  <    | V  | j  E d H  | j E d H  | j E d H  d S r/   )r  r4   r  r  r1   r0   r0   r3   r4     
   zNestedCriterion.nodes_r+   c                 C  s   t dd | j| j| jfD S )Nc                 S  r  r0   r  r  r0   r0   r3   r<     r  z0NestedCriterion.is_aggregate.<locals>.<listcomp>)r    r  r  r  r1   r0   r0   r3   r,     s   zNestedCriterion.is_aggregaterj   rk   rl   r&   c                 C  s4   | j ||| _ | j||| _| j||| _dS U  
        Replaces all occurrences of the specified table with the new table. Useful when reusing fields across queries.

        :param current_table:
            The table to be replaced.
        :param new_table:
            The table to replace with.
        :return:
            A copy of the criterion with the tables replaced.
        N)r  ro   r  r  rn   r0   r0   r3   ro     s   zNestedCriterion.replace_tabler   r   rL   c                 C  sN   dj | j|| jj| j|| jj| j|d}|jr%t	|| j
|dS |S )Nz4{left}{comparator}{right}{nested_comparator}{nested})r  r  r  r  r  )r,  rD   r   )r  r  r   r  r{   r  r  r  r   r   rD   rG  r0   r0   r3   r     s   


zNestedCriterion.get_sqlr/   )r  r   r  rv  r  r
   r  r
   r  r
   rD   rE   r-   rF   r>   r  r   r   r?   r@   rA   rJ   r4   r   r,   r   ro   r   r  r0   r0   r  r3   r    s    
r  c                      sR   e Zd Z	dd fddZd ddZed!ddZed"ddZd#ddZ	  Z
S )$rq   Nr  !Comparator | JSONOperators | Enumr  rC   r  rD   rE   r-   rF   c                   "   t  | || _|| _|| _dS )a  
        A wrapper for a basic criterion such as equality or inequality. This wraps three parts, a left and right term
        and a comparator which defines the type of comparison.


        :param comparator:
            Type: Comparator
            This defines the type of comparison, such as {quote}={quote} or {quote}>{quote}.
        :param left:
            The term on the left side of the expression.
        :param right:
            The term on the right side of the expression.
        N)r  rJ   r  r  r  )r2   r  r  r  rD   r  r0   r3   rJ   $  s   
zBasicCriterion.__init__r.   c                 c  ,    | V  | j  E d H  | j E d H  d S r/   )r  r4   r  r1   r0   r0   r3   r4   =     zBasicCriterion.nodes_r+   c                 C  s   dd | j | jfD }t|S )Nc                 S  r  r0   r  r  r0   r0   r3   r<   D  r  z/BasicCriterion.is_aggregate.<locals>.<listcomp>)r  r  r    )r2   aggrsr0   r0   r3   r,   B  s   zBasicCriterion.is_aggregaterj   rk   rl   r&   c                 C  $   | j ||| _ | j||| _dS r  r  ro   r  rn   r0   r0   r3   ro   G     zBasicCriterion.replace_tabler   r   rL   c                 C  s<   dj | jj| j|| j|d}|jrt|| j|S |S )Nz{left}{comparator}{right}r  r  r  )	r  r  r{   r  r   r  r   r   rD   rG  r0   r0   r3   r   X  s   

zBasicCriterion.get_sqlr/   )
r  r  r  rC   r  rC   rD   rE   r-   rF   r>   r  r   r   r  r0   r0   r  r3   rq   #  s    
rq   c                      sZ   e Zd ZdZdd fddZd ddZd ddZd ddZd ddZe	d!ddZ
  ZS )"JSONAttributeCriteriona~  
    A specialized criterion for accessing JSON column attributes/paths.

    Generates database-specific SQL for accessing nested JSON attributes:
    - PostgreSQL: data->'user'->'details'->>'age' or data->'tags'->>0
    - MySQL and SQLite: data->>'$.user.details.age' or data->>'$.tags[0]'
    - MS SQL: JSON_VALUE(data, '$.user.details.age') or JSON_VALUE(data, '$.tags[0]')
    Njson_columnrC   pathlist[str | int]rD   rE   r-   rF   c                   s   t  | || _|| _dS )z
        Initialize a JSON attribute access criterion.

        :param json_column: The JSON column/field to access
        :param path: The path to the attribute as a list of keys/indices
        :param alias: Optional alias for the expression
        N)r  rJ   r  r  )r2   r  r  rD   r  r0   r3   rJ   m  s   
zJSONAttributeCriterion.__init__r   r   rL   c                 C  s^   |j tjks|j tjkr| |}n|j tjkr| |}n| |}|jr-t	|| j
|S |S )z9Generate database-specific SQL for JSON attribute access.)r   r   r   r  _get_mysql_sqlr   _get_mssql_sql_get_postgres_sqlr   r   rD   rG  r0   r0   r3   r   z  s   
zJSONAttributeCriterion.get_sqlc                 C  sr   | j |}t| jD ]+\}}|t| jd k}|rdnd}t|tr,|| | 7 }q|| d| d7 }q|S )Nr   z->>z->')r  r   	enumerater  r  r8   rf   )r2   r   r,  ipartis_lastoperatorr0   r0   r3   r    s   
z(JSONAttributeCriterion._get_postgres_sqlc                 C  s\   g }| j D ]}|t|trd| dnd|  qdd| }| j| d| dS )NrD  rE  .r   rP   z->>'r  r  r
  r8   rf   rA  r  r   r2   r   
path_partsr  path_strr0   r0   r3   r    s
   
(z%JSONAttributeCriterion._get_mysql_sqlc                 C  s^   g }| j D ]}|t|trd| dnd|  qdd| }d| j| d| dS )	NrD  rE  r  r   rP   zJSON_VALUE(z, 'z')r  r  r0   r0   r3   r    s
   
(z%JSONAttributeCriterion._get_mssql_sqlrj   rk   rl   r&   c                 C  s   | j ||| _ d S r/   )r  ro   rn   r0   r0   r3   ro     s   z$JSONAttributeCriterion.replace_tabler/   )r  rC   r  r  rD   rE   r-   rF   r   r   )r?   r@   rA   r   rJ   r   r  r  r  r   ro   r  r0   r0   r  r3   r  c  s    	



r  c                      s^   e Zd Zdd  fd
dZd!ddZed"ddZed#ddZd$ddZ	ed%ddZ
  ZS )&r   Nr  r
   	containerrC   rD   rE   r-   rF   c                   s"   t  | || _|| _d| _dS )a  
        A wrapper for a "IN" criterion.  This wraps two parts, a term and a container.  The term is the part of the
        expression that is checked for membership in the container.  The container can either be a list or a subquery.


        :param term:
            The term to assert membership for within the container.
        :param container:
            A list or subquery.
        FN)r  rJ   r  r  _is_negated)r2   r  r  rD   r  r0   r3   rJ     s   
zContainsCriterion.__init__r.   c                 c  r  r/   )r  r4   r  r1   r0   r0   r3   r4     r  zContainsCriterion.nodes_r+   c                 C  r  r/   r  r1   r0   r0   r3   r,     r  zContainsCriterion.is_aggregaterj   rk   rl   r&   c                 C     | j ||| _ dS r  r  ro   rn   r0   r0   r3   ro        zContainsCriterion.replace_tabler   r   rL   c                 C  sD   |j dd}dj| j|| j|| jrdndd}t|| j|S )NT)subqueryz{term} {not_}IN {container}zNOT rP   )r  r  not_)r   r  r  r   r  r  r   rD   )r2   r   container_ctxr,  r0   r0   r3   r     s   

zContainsCriterion.get_sqlc                 C  
   d| _ d S r.  )r  r1   r0   r0   r3   ry     rN   zContainsCriterion.negater/   )r  r
   r  rC   rD   rE   r-   rF   r>   r  r   r   r   )r?   r@   rA   rJ   r4   r   r,   r   ro   r   ry   r  r0   r0   r  r3   r     s    

	r   c                      s8   e Zd Zdd fddZdddZedddZ  ZS )RangeCriterionNr  rC   r   r
   r   rD   rE   r-   rF   c                   s"   t  | || _|| _|| _d S r/   )r  rJ   r  r   r   )r2   r  r   r   rD   r  r0   r3   rJ     s   
zRangeCriterion.__init__r.   c                 c  r  r/   )r  r4   r   r   r1   r0   r0   r3   r4     r  zRangeCriterion.nodes_r+   c                 C  r  r/   r  r1   r0   r0   r3   r,     r  zRangeCriterion.is_aggregater/   )
r  rC   r   r
   r   r
   rD   rE   r-   rF   r>   r  )r?   r@   rA   rJ   r4   r   r,   r  r0   r0   r  r3   r    s
    
r  c                   @  s$   e Zd ZedddZdddZdS )r   rj   rk   rl   r-   r&   c                 C  r  r  r  rn   r0   r0   r3   ro     r  zBetweenCriterion.replace_tabler   r   rL   c                 C  6   dj | j|| j|| j|d}t|| j|S )Nz {term} BETWEEN {start} AND {end}r  r   r   r  r  r   r   r   r   rD   rG  r0   r0   r3   r     s   


zBetweenCriterion.get_sqlNr   r   )r?   r@   rA   r   ro   r   r0   r0   r0   r3   r     s    r   c                   @  s   e Zd ZdddZdS )	r   r   r   r-   rL   c                 C  r  )Nz{term} FROM {start} TO {end}r  r  rG  r0   r0   r3   r     s   


zPeriodCriterion.get_sqlNr   )r?   r@   rA   r   r0   r0   r0   r3   r     s    r   c                      sB   e Zd Zdd fd
dZdddZedddZdddZ  ZS )r|   Nr  rC   r{   r
   rD   rE   r-   rF   c                   s   t  | || _|| _d S r/   )r  rJ   r  r{   )r2   r  r{   rD   r  r0   r3   rJ     s   
zBitwiseAndCriterion.__init__r.   c                 c  r  r/   )r  r4   r{   r1   r0   r0   r3   r4   !  r  zBitwiseAndCriterion.nodes_rj   rk   rl   r&   c                 C  r  r  r  rn   r0   r0   r3   ro   &  r  z!BitwiseAndCriterion.replace_tabler   r   rL   c                 C  s&   dj | j|| jd}t|| j|S )Nz({term} & {value}))r  r{   )r  r  r   r{   r   rD   rG  r0   r0   r3   r   6  s
   
zBitwiseAndCriterion.get_sqlr/   )r  rC   r{   r
   rD   rE   r-   rF   r>   r   r   r  r0   r0   r  r3   r|     s    
r|   c                      sB   e Zd Zdd fdd	ZdddZedddZdddZ  ZS )ru   Nr  rC   rD   rE   r-   rF   c                   r1  r/   r  r2   r  rD   r  r0   r3   rJ   ?  r3  zNullCriterion.__init__r.   c                 c      | V  | j  E d H  d S r/   r  r4   r1   r0   r0   r3   r4   C     zNullCriterion.nodes_rj   rk   rl   r&   c                 C  r  r  r  rn   r0   r0   r3   ro   G  r  zNullCriterion.replace_tabler   r   rL   c                 C  "   dj | j|d}t|| j|S )Nz{term} IS NULLr  r  r  r   r   rD   rG  r0   r0   r3   r   W  s   
zNullCriterion.get_sqlr/   )r  rC   rD   rE   r-   rF   r>   r   r   r  r0   r0   r  r3   ru   >  s    
ru   c                   @  s    e Zd ZdddZdd
dZdS )rv  r   r   r-   rL   c                 C  sb   |j | | jd}|j | | jd}dj| jj| j|| j|d}|jr/dj|dS |S )Nsubcriterionz{left} {comparator} {right}r  z({criterion}))	criterion)	r   needs_bracketsr  r  r  r  r{   r   r  )r2   r   left_ctx	right_ctxr,  r0   r0   r3   r   _  s   

zComplexCriterion.get_sqlr  rC   rg   c                 C  s   t |to|j| jk S r/   )r8   rv  r  r  r0   r0   r3   r  m  r   zComplexCriterion.needs_bracketsNr   )r  rC   r-   rg   )r?   r@   rA   r   r  r0   r0   r0   r3   rv  ^  s    
rv  c                      sv   e Zd ZdZejejgZ	d(d) f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/d&d'Z  ZS )0r   z
    Wrapper for an arithmetic function.  Can be simple with two terms or complex with nested terms. Order of operations
    are also preserved.
    Nr  r   r  r
   r  rD   rE   r-   rF   c                   r  )a  
        Wrapper for an arithmetic expression.

        :param operator:
            Type: Arithmetic
            An operator for the expression such as {quote}+{quote} or {quote}/{quote}

        :param left:
            The term on the left side of the expression.
        :param right:
            The term on the right side of the expression.
        :param alias:
            (Optional) an alias for the term which can be used inside a select statement.
        :return:
        N)r  rJ   r  r  r  )r2   r  r  r  rD   r  r0   r3   rJ   y  s   
zArithmeticExpression.__init__r.   c                 c  r  r/   )r  r4   r  r1   r0   r0   r3   r4     r  zArithmeticExpression.nodes_r+   c                 C  s   t | jj| jjgS r/   )r    r  r,   r  r1   r0   r0   r3   r,     s   z!ArithmeticExpression.is_aggregaterj   rk   rl   r&   c                 C  r  )P  
        Replaces all occurrences of the specified table with the new table. Useful when reusing fields across queries.

        :param current_table:
            The table to be replaced.
        :param new_table:
            The table to replace with.
        :return:
            A copy of the term with the tables replaced.
        Nr  rn   r0   r0   r3   ro     r  z"ArithmeticExpression.replace_tablecurr_opleft_opArithmetic | Nonerg   c                 C  s$   |du rdS || j v rdS || j v S )a  
        Returns true if the expression on the left of the current operator needs to be enclosed in parentheses.

        :param current_op:
            The current operator.
        :param left_op:
            The highest level operator of the left expression.
        NF)	add_order)r2   r  r  r0   r0   r3   left_needs_parens  s
   	

z&ArithmeticExpression.left_needs_parensright_opc                 C  s2   |du rdS |t jkrdS |t jkrdS || jv S )a  
        Returns true if the expression on the right of the current operator needs to be enclosed in parentheses.

        :param current_op:
            The current operator.
        :param right_op:
            The highest level operator of the right expression.
        NFT)r   r   r   r  )r2   r  r  r0   r0   r3   right_needs_parens  s   	


z'ArithmeticExpression.right_needs_parensr   r   rL   c                 C  s   dd | j | jfD \}}dj| jj| | j|rdnd| j || | j|r,dnd| j|d}|jrAt	|| j
|S |S )Nc                 S  s   g | ]}t |d dqS )r  N)r  )r9   sider0   r0   r3   r<     r  z0ArithmeticExpression.get_sql.<locals>.<listcomp>z{left}{operator}{right}r  z{})r  r  r  )r  r  r  r  r{   r   r   r  r   r   rD   )r2   r   r  r  arithmetic_sqlr0   r0   r3   r     s   


zArithmeticExpression.get_sqlr/   )
r  r   r  r
   r  r
   rD   rE   r-   rF   r>   r  r   )r  r   r  r  r-   rg   )r  r   r  r  r-   rg   r   )r?   r@   rA   r   r   r   r   r  rJ   r4   r   r,   r   ro   r   r  r   r  r0   r0   r  r3   r   q  s    


r   c                      sl   e Zd Zd d! fddZd"d	d
Zed#ddZed$ddZed%ddZ	ed&ddZ
d'ddZ  ZS )(CaseNrD   rE   r-   rF   c                   s   t  j|d g | _d | _d S r  )r  rJ   _cases_elserI   r  r0   r3   rJ     s   
zCase.__init__r.   c                 c  sV    | V  | j D ]\}}| E d H  | E d H  q| jd ur)| j E d H  d S d S r/   )r  r4   r  r2   r  r  r0   r0   r3   r4     s   
zCase.nodes_r+   c                 C  s.   t dd | jD | jr| jjg S d g S )Nc                 S  s   g | ]
\}}|j p|j qS r0   r  r9   r  r  r0   r0   r3   r<     s    z%Case.is_aggregate.<locals>.<listcomp>)r    r  r  r,   r1   r0   r0   r3   r,     s   zCase.is_aggregater  r
   r  r&   c                 C  s   | j || |f d S r/   )r  r
  ra   r  r0   r0   r3   when  s   z	Case.whenrj   rk   rl   c                   s<    fdd| j D | _ | jr| j | _dS d| _dS )r  c                   s(   g | ]\}}|  |  gqS r0   r  r	  r  r0   r3   r<     s    

z&Case.replace_table.<locals>.<listcomp>N)r  r  ro   rn   r0   r  r3   ro     s   $zCase.replace_tablec                 C  s   |  || _| S r/   )ra   r  r  r0   r0   r3   else_  s   z
Case.else_r   r   rL   c                   sv   | j std|jdd d fdd| j D }| jr&d| j nd}d	j||d
}|jr9t|| j	|S |S )Nz:At least one 'when' case is required for a CASE statement.Fr    c                 3  s.    | ]\}}d j | | dV  qdS )zWHEN {when} THEN {then})r
  thenN)r  r   r	  when_then_else_ctxr0   r3   r  &  s    
zCase.get_sql.<locals>.<genexpr>z ELSE {}rP   zCASE {cases}{else_} END)casesr  )
r  r   r   rA  r  r  r   r   r   rD   )r2   r   r  r  case_sqlr0   r  r3   r   !  s   zCase.get_sqlr/   r   r>   r  )r  r
   r  r
   r-   r&   r   )r  r
   r-   r&   r   )r?   r@   rA   rJ   r4   r   r,   r   r
  ro   r  r   r  r0   r0   r  r3   r    s    

r  c                      sP   e Zd Zdd fdd	ZdddZdddZedddZed ddZ	  Z
S )!rx   Nr  r
   rD   rE   r-   rF   c                      t  j|d || _d S r  r  r  r  r0   r3   rJ   6     
zNot.__init__r.   c                 c  r  r/   r  r1   r0   r0   r3   r4   :  r  z
Not.nodes_r   r   rL   c                 C  s.   |j dd}dj| j|d}t|| j|S )NTr  z
NOT {term}r  )r   r  r  r   r   rD   )r2   r   not_ctxr,  r0   r0   r3   r   >  s   zNot.get_sqlr  c                   s,   t | j| t s S d
 fdd}|S )z
        Delegate method calls to the class wrapped by Not().
        Re-wrap methods on child classes of Term (e.g. isin, eg...) to retain 'NOT <term>' output.
        
inner_selfr
   argsr4  r-   Not | Tc                   s.    | g|R i |}t |tfrt|S |S r/   )r8   rC   rx   )r  r  r4  result	item_funcr0   r3   innerN  s   zNot.__getattr__.<locals>.innerN)r  r
   r  r
   r4  r
   r-   r  )r  r  inspectismethod)r2   r  r  r0   r  r3   __getattr__C  s
   
zNot.__getattr__rj   rk   rl   r&   c                 C  r  r  r  rn   r0   r0   r3   ro   V  r  zNot.replace_tabler/   r  r
   rD   rE   r-   rF   r>   r   )r  rL   r-   r
   r   )r?   r@   rA   rJ   r4   r   r   r  r   ro   r  r0   r0   r  r3   rx   5  s    

rx   c                      s4   e Zd Zdd fdd	ZdddZdddZ  ZS )r   Nr  r
   rD   rE   r-   rF   c                   r  r  r  r  r  r0   r3   rJ   h  r  zAll.__init__r.   c                 c  r  r/   r  r1   r0   r0   r3   r4   l  r  z
All.nodes_r   r   rL   c                 C  r  )Nz
{term} ALLr  r  rG  r0   r0   r3   r   p  rH  zAll.get_sqlr/   r  r>   r   r  r0   r0   r  r3   r   g  s    
r   c                   @  s6   e Zd Zdddd	ZdddZdddZdddZdS )CustomFunctionNr  rL   paramsSequence | Noner-   rF   c                 C  s   || _ || _d S r/   )r  r!  )r2   r  r!  r0   r0   r3   rJ   v  r  zCustomFunction.__init__r  r
   r4  Functionc              	   O  s   |   st| j|ddS | j| s2tdj| jddd tt	| j
D ddd |D dt| jg|R d|diS )	NrD   rH   zCFunction {name} require these arguments ({params}), ({args}) passedz, c                 s      | ]}t |V  qd S r/   rL   r9   pr0   r0   r3   r        z*CustomFunction.__call__.<locals>.<genexpr>c                 s  r$  r/   r%  r&  r0   r0   r3   r    r(  )r  r!  r  )_has_paramsr#  r  r   _is_valid_function_callr   r  rA  r   r   r!  )r2   r  r4  r0   r0   r3   __call__z  s   
zCustomFunction.__call__rg   c                 C  s
   | j d uS r/   )r!  r1   r0   r0   r3   r)    rK   zCustomFunction._has_paramsc                 G  s   t |t tt| jkS r/   )r  r   r   r!  )r2   r  r0   r0   r3   r*    r   z&CustomFunction._is_valid_function_callr/   )r  rL   r!  r"  r-   rF   )r  r
   r4  r
   r-   r#  )r-   rg   )r  r
   r-   rg   )r?   r@   rA   rJ   r+  r)  r*  r0   r0   r0   r3   r   u  s
    

r   c                      sp   e Zd Zd! fdd	Zd"ddZed#ddZed$ddZd%ddZ	e
d&ddZd'ddZd'dd Z  ZS )(r#  r  rL   r  r
   r4  r-   rF   c                   s<   t  |d | _ fdd|D  _|d _d S )NrD   c                   r  r0   r  r9   r-  r1   r0   r3   r<     r  z%Function.__init__.<locals>.<listcomp>schema)r  rJ   r   r  r  r-  r2   r  r  r4  r  r1   r3   rJ     s   zFunction.__init__r.   c                 c  r  r/   )r  r4   r   r0   r0   r3   r4     r  zFunction.nodes_r+   c                 C  r  )aa  
        This is a shortcut that assumes if a function has a single argument and that argument is aggregated, then this
        function is also aggregated. A more sophisticated approach is needed, however it is unclear how that might work.
        :returns:
            True if the function accepts one argument and that argument is aggregate.
        c                 S  r  r0   r  r9   r   r0   r0   r3   r<     r  z)Function.is_aggregate.<locals>.<listcomp>)r    r  r1   r0   r0   r3   r,     s   zFunction.is_aggregaterj   rk   rl   r&   c                   r  )r  c                   r  r0   r  r,  r  r0   r3   r<     r  z*Function.replace_table.<locals>.<listcomp>Nr  rn   r0   r  r3   ro     r  zFunction.replace_tabler   r   c                 C  s   d S r/   r0   r   r0   r0   r3   get_special_params_sql  r   zFunction.get_special_params_sqlr   c                 C  s(   |j dd}t| dr| |S t| S )NFr   r   )r   hasattrr   rL   )r   r   arg_ctxr0   r0   r3   get_arg_sql  s   zFunction.get_arg_sqlc                   sD     }djjd fddjD |rd| dS ddS )Nz{name}({args}{special})r>  c                 3  s    | ]	} | V  qd S r/   )r4  r/  r   r2   r0   r3   r    s    z,Function.get_function_sql.<locals>.<genexpr>r  rP   )r  r  special)r1  r  r  rA  r  )r2   r   special_params_sqlr0   r5  r3   get_function_sql  s   

zFunction.get_function_sqlc                 C  sB   |  |}| jd urdj| j||d}|jrt|| j|S |S )Nz{schema}.{function})r-  function)r8  r-  r  r   r   r   rD   )r2   r   function_sqlr0   r0   r3   r     s   


zFunction.get_sqlr  rL   r  r
   r4  r
   r-   rF   r>   r  r   )r   r   r-   r
   )r   r
   r   r   r-   rL   r   )r?   r@   rA   rJ   r4   r   r,   r   ro   r1  r   r4  r8  r   r  r0   r0   r  r3   r#    s    
	


r#  c                      sH   e Zd ZdZd fddZedd	d
ZdddZd fddZ  Z	S )AggregateFunctionTr-   rF   c                   s*   t  j|g|R i | g | _d| _d S NF)r  rJ   _filters_include_filterr.  r  r0   r3   rJ     s   
zAggregateFunction.__init__filtersr
   AnalyticFunctionc                 G     d| _ |  j|7  _d S r.  )r?  r>  )r2   r@  r0   r0   r3   filter     zAggregateFunction.filterr   r   rL   c                 C  s&   | j rt| j|}d| S d S )NzWHERE )r?  ru  r  r>  r   )r2   r   
criterionsr0   r0   r3   get_filter_sql  s   
z AggregateFunction.get_filter_sqlc                   s0   t  |}| |}| jr|dj|d7 }|S )Nz FILTER({filter_sql}))
filter_sql)r  r8  rF  r?  r  )r2   r   r,  rG  r  r0   r3   r8    s
   
z"AggregateFunction.get_function_sql)r-   rF   )r@  r
   r-   rA  r   )
r?   r@   rA   r,   rJ   r   rC  rF  r8  r  r0   r0   r  r3   r<    s    
r<  c                      sd   e Zd ZdZdZd fd
dZedddZed ddZd!ddZ	d"ddZ
d" fddZ  ZS )#rA  FTr  rL   r  r
   r4  r-   rF   c                   s<   t  j|g|R i | g | _g | _g | _d| _d| _d S r=  )r  rJ   r>  
_partition	_orderbysr?  _include_overr.  r  r0   r3   rJ     s   
zAnalyticFunction.__init__r~  r&   c                 G  rB  r.  )rJ  rH  r2   r~  r0   r0   r3   over  rD  zAnalyticFunction.overc                   s&   d| _ |  j fdd|D 7  _d S )NTc                   s   g | ]	}|  d fqS )order)r   r  r4  r0   r3   r<   
  s    z,AnalyticFunction.orderby.<locals>.<listcomp>)rJ  rI  )r2   r~  r4  r0   rN  r3   orderby  s    zAnalyticFunction.orderbyre  rT   orientOrder | Noner   r   c                 C  s(   |d u r	| |S dj| ||jdS )Nz{field} {orient})re  rP  )r   r  r{   )r2   re  rP  r   r0   r0   r3   _orderby_field  s   
zAnalyticFunction._orderby_fieldc                   sl   g }j r|djd fddj D d jr1|djd fddjD d d	|S )
NzPARTITION BY {args}r>  c                 3  s,    | ]}t |d r| nt|V  qdS )r   N)r2  r   rL   r&  r  r0   r3   r    s    
z5AnalyticFunction.get_partition_sql.<locals>.<genexpr>r0  zORDER BY {orderby}c                 3  s"    | ]\}} || V  qd S r/   )rR  )r9   re  rP  r5  r0   r3   r  #  s    
)rO  r  )rH  r
  r  rA  rI  )r2   r   r~  r0   r5  r3   get_partition_sql  s$   
z"AnalyticFunction.get_partition_sqlc                   s4   t  |}| |}|}| jr|dj|d7 }|S )Nz OVER({partition_sql}))partition_sql)r  r8  rS  rJ  r  )r2   r   r:  rT  r,  r  r0   r3   r8  +  s   
z!AnalyticFunction.get_function_sqlr;  )r~  r
   r-   r&   )r~  r
   r4  r
   r-   r&   )re  rT   rP  rQ  r   r   r-   rL   r   )r?   r@   rA   r,   is_analyticrJ   r   rL  rO  rR  rS  r8  r  r0   r0   r  r3   rA    s    

	rA  EdgeT WindowFrameAnalyticFunction.Edgec                      sr   e Zd ZG dd dZd fd
dZd ddZe	d!d"ddZe	d!d"ddZd#ddZ	d$ fddZ
  ZS )%WindowFrameAnalyticFunctionc                   @  s"   e Zd ZddddZdd	d
ZdS )rW  Nr{   str | int | Noner-   rF   c                 C  rG   r/   rg  r}   r0   r0   r3   rJ   ;  rK   z)WindowFrameAnalyticFunction.Edge.__init__rL   c                 C  s   dj | jpd| jdS )Nz{value} {modifier}	UNBOUNDED)r{   modifier)r  r{   r[  r1   r0   r0   r3   r   >  s   z(WindowFrameAnalyticFunction.Edge.__str__r/   )r{   rY  r-   rF   r   )r?   r@   rA   rJ   r   r0   r0   r0   r3   Edge:  s    r\  r  rL   r  r
   r4  r-   rF   c                   s*   t  j|g|R i | d | _d | _d S r/   )r  rJ   framer*   r.  r  r0   r3   rJ   E  s   
z$WindowFrameAnalyticFunction.__init__r]  r*   str | EdgeT	and_boundEdgeT | Nonec                 C  s4   | j s| jr	t || _ |r||f| _d S || _d S r/   )r]  r*   AttributeError)r2   r]  r*   r_  r0   r0   r3   _set_frame_and_boundsJ  s   z1WindowFrameAnalyticFunction._set_frame_and_boundsNr&   c                 C     |  d|| d S )NROWSrb  r2   r*   r_  r0   r0   r3   rowsS     z WindowFrameAnalyticFunction.rowsc                 C  rc  )NRANGEre  rf  r0   r0   r3   rangeY  rh  z!WindowFrameAnalyticFunction.rangec                 C  s:   t | jtsdj| j| jdS | j\}}dj| j||dS )Nz{frame} {bound})r]  r*   z#{frame} BETWEEN {lower} AND {upper})r]  r   r   )r8   r*   r^   r  r]  r   r0   r0   r3   get_frame_sql_  s   
z)WindowFrameAnalyticFunction.get_frame_sqlr   r   c                   s.   t  |}| js| js|S dj||  dS )Nz{over} {frame})rL  r]  )r  rS  r]  r*   r  rk  )r2   r   rT  r  r0   r3   rS  j  s   z-WindowFrameAnalyticFunction.get_partition_sqlr;  )r]  rL   r*   r^  r_  r`  r-   rF   r/   )r*   r^  r_  r`  r-   r&   r   r   )r?   r@   rA   r\  rJ   rb  r   rg  rj  rk  rS  r  r0   r0   r  r3   rX  9  s    
	
rX  c                      s6   e Zd Zd fdd	ZedddZdddZ  ZS )IgnoreNullsAnalyticFunctionr  rL   r  r
   r4  r-   rF   c                   s$   t  j|g|R i | d| _d S r=  )r  rJ   _ignore_nullsr.  r  r0   r3   rJ   t  s   
z$IgnoreNullsAnalyticFunction.__init__r&   c                 C  r  r.  rm  r1   r0   r0   r3   ignore_nullsx  rN   z(IgnoreNullsAnalyticFunction.ignore_nullsr   r   rE   c                 C  s   | j rdS d S )NzIGNORE NULLSrn  r   r0   r0   r3   r1  |  s   z2IgnoreNullsAnalyticFunction.get_special_params_sqlr;  r   )r   r   r-   rE   )r?   r@   rA   rJ   r   ro  r1  r  r0   r0   r  r3   rl  s  r  rl  c                
   @  s|   e Zd ZejdejdejdejdejdiZ	g dZ
g dZedZ										dd ddZd!ddZd"ddZdS )#IntervalINTERVAL '{expr} {unit}'zINTERVAL '{expr}' {unit}yearsmonthsdayshoursminutessecondsmicroseconds)YEARMONTHDAYHOURMINUTESECONDMICROSECONDz6(^0+\.)|(\.0+$)|(^[0\-.: ]+[\-: ])|([\-:. ][0\-.: ]+$)r   Nrs  rf   rt  ru  rv  rw  rx  ry  quartersweeksr   Dialects | Noner-   rF   c              
   C  s   |
| _ d | _d | _d| _|r|| _d S |	r|	| _d S t| j| j|||||||gD ]#\}}}|rLt	|}t
| |t| | jd u rI|| _|dk | _|| _q)d S )NFr   )r   largestsmallestis_negativer  r  zipunitslabelsrf   setattrabs)r2   rs  rt  ru  rv  rw  rx  ry  r  r  r   unitlabelr{   	int_valuer0   r0   r3   rJ     s0   

zInterval.__init__rL   c                 C  r   r/   r   r1   r0   r0   r3   r     rK   zInterval.__str__r   r   c                 C  s
  | j dkrt| d}d}nkt| drt| d}d}n^t| dr't| d}d}nQdjt| dd	t| d
d	t| dd	t| dd	t| dd	t| dd	t| dd	d}| jd|}| jr]d| }| j | jkrm| j  d| j }n| j d u rud}n| j }| j	|j
dj||dS )Nr  ry  r  QUARTERr  WEEKzB{years}-{months}-{days} {hours}:{minutes}:{seconds}.{microseconds}rs  r   rt  ru  rv  rw  rx  rr  rP   -r   r|  rq  )r   r  )r  r  r2  r  trim_patternr   r  r  	templatesr   r   )r2   r   r   r  r0   r0   r3   r     s:   












	
zInterval.get_sql)
r   r   r   r   r   r   r   r   r   N)rs  rf   rt  rf   ru  rf   rv  rf   rw  rf   rx  rf   ry  rf   r  rf   r  rf   r   r  r-   rF   r   r   )r?   r@   rA   r   r  r  VERTICAr   r   r  r  r  recompiler  rJ   r   r   r0   r0   r0   r3   rp    s.    


'rp  c                          e Zd Zdd fd
dZ  ZS )r   Nr  rC   exponentfloatrD   rE   r-   rF   c                      t  jd|||d d S )NPOWrH   rp  )r2   r  r  rD   r  r0   r3   rJ     r   zPow.__init__r/   )r  rC   r  r  rD   rE   r-   rF   rq  r0   r0   r  r3   r     rr  r   c                      r  )r   Nr  rC   modulusr  rD   rE   r-   rF   c                   r  )NMODrH   rp  )r2   r  r  rD   r  r0   r3   rJ     r   zMod.__init__r/   )r  rC   r  r  rD   rE   r-   rF   rq  r0   r0   r  r3   r     rr  r   c                      r  )Rollupr~  r
   r-   rF   c                   s   t  jdg|R   d S )NROLLUPrp  rK  r  r0   r3   rJ     r   zRollup.__init__)r~  r
   r-   rF   rq  r0   r0   r  r3   r    r  r  c                      s,   e Zd ZdZd fddZdd
dZ  ZS )PseudoColumnz
    Represents a pseudo column (a "column" which yields a value when selected
    but is not actually a real table column).
    r  rL   r-   rF   c                   s   t  jd d || _d S r  r  )r2   r  r  r0   r3   rJ     r  zPseudoColumn.__init__r   r   c                 C  s   | j S r/   )r  r   r0   r0   r3   r      r   zPseudoColumn.get_sql)r  rL   r-   rF   r   )r?   r@   rA   r   rJ   r   r  r0   r0   r  r3   r    s    r  c                      s>   e Zd ZU dZdZded< 	dd fddZdddZ  ZS )
AtTimezonez|
    Generates AT TIME ZONE SQL.
    Examples:
        AT TIME ZONE 'US/Eastern'
        AT TIME ZONE INTERVAL '-06:00'
    Nr+   r,   Fre  rf  zonerL   intervalrg   rD   rE   r-   rF   c                   s4   t  | t|tst|n|| _|| _|| _d S r/   )r  rJ   r8   rT   re  r  r  )r2   re  r  r  rD   r  r0   r3   rJ     s   
zAtTimezone.__init__r   r   c                 C  s2   dj | j|| jrdnd| jd}t|| j|S )Nz&{name} AT TIME ZONE {interval}'{zone}'z	INTERVAL rP   )r  r  r  )r  re  r   r  r  r   rD   rG  r0   r0   r3   r     s   
zAtTimezone.get_sql)FN)
re  rf  r  rL   r  rg   rD   rE   r-   rF   r   )	r?   r@   rA   r   r,   rB   rJ   r   r  r0   r0   r  r3   r    s   
 r  )c
__future__r   r  r'  r  sysr$  collections.abcr   r   r   datetimer   r   enumr   typingr	   r
   r   r   r   contextr   r   enumsr   r   r   r   r   r   r   r   r   
exceptionsr   r   utilsr   r   r   r   r    re   r!   r"   r#   version_infor&   typing_extensionsr'   r(   r)   rC   r   r  r   r`   rh   rd  rj  r[   rs  ru  r  rT   r  r  r_   r]   r  r  rq   r  r   r  r   r   r|   ru   rv  r   r  rx   r   r   r#  r<  rA  rV  rX  rl  rp  r   r   r  r  r  r0   r0   r0   r3   <module>   s    ,
 f$%B^		 2	#>@I8
# xL2H@:c