U
    ovgҀ                     @  s  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 d dlm	Z	 d dlm
Z
 d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ  ddl!mZ ddl"m#Z# dd l$m%Z% dd!l&m'Z' erdd"l(m)Z) dd#l"m*Z* dd$l"m+Z+ ed%e	d&Z,e'd' Z-e%rd(d)iZ.d*d)iZ/ni Z.i Z/ej0f d+d)ie.G d,d- d-ee, Z1G d.d/ d/ee1e,  Z2G d0d1 d1e j#e, Z3G d2d3 d3e3e1e,  Z4G d4d5 d5e4e, Z5G d6d7 d7e3ee1e,   Z6G d8d9 d9e6e, Z7G d:d; d;e4e8 Z9G d<d= d=e4e8 Z:G d>d? d?e4e Z;G d@dA dAe4e Z<G dBdC dCe4e Z=G dDdE dEe4e Z>G dFdG dGe6e8 Z?G dHdI dIe6e8 Z@G dJdK dKe6e ZAG dLdM dMe6e ZBG dNdO dOe6e ZCG dPdQ dQe6e ZDdRZEdSZFdTdUdVdWdXZGdS )Y    )annotationsN)date)datetime)	timedelta)Decimal)Any)cast)Generic)List)Optional)overload)Sequence)Tuple)Type)TYPE_CHECKING)TypeVar)Union   )ADJACENT_TO)CONTAINED_BY)CONTAINS)NOT_EXTEND_LEFT_OF)NOT_EXTEND_RIGHT_OF)OVERLAP)STRICTLY_LEFT_OF)STRICTLY_RIGHT_OF   )types)	operators)
TypeEngine)py310)Literal)ColumnElement)_TE)TypeEngineMixin_T)bound)z()[)z(]z[]slotsTZkw_onlyfrozenc                   @  s  e Zd ZU dZdZded< dZded< erTej	ddZ
ded	< ej	d
dZded< n8ej	f ddieZ
ded	< ej	f dd
ieZded< esdXdd
ddddddddZddddZeddddZeddddZeddddZeddddZeddddZedddd Zed!dd"d#Zd$dd%d&d'Zd(dd)d*ZdYdd+dd+dd,d-d.d/Zd(dd0d1d2Zd3dd0d4d5Zd6dd%d7d8ZeZd3dd0d9d:Zd3dd0d;d<Z e Z!d3dd0d=d>Z"e"Z#d3dd0d?d@Z$d3dd0dAdBZ%dd+dd+ddCdDdEZ&d3dd0dFdGZ'd3d3d0dHdIZ(d3d3d0dJdKZ)d3d3d0dLdMZ*d3d3d0dNdOZ+d3d3d0dPdQZ,d3d3d0dRdSZ-d+ddTdUZ.d+ddVdWZ/dS )ZRangea_  Represent a PostgreSQL range.

    E.g.::

        r = Range(10, 50, bounds="()")

    The calling style is similar to that of psycopg and psycopg2, in part
    to allow easier migration from previous SQLAlchemy versions that used
    these objects directly.

    :param lower: Lower bound value, or None
    :param upper: Upper bound value, or None
    :param bounds: keyword-only, optional string value that is one of
     ``"()"``, ``"[)"``, ``"(]"``, ``"[]"``.  Defaults to ``"[)"``.
    :param empty: keyword-only, optional bool indicating this is an "empty"
     range

    .. versionadded:: 2.0

    NzOptional[_T]lowerupperr'   )default_BoundsTypeboundsFboolemptyr-   )r/   r1   r+   r,   r/   r1   c                C  s   | j ||||d d S )Nr2   )__dict__update)selfr+   r,   r/   r1    r6   I/tmp/pip-unpacked-wheel-uqd9otp_/sqlalchemy/dialects/postgresql/ranges.py__init__a   s    	zRange.__init__returnc                 C  s   | j  S Nr1   r5   r6   r6   r7   __bool__s   s    zRange.__bool__c                 C  s   | j S z$A synonym for the 'empty' attribute.r<   r=   r6   r6   r7   isemptyv   s    zRange.isemptyc                 C  s   | j S r?   r<   r=   r6   r6   r7   is_empty|   s    zRange.is_emptyc                 C  s   | j d dkS )z,Return True if the lower bound is inclusive.r   [r/   r=   r6   r6   r7   	lower_inc   s    zRange.lower_incc                 C  s   | j  o| jdkS )zKReturn True if this range is non-empty and lower bound is
        infinite.N)r1   r+   r=   r6   r6   r7   	lower_inf   s    zRange.lower_infc                 C  s   | j d dkS )z,Return True if the upper bound is inclusive.r   ]rC   r=   r6   r6   r7   	upper_inc   s    zRange.upper_incc                 C  s   | j  o| jdkS )zOReturn True if this range is non-empty and the upper bound is
        infinite.N)r1   r,   r=   r6   r6   r7   	upper_inf   s    zRange.upper_infzAbstractSingleRange[_T]c                 C  s   t  S r;   )AbstractSingleRanger=   r6   r6   r7   __sa_type_engine__   s    zRange.__sa_type_engine__r%   valuer:   c                 C  s   | j r
