o
    ٭hr-                    @  s0  d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZ ddlmZmZ dd	lmZmZmZ dd
lmZmZ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"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+m,Z,m-Z- e	rej.dkrd dlm/Z/ nd dl0m/Z/ G dd de Z1G dd de1Z2G dd de2Z3G dd dZ4G dd de4Z5G dd de1Z6d<d!d"Z7G d#d$ d$Z8d=d&d'Z9G d(d) d)Z:e6Z;G d*d+ d+Z<G d,d- d-e1e&Z=G d.d/ d/e1e&Z>G d0d1 d1Z?G d2d3 d3Z@G d4d5 d5e@ZAG d6d7 d7e@ZBG d8d9 d9ZCG d:d; d;ZDdS )>    )annotationsN)Sequence)copy)reduce)TYPE_CHECKINGAnycastoverload   )DEFAULT_SQL_CONTEXT
SqlContext)DialectsJoinTypeSetOperation)JoinExceptionQueryExceptionRollupExceptionSetOperationException)ArithmeticExpression	CriterionEmptyCriterionFieldFunctionIndexNodeOrderParameterizerPeriodCriterionRollupStarTermTupleValueWrapper)builderformat_alias_sqlformat_quotesignore_copy)      )Selfc                   @  sl   e Zd ZdddZeddd	ZdddZedddZe	dddZ
e	dddZd ddZd!ddZdS )"
SelectablealiasstrreturnNonec                 C  
   || _ d S Nr+   selfr+    r4   \/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/pypika_tortoise/queries.py__init__'      
zSelectable.__init__r)   c                 C  r/   r0   r1   r2   r4   r4   r5   as_*      
zSelectable.as_namer   c                 C     t || dS Ntabler   r3   r:   r4   r4   r5   field.      zSelectable.fieldr   c                 C  s   t | S r0   )r   r3   r4   r4   r5   star1   s   zSelectable.starc                 C  
   |  |S r0   rA   r@   r4   r4   r5   __getattr__5   r9   zSelectable.__getattr__c                 C  rE   r0   rF   r@   r4   r4   r5   __getitem__9   r9   zSelectable.__getitem__c                 C  s   | j S r0   r1   rC   r4   r4   r5   get_table_name=      zSelectable.get_table_namectxr   c                 C  s   t  r0   )NotImplementedErrorr3   rK   r4   r4   r5   get_sql@   rJ   zSelectable.get_sqlN)r+   r,   r-   r.   )r+   r,   r-   r)   )r:   r,   r-   r   )r-   r   r-   r,   rK   r   r-   r,   )__name__
__module____qualname__r6   r#   r8   rA   propertyrD   r&   rG   rH   rI   rN   r4   r4   r4   r5   r*   &   s    


r*   c                      s@   e Zd Z	dd fdd	ZdddZdddZdddZ  ZS )AliasedQueryNr:   r,   querySelectable | Noner-   r.   c                   s   t  j|d || _|| _d S )Nr1   )superr6   r:   rV   )r3   r:   rV   	__class__r4   r5   r6   E   s   
zAliasedQuery.__init__rK   r   c                 C  s   | j d u r| jS | j |S r0   )rV   r:   rN   rM   r4   r4   r5   rN   N   s   
zAliasedQuery.get_sqlotherr   boolc                 C     t |to
| j|jkS r0   )
isinstancerU   r:   r3   r[   r4   r4   r5   __eq__S      zAliasedQuery.__eq__intc                 C  s   t t| jS r0   )hashr,   r:   rC   r4   r4   r5   __hash__V      zAliasedQuery.__hash__r0   )r:   r,   rV   rW   r-   r.   rP   r[   r   r-   r\   r-   rb   )rQ   rR   rS   r6   rN   r`   rd   __classcell__r4   r4   rY   r5   rU   D   s    
	
rU   c                      s    e Zd Zdd fd
dZ  ZS )CteNr:   r,   rV   QueryBuilder | Nonetermsr    r-   r.   c                   s   t  || || _|| _d S r0   )rX   r6   rV   rk   )r3   r:   rV   rk   rY   r4   r5   r6   [   s   
zCte.__init__r0   )r:   r,   rV   rj   rk   r    r-   r.   )rQ   rR   rS   r6   rh   r4   r4   rY   r5   ri   Z   s    ri   c                   @  sD   e Zd Zdddd	ZdddZdddZedddZdddZdS )SchemaNr:   r,   parentSchema | Noner-   r.   c                 C     || _ || _d S r0   )_name_parent)r3   r:   rm   r4   r4   r5   r6   b      
zSchema.__init__r[   r   r\   c                 C  s"   t |to| j|jko| j|jkS r0   )r^   rl   rp   rq   r_   r4   r4   r5   r`   f   s
   


zSchema.__eq__c                 C     |  | S r0   r`   r_   r4   r4   r5   __ne__m   rB   zSchema.__ne__itemTablec                 C  r;   )Nschemarw   r3   rv   r4   r4   r5   rG   p      zSchema.__getattr__rK   r   c                 C  s2   t | j|j}| jd urdj| j||dS |S )Nz{parent}.{schema})rm   ry   )r%   rp   
quote_charrq   formatrN   )r3   rK   
schema_sqlr4   r4   r5   rN   t   s   

zSchema.get_sqlr0   )r:   r,   rm   rn   r-   r.   rf   )rv   r,   r-   rw   rP   )	rQ   rR   rS   r6   r`   ru   r&   rG   rN   r4   r4   r4   r5   rl   a   s    

rl   c                   @  s   e Zd ZedddZdS )	Databaserv   r,   r-   rl   c                 C  r;   N)rm   rl   r{   r4   r4   r5   rG      r|   zDatabase.__getattr__N)rv   r,   r-   rl   )rQ   rR   rS   r&   rG   r4   r4   r4   r5   r      s    r   c                      s   e Zd Zeed=ddZeed>ddZed?ddZ			d@dA fddZdBddZdCddZe	dDdd Z
e	dEd#d$ZdBd%d&ZdFd*d+ZdBd,d-ZdFd.d/ZdGd1d2ZdHd6d7ZdId8d9ZdJd;d<Z  ZS )Krw   ry   r.   r-   c                 C     d S r0   r4   rx   r4   r4   r5   _init_schema      zTable._init_schemastr | list | tuple | Schemarl   c                 C  r   r0   r4   rx   r4   r4   r5   r      r   "str | list | tuple | Schema | Nonern   c                 C  sP   t | tr| S t | ttfrtdd | dd  t| d S | d ur&t| S d S )Nc                 S  r;   r   r   )objsr4   r4   r5   <lambda>   s    z$Table._init_schema.<locals>.<lambda>r
   r   )r^   rl   listtupler   rx   r4   r4   r5   r      s   
 Nr:   r,   Schema | str | Noner+   
str | None	query_clstype[Query] | Nonec                   sT   t  | || _| || _|d u rt}n	t|tstd|| _d | _	d | _
d S )Nz,Expected 'query_cls' to be subclass of Query)rX   r6   _table_namer   _schemaQuery
issubclass	TypeError
_query_cls_for_for_portion)r3   r:   ry   r+   r   rY   r4   r5   r6      s   

zTable.__init__c                 C  s   | j p| jS r0   )r+   r   rC   r4   r4   r5   rI      rB   zTable.get_table_namerK   r   c                 C  sv   t | j|j}| jd urdj| j||d}| jr&dj|| j|d}n| jr4dj|| j|d}t|| j	|S )Nz{schema}.{table})ry   r>   z{table} FOR {criterion})r>   	criterionz"{table} FOR PORTION OF {criterion})
r%   r   r}   r   r~   rN   r   r   r$   r+   )r3   rK   	table_sqlr4   r4   r5   rN      s   
zTable.get_sqltemporal_criterionr   r)   c                 C  &   | j rtd| jrtd|| _ d S )N)'Query' object already has attribute for_0'Query' object already has attribute for_portion)r   AttributeErrorr   )r3   r   r4   r4   r5   for_   
   
z
Table.for_period_criterionr   c                 C  r   )Nr   r   )r   r   r   )r3   r   r4   r4   r5   for_portion   r   zTable.for_portionc                 C  
   |  tS r0   rN   r   rC   r4   r4   r5   __str__   r7   zTable.__str__r[   r   r\   c                 C  s.   t |to| j|jko| j|jko| j|jkS r0   )r^   rw   r   r   r+   r_   r4   r4   r5   r`      s   



zTable.__eq__c                 C  s"   | j rd| j| j S d| jS )NzTable('{}', schema='{}')zTable('{}'))r   r~   r   rC   r4   r4   r5   __repr__   s   zTable.__repr__c                 C  rs   r0   rt   r_   r4   r4   r5   ru      rB   zTable.__ne__rb   c                 C  s   t t| S r0   )rc   r,   rC   r4   r4   r5   rd      rB   zTable.__hash__rk   1Sequence[int | float | str | bool | Term | Field]QueryBuilderc                 G     | j | j| S )a  
        Perform a SELECT operation on the current table

        :param terms:
            Type:  list[expression]

            A list of terms to select. These can be any type of int, float, str, bool or Term or a Field.

        :return:  QueryBuilder
        )r   from_selectr3   rk   r4   r4   r5   r         zTable.selectc                 C  s   | j | S )za
        Perform an UPDATE operation on the current table

        :return: QueryBuilder
        )r   updaterC   r4   r4   r5   r      s   zTable.update'int | float | str | bool | Term | Fieldc                 G  r   )a  
        Perform an INSERT operation on the current table

        :param terms:
            Type: list[expression]

            A list of terms to select. These can be any type of int, float, str, bool or  any other valid data

        :return: QueryBuilder
        )r   intoinsertr   r4   r4   r5   r     r   zTable.insert)ry   r.   r-   r.   )ry   r   r-   rl   )ry   r   r-   rn   NNN)
r:   r,   ry   r   r+   r   r   r   r-   r.   rO   rP   )r   r   r-   r)   )r   r   r-   r)   rf   rg   )rk   r   r-   r   r-   r   )rk   r   r-   r   )rQ   rR   rS   r	   staticmethodr   r6   rI   rN   r#   r   r   r   r`   r   ru   rd   r   r   r   rh   r4   r4   rY   r5   rw      s6    








