o
    Rh                    @   s  d dl m Z  d dlmZ d dlmZmZmZmZmZ	m
Z
mZmZ d dlmZ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 d dlm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' dZ(dZ)G d	d
 d
eZ*G dd de*Z+G dd dZ,G dd de,Z-G dd de*Z.dee	e/e/f e/f dedee. fddZ0G dd dZ1dee	e/e/f e/f dee1 fddZ2G dd dZ3e.Z4G dd dZ5G d d! d!e*eZ6G d"d# d#e*eZ7G d$d% d%Z8G d&d' d'Z9G d(d) d)e9Z:G d*d+ d+e9Z;G d,d- d-Z<G d.d/ d/Z=d0S )1    )copy)reduce)AnyListOptionalSequenceTupleTypeUnionSet)DialectsJoinTypeReferenceOptionSetOperation)ArithmeticExpression	CriterionEmptyCriterionFieldFunctionIndexNodeRollupStarTermr   ValueWrapperr   PeriodCriterion)JoinExceptionQueryExceptionRollupExceptionSetOperationExceptionbuilderformat_alias_sqlformat_quotesignore_copyzTimothy Heysztheys@kayak.comc                   @   s   e Zd ZdeddfddZededd fddZdedefd	d
Ze	de
fddZededefddZededefddZdefddZdS )
SelectablealiasreturnNc                 C   
   || _ d S Nr%   selfr%    r,   P/home/air/sanwanet/backup_V2/venv/lib/python3.10/site-packages/pypika/queries.py__init__&      
zSelectable.__init__c                 C   r'   r(   r)   r*   r,   r,   r-   as_)      
zSelectable.as_namec                 C      t || dS )Ntabler   r+   r2   r,   r,   r-   field-      zSelectable.fieldc                 C   s   t | S r(   )r   r+   r,   r,   r-   star0   s   zSelectable.starc                 C   
   |  |S r(   r8   r7   r,   r,   r-   __getattr__4   r1   zSelectable.__getattr__c                 C   r<   r(   r=   r7   r,   r,   r-   __getitem__8   r1   zSelectable.__getitem__c                 C   s   | j S r(   r)   r:   r,   r,   r-   get_table_name<   s   zSelectable.get_table_name)__name__
__module____qualname__strr.   r    r0   r   r8   propertyr   r;   r#   r>   r?   r@   r,   r,   r,   r-   r$   %   s    r$   c                       sb   e Zd Zddedee ddf fddZdedefdd	Zd
d de	fddZ
defddZ  ZS )AliasedQueryNr2   queryr&   c                    s   t  j|d || _|| _d S )Nr)   )superr.   r2   rG   )r+   r2   rG   	__class__r,   r-   r.   A      
zAliasedQuery.__init__kwargsc                 K   s"   | j d u r| jS | j jdi |S Nr,   )rG   r2   get_sqlr+   rL   r,   r,   r-   rN   F   s   
zAliasedQuery.get_sqlotherc                 C   s   t |to
| j|jkS r(   )
isinstancerF   r2   r+   rP   r,   r,   r-   __eq__K   s   zAliasedQuery.__eq__c                 C   s   t t| jS r(   )hashrD   r2   r:   r,   r,   r-   __hash__N      zAliasedQuery.__hash__r(   )rA   rB   rC   rD   r   r$   r.   r   rN   boolrS   intrU   __classcell__r,   r,   rI   r-   rF   @   s
     rF   c                   @   s~   e Zd Zddeded  ddfddZdd defdd	Zdd defd
dZe	deddfddZ
ddee dedefddZdS )SchemaNr2   parentr&   c                 C      || _ || _d S r(   )_name_parent)r+   r2   r[   r,   r,   r-   r.   S      
zSchema.__init__rP   c                 C   s"   t |to| j|jko| j|jkS r(   )rQ   rZ   r]   r^   rR   r,   r,   r-   rS   W   s   "zSchema.__eq__c                 C      |  | S r(   rS   rR   r,   r,   r-   __ne__Z   r9   zSchema.__ne__itemTablec                 C   r3   )Nschemard   r+   rc   r,   r,   r-   r>   ]      zSchema.__getattr__
quote_charrL   c                 K   s:   t | j|}| jd urdj| jjdd|i||dS |S )Nz{parent}.{schema}rj   )r[   rf   r,   )r"   r]   r^   formatrN   )r+   rj   rL   
schema_sqlr,   r,   r-   rN   a   s   
zSchema.get_sqlr(   )rA   rB   rC   rD   r   r.   rW   rS   rb   r#   r>   r   rN   r,   r,   r,   r-   rZ   R   s     rZ   c                   @   s"   e Zd ZededefddZdS )Databaserc   r&   c                 C   r3   N)r[   rZ   rh   r,   r,   r-   r>   o   ri   zDatabase.__getattr__N)rA   rB   rC   r#   rD   rZ   r>   r,   r,   r,   r-   rm   n   s    rm   c                       sl  e Zd Zedeeeeedf deeeeedf fddZ				d*dede
eeef  de
e de
ed	  ddf
 fd
dZdefddZdedefddZededd fddZededd fddZdefddZdefddZdefddZdedefddZdefd d!Zd"eeeeeeeef  dd#fd$d%Z d+d&d'Z!d"eeeeeeef dd#fd(d)Z"  Z#S ),rd   rf   Nr&   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   r3   rn   ro   )objsr,   r,   r-   <lambda>|   s    z$Table._init_schema.<locals>.<lambda>   r   )rQ   rZ   listtupler   re   r,   r,   r-   _init_schemau   s   
 zTable._init_schemar2   r%   	query_clsQueryc                    sL   t  | || _| || _|pt| _d | _d | _t	| jts$t
dd S )Nz,Expected 'query_cls' to be subclass of Query)rH   r.   _table_namerv   _schemarx   
_query_cls_for_for_portion
issubclass	TypeError)r+   r2   rf   r%   rw   rI   r,   r-   r.      s   
zTable.__init__c                 C   s   | j p| jS r(   )r%   ry   r:   r,   r,   r-   r@      r9   zTable.get_table_namerL   c                 K   s   | d}t| j|}| jd urdj| jjdi ||d}| jr0dj|| jjdi |d}n| jrAdj|| jjdi |d}t|| j	fi |S )Nrj   z{schema}.{table})rf   r5   z{table} FOR {criterion})r5   	criterionz"{table} FOR PORTION OF {criterion}r,   )
getr"   ry   rz   rk   rN   r|   r}   r!   r%   )r+   rL   rj   	table_sqlr,   r,   r-   rN      s   

zTable.get_sqltemporal_criterionc                 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}   )r+   r   r,   r,   r-   for_   
   
z
Table.for_period_criterionc                 C   r   )Nr   r   )r}   r   r|   )r+   r   r,   r,   r-   for_portion   r   zTable.for_portionc                 C      | j ddS N"rj   rN   r:   r,   r,   r-   __str__   r9   zTable.__str__c                 C   sB   t |tsdS | j|jkrdS | j|jkrdS | j|jkrdS dS NFT)rQ   rd   ry   rz   r%   rR   r,   r,   r-   rS      s   
zTable.__eq__c                 C   s"   | j rd| j| j S d| jS )NzTable('{}', schema='{}')zTable('{}'))rz   rk   ry   r:   r,   r,   r-   __repr__   s   zTable.__repr__rP   c                 C   r`   r(   ra   rR   r,   r,   r-   rb      r9   zTable.__ne__c                 C   s   t t| S r(   )rT   rD   r:   r,   r,   r-   rU      r9   zTable.__hash__terms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r+   r   r,   r,   r-   r         zTable.selectc                 C   s   | j | S )za
        Perform an UPDATE operation on the current table

        :return: QueryBuilder
        )r{   updater:   r,   r,   r-   r      s   zTable.updatec                 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   r,   r,   r-   r      r   zTable.insertNNNr&   r   )$rA   rB   rC   staticmethodr
   rD   rt   ru   rZ   rv   r   r	   r.   r@   r   rN   r    r   r   r   r   r   rW   rS   r   rb   rX   rU   r   floatr   r   r   r   r   rY   r,   r,   rI   r-   rd   t   s>    0