dS | jdkr@| jdkp>| jd dkr6|| jk S || jkS | jdkrl| jd dkrb|| jkS || jkS | jd dkr|| jkn|| jko| jd dkr|| jk S || jkS )z3Return True if this range contains the given value.FNr   )r   ()r1   r+   r,   r/   r5   rL   r6   r6   r7   _contains_value   s*    


zRange._contains_valuer   c                 C  sb   t | jtst | jtrdS t | jts4t | jtr8dS t | jtsPt | jtrZtddS dS dS )uA   Determine the “step” for this range, if it is a discrete one.r   N)days)
isinstancer+   intr,   r   r   r   r=   r6   r6   r7   _get_discrete_step   s     
zRange._get_discrete_stepstrrS   )value1bound1value2bound2only_valuesr:   c                 C  sx  |dk}|dk}||  kr$dkrBn n||kr4dS |r<dS dS n(|dkrV|rRdS dS |dkrj|rfdS dS ||kr~||kr~dS |dk}|dk}	|   }
|
dk	r|r|s||
7 }d}n|r||
7 }d}|r|	s||
7 }d}	n|	r||
7 }d}	||k rdS ||krdS |rdS |r|	rdS |sH|	sH||kr8dS |rBdS dS n,|s\|rXdS dS |	sp|rldS dS dS dS )	a  Compare two range bounds.

        Return -1, 0 or 1 respectively when `value1` is less than,
        equal to or greater than `value2`.

        When `only_value` is ``True``, do not consider the *inclusivity*
        of the edges, just their values.
        >   rB   rN   Nr   r   >   rB   rF   TF)rT   )r5   rV   rW   rX   rY   rZ   Zvalue1_is_lower_boundZvalue2_is_lower_boundZ
value1_incZ
value2_incstepr6   r6   r7   _compare_edges   s^    

zRange._compare_edgesotherr:   c           
      C  s   t |tstS | jr|jrdS | j|jkr.dS | j}| jd }|j}|jd }| j}| jd }|j}|jd }	| ||||dko| ||||	dkS )zCompare this range to the `other` taking into account
        bounds inclusivity, returning ``True`` if they are equal.
        TFr   r   )rR   r*   NotImplementedr1   r+   r/   r,   r]   
r5   r_   slowerslower_bolowerolower_bsuppersupper_boupperoupper_br6   r6   r7   __eq__+  s"    




zRange.__eq__z	Range[_T]c           
      C  s   | j r
dS |j rdS | j}| jd }|j}|jd }| ||||dk rLdS | j}| jd }|j}|jd }	| ||||	dkrdS dS )z7Determine whether this range is a contained by `other`.TFr   r   )r1   r+   r/   r]   r,   ra   r6   r6   r7   contained_byF  s"    