rw   namestuple[str, str] | strkwargsr   r-   list[Table]c                  O  sZ   g }| D ]&}d}t |trt|dkr|\}}t|||d|dd}|| q|S )z
    Shortcut to create many tables. If `names` param is a tuple, the first
    position will refer to the `_table_name` while the second will be its `alias`.
    Any other data structure will be treated as a whole as the `_table_name`.
    N   ry   r   )r:   r+   ry   r   )r^   r   lenrw   getappend)r   r   tablesr:   r+   tr4   r4   r5   make_tables  s   r   c                   @  s@   e Zd ZdZ			ddddZdddZdddZdddZdS )ColumnzRepresents a column.Ncolumn_namer,   column_typer   nullablebool | NonedefaultAny | Term | Noner-   r.   c                 C  s<   || _ || _|| _|d u st|tr|| _d S t|| _d S r0   )r:   typer   r^   r    r"   r   )r3   r   r   r   r   r4   r4   r5   r6   *  s   zColumn.__init__rK   r   c                 C  s   dj t| j|jd}|S )Nz{name})r:   )r~   r%   r:   r}   r3   rK   
column_sqlr4   r4   r5   get_name_sql8  s   zColumn.get_name_sqlc              
   C  sh   dj | || jrd | jnd| jd urd | jrdndnd| jr.d d| j| ndd}|S )Nz{name}{type}{nullable}{default}z {} NULLzNOT NULLzDEFAULT )r:   r   r   r   )r~   r   r   r   r   rN   r   r4   r4   r5   rN   ?  s   zColumn.get_sqlc                 C  r   r0   r   rC   r4   r4   r5   r   M  r7   zColumn.__str__r   )
r   r,   r   r   r   r   r   r   r-   r.   rP   rO   )rQ   rR   rS   __doc__r6   r   rN   r   r4   r4   r4   r5   r   '  s    

r   list[Column]c                  G  sR   g }| D ]"}t |trt|dkrt|d |d d}nt|d}|| q|S )z
    Shortcut to create many columns. If `names` param is a tuple, the first
    position will refer to the `name` while the second will be its `type`.
    Any other data structure will be treated as a whole as the `name`.
    r   r   r
   r   r   )r   )r^   r   r   r   r   )r   columnsr:   columnr4   r4   r5   make_columnsQ  s   
r   c                   @  s    e Zd Zddd	ZdddZdS )	PeriodForr:   r,   start_columnstr | Column
end_columnr-   r.   c                 C  s@   || _ t|tr
|nt|| _t|tr|| _d S t|| _d S r0   )r:   r^   r   r   r   r3   r:   r   r   r4   r4   r5   r6   c  s   "zPeriodFor.__init__rK   r   c                 C  s.   dj t| j|j| j|| j|d}|S )Nz9PERIOD FOR {name} ({start_column_name},{end_column_name}))r:   start_column_nameend_column_name)r~   r%   r:   r}   r   r   r   )r3   rK   period_for_sqlr4   r4   r5   rN   o  s   

zPeriodFor.get_sqlN)r:   r,   r   r   r   r   r-   r.   rP   )rQ   rR   rS   r6   rN   r4   r4   r4   r5   r   b  s    
r   c                   @  s   e Zd ZU dZeZded< ed.dd	Zed/ddZ	ed0ddZ
ed1ddZed2ddZed3ddZed4d d!Zed5d"d#Zed6d&d'Zed7d+d,Zd-S )8r   z
    Query is the primary class and entry point in pypika. It is used to build queries iteratively using the builder
    design
    pattern.

    This class is immutable.
    r   SQL_CONTEXTr   r   r-   r   c                 K  s   t di |S Nr4   )r   )clsr   r4   r4   r5   _builder  s   zQuery._builderr>   Selectable | strc                 K     | j di ||S )aH  
        Query builder entry point.  Initializes query building and sets the table to select from.  When using this
        function, the query becomes a SELECT query.

        :param table:
            Type: Table or str

            An instance of a Table object or a string table name.

        :returns QueryBuilder
        Nr4   )r   r   r   r>   r   r4   r4   r5   r        zQuery.from_str | TableCreateQueryBuilderc                 C     t  |S )a(  
        Query builder entry point. Initializes query building and sets the table name to be created. When using this
        function, the query becomes a CREATE statement.

        :param table: An instance of a Table object or a string table name.

        :return: CreateQueryBuilder
        )r   create_tabler   r>   r4   r4   r5   r        
zQuery.create_tableDropQueryBuilderc                 C  r   )a$  
        Query builder entry point. Initializes query building and sets the table name to be dropped. When using this
        function, the query becomes a DROP statement.

        :param table: An instance of a Table object or a string table name.

        :return: DropQueryBuilder
        )r   
drop_tabler   r4   r4   r5   r     r   zQuery.drop_tableTable | strc                 K  r   )aI  
        Query builder entry point.  Initializes query building and sets the table to insert into.  When using this
        function, the query becomes an INSERT query.

        :param table:
            Type: Table or str

            An instance of a Table object or a string table name.

        :returns QueryBuilder
        Nr4   )r   r   r   r4   r4   r5   r     r   z
Query.intostr | Selectabler:   r,   rk   r    c                 O  s    | j di |j||g|R  S r   )r   with_)r   r>   r:   rk   r   r4   r4   r5   r     s    zQuery.with_int | float | str | bool | Termc                 O  s   | j di |j| S )a  
        Query builder entry point.  Initializes query building without a table and selects fields.  Useful when testing
        SQL functions.

        :param terms:
            Type: list[expression]

            A list of terms to select.  These can be any type of int, float, str, bool, or Term.  They cannot be a Field
            unless the function ``Query.from_`` is called first.

        :returns QueryBuilder
        Nr4   )r   r   )r   rk   r   r4   r4   r5   r     s   zQuery.selectc                 K  r   )aD  
        Query builder entry point.  Initializes query building and sets the table to update.  When using this
        function, the query becomes an UPDATE query.

        :param table:
            Type: Table or str

            An instance of a Table object or a string table name.

        :returns QueryBuilder
        Nr4   )r   r   r   r4   r4   r5   r     r   zQuery.update
table_name_TableClassc                 K  s   | |d< t |fi |S )z
        Convenience method for creating a Table that uses this Query class.

        :param table_name:
            Type: str

            A string table name.

        :returns Table
        r   rz   )r   r   r   r4   r4   r5   rw     s   zQuery.Tabler   r   list[_TableClass]c                 O  s   | |d< t |i |S )a!  
        Convenience method for creating many tables that uses this Query class.
        See ``Query.make_tables`` for details.

        :param names:
            Type: list[str or tuple]

            A list of string table names, or name and alias tuples.

        :returns Table
        r   )r   )r   r   r   r4   r4   r5   Tables  s   zQuery.TablesN)r   r   r-   r   )r>   r   r   r   r-   r   )r>   r   r-   r   )r>   r   r-   r   )r>   r   r   r   r-   r   )
r>   r   r:   r,   rk   r    r   r   r-   r   )rk   r   r   r   r-   r   )r>   r   r-   r   )r   r,   r-   r   )r   r   r   r   r-   r   )rQ   rR   rS   r   r   r   __annotations__classmethodr   r   r   r   r   r   r   r   rw   r   r4   r4   r4   r5   r   }  s.   
 r   c                      s   e Zd ZdZdefd= fddZed>ddZed?ddZed@ddZ	edAd d!Z
edAd"d#ZedAd$d%ZedAd&d'ZedAd(d)ZdAd*d+ZdAd,d-ZdBd.d/ZdCd1d2ZdDd5d6ZdDd7d8ZdDd9d:ZdDd;d<Z  ZS )E_SetOperationa  
    A Query class wrapper for a all set operations, Union DISTINCT or ALL, Intersect, Except or Minus

    Created via the functions `Query.union`,`Query.union_all`,`Query.intersect`, `Query.except_of`,`Query.minus`.

    This class should not be instantiated directly.
    N