&
*rd   namesrL   r&   c                  O   sr   g }| D ]2}t |tr$t|dkr$t|d |d |d|dd}n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`.
       r   rs   rf   rw   )r2   r%   rf   rw   )r2   rf   rw   )rQ   ru   lenrd   r   append)r   rL   tablesr2   tr,   r,   r-   make_tables   s    r   c                   @   s|   e Zd ZdZ			ddedee dee deeee	f  ddf
dd	Z
d
edefddZd
edefddZdefddZdS )ColumnzRepresents a column.Ncolumn_namecolumn_typenullabledefaultr&   c                 C   s<   || _ || _|| _|d u st|tr|| _d S t|| _d S r(   )r2   typer   rQ   r   r   r   )r+   r   r   r   r   r,   r,   r-   r.     s   *zColumn.__init__rL   c                 K   s"   | d}djt| j|d}|S )Nrj   z{name})r2   )r   rk   r"   r2   )r+   rL   rj   
column_sqlr,   r,   r-   get_name_sql  s
   

zColumn.get_name_sqlc                 K   st   dj | jdi || jrd | jnd| jd ur"d | jrdndnd| jr4d d| jjdi | ndd}|S )	Nz{name}{type}{nullable}{default}z {} NULLzNOT NULLzDEFAULT )r2   r   r   r   r,   )rk   r   r   r   r   rN   )r+   rL   r   r,   r,   r-   rN   &  s    $zColumn.get_sqlc                 C   r   r   r   r:   r,   r,   r-   r   0  r9   zColumn.__str__r   )rA   rB   rC   __doc__rD   r   rW   r
   r   r   r.   r   rN   r   r,   r,   r,   r-   r     s&    
	
r   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   rs   r   r   )r   )rQ   ru   r   r   r   )r   columnsr2   columnr,   r,   r-   make_columns4  s   
r   c                   @   sH   e Zd Zdedeeef deeef ddfddZdedefd	d
ZdS )	PeriodForr2   start_column
end_columnr&   Nc                 C   s@   || _ t|tr
|nt|| _t|tr|| _d S t|| _d S r(   )r2   rQ   r   r   r   r+   r2   r   r   r,   r,   r-   r.   F  s   "zPeriodFor.__init__rL   c                 K   sB   | d}djt| j|| jjdi || jjdi |d}|S )Nrj   z9PERIOD FOR {name} ({start_column_name},{end_column_name}))r2   start_column_nameend_column_namer,   )r   rk   r"   r2   r   r   r   )r+   rL   rj   period_for_sqlr,   r,   r-   rN   K  s   

zPeriodFor.get_sql)	rA   rB   rC   rD   r
   r   r.   r   rN   r,   r,   r,   r-   r   E  s    *r   c                	   @   s  e Zd ZdZededdfddZedeee	f deddfdd	Z
edee	ef dd
fddZedeeef ddfddZedee	ef ddfddZede	ddfddZede	ddfddZedeee	f deddfddZedee	ef de	deddfddZedeeee	eef deddfdd Zedee	ef ddfd!d"Zed#e	defd$d%Zed&eee	e	f e	f dedee fd'd(Zd)S )*rx   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.
    rL   r&   r   c                 K   s   t di |S rM   )r   )clsrL   r,   r,   r-   _builderd  s   zQuery._builderr5   c                 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
        Nr,   )r   r   r   r5   rL   r,   r,   r-   r   h     zQuery.from_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   r5   r,   r,   r-   r   w     
zQuery.create_tabledatabase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 database: An instance of a Database object or a string database name.

        :return: DropQueryBuilder
        )r   drop_database)r   r   r,   r,   r-   r     r   zQuery.drop_databasec                 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   r,   r,   r-   r     r   zQuery.drop_tableuserc                 C   r   )z
        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 user: String user name.

        :return: DropQueryBuilder
        )r   	drop_user)r   r   r,   r,   r-   r     r   zQuery.drop_userviewc                 C   r   )z
        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 view: String view name.

        :return: DropQueryBuilder
        )r   	drop_view)r   r   r,   r,   r-   r     r   zQuery.drop_viewc                 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
        Nr,   )r   r   r   r,   r,   r-   r     r   z
Query.intor2   c                 K   s   | j di |||S rM   )r   with_)r   r5   r2   rL   r,   r,   r-   r     s   zQuery.with_r   c                 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
        Nr,   )r   r   )r   r   rL   r,   r,   r-   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
        Nr,   )r   r   r   r,   r,   r-   r     r   zQuery.update
table_namec                 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
        rw   rg   )r   r   rL   r,   r,   r-   rd     s   zQuery.Tabler   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
        rw   )r   )r   r   rL   r,   r,   r-   Tables  s   zQuery.TablesN)rA   rB   rC   r   classmethodr   r   r
   r$   rD   r   rd   r   rm   r   r   r   r   r   r   rX   r   rW   r   r   r   _TableClass
TypedTupler   r   r,   r,   r,   r-   rx   [  s8      $&0rx   c                       s  e Zd ZdZdefdddddedee dee f
 fd	d
Z	e
dededd fddZe
dedd fddZe
dedd fddZe
dedd fddZe
dedd fddZe
dedd fddZe
dedd fddZe
dedd fdd Zdedd fd!d"Zdedd fd#d$Zd5d%d&Zdefd'd(Zd6d*ed+ededefd,d-Zd7d.ee dedefd/d0Zdefd1d2Zdefd3d4Z  Z S )8_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%   wrapper_clsc                    s:   t  | || _||fg| _g | _d | _d | _|| _d S r(   )rH   r.   r   _set_operation	_orderbys_limit_offset_wrapper_cls)r+   r   r   r   r%   r   rI   r,   r-   r.     s   
z_SetOperation.__init__fieldsrL   r&   c                 O   sN   |D ]"}t |trt|| jjd dn| j|}| j||df qd S Nr   r4   order)	rQ   rD   r   r   _fromwrap_constantr   r   r   r+   r   rL   r8   r,   r,   r-   orderby   s   
z_SetOperation.orderbylimitc                 C   r'   r(   r   r+   r   r,   r,   r-   r   +  r1   z_SetOperation.limitoffsetc                 C   r'   r(   r   r+   r   r,   r,   r-   r   /  r1   z_SetOperation.offsetrP   c                 C      | j tj|f d S r(   )r   r   r   unionrR   r,   r,   r-   r   3     z_SetOperation.unionc                 C   r   r(   )r   r   r   	union_allrR   r,   r,   r-   r   7  r   z_SetOperation.union_allc                 C   r   r(   )r   r   r   	intersectrR   r,   r,   r-   r   ;  r   z_SetOperation.intersectc                 C   r   r(   )r   r   r   	except_ofrR   r,   r,   r-   r   ?  r   z_SetOperation.except_ofc                 C   r   r(   )r   r   r   minusrR   r,   r,   r-   r   C  r   z_SetOperation.minusc                 C   r<   r(   r   rR   r,   r,   r-   __add__G  r/   z_SetOperation.__add__c                 C   r<   r(   r   rR   r,   r,   r-   __mul__J  r/   z_SetOperation.__mul__c                 C   r<   r(   r   rR   r,   r,   r-   __sub__M  r/   z_SetOperation.__sub__c                 C      |   S r(   r   r:   r,   r,   r-   r   P     z_SetOperation.__str__F
with_aliassubqueryc           
      K   s"  d}| d| jj | d| jj | jjd
d| jji|}|}| jD ].\}}|jd
d| jji|}	t| jjt|jkrHt	dj
||	d||j
|j|	d7 }q$| jr`|| jd
i |7 }| jd urk||  7 }| jrt||  7 }|rdj
d
d	|i|}|rt|| jp| jfi |S |S )Nz {type} {query_string}dialectrj   r   zQueries 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})rG   r,   )
setdefaultr   r   
QUOTE_CHARrN   wrap_set_operation_queriesr   r   _selectsr   rk   valuer   _orderby_sqlr   
_limit_sqlr   _offset_sqlr!   r%   ry   )
r+   r   r   rL   set_operation_templatebase_querystringquerystringr   r   set_operation_querystringr,   r,   r-   rN   S  s@   