zRange.contained_byzUnion[_T, Range[_T]]c                 C  s"   t |tr|| S | |S dS )z.Determine whether this range contains `value`.N)rR   r*   rk   rP   rO   r6   r6   r7   containsc  s    

zRange.containsc           
      C  s   | j s|j rdS | j}| jd }| j}| jd }|j}|jd }|j}|jd }	| ||||dkr|| ||||	dkr|dS | ||||dkr| ||||dkrdS dS )z3Determine whether this range overlaps with `other`.Fr   r   Tr1   r+   r/   r,   r]   
r5   r_   rb   rc   rf   rg   rd   re   rh   ri   r6   r6   r7   overlapsm  s*    



zRange.overlapsc                 C  sD   | j s|j rdS | j}| jd }|j}|jd }| ||||dk S )zBDetermine whether this range is completely to the left of `other`.Fr   r   )r1   r,   r/   r+   r]   )r5   r_   rf   rg   rd   re   r6   r6   r7   strictly_left_of  s    

zRange.strictly_left_ofc                 C  sD   | j s|j rdS | j}| jd }|j}|jd }| ||||dkS )zCDetermine whether this range is completely to the right of `other`.Fr   r   rm   )r5   r_   rb   rc   rh   ri   r6   r6   r7   strictly_right_of  s    

zRange.strictly_right_ofc                 C  sD   | j s|j rdS | j}| jd }|j}|jd }| ||||dkS )z>Determine whether this does not extend to the left of `other`.Fr   )r1   r+   r/   r]   )r5   r_   rb   rc   rd   re   r6   r6   r7   not_extend_left_of  s    

zRange.not_extend_left_ofc                 C  sD   | j s|j rdS | j}| jd }|j}|jd }| ||||dkS )z?Determine whether this does not extend to the right of `other`.Fr   r   )r1   r,   r/   r]   )r5   r_   rf   rg   rh   ri   r6   r6   r7   not_extend_right_of  s    