base_queryr   set_operation_queryset_operationr   r+   r   wrapper_clstype[ValueWrapper]r-   r.   c                   s:   t  | || _||fg| _g | _d | _d | _|| _d S r0   )rX   r6   r   _set_operation	_orderbys_limit_offset_wrapper_cls)r3   r   r   r   r+   r   rY   r4   r5   r6     s   
z_SetOperation.__init__fieldsr   r   r   r)   c                 O  sN   |D ]"}t |trt|| jjd dn| j|}| j||df qd S Nr   r=   order)	r^   r,   r   r   _fromwrap_constantr   r   r   r3   r  r   rA   r4   r4   r5   orderby   s   
z_SetOperation.orderbylimitrb   c                 C     t t| || _d S r0   r   r"   r  r   r3   r  r4   r4   r5   r  +     z_SetOperation.limitoffsetc                 C  r	  r0   r   r"   r  r   r3   r  r4   r4   r5   r  /  r  z_SetOperation.offsetr[   r*   c                 C     | j tj|f d S r0   )r   r   r   unionr_   r4   r4   r5   r  3  r  z_SetOperation.unionc                 C  r  r0   )r   r   r   	union_allr_   r4   r4   r5   r  7  r  z_SetOperation.union_allc                 C  r  r0   )r   r   r   	intersectr_   r4   r4   r5   r  ;  r  z_SetOperation.intersectc                 C  r  r0   )r   r   r   	except_ofr_   r4   r4   r5   r  ?  r  z_SetOperation.except_ofc                 C  r  r0   )r   r   r   minusr_   r4   r4   r5   r  C  r  z_SetOperation.minusc                 C  rE   r0   r  r_   r4   r4   r5   __add__G  r7   z_SetOperation.__add__c                 C  rE   r0   r  r_   r4   r4   r5   __mul__J  r7   z_SetOperation.__mul__c                 C  rE   r0   r  r_   r4   r4   r5   __sub__M  r7   z_SetOperation.__sub__r,   c                 C  r   r0   r   rC   r4   r4   r5   r   P  r7   z_SetOperation.__str__rK   r   c           	      C  s   d}|j | jj| jjjj|jd}|j | jjd}| j|}|}| j	D ]'\}}||}t
| jjt
|jkrAtdj||d||j|j|d7 }q$| jrV|| |7 }|| |7 }|| |7 }|jrmdj|d}|jrzt|| jpw| j|S |S )	Nz {type} {query_string})dialectr}   parameterizersubqueryzQueries must have an equal number of select statements in a set operation.

Main Query:
{query1}

Set Operations Query:
{query2})query1query2)r   query_string	({query})rV   )r   r   r  	QUERY_CLSr   r}   r  wrap_set_operation_queriesrN   r   r   _selectsr   r~   valuer   _orderby_sql
_limit_sql_offset_sqlr  
with_aliasr$   r+   r   )	r3   rK   set_operation_templateset_ctxbase_querystringquerystringr   r   set_operation_querystringr4   r4   r5   rN   S  sD   



z_SetOperation.get_sqlc                 C  s   g }dd | j jD }| jD ])\}}|jr!|j|v r!t|j|jn||}||dur4dj||j	dn| qdjd
|dS )	a  
        Produces the ORDER BY part of the query.  This is a list of fields and possibly their directionality, ASC or
        DESC. The clauses are stored in the query under self._orderbys as a list of tuples containing the field and
        directionality (which can be None).

        If an order by field is used in the select clause, determined by a matching , then the ORDER BY clause will use
        the alias, otherwise the field will be rendered as SQL.
        c                 S     h | ]}|j qS r4   r1   .0r   r4   r4   r5   	<setcomp>      z-_SetOperation._orderby_sql.<locals>.<setcomp>N{term} {orient}termorient ORDER BY {orderby},r  )r   r'  r   r+   r%   r}   rN   r   r~   r(  joinr3   rK   clausesselected_aliasesrA   directionalityr9  r4   r4   r5   r)    s   	z_SetOperation._orderby_sqlc                 C  "   | j d u rdS dj| j |dS Nr   z OFFSET {offset})r  r   r~   rN   rM   r4   r4   r5   r+       
z_SetOperation._offset_sqlc                 C  rC  Nr   z LIMIT {limit})r  r   r~   rN   rM   r4   r4   r5   r*    rF  z_SetOperation._limit_sql)r   r   r   r   r   r   r+   r   r   r   r-   r.   )r  r   r   r   r-   r)   r  rb   r-   r)   r  rb   r-   r)   )r[   r*   r-   r)   )r[   r   r-   r)   rO   rP   )rQ   rR   rS   r   r"   r6   r#   r  r  r  r  r  r  r  r  r  r  r  r   rN   r)  r+  r*  rh   r4   r4   rY   r5   r     s:    






.
r   c                      sL  e Zd ZdZeZdedfd
 fd
dZdddZe	dddZ
e		ddddZdddZdd!d"Zdd#d$Ze	dd'd(Ze	dd,d-Ze	dd1d2Ze	dd5d6Ze	dd8d9Ze	dd:d;Ze	dd<d=Ze	dd>d?Ze	dd@dAZe	ddBdCZe	ddEdFZe	ddGdHZe	ddIdJZe		K	K	L	KdddRdSZe	ddTdUZe	ddXdYZe	dd[d\Ze	dd]d^Z e	dd`daZ!e	ddbdcZ"e	ddfdgZ#e	ddidjZ$e	e%j&fddpdqZ'ddsdtZ(ddudvZ)ddwdxZ*ddydzZ+dd{d|Z,dd}d~Z-dddZ.dddZ/dddZ0e	d ddZ1e	d!ddZ2e	d"ddZ3e	d"ddZ4e	d"ddZ5e	d"ddZ6e	d"ddZ7e	d#ddZ8d"ddZ9d"ddZ:d"ddZ;e	d$ddZ<d% fddZ=e>d&ddZ?d'ddZ@d(ddZAd)ddZBd*ddZCd+ddZDd,ddZEd-ddZFd.ddńZGd/ddǄZHd0ddɄZId0dd˄ZJd1dd̈́ZKd1ddτZLd2ddфZMdd3ddԄZNd4ddׄZOdddلZPdd5dd܄ZQdddބZRd6dddZSdddZTdddZUdddZVe>dddZWdddZXdddZYdddZZdddZ[dddZ\dddZ]dddZ^dddZ_dddZ`dddZadddZbd0d dZcdddZddddZedddZfddd	Zg  ZhS (7  r   z
    Query Builder is the main class in pypika which stores the state of a query and offers functions which allow the
    state to be branched immutably.
    Tr&  r\   r   r   	immutabler-   r.   c                   s  t  d  g | _d | _d | _d| _d| _g | _g | _g | _	g | _
g | _g | _d| _d| _d| _d| _t | _d| _d | _d | _g | _d| _d | _g | _g | _g | _d | _d | _g | _d| _t | _ d| _!d| _"d| _#d| _$|| _%|| _&|| _'d| _(g | _)d| _*g | _+d | _,d | _-d S )NFr   ).rX   r6   r  _insert_table_update_table_delete_from_replace_withr'  _force_indexes_use_indexes_columns_values	_distinct_for_update_for_update_nowait_for_update_skip_lockedset_for_update_of_for_update_no_key_wheres
_prewheres	_groupbys_with_totals_havingsr   _joins_unionsr   r   _updates_select_star_select_star_tables_mysql_rollup_select_into_subquery_count_foreign_tabler&  r   rK  _on_conflict_on_conflict_fields_on_conflict_do_nothing_on_conflict_do_updates_on_conflict_wheres_on_conflict_do_update_wheres)r3   r&  r   rK  rY   r4   r5   r6     sX   
zQueryBuilder.__init__r)   c                 C  s   t | t | }|j| j t| j|_t| j|_t| j|_t| j|_t| j	|_	t| j
|_
t| j|_t| j|_t| j|_t| j|_t| j|_t| j|_t| j|_|S r0   )r   __new____dict__r   r   r  rP  r'  rS  rT  r^  r   ra  rb  rc  re  rk  rm  )r3   newoner4   r4   r5   __copy__  s    zQueryBuilder.__copy__target_fields
str | Termc                 G  sV   | j stdd| _|D ]}t|tr| j| | qt|tr(| j| qd S )Nz(On conflict only applies to insert queryT)	rL  r   rj  r^   r,   rk  r   _conflict_field_strr    )r3   rt  target_fieldr4   r4   r5   on_conflict  s   

zQueryBuilder.on_conflictNupdate_fieldstr | Fieldupdate_value
Any | Nonec                 C  sp   | j rtdt|tr| |}nt|tr|}ntd|d ur.| j|t|f d S | j|d f d S )N"Can not have two conflict handlerszUnsupported update_field)	rl  r   r^   r,   rv  r   rm  r   r"   )r3   ry  r{  rA   r4   r4   r5   	do_update  s   

zQueryBuilder.do_updater9  r,   Field | Nonec                 C  s   | j r
t|| j dS d S r<   )rL  r   r3   r9  r4   r4   r5   rv    s   z QueryBuilder._conflict_field_strrK   r   c                   s   | j st| jdkr| jsdS td| jr| jstdd}| jr=|jdd  fdd	| jD }|d
d| d 7 }| jrR|jdd}|dj| j	|d7 }|S )Nr   r   z"No handler defined for on conflictz,Can not have fieldless on conflict do updatez ON CONFLICTTr,  c                      g | ]}|  qS r4   rN   r4  fon_conflict_ctxr4   r5   
<listcomp>0  s    z1QueryBuilder._on_conflict_sql.<locals>.<listcomp>z (, )r   WHERE {where}where)
rl  r   rm  rk  r   r   r>  rn  r~   rN   )r3   rK   conflict_queryr  	where_ctxr4   r  r5   _on_conflict_sql$  s&   