z_SetOperation.get_sqlrj   c                 K   s   g }dd | j jD }| jD ]-\}}|jr |j|v r t|j|n	|jd
d|i|}||dur8d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 r,   r)   .0rq   r,   r,   r-   	<setcomp>      z-_SetOperation._orderby_sql.<locals>.<setcomp>rj   N{term} {orient}termorient ORDER BY {orderby},r   r,   )
r   r  r   r%   r"   rN   r   rk   r  join)r+   rj   rL   clausesselected_aliasesr8   directionalityr  r,   r,   r-   r	    s   	
z_SetOperation._orderby_sqlc                 C      dj | jdS Nz OFFSET {offset})r   rk   r   r:   r,   r,   r-   r    rV   z_SetOperation._offset_sqlc                 C   r   Nz LIMIT {limit})r   rk   r   r:   r,   r,   r-   r
    rV   z_SetOperation._limit_sql)rP   r   r&   r   FFr(   )!rA   rB   rC   r   r   r   r   rD   r	   r.   r    r   r   r   rX   r   r   r$   r   r   r   r   r   r   r   r   r   rW   rN   r	  r  r
  rY   r,   r,   rI   r-   r     sN    

-r   c                       sF  e Zd ZdZdZdZdZdZeZ	dde
ddfdee ded	ee
 d
edef
 fddZdddZedeeeef dd fddZedee dee dd fddZedededd fddZedeeef dd fddZededd fdd Zedd!d"Zedeeef dd fd#d$Zededd fd%d&Zededd fd'd(Zededd fd)d*Z ed+eee!f deee!f dd fd,d-Z"ed+eee!f deee!f dd fd.d/Z#edd0d1Z$edd2d3Z%edd4d5Z&ed6e'dd fd7d8Z(ed6ee)e*f dd fd9d:Z+ed6ee)e*f dd fd;d<Z,edeee-e)f dd fd=d>Z.edd?d@Z/edee0e1e2e)f dAedd fdBdCZ3edDedAedd fdEdFZ4ee5j6fdGeed e7ef dHe5ddIfdJdKZ8dGeed e7f ddIfdLdMZ9dGeed e7f ddIfdNdOZ:dGeed e7f ddIfdPdQZ;dGeed e7f ddIfdRdSZ<dGeed e7f ddIfdTdUZ=dGeed e7f ddIfdVdWZ>dGeed e7f ddIfdXdYZ?dGeed e7f ddIfdZd[Z@dGeed e7f ddIfd\d]ZAed^e-dd fd_d`ZBedae-dd fdbdcZCeddd deDfdedfZEeddd deDfdgdhZFeddd deDfdidjZGeddd deDfdkdlZHeddd deDfdmdnZIedoeeJef dpedd fdqdrZ2ddd deDfdsdtZKddd deDfdudvZLddd deDfdwdxZMedyeNdd fdzd{ZNdGeded eJf f fd|d}ZOePdd~eQeJ dee deRe fddZSd+eddfddZTd+eJddfddZUdeVddfddZWdeReJ fddZXdddZYdedefddZZd+e)defddZ[dddZ\deddfddZ]defddZ^defddZ_ddd defddZ`ddd defddZade-fddZbdAecddfddZdddededAedefddZededefddZfdAedefddZgdAedefddZhdefddZidAedefddZjdAedefddZkdAedefddZlePdAedefddZmdAedefddZnddedAedefddZodAedefddZpdAedefddZqddedAedefddZrddedAedefddĄZsdAedefddƄZtdAedefddȄZuddee dAedefddʄZvddee dAedefdd̄Zw			ddee dee dedAedef
ddЄZx			ddee dee dedAedef
ddӄZydefddՄZzddee dAedefddׄZ{defddلZ|defddۄZ}dAedefdd݄Z~  ZS )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.
    r   'NTFr   r  r   	immutable
as_keywordc                    s   t  d  g | _d | _d | _d| _d| _g | _g | _g | _	g | _
g | _g | _d| _d| _d| _d | _d | _g | _d| _d | _g | _g | _g | _g | _d | _d | _g | _d| _t | _d| _d| _ d| _!d| _"|| _#|| _$|| _%|| _&|| _'d S )NFr   )(rH   r.   r   _insert_table_update_table_delete_from_replace_withr  _force_indexes_use_indexes_columns_values	_distinct_ignore_for_update_wheres
_prewheres	_groupbys_with_totals_havingsr   _joins_unions_usingr   r   _updates_select_starset_select_star_tables_mysql_rollup_select_into_subquery_count_foreign_tabler   r(  r  r   r'  )r+   r   r  r   r'  r(  rI   r,   r-   r.     sL   
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 r(   )r   __new____dict__r   r   r@  r   r-  r  r0  r1  r7  r   r:  r;  r=  r.  r/  )r+   newoner,   r,   r-   __copy__  s    zQueryBuilder.__copy__
selectablec                 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%drs   )
r   r   rQ   rD   rd   r   r   r%   rC  max)r+   rI  sub_query_countr,   r,   r-   r     s   

zQueryBuilder.from_current_table	new_tablec                    sd   fdd| j D | _ | j krn| j| _| j krn| j| _ fdd| jD | _ fdd| jD | _ fdd| jD | _ fdd| jD | _| jr\| j nd| _| j	ri| 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 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 r,   r,   )r  r5   rM  rN  r,   r-   
<listcomp>      z.QueryBuilder.replace_table.<locals>.<listcomp>c                       g | ]}|  qS r,   replace_table)r  alias_queryrO  r,   r-   rP  #      c                    rR  r,   rS  r  r   rO  r,   r-   rP  $  rV  c                    rR  r,   rS  r  r   rO  r,   r-   rP  %  rV  c                    s    g | ]} fd d|D qS )c                    rR  r,   rS  r  r  rO  r,   r-   rP  '  rV  z9QueryBuilder.replace_table.<locals>.<listcomp>.<listcomp>r,   )r  
value_listrO  r,   r-   rP  &  s    Nc                    rR  r,   rS  )r  groupbyrO  r,   r-   rP  ,  rV  c                    s$   g | ]}|d    |d fqS )r   rs   rS  )r  r   rO  r,   r-   rP  .  s    c                    rR  r,   rS  r  r  rO  r,   r-   rP  1  rV  )r   r)  r*  r-  r  r0  r1  r5  rT  r6  r7  r9  r   r:  r@  removeaddr+   rM  rN  r,   rO  r-   rT    s*   
zQueryBuilder.replace_tabler2   c                 C   s   t ||}| j| d S r(   )rF   r-  r   )r+   rI  r2   r   r,   r,   r-   r   7  s   
zQueryBuilder.with_r5   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)r)  r   r  rB  rQ   rd   r+   r5   r,   r,   r-   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   )
rQ   r   _select_fieldrD   _select_field_strr   r   _select_otherr   r   r+   r   r  r,   r,   r-   r   F  s   