zRange.not_extend_right_of)rV   rW   rX   rY   r:   c                 C  s   |  ||||d}|dkrr|  }|dkr.dS |dkrT|dkrJ||| kS ||kS q|dkrd||kS ||| kS n`|dkr|dkr|dks|dkr|d	kr|  }|dk	rdS |dkr|dkp|dko|d	kS dS dS )
zTDetermine whether an upper bound is immediately successive to a
        lower bound.Tr[   NFrF   rB   r   rM   rN   )r]   rT   )r5   rV   rW   rX   rY   resr\   r6   r6   r7   _upper_edge_adjacent_to_lower  s>    
z#Range._upper_edge_adjacent_to_lowerc           
      C  sp   | j s|j rdS | j}| jd }| j}| jd }|j}|jd }|j}|jd }	| ||||pn| ||	||S )z8Determine whether this range is adjacent to the `other`.Fr   r   )r1   r+   r/   r,   ru   rn   r6   r6   r7   adjacent_to  s.    



      zRange.adjacent_toc                 C  s   | j r
|S |j r| S | |s0| |s0td| j}| jd }| j}| jd }|j}|jd }|j}|jd }	| ||||dk r|}
|}n|}
|}| ||||	dkr|}|}n|}|	}t|
|t	t
|| dS )zCompute the union of this range with the `other`.

        This raises a ``ValueError`` exception if the two ranges are
        "disjunct", that is neither adjacent nor overlapping.
        zAAdding non-overlapping and non-adjacent ranges is not implementedr   r   rC   )r1   ro   rv   
ValueErrorr+   r/   r,   r]   r*   r   r.   r5   r_   rb   rc   rf   rg   rd   re   rh   ri   Zrlowerrlower_bZrupperrupper_br6   r6   r7   union  s>    



  zRange.unionc                 C  s
   |  |S r;   )r{   r5   r_   r6   r6   r7   __add__@  s    zRange.__add__c                 C  s  | j s|j r| S | j}| jd }| j}| jd }|j}|jd }|j}|jd }	| ||||}
| ||||	}|
dk r|dkrtd| ||||	}| ||||}|dks|dk r| S |
dkr|dkrtddddS |
dkrZ|dkrZ|dkrZ|dkrdnd	}|dkrB|d	krB| ||||dkrBtddddS t||tt|| d
S |
dkr|dkr|dkr|	d	krdnd}|dkr|d	kr| ||||dkrtddddS t||tt|| d
S dst	d|  d| dS )zCompute the difference between this range and the `other`.

        This raises a ``ValueError`` exception if the two ranges are
        "disjunct", that is neither adjacent nor overlapping.
        r   r   z5Subtracting a strictly inner range is not implementedNTr<   rB   rM   rF   rC   rN   FzUnhandled case computing z - )
r1   r+   r/   r,   r]   rw   r*   r   r.   AssertionError)r5   r_   rb   rc   rf   rg   rd   re   rh   ri   Zsl_vs_olZsu_vs_ouZsl_vs_ouZsu_vs_olrz   ry   r6   r6   r7   
differenceC  sn    



zRange.differencec                 C  s
   |  |S r;   )r   r|   r6   r6   r7   __sub__  s    zRange.__sub__c                 C  s   | j s|j s| |s$tddddS | j}| jd }| j}| jd }|j}|jd }|j}|jd }	| ||||dk r|}
|}n|}
|}| ||||	dkr|}|	}n|}|}t|
|tt|| dS )zdCompute the intersection of this range with the `other`.

        .. versionadded:: 2.0.10

        NTr<   r   r   rC   )	r1   ro   r*   r+   r/   r,   r]   r   r.   rx   r6   r6   r7   intersection  s2    



zRange.intersectionc                 C  s
   |  |S r;   )r   r|   r6   r6   r7   __mul__  s    zRange.__mul__c                 C  s   |   S r;   )
_stringifyr=   r6   r6   r7   __str__  s    zRange.__str__c                 C  s^   | j r
dS | j| j }}|d kr$dn|}|d kr4dn|}td| j\}}| | d| | S )Nr1    zTuple[str, str],)r1   r+   r,   r   r/   )r5   lrZb0Zb1r6   r6   r7   r     s    zRange._stringify)NN)F)0__name__
__module____qualname____doc__r+   __annotations__r,   r   dataclassesfieldr/   r1   	dc_kwonlyr    r8   r>   propertyr@   rA   rD   rE   rG   rH   rJ   rP   rT   r]   rj   rk   rl   __contains__ro   rp   
__lshift__rq   
__rshift__rr   rs   ru   rv   r{   r}   r   r   r   r   r   r   r6   r6   r6   r7   r*   ;   sn   
   Y /.L&r*   c                   @  s"   e Zd ZdZeddddZdS )
MultiRangea?  Represents a multirange sequence.

    This list subclass is an utility to allow automatic type inference of
    the proper multi-range SQL type depending on the single range values.
    This is useful when operating on literal multi-ranges::

        import sqlalchemy as sa
        from sqlalchemy.dialects.postgresql import MultiRange, Range

        value = literal(MultiRange([Range(2, 4)]))

        select(tbl).where(tbl.c.value.op("@")(MultiRange([Range(-3, 7)])))

    .. versionadded:: 2.0.26

    .. seealso::

        - :ref:`postgresql_multirange_list_use`.
    zAbstractMultiRange[_T]r9   c                 C  s   t  S r;   )AbstractMultiRanger=   r6   r6   r7   rJ     s    zMultiRange.__sa_type_engine__N)r   r   r   r   r   rJ   r6   r6   r6   r7   r     s   r   c                      sx   e Zd ZdZdZdZeddddddZed	dd
dddZddd
d fddZG dd dej	e
e  Z  ZS )AbstractRangez0Base class for single and multi Range SQL types.Tz	Type[_TE]r   r#   )clskwr:   c                 K  s   d S r;   r6   r5   r   r   r6   r6   r7   adapt  s    zAbstractRange.adaptzType[TypeEngineMixin]zTypeEngine[Any]c                 K  s   d S r;   r6   r   r6   r6   r7   r     s    z-Type[Union[TypeEngine[Any], TypeEngineMixin]]c                   sL   t |ttfr<|| jk	r<| j}t| d|| jfd|i S t |S dS )a	  Dynamically adapt a range type to an abstract impl.

        For example ``INT4RANGE().adapt(_Psycopg2NumericRange)`` should
        produce a type that will have ``_Psycopg2NumericRange`` behaviors
        and also render as ``INT4RANGE`` in SQL and DDL.

        Z	RangeImpl__visit_name__N)
issubclassAbstractSingleRangeImplAbstractMultiRangeImpl	__class__r   typesuperr   )r5   r   r   Z
visit_namer   r6   r7   r     s    c                   @  s   e Zd ZdZddddddZddddd	Zdddd
dZdddddZeZdddddZ	e	Z
dddddZdddddZdddddZdddddZdddddZdddddZdS )z AbstractRange.comparator_factoryz-Define comparison operations for range types.r   zColumnElement[bool])r_   r   r:   c                 K  s   | j t|S )a
  Boolean expression. Returns true if the right hand operand,
            which can be an element or a range, is contained within the
            column.

            kwargs may be ignored by this operator but are required for API
            conformance.
            )exproperater   )r5   r_   r   r6   r6   r7   rl     s    z)AbstractRange.comparator_factory.containsr^   c                 C  s   | j t|S )zsBoolean expression. Returns true if the column is contained
            within the right hand operand.
            )r   r   r   r|   r6   r6   r7   rk   #  s    z-AbstractRange.comparator_factory.contained_byc                 C  s   | j t|S )zBoolean expression. Returns true if the column overlaps
            (has points in common with) the right hand operand.
            )r   r   r   r|   r6   r6   r7   ro   )  s    z)AbstractRange.comparator_factory.overlapsc                 C  s   | j t|S )zsBoolean expression. Returns true if the column is strictly
            left of the right hand operand.
            )r   r   r   r|   r6   r6   r7   rp   /  s    z1AbstractRange.comparator_factory.strictly_left_ofc                 C  s   | j t|S )ztBoolean expression. Returns true if the column is strictly
            right of the right hand operand.
            )r   r   r   r|   r6   r6   r7   rq   7  s    z2AbstractRange.comparator_factory.strictly_right_ofc                 C  s   | j t|S )zBoolean expression. Returns true if the range in the column
            does not extend right of the range in the operand.
            )r   r   r   r|   r6   r6   r7   rs   ?  s    z4AbstractRange.comparator_factory.not_extend_right_ofc                 C  s   | j t|S )zBoolean expression. Returns true if the range in the column
            does not extend left of the range in the operand.
            )r   r   r   r|   r6   r6   r7   rr   E  s    z3AbstractRange.comparator_factory.not_extend_left_ofc                 C  s   | j t|S )z}Boolean expression. Returns true if the range in the column
            is adjacent to the range in the operand.
            )r   r   r   r|   r6   r6   r7   rv   K  s    z,AbstractRange.comparator_factory.adjacent_toc                 C  s   | j tj|S zRange expression. Returns the union of the two ranges.
            Will raise an exception if the resulting range is not
            contiguous.
            )r   r   r   addr|   r6   r6   r7   r{   Q  s    z&AbstractRange.comparator_factory.unionc                 C  s   | j tj|S r   )r   r   r   subr|   r6   r6   r7   r   X  s    z+AbstractRange.comparator_factory.differencezColumnElement[Range[_T]]c                 C  s   | j tj|S )zRange expression. Returns the intersection of the two ranges.
            Will raise an exception if the resulting range is not
            contiguous.
            )r   r   r   mulr|   r6   r6   r7   r   _  s    z-AbstractRange.comparator_factory.intersectionN)r   r   r   r   rl   rk   ro   rp   r   rq   r   rs   rr   rv   r{   r   r   r6   r6   r6   r7   comparator_factory  s   
r   )r   r   r   r   Zrender_bind_cast__abstract__r   r   r   Z
Comparatorr*   r   r   __classcell__r6   r6   r   r7   r     s   "r   c                   @  s$   e Zd ZdZdZdddddZdS )	rI   zBase for PostgreSQL RANGE types.

    These are types that return a single :class:`_postgresql.Range` object.

    .. seealso::

        `PostgreSQL range functions <https://www.postgresql.org/docs/current/static/functions-range.html>`_

    Tz