zQueryBuilder._on_conflict_sqlc                 C  s   |j dd}| jrdS t| jdkrdg }|j dd}| jD ]'\}}|r4|dj||||d q|dj||||d qd	jd
|d}| jrb|dj| j|j dddd7 }|S dS )NFwith_namespacez DO NOTHINGr   T{field}={value}rA   r(  z{field}=EXCLUDED.{value}z DO UPDATE SET {updates}r<  )updatesr  )r  r  r  r   )	r   rl  r   rm  r   r~   rN   r>  ro  )r3   rK   r  	value_ctxrA   r(  
action_sqlr4   r4   r5   _on_conflict_action_sql>  s8   z$QueryBuilder._on_conflict_action_sql
selectableSelectable | Query | strc                 C  sx   | j t|trt|n| t|ttfr8|jdu r:t|tr$|j}nd}t	| j|}d| |_|d | _dS dS dS )a  
        Adds a table to the query. This function can only be called once and will raise an AttributeError if called a
        second time.

        :param selectable:
            Type: ``Table``, ``Query``, or ``str``

            When a ``str`` is passed, a table with the name matching the ``str`` value is used.

        :returns
            A copy of the query with the table added.
        Nr   sq%dr
   )
r  r   r^   r,   rw   r   r   r+   rh  max)r3   r  sub_query_countr4   r4   r5   r   _  s   


zQueryBuilder.from_current_tableTable | None	new_tablec                   s^   fdd| j D | _ | j kr| _| j kr| _ fdd| jD | _ fdd| jD | _ fdd| jD | _ fdd| jD | _| jrV| j nd| _| j	rc| j	 nd| _	 fdd| j
D | _
| jr|| j nd| _ fd	d| jD | _ fd
d| jD | _ | jv r| j  | jtt dS dS )ak  
        Replaces all occurrences of the specified table with the new table. Useful when reusing fields across
        queries.

        :param current_table:
            The table instance to be replaces.
        :param new_table:
            The table instance to replace with.
        :return:
            A copy of the query with the tables replaced.
        c                   s   g | ]
}| kr
n|qS r4   r4   )r4  r>   r  r  r4   r5   r    s    z.QueryBuilder.replace_table.<locals>.<listcomp>c                      g | ]}|  qS r4   replace_table)r4  alias_queryr  r4   r5   r    s    
c                   r  r4   r  r4  r   r  r4   r5   r        c                   r  r4   r  r4  r   r  r4   r5   r    r  c                   s    g | ]} fd d|D qS )c                   r  r4   r  r4  r(  r  r4   r5   r    r  z9QueryBuilder.replace_table.<locals>.<listcomp>.<listcomp>r4   )r4  
value_listr  r4   r5   r    s    Nc                   r  r4   r  )r4  groupbyr  r4   r5   r    s    c                   s$   g | ]}|d    |d fqS )r   r
   r  )r4  r  r  r4   r5   r        c                   r  r4   r  r4  r>  r  r4   r5   r    r  )r  rL  rM  rP  r'  rS  rT  r\  r  r]  r^  r`  r   ra  re  removeaddr   rw   r3   r  r  r4   r  r5   r  ~  s@   


zQueryBuilder.replace_tabler:   rk   r    c                 G  s"   t ||g|R  }| j| d S r0   )ri   rP  r   )r3   r  r:   rk   r   r4   r4   r5   r     s   zQueryBuilder.with_r>   r   c                 C  sD   | j d urtdd | jrd| _t|tr|| _ d S t|| _ d S )N$'Query' object has no attribute '%s'r   T)rL  r   r'  rg  r^   rw   r3   r>   r4   r4   r5   r     s
   
"zQueryBuilder.intor   c                 G  sj   |D ]0}t |tr| | qt |tr| | qt |ttfr'| | q| | j|| j	d qd S N)r   )
r^   r   _select_fieldr,   _select_field_strr   r   _select_otherr  r   r3   rk   r9  r4   r4   r5   r     s   

zQueryBuilder.selectc                 C  s(   | j s	| js	| jrtdd d| _ d S )Nr  deleteT)rN  r'  rM  r   rC   r4   r4   r5   r    s   
zQueryBuilder.deletec                 C  sD   | j d us| js| jrtdd t|tr|| _ d S t|| _ d S )Nr  r   )rM  r'  rN  r   r^   rw   r  r4   r4   r5   r     s   "zQueryBuilder.updatec                 G  sf   | j d u rtdd |rt|d ttfr|d }|D ]}t|tr*t|| j d}| j| qd S )Nr  r   r   r=   )	rL  r   r^   r   r   r,   r   rS  r   r  r4   r4   r5   r     s   

zQueryBuilder.columnsc                 G  2   | j d u rtdd |r| j|  d| _d S d S )Nr  r   FrL  r   _validate_terms_and_appendrO  r   r4   r4   r5   r        


zQueryBuilder.insertc                 G  r  )Nr  r   Tr  r   r4   r4   r5   replace  r  zQueryBuilder.replacestr | Indexc                 G  H   |g|R D ]}t |tr| j| qt |tr!| jt| qd S r0   )r^   r   rQ  r   r,   r3   r9  rk   r   r4   r4   r5   force_index     

zQueryBuilder.force_indexc                 G  r  r0   )r^   r   rR  r   r,   r  r4   r4   r5   	use_index  r  zQueryBuilder.use_indexc                 C  
   d| _ d S NTrU  rC   r4   r4   r5   distinct  r9   zQueryBuilder.distinctFr4   nowaitskip_lockedoftuple[str, ...]no_keyc                 C  s&   d| _ || _|| _t|| _|| _d S r  )rV  rX  rW  rY  rZ  r[  )r3   r  r  r  r  r4   r4   r5   
for_update  s
   

zQueryBuilder.for_updatec                 C  s    t | jdkrtdd| _d S )Nr   r}  T)r   rm  r   rl  rC   r4   r4   r5   
do_nothing)  s   
zQueryBuilder.do_nothingr   r   c                 C  s2   |  |sd| _| jr|  j|M  _d S || _d S r  )_validate_tableri  r]  r3   r   r4   r4   r5   prewhere/  s
   

zQueryBuilder.prewhereTerm | EmptyCriterionc                 C  s   t |trd S | js#| |sd| _| jr|  j|M  _d S || _d S | jr*td| jrA| j	rA| j
r<|  j
|M  _
d S || _
d S | jrU| jrP|  j|M  _d S || _d S td)NTz"DO NOTHING doest not support WHEREz(Can not have fieldless ON CONFLICT WHERE)r^   r   rj  r  ri  r\  rl  r   rk  rm  ro  rn  r  r4   r4   r5   r  9  s&   




zQueryBuilder.wherec                 C  s"   | j r|  j |M  _ d S || _ d S r0   )r`  r  r4   r4   r5   havingT  s   
zQueryBuilder.havingstr | int | Termc                 G  sb   |D ],}t |trt|| jd d}nt |tr(tt|| jd d}||}| j| qd S )Nr   r=   )r^   r,   r   r  rb   r  r^  r   )r3   rk   r9  rA   r4   r4   r5   r  [  s   


zQueryBuilder.groupbyc                 C  r  r  )r_  rC   r4   r4   r5   with_totalsf  r9   zQueryBuilder.with_totalslist | tuple | set | Termr   c                 O  s   d| dk}| jrtdd dd |D }|r.|s"| js"tdd| _|  j|7  _d S d	t| jk rIt| jd
 trI| jd
  j|7  _d S | j	t|  d S )Nmysqlvendorr  rollupc                 S  s(   g | ]}t |tttfrt| n|qS r4   )r^   r   r   rY  r!   r4  r9  r4   r4   r5   r  s  s    z'QueryBuilder.rollup.<locals>.<listcomp>zWAt least one group is required. Call Query.groupby(term) or passas parameter to rollup.Tr   )
r   rf  r   r^  r   r   r^   r   argsr   )r3   rk   r   	for_mysqlr4   r4   r5   r  j  s    
zQueryBuilder.rollupr  c                 O  sJ   |D ] }t |trt|| jd dn| |}| j||df qd S r  )r^   r,   r   r  r  r   r   r   r  r4   r4   r5   r    s   zQueryBuilder.orderbyrv   0Table | QueryBuilder | AliasedQuery | Selectablehowr   Joinerc                 C  s   t |trt| ||ddS t |tr$|jd u r| | t| ||ddS t |tr1t| ||ddS t |tr>t| ||ddS tdt	| )Nr>   )
type_labelr  zCannot join on type '%s')
r^   rw   r  r   r+   _tag_subqueryrU   r*   
ValueErrorr   r3   rv   r  r4   r4   r5   r>    s   