zQueryBuilder.selectc                 C   s(   | j s	| js	| jrtdd d| _ d S )Nr`  deleteT)r+  r  r*  r   r:   r,   r,   r-   rg  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   )r*  r  r+  r   rQ   rd   ra  r,   r,   r-   r   Y  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   r4   )	r)  r   rQ   rt   ru   rD   r   r0  r   rf  r,   r,   r-   r   `  s   

zQueryBuilder.columnsc                 G      | j |  d| _d S NF_apply_termsr,  r   r,   r,   r-   r   m     

zQueryBuilder.insertc                 G   rh  NTrj  r   r,   r,   r-   replacer  rl  zQueryBuilder.replacer  c                 G   H   |g|R D ]}t |tr| j| qt |tr!| jt| qd S r(   )rQ   r   r.  r   rD   r+   r  r   r   r,   r,   r-   force_indexw     

zQueryBuilder.force_indexc                 G   ro  r(   )rQ   r   r/  r   rD   rp  r,   r,   r-   	use_index  rr  zQueryBuilder.use_indexc                 C   
   d| _ d S rm  r2  r:   r,   r,   r-   distinct  r1   zQueryBuilder.distinctc                 C   rt  rm  r4  r:   r,   r,   r-   
for_update  r1   zQueryBuilder.for_updatec                 C   rt  rm  )r3  r:   r,   r,   r-   ignore  r1   zQueryBuilder.ignorer   c                 C   s2   |  |sd| _| jr|  j|M  _d S || _d S rm  )_validate_tablerD  r6  r+   r   r,   r,   r-   prewhere  s
   

zQueryBuilder.prewherec                 C   s@   t |trd S | |sd| _| jr|  j|M  _d S || _d S rm  )rQ   r   rz  rD  r5  r{  r,   r,   r-   where  s   


zQueryBuilder.wherec                 C   s0   t |trd S | jr|  j|M  _d S || _d S r(   )rQ   r   r9  r{  r,   r,   r-   having  s
   

zQueryBuilder.havingc                 G   s^   |D ]*}t |trt|| jd d}nt |tr&tt|| jd d|}| j| qd S )Nr   r4   )rQ   rD   r   r   rX   r   r7  r   rf  r,   r,   r-   r[    s   

zQueryBuilder.groupbyc                 C   rt  rm  )r8  r:   r,   r,   r-   with_totals  r1   zQueryBuilder.with_totalsrL   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 r,   )rQ   rt   ru   r?  r   r  r  r,   r,   r-   rP    s   ( z'QueryBuilder.rollup.<locals>.<listcomp>zWAt least one group is required. Call Query.groupby(term) or passas parameter to rollup.Tr   )
r   rA  r   r7  r   r   rQ   r   argsr   )r+   r   rL   	for_mysqlr,   r,   r-   r    s   
zQueryBuilder.rollupr   c                 O   sJ   |D ] }t |trt|| jd dn| |}| j||df qd S r   )rQ   rD   r   r   r   r   r   r   r   r,   r,   r-   r     s   &zQueryBuilder.orderbyrc   how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	| )Nr5   )
type_labelr   zCannot join on type '%s')
rQ   rd   r  r   r%   _tag_subqueryrF   r$   
ValueErrorr   r+   rc   r  r,   r,   r-   r    s   





zQueryBuilder.joinc                 C      |  |tjS r(   )r  r   innerrh   r,   r,   r-   
inner_join  rV   zQueryBuilder.inner_joinc                 C   r  r(   )r  r   leftrh   r,   r,   r-   	left_join  rV   zQueryBuilder.left_joinc                 C   r  r(   )r  r   
left_outerrh   r,   r,   r-   left_outer_join  rV   zQueryBuilder.left_outer_joinc                 C   r  r(   )r  r   rightrh   r,   r,   r-   
right_join   rV   zQueryBuilder.right_joinc                 C   r  r(   )r  r   right_outerrh   r,   r,   r-   right_outer_join  rV   zQueryBuilder.right_outer_joinc                 C   r  r(   )r  r   outerrh   r,   r,   r-   
outer_join  rV   zQueryBuilder.outer_joinc                 C   r  r(   )r  r   
full_outerrh   r,   r,   r-   full_outer_join	  rV   zQueryBuilder.full_outer_joinc                 C   r  r(   )r  r   crossrh   r,   r,   r-   
cross_join  rV   zQueryBuilder.cross_joinc                 C   r  r(   )r  r   rT   rh   r,   r,   r-   	hash_join  rV   zQueryBuilder.hash_joinr   c                 C   r'   r(   r   r   r,   r,   r-   r     r1   zQueryBuilder.limitr   c                 C   r'   r(   r   r   r,   r,   r-   r     r1   zQueryBuilder.offsetrP   c                 C      t | |tj| jdS rb  )r   r   r   r   rR   r,   r,   r-   r        zQueryBuilder.unionc                 C   r  rb  )r   r   r   r   rR   r,   r,   r-   r     r  zQueryBuilder.union_allc                 C   r  rb  )r   r   r   r   rR   r,   r,   r-   r   "  r  zQueryBuilder.intersectc                 C   r  rb  )r   r   r   r   rR   r,   r,   r-   r   &  r  zQueryBuilder.except_ofc                 C   r  rb  )r   r   r   r   rR   r,   r,   r-   r   *  r  zQueryBuilder.minusr8   r  c                 C   s0   t |ts	t|n|}| j|| |f d S r(   )rQ   r   r=  r   r   )r+   r8   r  r,   r,   r-   r?  .  s   zQueryBuilder.setc                 C   r<   r(   r   rR   r,   r,   r-   r   3  r/   zQueryBuilder.__add__c                 C   r<   r(   r   rR   r,   r,   r-   r   6  r/   zQueryBuilder.__mul__c                 C   r<   r(   r   rR   r,   r,   r-   r   9  r/   zQueryBuilder.__sub__slicec                 C   s   |j | _|j| _d S r(   )startr   stopr   )r+   r  r,   r,   r-   r  <  s   zQueryBuilder.slicec                    s    t |tst |S | |S r(   )rQ   r  rH   r?   rh   rI   r,   r-   r?   A  s   

zQueryBuilder.__getitem__	field_setrj   c                    s    fdd| D S )Nc                    s   g | ]}|j p|j d qS )r   )r%   rN   r  r8   r   r,   r-   rP  H  s    z.QueryBuilder._list_aliases.<locals>.<listcomp>r,   )r  rj   r,   r   r-   _list_aliasesF  s   zQueryBuilder._list_aliasesc                 C   sV   dt | jkrtdj|d|dkrd| _t g| _d S | t|| jd d d S )Nr   z.Cannot select {term}, no FROM table specified.r  *Tr4   )	r   r   r   rk   r>  r   r  rc  r   r+   r  r,   r,   r-   rd  J  s   
zQueryBuilder._select_field_strc                    sX   | j rd S  j| jv rd S t tr$ fdd| jD | _| j j | j  d S )Nc                    s&   g | ]}t |d r j|jkr|qS r4   )hasattrr5   rW  r  r,   r-   rP  _  s    
z.QueryBuilder._select_field.<locals>.<listcomp>)r>  r5   r@  rQ   r   r  r^  r   r  r,   r  r-   rc  U  s   