Range[Any]r   rK   c                 C  s   |j d k	r|j n|j}t|tr6t|r.t S t S nFt|ttfrJt	 S t|t
rf|js`t S t S t|trvt S tjS d S r;   )r+   r,   rR   rS   	_is_int32	INT4RANGE	INT8RANGEr   floatNUMRANGEr   tzinfoTSRANGE	TSTZRANGEr   	DATERANGEsqltypesNULLTYPE)r5   rL   specr6   r6   r7   _resolve_for_literalt  s    


z(AbstractSingleRange._resolve_for_literalNr   r   r   r   r   r   r6   r6   r6   r7   rI   g  s   
rI   c                   @  s   e Zd ZdZdS )r   zQMarker for AbstractSingleRange that will apply a subclass-specific
    adaptationNr   r   r   r   r6   r6   r6   r7   r     s   r   c                   @  s$   e Zd ZdZdZdddddZdS )	r   zBase for PostgreSQL MULTIRANGE types.

    these are types that return a sequence of :class:`_postgresql.Range`
    objects.

    TzSequence[Range[Any]]r   rK   c                 C  s   |s
t jS |d }|jd k	r"|jn|j}t|trRtdd |D rJt S t S nFt|t	t
frft S t|tr|js|t S t S t|trt S t jS d S )Nr   c                 s  s   | ]}t |V  qd S r;   )r   ).0r   r6   r6   r7   	<genexpr>  s     z:AbstractMultiRange._resolve_for_literal.<locals>.<genexpr>)r   r   r+   r,   rR   rS   allINT4MULTIRANGEINT8MULTIRANGEr   r   NUMMULTIRANGEr   r   TSMULTIRANGETSTZMULTIRANGEr   DATEMULTIRANGE)r5   rL   firstr   r6   r6   r7   r     s    


z'AbstractMultiRange._resolve_for_literalNr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZdS )r   zPMarker for AbstractMultiRange that will apply a subclass-specific
    adaptationNr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z(Represent the PostgreSQL INT4RANGE type.Nr   r   r   r   r   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z(Represent the PostgreSQL INT8RANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z'Represent the PostgreSQL NUMRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z(Represent the PostgreSQL DATERANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   &Represent the PostgreSQL TSRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   (Represent the PostgreSQL TSTZRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z-Represent the PostgreSQL INT4MULTIRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z-Represent the PostgreSQL INT8MULTIRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z,Represent the PostgreSQL NUMMULTIRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   z-Represent the PostgreSQL DATEMULTIRANGE type.Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   r   Nr   r6   r6   r6   r7   r     s   r   c                   @  s   e Zd ZdZd ZdS )r   r   Nr   r6   r6   r6   r7   r     s   r   ii   z
Range[int]r0   )r   r:   c                 C  sH   | j d ks$t| j   kotkn  oF| jd kpFt| j  koBtkS   S r;   )r+   _min_int_32_max_int_32r,   )r   r6   r6   r7   r     s    $"r   )H
__future__r   r   r   r   r   decimalr   typingr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZsqlZsql.type_apir   utilr    Zutil.typingr!   Zsql.elementsr"   r#   r$   r%   r.   Zdc_slotsr   Z	dataclassr*   r   r   rI   r   r   r   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r6   r6   r6   r7   <module>   s   
      #$