zQueryBuilder.join#Table | QueryBuilder | AliasedQueryc                 C     |  |tjS r0   )r>  r   innerr{   r4   r4   r5   
inner_join  re   zQueryBuilder.inner_joinc                 C  r  r0   )r>  r   leftr{   r4   r4   r5   	left_join  re   zQueryBuilder.left_joinc                 C  r  r0   )r>  r   
left_outerr{   r4   r4   r5   left_outer_join  re   zQueryBuilder.left_outer_joinc                 C  r  r0   )r>  r   rightr{   r4   r4   r5   
right_join  re   zQueryBuilder.right_joinc                 C  r  r0   )r>  r   right_outerr{   r4   r4   r5   right_outer_join  re   zQueryBuilder.right_outer_joinc                 C  r  r0   )r>  r   outerr{   r4   r4   r5   
outer_join  re   zQueryBuilder.outer_joinc                 C  r  r0   )r>  r   
full_outerr{   r4   r4   r5   full_outer_join  re   zQueryBuilder.full_outer_joinc                 C  r  r0   )r>  r   crossr{   r4   r4   r5   
cross_join  re   zQueryBuilder.cross_joinc                 C  r  r0   )r>  r   rc   r{   r4   r4   r5   	hash_join  re   zQueryBuilder.hash_joinr  rb   c                 C  r	  r0   r
  r  r4   r4   r5   r    r  zQueryBuilder.limitr  c                 C  r	  r0   r  r  r4   r4   r5   r    r  zQueryBuilder.offsetr[   r   c                 C     t | |tj| jdS r  )r   r   r  r   r_   r4   r4   r5   r       zQueryBuilder.unionc                 C  r  r  )r   r   r  r   r_   r4   r4   r5   r    r  zQueryBuilder.union_allc                 C  r  r  )r   r   r  r   r_   r4   r4   r5   r    r  zQueryBuilder.intersectc                 C  r  r  )r   r   r  r   r_   r4   r4   r5   r    r  zQueryBuilder.except_ofc                 C  r  r  )r   r   r  r   r_   r4   r4   r5   r    r  zQueryBuilder.minusrA   Field | strr(  c                 C  s:   t |ts	t|n|}| j|| jd}| j||f d S r  )r^   r   r  r   rc  r   )r3   rA   r(  r4   r4   r5   rY    s   zQueryBuilder.setc                 C  rE   r0   r  r_   r4   r4   r5   r    r7   zQueryBuilder.__add__c                 C  rE   r0   r  r_   r4   r4   r5   r    r7   zQueryBuilder.__mul__c                 C  rE   r0   r  r_   r4   r4   r5   r    r7   zQueryBuilder.__sub__slicec                 C  sD   |j d urtt| |j | _|jd ur tt| |j| _d S d S r0   )startr   r"   r  r   stopr   )r3   r  r4   r4   r5   r    s
   

zQueryBuilder.sliceSelf | Fieldc                   s    t |tst |S | |S r0   )r^   r  rX   rH   r{   rY   r4   r5   rH     s   

zQueryBuilder.__getitem__	field_setSequence[Field]	list[str]c                   s    fdd| D S )Nc                   s   g | ]
}|j p| qS r4   )r+   rN   r4  rA   rK   r4   r5   r    s    z.QueryBuilder._list_aliases.<locals>.<listcomp>r4   )r  rK   r4   r  r5   _list_aliases  s   zQueryBuilder._list_aliasesc                 C  sV   dt | jkrtd| d|dkrd| _t g| _d S | t|| jd d d S )Nr   zCannot select z, no FROM table specified.*Tr=   )r   r  r   rd  r   r'  r  r   r  r4   r4   r5   r     s   
zQueryBuilder._select_field_strr   c                   s^   | j rd S  j| jv rd S t tr' fdd| jD | _| jtt j | j	  d S )Nc                   s&   g | ]}t |d r j|jkr|qS r=   )hasattrr>   r  r9  r4   r5   r    s    
z.QueryBuilder._select_field.<locals>.<listcomp>)
rd  r>   re  r^   r   r'  r  r   rw   r   r  r4   r  r5   r    s   

zQueryBuilder._select_fieldfunctionr   c                 C  s   | j | d S r0   )r'  r   )r3   r  r4   r4   r5   r    s   zQueryBuilder._select_otherlist[Field]c                 C  s   g S r0   r4   rC   r4   r4   r5   fields_!     zQueryBuilder.fields_r>  Joinc                   sv   | j | jg | j   | j t fdd D }tjtr3jj	d u r3|r3jj
d j_	| j d S )Nc                 3  s$    | ]}t |toj v V  qd S r0   )r^   rw   rv   r4  clausebase_tablesr>  r4   r5   	<genexpr>)  s    
z'QueryBuilder.do_join.<locals>.<genexpr>2)r  rM  rP  validatera  anyr^   rv   rw   r+   r   r   )r3   r>  table_in_queryr4   r  r5   do_join%  s   zQueryBuilder.do_joinrw   c                   s   t  fdd| jD S )Nc                 3  s    | ]} |j kV  qd S r0   rv   r  r=   r4   r5   r  4      z)QueryBuilder.is_joined.<locals>.<genexpr>)r  ra  r  r4   r=   r5   	is_joined3  s   zQueryBuilder.is_joinedc                 C  sh   | j | jg }| D ]&}|j|v }|jdd | jD v }t|jdu| | |j| jkgr1 dS qdS )z
        Returns False if the term references a table not already part of the
        FROM clause or JOINS and True otherwise.
        c                 S     g | ]}|j qS r4   r  r  r4   r4   r5   r  ?  r6  z0QueryBuilder._validate_table.<locals>.<listcomp>NFT)r  rM  r
  r>   ra  all)r3   r9  r  rA   table_in_base_tablestable_in_joinsr4   r4   r5   r  6  s   

	zQueryBuilder._validate_tabler  c                 C  s   d| j  |_|  j d7  _ d S )Nr  r
   )rh  r+   )r3   r  r4   r4   r5   r  K  s   zQueryBuilder._tag_subqueryc                   sB   t |d tttfs|g}|D ]} j fdd|D  qdS )z
        Handy function for INSERT and REPLACE statements in order to check if
        terms are introduced and how append them to `self._values`
        r   c                   s$   g | ]}t |tr|n |qS r4   )r^   r    r  r  rC   r4   r5   r  Y  r  z;QueryBuilder._validate_terms_and_append.<locals>.<listcomp>N)r^   r   r   rY  rT  r   )r3   rk   valuesr4   rC   r5   r  O  s   
z'QueryBuilder._validate_terms_and_appendc                 C     |  | jjS r0   rN   r%  r   rC   r4   r4   r5   r   _  re   zQueryBuilder.__str__c                 C     |   S r0   r   rC   r4   r4   r5   r   b     zQueryBuilder.__repr__c                 C  r]   r0   )r^   r   r+   r_   r4   r4   r5   r`   e  ra   zQueryBuilder.__eq__c                 C  rs   r0   rt   r_   r4   r4   r5   ru   h  rB   zQueryBuilder.__ne__c                 C  s   t | jtdd | jD  S )Nc                 s  s    | ]}t |V  qd S r0   )rc   r  r4   r4   r5   r  l  s    z(QueryBuilder.__hash__.<locals>.<genexpr>)rc   r+   sumr  rC   r4   r4   r5   rd   k  s   zQueryBuilder.__hash__SqlContext | Nonec                   s   s| j j | js| js| js| jsdS | jr| js| jsdS | jr'| js'dS t| j	}dt
| jk }dt
| jk oAt| jd t}| j}| joJ| j} jt|||||gd | jr| jrd|  }nd}||  7 }| j	r|dd fdd| j	D  7 }||  7 }| jr||  7 }| jr||  7 }|S | jr|  }nr| js| jr| jr|  }nd}| jr||  7 }n||  7 }| jr||  7 }| jr||   7 }| j!r|| " 7 }|| # 7 }|S |d| $  7 }n| jr|  }nd}|| $ 7 }| jr|| % 7 }| jr$||  7 }| j&r/|| ' 7 }| j(r:|| ) 7 }| j	rO|dd fdd| j	D  7 }| j*rZ|| + 7 }| jre||  7 }| j,rz|| - 7 }| j.rz|| / 7 }| j0r|| 1 7 }| j2r|| 3 7 }| 4| }| j5r|| 6 7 } j7rd	j8|d
}| j!r|| " 7 }|| # 7 } j9rt:|| j; S |S )Nr   r
   r   r   c                 3      | ]}|  V  qd S r0   r  r  r  r4   r5   r    r  z'QueryBuilder.get_sql.<locals>.<genexpr>c                 3  r'  r0   r  r  r  r4   r5   r    r  r#  r$  )<r%  r   r'  rL  rN  rM  rT  rc  r\   ra  r   r  r^   r   ri  r   r  rP  	_with_sql_update_sqlr>  _set_sql	_from_sqlr\  