zQueryBuilder._select_fieldfunctionc                 C   s   | j | d S r(   )r  r   )r+   r  r,   r,   r-   re  f  s   zQueryBuilder._select_otherc                 C   s   g S r(   r,   r:   r,   r,   r-   fields_i     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 r(   )rQ   rd   rc   r  clausebase_tablesr  r,   r-   	<genexpr>q     " z'QueryBuilder.do_join.<locals>.<genexpr>2)r   r*  r-  validater:  anyrQ   rc   rd   r%   ry   r   )r+   r  table_in_queryr,   r  r-   do_joinm  s   zQueryBuilder.do_joinc                    s   t  fdd| jD S )Nc                 3   s    | ]} |j kV  qd S r(   rc   r\  r4   r,   r-   r  z  s    z)QueryBuilder.is_joined.<locals>.<genexpr>)r  r:  ra  r,   r4   r-   	is_joinedy  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 r,   r  r\  r,   r,   r-   rP    r  z0QueryBuilder._validate_table.<locals>.<listcomp>NFT)r   r*  r  r5   r:  all)r+   r  r  r8   table_in_base_tablestable_in_joinsr,   r,   r-   rz  |  s   

	zQueryBuilder._validate_tabler   c                 C   s   d| j  |_|  j d7  _ d S )NrJ  rs   )rC  r%   )r+   r   r,   r,   r-   r    s   zQueryBuilder._tag_subqueryc                    s`    j du rtdd |sdS 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`
        Nr`  r   r   c                    s$   g | ]}t |tr|n |qS r,   )rQ   r   r   rY  r:   r,   r-   rP    s   $ z-QueryBuilder._apply_terms.<locals>.<listcomp>)r)  r   rQ   rt   ru   r?  r1  r   )r+   r   valuesr,   r:   r-   rk    s   
zQueryBuilder._apply_termsc                 C   s   | j | jdS )N)r   )rN   r   r:   r,   r,   r-   r     rV   zQueryBuilder.__str__c                 C   r   r(   r   r:   r,   r,   r-   r     r   zQueryBuilder.__repr__c                 C   s"   t |tsdS | j|jksdS dS r   )rQ   r   r%   rR   r,   r,   r-   rS     s
   
zQueryBuilder.__eq__c                 C   r`   r(   ra   rR   r,   r,   r-   rb     r9   zQueryBuilder.__ne__c                 C   s   t | jtdd | jD  S )Nc                 s   s    | ]}t |V  qd S r(   )rT   r  r,   r,   r-   r    s    z(QueryBuilder.__hash__.<locals>.<genexpr>)rT   r%   sumr   r:   r,   r,   r-   rU        zQueryBuilder.__hash__c                 C   sJ   | d| j | d| j | d| j | d| j | d| j d S )Nrj   secondary_quote_charalias_quote_charr(  r   )r  r  SECONDARY_QUOTE_CHARALIAS_QUOTE_CHARr(  r   rO   r,   r,   r-   _set_kwargs_defaults  s
   z!QueryBuilder._set_kwargs_defaultsr   c           
         s,  |    | 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 o@t| j
d t}| j}| joI| j
}t|||||g d< | jr| jrd| jdi  }	nd}	|	| jdi  7 }	| jr|	dd fdd| jD  7 }	|	| jdi  7 }	| j
r|	| jdi  7 }	| jr|	| jdi  7 }	| jd ur|	|  7 }	|	S | jr| jdi  }	n| js| jr| jr| jdi  }	nd}	| jr|	| jdi  7 }	n
|	| jdi  7 }	| jr|	| jdi  7 }	| jr|	| j di  7 }	|	S |	d| j!di   7 }	n'| jr&| jdi  }	nd}	|	| j!di  7 }	| jr@|	| j"di  7 }	| j
rN|	| jdi  7 }	| j#r\|	| j$di  7 }	| j%rj|	| j&di  7 }	| j'rx|	| j(di  7 }	| jr|	dd fdd| jD  7 }	| j)r|	| j*di  7 }	| jr|	| jdi  7 }	| j+r|	| j,di  7 }	| j-r|	| . 7 }	| j/r|	| j0di  7 }	| j1r|	| j2di  7 }	| 3|	}	| j4r|	| j5di  7 }	|rd	j6|	d
}	|r| j7d u r| j8n| j7 d< t9|	| j:fi  S |	S )Nr   rs   r   with_namespace c                 3        | ]}|j di  V  qd S rM   r   r\  rL   r,   r-   r        z'QueryBuilder.get_sql.<locals>.<genexpr>c                 3   r  rM   r   r\  r  r,   r-   r  "  r  r  rG   r  r,   );r  r  r)  r+  r*  r1  r=  rW   r:  r   r   rQ   r   rD  r  r-  	_with_sql_update_sqlr  _set_sql	_from_sqlr5  
_where_sqlr   r
  _delete_sqlrB  r,  _replace_sql_insert_sqlr0  _columns_sql_values_sql_select_sql	_into_sqlr<  
_using_sqlr.  _force_index_sqlr/  _use_index_sqlr6  _prewhere_sqlr7  
_group_sqlrA  _rollup_sqlr9  _having_sqlr   r	  _apply_paginationr4  _for_update_sqlrk   QUERY_ALIAS_QUOTE_CHARr  r!   r%   )
r+   r   r   rL   	has_joinshas_multiple_from_clauseshas_subquery_from_clausehas_reference_to_foreign_tablehas_update_fromr  r,   r  r-   rN     s   


"
"
zQueryBuilder.get_sqlr  c                 C   s,   | j d ur||  7 }| jr||  7 }|S r(   )r   r
  r   r  )r+   r  r,   r,   r-   r  E  s
   
zQueryBuilder._apply_paginationc                    s   dd  fdd| jD  S )NzWITH r  c                 3   s4    | ]}|j d  |jdddd  d V  qdS )z AS (Fr   r   z) Nr,   )r2   rN   r  r  r,   r-   r  O  s
    "
z)QueryBuilder._with_sql.<locals>.<genexpr>)r  r-  rO   r,   r  r-   r  N  s   
zQueryBuilder._with_sqlc                 K      | j rd}|S d}|S )Nz	DISTINCT r   ru  )r+   rL   rv  r,   r,   r-   _distinct_sqlT  
   zQueryBuilder._distinct_sqlc                 K   r  )Nz FOR UPDATEr   rw  )r+   rL   rx  r,   r,   r-   r  \  r  zQueryBuilder._for_update_sqlc                    s0   dj | jdi  d fdd| jD dS )NzSELECT {distinct}{select}r  c                 3   &    | ]}|j dd d d V  qdS T)r   r   Nr,   r   r  r  r,   r-   r  g     $ z+QueryBuilder._select_sql.<locals>.<genexpr>)rv  r   r,   )rk   r  r  r  rO   r,   r  r-   r  d  s   zQueryBuilder._select_sqlc                 K   s*   dj | jjdi || jrddS ddS )NzINSERT {ignore}INTO {table}zIGNORE r   )r5   ry  r,   )rk   r)  rN   r3  rO   r,   r,   r-   r  j  s   zQueryBuilder._insert_sqlc                 K      dj | jjdi |dS )NzREPLACE INTO {table}r4   r,   rk   r)  rN   rO   r,   r,   r-   r  p     zQueryBuilder._replace_sqlc                  K      dS )NDELETEr,   r  r,   r,   r-   r  u  r  zQueryBuilder._delete_sqlc                 K   r  )NzUPDATE {table}r4   r,   )rk   r*  rN   rO   r,   r,   r-   r  y  s   zQueryBuilder._update_sqlr  c                    "   dj d fdd| jD dS )z
        SQL for Columns clause for INSERT queries
        :param with_namespace:
            Remove from kwargs, never format the column terms with namespaces since only one table can be inserted into
        z ({columns})r  c                 3   s$    | ]}|j dd di V  qdS )r  FNr,   r   r  r  r,   r-   r    r  z,QueryBuilder._columns_sql.<locals>.<genexpr>r   )rk   r  r0  r+   r  rL   r,   r  r-   r  |  s   zQueryBuilder._columns_sqlc                    r  )Nz VALUES ({values})z),(c                 3   s(    | ]}d   fdd|D V  qdS )r  c                 3   r  r  r   r  r  r,   r-   r    r  z5QueryBuilder._values_sql.<locals>.<genexpr>.<genexpr>N)r  )r  rowr  r,   r-   r    s    