_where_sql_delete_sqlrg  rO  _replace_sql_insert_sqlrS  _columns_sql_values_sqlrj  r  r  _select_sql	_into_sqlrQ  _force_index_sqlrR  _use_index_sqlr]  _prewhere_sqlr^  
_group_sqlrf  _rollup_sqlr`  _having_sqlr   r)  _apply_paginationrV  _for_update_sqlr  r~   r,  r$   r+   )r3   rK   	has_joinshas_multiple_from_clauseshas_subquery_from_clausehas_reference_to_foreign_tablehas_update_fromr0  r4   r  r5   rN   n  s   
""zQueryBuilder.get_sqlr0  c                 C  s    ||  |7 }|| |7 }|S r0   )r*  r+  )r3   r0  rK   r4   r4   r5   r:    s   zQueryBuilder._apply_paginationc                   sp   dd | j D }d}| j D ]}|jj|v rd} nqjddd d|r&dnd d	 fd
d| j D  S )Nc                 S  r  r4   r1   )r4  r   r4   r4   r5   r    r6  z*QueryBuilder._with_sql.<locals>.<listcomp>FTr  r,  zWITH z
RECURSIVE r   r<  c                 3  sT    | ]%}|j |jrd dfdd|jD  d nd d |  d V  qdS )	(r<  c                   r  r4   r  r  r  r4   r5   r        z4QueryBuilder._with_sql.<locals>.<genexpr>.<listcomp>r  r   z AS (z) N)r+   rk   r>  rN   r  as_ctxrK   r4   r5   r    s    
$
z)QueryBuilder._with_sql.<locals>.<genexpr>)rP  rV   r   r   r>  )r3   rK   	all_alias	recursiver   r4   rD  r5   r(    s   
 

zQueryBuilder._with_sqltuple[str, list]c                 C  s2   |s| j j}|js|jt d}| ||jjfS )zV
        Returns a tuple containing the query string and a list of parameters
        )r  )r%  r   r  r   r   rN   r  rM   r4   r4   r5   get_parameterized_sql  s   z"QueryBuilder.get_parameterized_sqlc                 C  s   | j rdS dS )Nz	DISTINCT r   r  rM   r4   r4   r5   _distinct_sql  re   zQueryBuilder._distinct_sqlUPDATEc                   sf   | j r/d| }| jr|dd fdd| jD  7 }| jr&|d7 }|S | jr-|d7 }|S d}|S )	Nz FOR z OF r  c                   s   g | ]	}t | qS r4   )rw   rN   )r4  rv   r  r4   r5   r  #  s    z0QueryBuilder._for_update_sql.<locals>.<listcomp>z NOWAITz SKIP LOCKEDr   )rV  rZ  r>  rW  rX  )r3   rK   lock_strengthr  r4   r  r5   r;    s   
zQueryBuilder._for_update_sqlc                   s8   |j ddd dj| |d fdd| jD dS )NTrA  zSELECT {distinct}{select}r<  c                 3  r'  r0   r  r  
select_ctxr4   r5   r  2  r  z+QueryBuilder._select_sql.<locals>.<genexpr>)r  r   )r   r~   rJ  r>  r'  rM   r4   rM  r5   r2  .  s
   zQueryBuilder._select_sqlc                 C     | j |}d| S )NzINSERT INTO rL  rN   r3   rK   r>   r4   r4   r5   r/  5     
zQueryBuilder._insert_sqlc                 C  rO  )NzREPLACE INTO rP  rQ  r4   r4   r5   r.  9  rR  zQueryBuilder._replace_sqlc                 C     dS )NDELETEr4   r  r4   r4   r5   r-  =  r  zQueryBuilder._delete_sqlc                 C  rO  )NzUPDATE )rM  rN   rQ  r4   r4   r5   r)  A  rR  zQueryBuilder._update_sqlc                   s.    j dd djd fdd| jD dS )z;
        SQL for Columns clause for INSERT queries
        Fr  z ({columns})r<  c                 3  r'  r0   r  r  r  r4   r5   r  K  r  z,QueryBuilder._columns_sql.<locals>.<genexpr>)r   )r   r~   r>  rS  rM   r4   r  r5   r0  E  s   "zQueryBuilder._columns_sqlc                   0   |j ddd djd fdd| jD dS )NTrA  z VALUES ({values})z),(c                 3  s(    | ]}d   fdd|D V  qdS )r<  c                 3  r'  r0   r  r  
values_ctxr4   r5   r  Q  r  z5QueryBuilder._values_sql.<locals>.<genexpr>.<genexpr>N)r>  )r4  rowrV  r4   r5   r  P  s    
z+QueryBuilder._values_sql.<locals>.<genexpr>)r  )r   r~   r>  rT  rM   r4   rV  r5   r1  M  s   zQueryBuilder._values_sqlc                 C  s    |j dd}dj| j|dS )NFr  z INTO {table}r=   )r   r~   rL  rN   )r3   rK   into_ctxr4   r4   r5   r3  U  s   
zQueryBuilder._into_sqlc                   rU  )NTrA  z FROM {selectable}r<  c                 3  r'  r0   r  r  from_ctxr4   r5   r  ^  r  z)QueryBuilder._from_sql.<locals>.<genexpr>)r  )r   r~   r>  r  rM   r4   rZ  r5   r+  [  s   zQueryBuilder._from_sqlc                   "   dj d fdd| jD dS )Nz FORCE INDEX ({indexes})r<  c                 3  r'  r0   r  r4  indexr  r4   r5   r  c  r  z0QueryBuilder._force_index_sql.<locals>.<genexpr>indexes)r~   r>  rQ  rM   r4   r  r5   r4  a     zQueryBuilder._force_index_sqlc                   r\  )Nz USE INDEX ({indexes})r<  c                 3  r'  r0   r  r]  r  r4   r5   r  h  r  z.QueryBuilder._use_index_sql.<locals>.<genexpr>r_  )r~   r>  rR  rM   r4   r  r5   r5  f  ra  zQueryBuilder._use_index_sqlc                 C  *   |j dd}tt| j}dj||dS )NTr  z PREWHERE {prewhere})r  )r   r   r   r]  r~   rN   )r3   rK   prewhere_sql	prewheresr4   r4   r5   r6  k     zQueryBuilder._prewhere_sqlc                 C  rb  )NTr  r  r  )r   r   r   r\  r~   rN   )r3   rK   r  wheresr4   r4   r5   r,  p  re  zQueryBuilder._where_sqlc                 C  s   g }dd | j D }| jD ]9}|j }r>||v r>|jr(|t||jp$|j q| j D ]}|j|kr<|||  nq+q||| qdj	d
|d}| jrW|d S |S )a  
        Produces the GROUP BY part of the query.  This is a list of fields. The clauses are stored in the query under
        self._groupbys as a list fields.

        If an groupby field is used in the select clause,
        determined by a matching alias, and the groupby_alias is set True
        then the GROUP BY clause will use the alias,
        otherwise the entire field will be rendered as SQL.
        c                 S  r2  r4   r1   r3  r4   r4   r5   r5    r6  z*QueryBuilder._group_sql.<locals>.<setcomp>z GROUP BY {groupby}r<  )r  z WITH TOTALS)r'  r^  r+   groupby_aliasr   r%   alias_quote_charr}   rN   r~   r>  r_  )r3   rK   r@  rA  rA   r+   r   sqlr4   r4   r5   r7  u  s"   


zQueryBuilder._group_sqlc                 C  s   g }dd | j D }| jD ]/\}}|jr&|jr&|j|v r&t|j|jp$|jn||}||dur9dj	||j
dn| qdj	d|dS )	a  
        Produces the ORDER BY part of the query.  This is a list of fields and possibly their directionality, ASC or
        DESC. The clauses are stored in the query under self._orderbys as a list of tuples containing the field and
        directionality (which can be None).

        If an order by field is used in the select clause,
        determined by a matching, and the orderby_alias
        is set True then the ORDER BY clause will use
        the alias, otherwise the field will be rendered as SQL.
        c                 S  r2  r4   r1   r3  r4   r4   r5   r5    r6  z,QueryBuilder._orderby_sql.<locals>.<setcomp>Nr7  r8  r;  r<  r=  )r'  r   orderby_aliasr+   r%   rh  r}   rN   r   r~   r(  r>  r?  r4   r4   r5   r)    s"   zQueryBuilder._orderby_sqlc                 C  rS  )Nz WITH ROLLUPr4   rC   r4   r4   r5   r8       zQueryBuilder._rollup_sqlc                 C  rO  )Nz HAVING )r`  rN   )r3   rK   r  r4   r4   r5   r9    rR  zQueryBuilder._having_sqlc                 C  rC  rD  rE  rM   r4   r4   r5   r+    rF  zQueryBuilder._offset_sqlc                 C  rC  rG  rH  rM   r4   r4   r5   r*    rF  zQueryBuilder._limit_sqlc                   s0    j dddjd fdd| jD dS )NFr  z
 SET {set}r<  c                 3  s.    | ]\}}d j || dV  qdS )r  r  N)r~   rN   )r4  rA   r(  rK   	field_ctxr4   r5   r    s    
z(QueryBuilder._set_sql.<locals>.<genexpr>)rY  )r   r~   r>  rc  rM   r4   rl  r5   r*    s   zQueryBuilder._set_sql)r&  r\   r   r   rK  r\   r-   r.   r-   r)   )rt  ru  r-   r)   r0   )ry  rz  r{  r|  r-   r)   )r9  r,   r-   r  rP   )r  r  r-   r)   r  r  r  r  r-   r)   )r  r   r:   r,   rk   r    r-   r)   )r>   r   r-   r)   )rk   r   r-   r)   )r9  r  rk   r  r-   r)   )FFr4   F)
r  r\   r  r\   r  r  r  r\   r-   r)   )r   r   r-   r)   )r   r  r-   r)   )rk   r  r-   r)   )rk   r  r   r   r-   r)   )r  r   r   r   r-   r)   )rv   r  r  r   r-   r  )rv   r  r-   r  rI  rJ  )r[   r)   r-   r   )rA   r  r(  r   r-   r)   )r  r  r-   r)   )rv   r   r-   r  )r  r   rK   r   r-   r  )r9  r,   r-   r.   )r9  r   r-   r.   )r  r   r-   r.   )r-   r	  )r>  r  r-   r.   )r>   rw   r-   r\   )r9  r    r-   r\   )r  r)   r-   r.   )rk   r   r-   r.   rO   rf   rg   rK   r%  r-   r,   )r0  r,   rK   r   r-   r,   )rK   r%  r-   rH  )rK  )irQ   rR   rS   r   r   r%  r"   r6   rs  r#   rx  r~  rv  r  r  r   r  r   r   r   r  r   r   r   r  r  r  r  r  r  r  r  r  r  r  r  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  rH   r   r  r  r  r  r
  r  r  r  r  r  r   r   r`   ru   rd   rN   r:  r(  rI  rJ  r;  r2  r/  r.  r-  r)  r0  r1  r3  r+  r4  r5  r6  r,  r7  r)  r8  r9  r+  r*  r*  rh   r4   r4   rY   r5   r     s   ?!8				

 "r   c                   @  s@   e Zd ZdddZddddZdddZdddZd ddZdS )!r  rV   r   rv   (Selectable | QueryBuilder | AliasedQueryr  r   r  r,   r-   r.   c                 C  s   || _ || _|| _|| _d S r0   )rV   rv   r  r  )r3   rV   rv   r  r  r4   r4   r5   r6     s   
zJoiner.__init__Nr   Criterion | Nonecollater   c                 C  s:   |d u rt dj| jd| jt| j| j|| | jS )NzIParameter 'criterion' is required for a {type} JOIN but was not supplied.r   )r   r~   r  rV   r  JoinOnrv   r  )r3   r   rs  r4   r4   r5   on  s   z	Joiner.onr  r   c                 G  sx   |st dj| jdd }|D ]}t|| jjd dt|| jdk}|d u r(|n||@ }q| jt| j| j	| | jS )NzFParameter 'fields' is required for a {type} JOIN but was not supplied.rt  r   r=   )
r   r~   r  r   rV   r  rv   r  ru  r  )r3   r  r   rA   
consituentr4   r4   r5   on_field  s   "zJoiner.on_fieldc                 G  s>   |st dj| jd| jt| j| jdd |D  | jS )Nz[Parameter 'fields' is required when joining with {type}a using clause but was not supplied.rt  c                 S  s   g | ]}t |qS r4   r?   r  r4   r4   r5   r    s    z Joiner.using.<locals>.<listcomp>)r   r~   r  rV   r  	JoinUsingrv   r  )r3   r  r4   r4   r5   using  s   zJoiner.usingc                 C  s   | j t| jtj | j S )zReturn cross join)rV   r  r  rv   r   r  rC   r4   r4   r5   r  
  s   zJoiner.cross)
rV   r   rv   rq  r  r   r  r,   r-   r.   r0   )r   rr  rs  r   r-   r   )r  r   r-   r   r   )rQ   rR   rS   r6   rv  rx  rz  r  r4   r4   r4   r5   r    s    



r  c                   @  s8   e Zd ZdddZdddZdddZedddZdS )r  rv   r    r  r   r-   r.   c                 C  ro   r0   )rv   r  r  r4   r4   r5   r6     rr   zJoin.__init__rK   r   r,   c                 C  s@   |j ddd}dj| j|d}| jjrdj|| jjdS |S )NTrA  zJOIN {table}r=   z{type} {join})r>  r   )r   r~   rv   rN   r  r(  )r3   rK   join_ctxri  r4   r4   r5   rN     s   
zJoin.get_sqlr  Sequence[Table]ra  c                 C  r   r0   r4   r3   r  ra  r4   r4   r5   r     rk  zJoin.validater  r  r  r)   c                 C  s   | j ||| _ dS X  
        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 join with the tables replaced.
        N)rv   r  r  r4   r4   r5   r  #  s   zJoin.replace_tableN)rv   r    r  r   r-   r.   rP   r  r|  ra  r|  r-   r.   ro  )rQ   rR   rS   r6   rN   r  r#   r  r4   r4   r4   r5   r    s    



r  c                      sH   e Zd Z	dd fddZd  fddZd!ddZed"ddZ  ZS )#ru  Nrv   r    r  r   criteriar   rs  r   r-   r.   c                   s   t  || || _|| _d S r0   )rX   r6   r   rs  )r3   rv   r  r  rs  rY   r4   r5   r6   6  s   
zJoinOn.__init__rK   r   r,   c                   sF   t  |}|jdd}dj|| j|| jrd| jdS ddS )NTr  z{join} ON {criterion}{collate}z COLLATE {}r   )r>  r   rs  )rX   rN   r   r~   r   rs  )r3   rK   join_sqlcriterion_ctxrY   r4   r5   rN   A  s   
zJoinOn.get_sqlr  r|  ra  c                 C  sb   t dd | j D }t |dd |D B | jhB }|| }|r/tdjdtt|dd S )Nc                 S  r  r4   r=   r  r4   r4   r5   r  K  r6  z#JoinOn.validate.<locals>.<listcomp>c                 S  r2  r4   r  r  r4   r4   r5   r5  L  r6  z"JoinOn.validate.<locals>.<setcomp>zInvalid join criterion. One field is required from the joined item and another from the selected table or an existing join.  Found [{tables}]r  )r   )	rY  r   r
  rv   r   r~   r>  mapr,   )r3   r  ra  criterion_tablesavailable_tablesmissing_tablesr4   r4   r5   r  J  s   zJoinOn.validater  r  r  r)   c                 C  s$   | j |kr|| _ | j||| _dS r~  )rv   r   r  r  r4   r4   r5   r  V  s   
zJoinOn.replace_tabler0   )
rv   r    r  r   r  r   rs  r   r-   r.   rP   r  ro  	rQ   rR   rS   r6   rN   r  r#   r  rh   r4   r4   rY   r5   ru  5  s    
	ru  c                      sD   e Zd Zd fd	d
Zd fddZdddZedddZ  ZS )ry  rv   r    r  r   r  r   r-   r.   c                   s   t  || || _d S r0   )rX   r6   r  )r3   rv   r  r  rY   r4   r5   r6   k  s   
zJoinUsing.__init__rK   r   r,   c                   s0   t   }dj|d fdd| jD dS )Nz{join} USING ({fields})r<  c                 3  r'  r0   r  r  r  r4   r5   r  s  r  z$JoinUsing.get_sql.<locals>.<genexpr>)r>  r  )rX   rN   r~   r>  r  )r3   rK   r  rY   r  r5   rN   o  s
   zJoinUsing.get_sqlr  r|  ra  c                 C  r   r0   r4   r}  r4   r4   r5   r  v  rk  zJoinUsing.validater  r  r  r)   c                   s,   | j  kr| _  fdd| jD | _dS )r  c                   r  r4   r  r  r  r4   r5   r    r  z+JoinUsing.replace_table.<locals>.<listcomp>N)rv   r  r  r4   r  r5   r  y  s   
zJoinUsing.replace_table)rv   r    r  r   r  r   r-   r.   rP   r  ro  r  r4   r4   rY   r5   ry  j  s    
ry  c                   @  s  e Zd ZdZeZdBdCddZedDddZedEddZ	edEddZ
edEddZedFddZedGddZedHddZedHdd ZedId#d$ZedEd%d&ZdJd*d+ZdKd-d.ZdKd/d0ZdLd2d3ZdLd4d5ZdLd6d7ZdKd8d9ZdKd:d;ZdKd<d=ZdMd>d?ZdMd@dAZdS )Nr   z5
    Query builder used to build CREATE queries.
    Nr  Dialects | Noner-   r.   c                 C  sF   d | _ d| _d| _d | _g | _g | _d| _d | _g | _d| _	|| _
d S )NF)_create_table
_temporary	_unlogged
_as_selectrS  _period_fors_with_system_versioning_primary_key_uniques_if_not_existsr  )r3   r  r4   r4   r5   r6     s   
zCreateQueryBuilder.__init__r>   r   r)   c                 C  s0   | j rtdt|tr|| _ dS t|| _ dS )z
        Creates the table.

        :param table:
            An instance of a Table object or a string table name.

        :raises AttributeError:
            If the table is already created.

        :return:
            CreateQueryBuilder.
        z1'Query' object already has attribute create_tableN)r  r   r^   rw   r  r4   r4   r5   r     s   "zCreateQueryBuilder.create_tablec                 C  
   d| _ dS )z^
        Makes the table temporary.

        :return:
            CreateQueryBuilder.
        TN)r  rC   r4   r4   r5   	temporary     
zCreateQueryBuilder.temporaryc                 C  r  )z]
        Makes the table unlogged.

        :return:
            CreateQueryBuilder.
        TN)r  rC   r4   r4   r5   unlogged  r  zCreateQueryBuilder.unloggedc                 C  r  )z[
        Adds system versioning.

        :return:
            CreateQueryBuilder.
        TNr  rC   r4   r4   r5   with_system_versioning  r  z)CreateQueryBuilder.with_system_versioningr   str | tuple[str, str] | Columnc                 G  sZ   | j rtd|D ]!}t|trt|}nt|tr$t|d |d d}| j| q	dS )a  
        Adds the columns.

        :param columns:
            Type:  str | tuple[str, str] | Column

            A list of columns.

        :raises AttributeError:
            If the table is an as_select table.

        :return:
            CreateQueryBuilder.
        z.'Query' object already has attribute as_selectr   r
   r   N)r  r   r^   r,   r   r   rS  r   )r3   r   r   r4   r4   r5   r     s   


zCreateQueryBuilder.columnsr   r   r   c                 C  s   | j t||| dS )a&  
        Adds a PERIOD FOR clause.

        :param name:
            The period name.

        :param start_column:
            The column that starts the period.

        :param end_column:
            The column that ends the period.

        :return:
            CreateQueryBuilder.
        N)r  r   r   r   r4   r4   r5   
period_for  s   zCreateQueryBuilder.period_forc                 G  s   | j dd |D  dS )z
        Adds a UNIQUE constraint.

        :param columns:
            Type:  str | tuple[str, str] | Column

            A list of columns.

        :return:
            CreateQueryBuilder.
        c                 S  "   g | ]}t |tr|nt|qS r4   r^   r   r  r4   r4   r5   r    s   " z-CreateQueryBuilder.unique.<locals>.<listcomp>N)r  r   r3   r   r4   r4   r5   unique  s   zCreateQueryBuilder.uniquec                 G  s"   | j rtddd |D | _ dS )a!  
        Adds a primary key constraint.

        :param columns:
            Type:  str | tuple[str, str] | Column

            A list of columns.

        :raises AttributeError:
            If the primary key is already defined.

        :return:
            CreateQueryBuilder.
        z0'Query' object already has attribute primary_keyc                 S  r  r4   r  r  r4   r4   r5   r  &  s    z2CreateQueryBuilder.primary_key.<locals>.<listcomp>N)r  r   r  r4   r4   r5   primary_key  s
   zCreateQueryBuilder.primary_keyquery_builderr   c                 C  s*   | j rtdt|tstd|| _dS )z
        Creates the table from a select statement.

        :param query_builder:
            The query.

        :raises AttributeError:
            If columns have been defined for the table.

        :return:
            CreateQueryBuilder.
        z,'Query' object already has attribute columnsz.Expected 'item' to be instance of QueryBuilderN)rS  r   r^   r   r   r  )r3   r  r4   r4   r5   	as_select*  s
   

zCreateQueryBuilder.as_selectc                 C  r  r  )r  rC   r4   r4   r5   if_not_exists@  r9   z CreateQueryBuilder.if_not_existsrK   r%  r,   c                 C  sh   |p| j j}| jsdS | js| jsdS | |}| jr"|| | S | |}| |}dj	|||dS )zr
        Gets the sql statement string.

        :return: The create table statement.
        :rtype: str
        r   z&{create_table} ({body}){table_options})r   bodytable_options)
r%  r   r  rS  r  _create_table_sql_as_select_sql	_body_sql_table_options_sqlr~   )r3   rK   r   r  r  r4   r4   r5   rN   D  s   


zCreateQueryBuilder.get_sqlr   c                 C  s@   d}| j rd}n| jrd}d}| jrd}dj||| j|dS )Nr   z
TEMPORARY z	UNLOGGED zIF NOT EXISTS z/CREATE {table_type}TABLE {if_not_exists}{table})
table_typer  r>   )r  r  r  r~   r  rN   )r3   rK   r  r  r4   r4   r5   r  _  s   
z$CreateQueryBuilder._create_table_sqlc                 C  s   d}| j r	|d7 }|S )Nr   z WITH SYSTEM VERSIONINGr  )r3   rK   r  r4   r4   r5   r  p  s   z%CreateQueryBuilder._table_options_sqlr  c                       fdd| j D S )Nc                   r  r4   r  r  r  r4   r5   r  y  rC  z6CreateQueryBuilder._column_clauses.<locals>.<listcomp>)rS  rM   r4   r  r5   _column_clausesx     z"CreateQueryBuilder._column_clausesc                   r  )Nc                   r  r4   r  )r4  r  r  r4   r5   r  |  rC  z:CreateQueryBuilder._period_for_clauses.<locals>.<listcomp>)r  rM   r4   r  r5   _period_for_clauses{  r  z&CreateQueryBuilder._period_for_clausesc                   r  )Nc                   s,   g | ]}d j d fdd|D dqS )zUNIQUE ({unique})r<  c                 3  r'  r0   r   r  r  r4   r5   r    r  zDCreateQueryBuilder._unique_key_clauses.<locals>.<listcomp>.<genexpr>)r  )r~   r>  )r4  r  r  r4   r5   r    s    z:CreateQueryBuilder._unique_key_clauses.<locals>.<listcomp>)r  rM   r4   r  r5   _unique_key_clauses~  s   
z&CreateQueryBuilder._unique_key_clausesc                   s&   d  fdd| jD }d| dS )Nr<  c                 3  r'  r0   r  r  r  r4   r5   r    s    

z9CreateQueryBuilder._primary_key_clause.<locals>.<genexpr>zPRIMARY KEY (r  )r>  r  )r3   rK   r   r4   r  r5   _primary_key_clause  s   z&CreateQueryBuilder._primary_key_clausec                 C  sF   |  |}|| |7 }|| |7 }| jr|| | d|S )Nr<  )r  r  r  r  r   r  r>  )r3   rK   r@  r4   r4   r5   r    s   

zCreateQueryBuilder._body_sqlc                 C  s   dj | j|dS )Nz AS ({query})r$  )r~   r  rN   rM   r4   r4   r5   r    s   
z!CreateQueryBuilder._as_select_sqlc                 C  r  r0   r   rC   r4   r4   r5   r     re   zCreateQueryBuilder.__str__c                 C  r!  r0   r"  rC   r4   r4   r5   r     r#  zCreateQueryBuilder.__repr__r0   )r  r  r-   r.   r>   r   r-   r)   rn  )r   r  r-   r)   )r   r   r   r   r-   r)   )r   r   r-   r)   )r  r   r-   r)   rp  rP   )rK   r   r-   r  rO   )rQ   rR   rS   r   r   r%  r6   r#   r   r  r  r  r   r  r  r  r  r  rN   r  r  r  r  r  r  r  r  r   r   r4   r4   r4   r5   r     sF    			









r   c                   @  sh   e Zd ZdZeZeZdddZd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dS )!r   z3
    Query builder used to build DROP queries.
    r-   r.   c                 C  s   d | _ d | _d S r0   )_drop_table
_if_existsrC   r4   r4   r5   r6     rr   zDropQueryBuilder.__init__NrK   r%  r,   c                 C  s"   |p| j }| js
dS | |}|S )Nr   )r   r  _drop_table_sql)r3   rK   r0  r4   r4   r5   rN     s
   

zDropQueryBuilder.get_sqlr>   r   r)   c                 C  s0   | j rtdt|tr|| _ d S t|| _ d S )Nz/'Query' object already has attribute drop_table)r  r   r^   rw   r  r4   r4   r5   r     s   "zDropQueryBuilder.drop_tablec                 C  r  r  )r  rC   r4   r4   r5   	if_exists  r9   zDropQueryBuilder.if_existsr   c                 C  s.   | j rdnd}tt| j}dj|||dS )Nz
IF EXISTS r   zDROP TABLE {if_exists}{table})r  r>   )r  r   rw   r  r~   rN   )r3   rK   r  r   r4   r4   r5   r    s   z DropQueryBuilder._drop_table_sqlc                 C  r  r0   r   rC   r4   r4   r5   r     re   zDropQueryBuilder.__str__c                 C  r!  r0   r"  rC   r4   r4   r5   r     r#  zDropQueryBuilder.__repr__)r-   r.   r0   rp  r  rn  rP   rO   )rQ   rR   rS   r   r   r   r   r%  r6   rN   r#   r   r  r  r   r   r4   r4   r4   r5   r     s    



r   )r   r   r   r   r-   r   )r   r   r-   r   )E
__future__r   syscollections.abcr   r   	functoolsr   typingr   r   r   r	   contextr   r   enumsr   r   r   
exceptionsr   r   r   r   rk   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   utilsr#   r$   r%   r&   version_infor)   typing_extensionsr*   rU   ri   rl   r   rw   r   r   r   r   r   r   r   r   r  r  ru  ry  r   r   r4   r4   r4   r5   <module>   s`    D
  

* 	 "        6=$5#  