z+QueryBuilder._values_sql.<locals>.<genexpr>)r  )rk   r  r1  rO   r,   r  r-   r    s
   zQueryBuilder._values_sqlc                 K   s   dj | jjdddi|dS )Nz INTO {table}r   Fr4   r,   r  rO   r,   r,   r-   r    s   zQueryBuilder._into_sqlc                    r  )Nz FROM {selectable}r  c                 3   r  Tr  Nr,   r   r  r  r,   r-   r    r  z)QueryBuilder._from_sql.<locals>.<genexpr>rI  )rk   r  r   r  r,   r  r-   r       zQueryBuilder._from_sqlc                    r  )Nz USING {selectable}r  c                 3   r  r  r   r  r  r,   r-   r    r  z*QueryBuilder._using_sql.<locals>.<genexpr>r  )rk   r  r<  r  r,   r  r-   r    r  zQueryBuilder._using_sqlc                    r  )Nz FORCE INDEX ({indexes})r  c                 3   r  rM   r   r  indexr  r,   r-   r    r  z0QueryBuilder._force_index_sql.<locals>.<genexpr>indexes)rk   r  r.  rO   r,   r  r-   r    r  zQueryBuilder._force_index_sqlc                    r  )Nz USE INDEX ({indexes})r  c                 3   r  rM   r   r  r  r,   r-   r    r  z.QueryBuilder._use_index_sql.<locals>.<genexpr>r  )rk   r  r/  rO   r,   r  r-   r    r  zQueryBuilder._use_index_sqlc                 K       dj | jjd|dd|dS )Nz PREWHERE {prewhere}Trj   r   )r|  r,   )rk   r6  rN   r+   rj   rL   r,   r,   r-   r    s   zQueryBuilder._prewhere_sqlc                 K   r  )Nz WHERE {where}Tr  )r}  r,   )rk   r5  rN   r  r,   r,   r-   r    s    zQueryBuilder._where_sqlr  groupby_aliasc           	      K   s   g }dd | j D }| jD ]&}|r%|jr%|j|v r%|t|j|p!| q||jd	||d| qdjd|d}| jrD|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   r  r,   r)   r  r,   r,   r-   r    r  z*QueryBuilder._group_sql.<locals>.<setcomp>rj   r  z GROUP BY {groupby}r  )r[  z WITH TOTALSNr,   )	r  r7  r%   r   r"   rN   rk   r  r8  )	r+   rj   r  r  rL   r  r  r8   sqlr,   r,   r-   r    s   
zQueryBuilder._group_sqlorderby_aliasc           
      K   s   g }dd | j D }| jD ]2\}}|r#|jr#|j|v r#t|j|p!|n
|jd
||d|}	||dur<d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   r  r,   r)   r  r,   r,   r-   r    r  z,QueryBuilder._orderby_sql.<locals>.<setcomp>r  Nr  r  r  r  r  r,   )	r  r   r%   r"   rN   r   rk   r  r  )
r+   rj   r  r  rL   r  r  r8   r  r  r,   r,   r-   r	    s   
zQueryBuilder._orderby_sqlc                 C   r  )Nz WITH ROLLUPr,   r:   r,   r,   r-   r       zQueryBuilder._rollup_sqlc                 K   s   dj | jjdd|i|dS )Nz HAVING {having}rj   )r~  r,   )rk   r9  rN   r  r,   r,   r-   r    r  zQueryBuilder._having_sqlc                 C   r   r!  r"  r:   r,   r,   r-   r    rV   zQueryBuilder._offset_sqlc                 C   r   r#  r$  r:   r,   r,   r-   r
    rV   zQueryBuilder._limit_sqlc                    r  )Nz
 SET {set}r  c              	   3   sB    | ]\}}d j |jdi t dd|jdi  dV  qdS )z{field}={value}F)r  )r8   r  Nr,   )rk   rN   dict)r  r8   r  r  r,   r-   r    s    $
z(QueryBuilder._set_sql.<locals>.<genexpr>)r?  )rk   r  r=  rO   r,   r  r-   r    s
   zQueryBuilder._set_sqlr   r(   )r  r  r&   N)r   r   r&   Nr%  )F)NNT)rA   rB   rC   r   r  r  r  r  rx   	QUERY_CLSr   r   r   rW   r	   r.   rH  r    r
   r$   rD   r   rd   rT  r   r   r   r   rg  r   r   r   rn  r   rq  rs  rv  rx  ry  r   r|  r   r   r}  r~  rX   r[  r  rt   ru   r?  r  r   r   r  rF   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  rd  rc  r   re  r  r  r  rz  r  rk  r   r   rS   rb   rU   r	  r  rN   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,   rI   r-   r     sf   
: $	((			$ &

	 	

!
 r   c                
   @   s   e Zd Zdedeedef dededdf
dd	Z	dd
e
e de
e defddZdedefddZdedefddZdefddZdS )r  rG   rc   r   r  r  r&   Nc                 C   s   || _ || _|| _|| _d S r(   )rG   rc   r  r  )r+   rG   rc   r  r  r,   r,   r-   r.     s   
zJoiner.__init__r   collatec                 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   rk   r  rG   r  JoinOnrc   r  )r+   r   r  r,   r,   r-   on  s   z	Joiner.onr   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.r  r   r4   )
r   rk   r  r   rG   r   rc   r  r  r  )r+   r   r   r8   
consituentr,   r,   r-   on_field  s   "zJoiner.on_fieldc                 G   s4   |st d| jt| j| jdd |D  | jS )NzUParameter 'fields' is required when joining with a using clause but was not supplied.c                 S   s   g | ]}t |qS r,   r6   r  r,   r,   r-   rP  )  s    z Joiner.using.<locals>.<listcomp>)r   rG   r  	JoinUsingrc   r  )r+   r   r,   r,   r-   using%  s   "zJoiner.usingc                 C   s   | j t| jtj | j S )zReturn cross join)rG   r  r  rc   r   r  r:   r,   r,   r-   r  ,  s   zJoiner.crossr(   )rA   rB   rC   r   r
   rd   rF   r   rD   r.   r   r   r  r   r  r  r  r,   r,   r,   r-   r    s     
 
r  c                   @   st   e Zd ZdededdfddZdedefdd	Zd
e	e
 de	e
 ddfddZedee
 dee
 dd fddZdS )r  rc   r  r&   Nc                 C   r\   r(   )rc   r  r  r,   r,   r-   r.   4  r_   zJoin.__init__rL   c                 K   s>   dj | jjdddd|d}| jjrdj || jjdS |S )NzJOIN {table}Tr  r4   z{type} {join})r  r   r,   )rk   rc   rN   r  r  )r+   rL   r  r,   r,   r-   rN   8  s   zJoin.get_sqlr   r:  c                 C      d S r(   r,   r+   r   r:  r,   r,   r-   r  A  r  zJoin.validaterM  rN  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)rc   rT  r_  r,   r,   r-   rT  D  s   zJoin.replace_table)rA   rB   rC   r   r   r.   r   rD   rN   r   rd   r  r    r   rT  r,   r,   r,   r-   r  3  s    	$r  c                       s   e Zd Zddedededee ddf
 fddZd	e	def fd
dZ
dee dee ddfddZedee dee dd fddZ  ZS )r  Nrc   r  criteriar  r&   c                    s   t  || || _|| _d S r(   )rH   r.   r   r  )r+   rc   r  r  r  rI   r,   r-   r.   U  rK   zJoinOn.__init__rL   c                    sJ   t  jdi |}dj|| jjdddi|| jr!d| jdS ddS )Nz{join} ON {criterion}{collate}r   Tz COLLATE {}r   )r  r   r  r,   )rH   rN   rk   r   r  r+   rL   join_sqlrI   r,   r-   rN   Z  s   zJoinOn.get_sqlr   r:  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  r,   r4   )r  fr,   r,   r-   rP  c  r  z#JoinOn.validate.<locals>.<listcomp>c                 S   r  r,   r  r\  r,   r,   r-   r  d  r  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}]z, )r   )	r?  r   r  rc   r   rk   r  maprD   )r+   r   r:  criterion_tablesavailable_tablesmissing_tablesr,   r,   r-   r  b  s   zJoinOn.validaterM  rN  c                 C   s*   | j |kr|n| j | _ | j||| _dS r  )rc   r   rT  r_  r,   r,   r-   rT  n  s   zJoinOn.replace_tabler(   )rA   rB   rC   r   r   r   r   rD   r.   r   rN   r   rd   r  r    rT  rY   r,   r,   rI   r-   r  T  s    ((r  c                       s   e Zd Zdededee ddf fddZdede	f fd	d
Z
dee dee ddfddZedee dee dd fddZ  ZS )r  rc   r  r   r&   Nc                    s   t  || || _d S r(   )rH   r.   r   )r+   rc   r  r   rI   r,   r-   r.     s   
zJoinUsing.__init__rL   c                    s6   t  jdi  }dj|d fdd| jD dS )Nz{join} USING ({fields})r  c                 3   r  rM   r   r  r  r,   r-   r    r  z$JoinUsing.get_sql.<locals>.<genexpr>)r  r   r,   )rH   rN   rk   r  r   r  rI   r  r-   rN     s
   zJoinUsing.get_sqlr   r:  c                 C   r  r(   r,   r  r,   r,   r-   r    r  zJoinUsing.validaterM  rN  c                    s2   | j  krn| j | _  fdd| jD | _dS )r  c                    rR  r,   rS  r  rO  r,   r-   rP    rV  z+JoinUsing.replace_table.<locals>.<listcomp>N)rc   r   r_  r,   rO  r-   rT    s   zJoinUsing.replace_table)rA   rB   rC   r   r   r   r   r.   r   rD   rN   rd   r  r    r   rT  rY   r,   r,   rI   r-   r    s    "(r  c                   @   sr  e Zd ZdZdZdZdZeZdEde	e
 ddfddZd	eddfd
dZedeeef dd fddZedFddZedFddZedFddZedeeeeef ef dd fddZedeeef deeef dd fddZedeeef dd fddZedeeef dd fddZe		dGdeeeef  d eeef d!eeeef  d"ed#edd fd$d%Zed&edd fd'd(Z edFd)d*Z!d	e"defd+d,Z#d	e"defd-d.Z$defd/d0Z%dee fd1d2Z&dee fd3d4Z'dee fd5d6Z(defd7d8Z)defd9d:Z*defd;d<Z+d	e"defd=d>Z,deeeef  dee fd?d@Z-defdAdBZ.defdCdDZ/dS )Hr   z5
    Query builder used to build CREATE queries.
    r   r&  Nr   r&   c                 C   sd   d | _ d| _d| _d | _g | _g | _d| _d | _g | _d| _	|| _
d | _d | _d | _d | _d | _d S ri  )_create_table
_temporary	_unlogged
_as_selectr0  _period_fors_with_system_versioning_primary_key_uniques_if_not_existsr   _foreign_key_foreign_key_reference_table_foreign_key_reference_foreign_key_on_update_foreign_key_on_deleter+   r   r,   r,   r-   r.     s    
zCreateQueryBuilder.__init__rL   c                 C   .   | d| j | d| j | d| j d S Nrj   r  r   r  r  r  r   rO   r,   r,   r-   r       z'CreateQueryBuilder._set_kwargs_defaultsr5   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   rQ   rd   ra  r,   r,   r-   r     s   "zCreateQueryBuilder.create_tablec                 C   
   d| _ dS )z^
        Makes the table temporary.

        :return:
            CreateQueryBuilder.
        TN)r   r:   r,   r,   r-   	temporary     
zCreateQueryBuilder.temporaryc                 C   r2  )z]
        Makes the table unlogged.

        :return:
            CreateQueryBuilder.
        TN)r!  r:   r,   r,   r-   unlogged  r4  zCreateQueryBuilder.unloggedc                 C   r2  )z[
        Adds system versioning.

        :return:
            CreateQueryBuilder.
        TNr$  r:   r,   r,   r-   with_system_versioning  r4  z)CreateQueryBuilder.with_system_versioningr   c                 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:  Union[str, TypedTuple[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   rs   r   N)r"  r   rQ   rD   r   ru   r0  r   )r+   r   r   r,   r,   r-   r     s   


zCreateQueryBuilder.columnsr   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   r,   r,   r-   
period_for  s   zCreateQueryBuilder.period_forc                 G   s   | j | | dS )z
        Adds a UNIQUE constraint.

        :param columns:
            Type:  Union[str, Column]

            A list of columns.

        :return:
            CreateQueryBuilder.
        N)r&  r   _prepare_columns_inputr+   r   r,   r,   r-   unique   r   zCreateQueryBuilder.uniquec                 G   s   | j rtd| || _ dS )a  
        Adds a primary key constraint.

        :param columns:
            Type:  Union[str, Column]

            A list of columns.

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

        :return:
            CreateQueryBuilder.
        z0'Query' object already has attribute primary_keyN)r%  r   r9  r:  r,   r,   r-   primary_key/  s   zCreateQueryBuilder.primary_keyreference_tablereference_columns	on_delete	on_updatec                 C   s<   | j rtd| || _ || _| || _|| _|| _dS )a  
        Adds a foreign key constraint.

        :param columns:
            Type:  List[Union[str, Column]]

            A list of foreign key columns.

        :param reference_table:
            Type: Union[str, Table]

            The parent table name.

        :param reference_columns:
            Type: List[Union[str, Column]]

            Parent key columns.

        :param on_delete:
            Type: ReferenceOption

            Delete action.

        :param on_update:
            Type: ReferenceOption

            Update option.

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

        :return:
            CreateQueryBuilder.
        z0'Query' object already has attribute foreign_keyN)r(  r   r9  r)  r*  r,  r+  )r+   r   r=  r>  r?  r@  r,   r,   r-   foreign_keyC  s   +
zCreateQueryBuilder.foreign_keyquery_builderc                 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)r0  r   rQ   r   r   r"  )r+   rB  r,   r,   r-   	as_selectv  s
   

zCreateQueryBuilder.as_selectc                 C   rt  rm  )r'  r:   r,   r,   r-   if_not_exists  r1   z CreateQueryBuilder.if_not_existsc                 K   s~   |  | | js
dS | js| jsdS | jdi |}| jr'|| jdi | S | jdi |}| jdi |}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_optionsNr,   )	r  r  r0  r"  _create_table_sql_as_select_sql	_body_sql_table_options_sqlrk   )r+   rL   r   rE  rF  r,   r,   r-   rN     s   
zCreateQueryBuilder.get_sqlc                 K   sF   d}| j rd}n| jrd}d}| jrd}dj||| jjdi |dS )Nr   z
TEMPORARY z	UNLOGGED zIF NOT EXISTS z/CREATE {table_type}TABLE {if_not_exists}{table})
table_typerD  r5   r,   )r   r!  r'  rk   r  rN   )r+   rL   rK  rD  r,   r,   r-   rG    s   z$CreateQueryBuilder._create_table_sqlc                 K   s   d}| j r	|d7 }|S )Nr   z WITH SYSTEM VERSIONINGr6  )r+   rL   rF  r,   r,   r-   rJ    s   z%CreateQueryBuilder._table_options_sqlc                        fdd| j D S )Nc                       g | ]
}|j d i  qS r,   r   rX  r  r,   r-   rP    rQ  z6CreateQueryBuilder._column_clauses.<locals>.<listcomp>)r0  rO   r,   r  r-   _column_clauses     z"CreateQueryBuilder._column_clausesc                    rL  )Nc                    rM  rN  r   )r  r8  r  r,   r-   rP    rQ  z:CreateQueryBuilder._period_for_clauses.<locals>.<listcomp>)r#  rO   r,   r  r-   _period_for_clauses  rP  z&CreateQueryBuilder._period_for_clausesc                    rL  )Nc                    s,   g | ]}d j d fdd|D dqS )zUNIQUE ({unique})r  c                 3   r  rM   r   rX  r  r,   r-   r    r  zDCreateQueryBuilder._unique_key_clauses.<locals>.<listcomp>.<genexpr>)r;  )rk   r  )r  r;  r  r,   r-   rP    s    z:CreateQueryBuilder._unique_key_clauses.<locals>.<listcomp>)r&  rO   r,   r  r-   _unique_key_clauses  s   
z&CreateQueryBuilder._unique_key_clausesc                    r  )NzPRIMARY KEY ({columns})r  c                 3   r  rM   rR  rX  r  r,   r-   r    r  z9CreateQueryBuilder._primary_key_clause.<locals>.<genexpr>r  )rk   r  r%  rO   r,   r  r-   _primary_key_clause  r  z&CreateQueryBuilder._primary_key_clausec                    sz   dj d fdd| jD | jjd	i  d fdd| jD d}| jr0|d| jj 7 }| jr;|d| jj 7 }|S )
NzEFOREIGN KEY ({columns}) REFERENCES {table_name} ({reference_columns})r  c                 3   r  rM   rR  rX  r  r,   r-   r    r  z9CreateQueryBuilder._foreign_key_clause.<locals>.<genexpr>c                 3   r  rM   rR  rX  r  r,   r-   r    r  )r   r   r>  z ON DELETE z ON UPDATE r,   )	rk   r  r(  r)  rN   r*  r,  r  r+  )r+   rL   r  r,   r  r-   _foreign_key_clause  s   z&CreateQueryBuilder._foreign_key_clausec                 K   sz   | j di |}|| jdi |7 }|| jdi |7 }| jr*|| jdi | | jr8|| jdi | d|S )Nr  r,   )	rO  rQ  rS  r%  r   rT  r(  rU  r  )r+   rL   r  r,   r,   r-   rI    s   
zCreateQueryBuilder._body_sqlc                 K   r  )Nz AS ({query})r  r,   )rk   r"  rN   rO   r,   r,   r-   rH    r  z!CreateQueryBuilder._as_select_sqlc                 C   s   dd |D S )Nc                 S   s"   g | ]}t |tr|nt|qS r,   )rQ   r   rX  r,   r,   r-   rP    s   " z=CreateQueryBuilder._prepare_columns_input.<locals>.<listcomp>r,   r:  r,   r,   r-   r9    rV   z)CreateQueryBuilder._prepare_columns_inputc                 C   r   r(   r   r:   r,   r,   r-   r     r   zCreateQueryBuilder.__str__c                 C   r   r(   r  r:   r,   r,   r-   r     r   zCreateQueryBuilder.__repr__r(   )r&   r   )NN)0rA   rB   rC   r   r  r  r  rx   r
  r   r   r.   r	  r  r    r
   rd   rD   r   r3  r5  r7  r   r   r   r8  r;  r<  r   r   rA  r   rC  rD  r   rN   rG  rJ  rO  rQ  rS  rT  rU  rI  rH  r9  r   r   r,   r,   r,   r-   r     s~    			&


2"r   c                   @   s  e Zd ZdZdZdZdZeZd$de	e
 ddfddZd	eddfd
dZedeeef dd fddZedeeef dd fddZededd fddZededd fddZed%ddZdedeeeef ddfddZd	edefddZdefd d!Zdefd"d#ZdS )&r   z3
    Query builder used to build DROP queries.
    r   r&  Nr   r&   c                 C   s   d | _ d| _d | _|| _d S )Nr   )_drop_target_kind_drop_target
_if_existsr   r-  r,   r,   r-   r.     s   
zDropQueryBuilder.__init__rL   c                 C   r.  r/  r0  rO   r,   r,   r-   r    r1  z%DropQueryBuilder._set_kwargs_defaultsr   c                 C   &   t |tr|nt|}| d| d S )NDATABASE)rQ   rm   _set_target)r+   r   targetr,   r,   r-   r        zDropQueryBuilder.drop_databaser5   c                 C   rY  )NTABLE)rQ   rd   r[  )r+   r5   r\  r,   r,   r-   r     r]  zDropQueryBuilder.drop_tabler   c                 C      |  d| d S )NUSERr[  )r+   r   r,   r,   r-   r        zDropQueryBuilder.drop_userr   c                 C   r_  )NVIEWra  )r+   r   r,   r,   r-   r      rb  zDropQueryBuilder.drop_viewc                 C   rt  rm  )rX  r:   r,   r,   r-   	if_exists$  r1   zDropQueryBuilder.if_existskindr\  c                 C   s   | j rtd|| _|| _ d S )Nz4'DropQuery' object already has attribute drop_target)rW  r   rV  )r+   re  r\  r,   r,   r-   r[  (  s   
zDropQueryBuilder._set_targetc                 K   s|   |  | | jr
dnd}d}t| jtr| jjdi |}nt| jtr.| jjdi |}nt| j| j}dj	| j
||dS )Nz
IF EXISTS r   zDROP {kind} {if_exists}{name})re  rd  r2   r,   )r  rX  rQ   rW  rm   rN   rd   r"   r  rk   rV  )r+   rL   rd  target_namer,   r,   r-   rN   .  s   
zDropQueryBuilder.get_sqlc                 C   r   r(   r   r:   r,   r,   r-   r   ?  r   zDropQueryBuilder.__str__c                 C   r   r(   r  r:   r,   r,   r-   r   B  r   zDropQueryBuilder.__repr__r(   )r&   r   )rA   rB   rC   r   r  r  r  rx   r
  r   r   r.   r	  r  r    r
   rm   rD   r   rd   r   r   r   rd  r[  r   rN   r   r   r,   r,   r,   r-   r     s,     r   N)>r   	functoolsr   typingr   r   r   r   r   r   r	   r
   r   pypika.enumsr   r   r   r   pypika.termsr   r   r   r   r   r   r   r   r   r   r   r   pypika.utilsr   r   r   r   r    r!   r"   r#   
__author__	__email__r$   rF   rZ   rm   rd   rD   r   r   r   r   r   rx   r   r   r  r  r  r  r   r   r,   r,   r,   r-   <module>   sL    (@( *&& +       k/!+   `