
    6iC                    d   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 e	rTd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
d"e#      Z. e
d$e#      Z/ej`                  f	 	 	 	 	 	 	 d,d%Zej`                  f	 	 	 	 	 	 	 d,d&Z1 G d' d(ejd                  e.         Z3 G d) d*ejh                  e.         Z4d-d+Z5y).    )annotationsN)Any)Iterable)Optional)Sequence)TYPE_CHECKING)TypeVar)Union   )CONTAINED_BY)CONTAINS)OVERLAP   )types)util)
expression)	operators)InternalTraversal)Dialect)_ColumnExpressionArgument)_TypeEngineArgument)ColumnElement)Grouping)BindParameter)OperatorType)_SelectIterable)_BindProcessorType)_LiteralProcessorType)_ResultProcessorType)
TypeEngine)_TraverseInternalsType)Self_T)bound_CTc                &    |j                  | |      S )zjA synonym for the ARRAY-level :meth:`.ARRAY.Comparator.any` method.
    See that method for details.

    )anyotherarrexproperators      g/home/azureuser/techstart-app/venv/lib/python3.12/site-packages/sqlalchemy/dialects/postgresql/array.pyr   r   2        ;;uh''    c                &    |j                  | |      S )zjA synonym for the ARRAY-level :meth:`.ARRAY.Comparator.all` method.
    See that method for details.

    )allr(   s      r,   Allr1   ?   r-   r.   c                       e Zd ZU dZd ZdZdej                  fdej                  fgZ	de
d<   dd	 	 	 	 	 d fd	Zedd
       Z	 	 d	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 ddZ xZS )arraya  A PostgreSQL ARRAY literal.

    This is used to produce ARRAY literals in SQL expressions, e.g.::

        from sqlalchemy.dialects.postgresql import array
        from sqlalchemy.dialects import postgresql
        from sqlalchemy import select, func

        stmt = select(array([1, 2]) + array([3, 4, 5]))

        print(stmt.compile(dialect=postgresql.dialect()))

    Produces the SQL:

    .. sourcecode:: sql

        SELECT ARRAY[%(param_1)s, %(param_2)s] ||
            ARRAY[%(param_3)s, %(param_4)s, %(param_5)s]) AS anon_1

    An instance of :class:`.array` will always have the datatype
    :class:`_types.ARRAY`.  The "inner" type of the array is inferred from the
    values present, unless the :paramref:`_postgresql.array.type_` keyword
    argument is passed::

        array(["foo", "bar"], type_=CHAR)

    When constructing an empty array, the :paramref:`_postgresql.array.type_`
    argument is particularly important as PostgreSQL server typically requires
    a cast to be rendered for the inner type in order to render an empty array.
    SQLAlchemy's compilation for the empty array will produce this cast so
    that::

        stmt = array([], type_=Integer)
        print(stmt.compile(dialect=postgresql.dialect()))

    Produces:

    .. sourcecode:: sql

        ARRAY[]::INTEGER[]

    As required by PostgreSQL for empty arrays.

    .. versionadded:: 2.0.40 added support to render empty PostgreSQL array
       literals with a required cast.

    Multidimensional arrays are produced by nesting :class:`.array` constructs.
    The dimensionality of the final :class:`_types.ARRAY`
    type is calculated by
    recursively adding the dimensions of the inner :class:`_types.ARRAY`
    type::

        stmt = select(
            array(
                [array([1, 2]), array([3, 4]), array([column("q"), column("x")])]
            )
        )
        print(stmt.compile(dialect=postgresql.dialect()))

    Produces:

    .. sourcecode:: sql

        SELECT ARRAY[
            ARRAY[%(param_1)s, %(param_2)s],
            ARRAY[%(param_3)s, %(param_4)s],
            ARRAY[q, x]
        ] AS anon_1

    .. versionadded:: 1.3.6 added support for multidimensional array literals

    .. seealso::

        :class:`_postgresql.ARRAY`

    
postgresqlclausestyper!   _traverse_internalsN)type_c               j   t        |   t        j                  g|i | ||n4| j                  r| j                  d   j
                  nt        j                  }t        |t              r8t        |j                  |j                  |j                  dz   nd      | _        yt        |      | _        y)a  Construct an ARRAY literal.

        :param clauses: iterable, such as a list, containing elements to be
         rendered in the array
        :param type\_: optional type.  If omitted, the type is inferred
         from the contents of the array.

        Nr   r      )
dimensions)super__init__r   comma_opr5   r6   sqltypesNULLTYPE
isinstanceARRAY	item_typer;   )selfr5   r8   kw	main_type	__class__s        r,   r=   zarray.__init__   s     	++<g<<   )-a%%8;L;L 	 i'## !++7 ((1,DI i(DIr.   c                    | fS N rD   s    r,   _select_iterablezarray._select_iterable   s	    wr.   c                    |s|t         j                  u r%t        j                  d |||| j                  d      S t        |D cg c]  }| j                  ||d|       c}      S c c}w )NT)_compared_to_operatorr8   _compared_to_typeunique)_assume_scalarr8   )r   getitemr   r   r6   r3   _bind_param)rD   r+   objr8   rQ   os         r,   rS   zarray._bind_param   s     X):)::++&."&))  
 !	  $$ !D %  s   A&c                    |t         j                  t         j                  t         j                  fv rt	        j
                  |       S | S rI   )r   any_opall_oprR   r   r   )rD   againsts     r,   
self_groupzarray.self_group   s;     y'')9)99;L;LMM&&t,,Kr.   )r5   zIterable[_T]r8   z!Optional[_TypeEngineArgument[_T]]rE   
typing_Any)returnr   )NF)
r+   r   rT   r[   r8   zOptional[TypeEngine[_T]]rQ   boolr\   zBindParameter[_T]rI   )rY   zOptional[OperatorType]r\   zUnion[Self, Grouping[_T]])__name__
__module____qualname____doc____visit_name__stringify_dialectr   dp_clauseelement_tupledp_typer7   __annotations__r=   propertyrL   rS   rZ   __classcell__)rG   s   @r,   r3   r3   L   s    KZ N$ 
%<<=	"**+3/  48	!)!) 1	!)
 !)F   +/$  (	
  
8 15-	"r.   r3   c                      e Zd ZdZ	 	 	 d
	 	 	 	 	 	 	 ddZ G d dej                  j                  e         ZeZ	e
j                  dd       Z	 	 	 	 ddZ	 	 	 	 ddZ	 	 	 	 	 	 dd	Zy)rB   an
  PostgreSQL ARRAY type.

    The :class:`_postgresql.ARRAY` type is constructed in the same way
    as the core :class:`_types.ARRAY` type; a member type is required, and a
    number of dimensions is recommended if the type is to be used for more
    than one dimension::

        from sqlalchemy.dialects import postgresql

        mytable = Table(
            "mytable",
            metadata,
            Column("data", postgresql.ARRAY(Integer, dimensions=2)),
        )

    The :class:`_postgresql.ARRAY` type provides all operations defined on the
    core :class:`_types.ARRAY` type, including support for "dimensions",
    indexed access, and simple matching such as
    :meth:`.types.ARRAY.Comparator.any` and
    :meth:`.types.ARRAY.Comparator.all`.  :class:`_postgresql.ARRAY`
    class also
    provides PostgreSQL-specific methods for containment operations, including
    :meth:`.postgresql.ARRAY.Comparator.contains`
    :meth:`.postgresql.ARRAY.Comparator.contained_by`, and
    :meth:`.postgresql.ARRAY.Comparator.overlap`, e.g.::

        mytable.c.data.contains([1, 2])

    Indexed access is one-based by default, to match that of PostgreSQL;
    for zero-based indexed access, set
    :paramref:`_postgresql.ARRAY.zero_indexes`.

    Additionally, the :class:`_postgresql.ARRAY`
    type does not work directly in
    conjunction with the :class:`.ENUM` type.  For a workaround, see the
    special type at :ref:`postgresql_array_of_enum`.

    .. container:: topic

        **Detecting Changes in ARRAY columns when using the ORM**

        The :class:`_postgresql.ARRAY` type, when used with the SQLAlchemy ORM,
        does not detect in-place mutations to the array. In order to detect
        these, the :mod:`sqlalchemy.ext.mutable` extension must be used, using
        the :class:`.MutableList` class::

            from sqlalchemy.dialects.postgresql import ARRAY
            from sqlalchemy.ext.mutable import MutableList


            class SomeOrmClass(Base):
                # ...

                data = Column(MutableList.as_mutable(ARRAY(Integer)))

        This extension will allow "in-place" changes such to the array
        such as ``.append()`` to produce events which will be detected by the
        unit of work.  Note that changes to elements **inside** the array,
        including subarrays that are mutated in place, are **not** detected.

        Alternatively, assigning a new array value to an ORM element that
        replaces the old one will always trigger a change event.

    .. seealso::

        :class:`_types.ARRAY` - base array type

        :class:`_postgresql.array` - produces a literal array value.

    Nc                    t        |t              rt        d      t        |t              r |       }|| _        || _        || _        || _        y)a-  Construct an ARRAY.

        E.g.::

          Column("myarray", ARRAY(Integer))

        Arguments are:

        :param item_type: The data type of items of this array. Note that
          dimensionality is irrelevant here, so multi-dimensional arrays like
          ``INTEGER[][]``, are constructed as ``ARRAY(Integer)``, not as
          ``ARRAY(ARRAY(Integer))`` or such.

        :param as_tuple=False: Specify whether return results
          should be converted to tuples from lists. DBAPIs such
          as psycopg2 return lists by default. When tuples are
          returned, the results are hashable.

        :param dimensions: if non-None, the ARRAY will assume a fixed
         number of dimensions.  This will cause the DDL emitted for this
         ARRAY to include the exact number of bracket clauses ``[]``,
         and will also optimize the performance of the type overall.
         Note that PG arrays are always implicitly "non-dimensioned",
         meaning they can store any number of dimensions no matter how
         they were declared.

        :param zero_indexes=False: when True, index values will be converted
         between Python zero-based and PostgreSQL one-based indexes, e.g.
         a value of one will be added to all index values before passing
         to the database.

        zUDo not nest ARRAY types; ARRAY(basetype) handles multi-dimensional arrays of basetypeN)rA   rB   
ValueErrorr6   rC   as_tupler;   zero_indexes)rD   rC   rl   r;   rm   s        r,   r=   zARRAY.__init__6  sQ    N i'?  i&!I" $(r.   c                  4    e Zd ZdZ	 	 	 	 	 	 ddZddZddZy)ARRAY.Comparatora*  Define comparison operations for :class:`_types.ARRAY`.

        Note that these operations are in addition to those provided
        by the base :class:`.types.ARRAY.Comparator` class, including
        :meth:`.types.ARRAY.Comparator.any` and
        :meth:`.types.ARRAY.Comparator.all`.

        c                N    | j                  t        |t        j                        S )zBoolean expression.  Test if elements are a superset of the
            elements of the argument array expression.

            kwargs may be ignored by this operator but are required for API
            conformance.
            result_type)operater   r?   Boolean)rD   r)   kwargss      r,   containszARRAY.Comparator.containss  s     <<%X=M=M<NNr.   c                N    | j                  t        |t        j                        S )zBoolean expression.  Test if elements are a proper subset of the
            elements of the argument array expression.
            rq   )rs   r   r?   rt   rD   r)   s     r,   contained_byzARRAY.Comparator.contained_by~  s'     <<e1A1A    r.   c                N    | j                  t        |t        j                        S )zuBoolean expression.  Test if array has elements in common with
            an argument array expression.
            rq   )rs   r   r?   rt   rx   s     r,   overlapzARRAY.Comparator.overlap  s     <<H<L<L<MMr.   N)r)   r[   ru   r[   r\   ColumnElement[bool])r)   r[   r\   r|   )r^   r_   r`   ra   rv   ry   r{   rJ   r.   r,   
Comparatorro   i  s3    			O#		O/9		O 		O		Nr.   r}   c                z    t        | j                  t        j                        xr | j                  j                  S rI   )rA   rC   r?   Enumnative_enumrK   s    r,   _against_native_enumzARRAY._against_native_enum  s-     t~~x}}5 +**	
r.   c                ~      j                   j                  |      j                  |      y ddd fd}|S )Nc                ,    ddj                  |        dS )NzARRAY[z, ])join)elementss    r,   to_strz'ARRAY.literal_processor.<locals>.to_str  s    DIIh/022r.   c                D    j                  | j                        }|S rI   )_apply_item_processorr;   )valueinner	item_procrD   r   s     r,   processz(ARRAY.literal_processor.<locals>.process  s'    ..y$//6E Lr.   )r   zIterable[typing_Any]r\   str)r   Sequence[typing_Any]r\   r   )rC   dialect_implliteral_processor)rD   dialectr   r   r   s   `  @@r,   r   zARRAY.literal_processor  sC     NN//8JJ
	 	3	 r.   c                t      j                   j                  |      j                  |      	 	 	 	 d fd}|S )Nc                P    | | S j                  | j                  t              S rI   )r   r;   listr   r   rD   s    r,   r   z%ARRAY.bind_processor.<locals>.process  s/     }119doot r.   )r   Optional[Sequence[typing_Any]]r\   zOptional[list[typing_Any]])rC   r   bind_processor)rD   r   r   r   s   `  @r,   r   zARRAY.bind_processor  sC     NN//8GG
		1	'	 r.   c                      j                   j                  |      j                  ||      	 	 	 	 d fd} j                  r(|t	        j
                  d      dfd	 	 	 	 dfd}|S )Nc                |    | | S j                  | j                  j                  r
t              S t              S rI   )r   r;   rl   tupler   r   s    r,   r   z'ARRAY.result_processor.<locals>.process  sG     }11OO!]]E	  15	 r.   z^{(.*)}$c                Z    j                  |       j                  d      }t        |      S )Nr   )matchgroup_split_enum_values)r   r   patterns     r,   handle_raw_stringz1ARRAY.result_processor.<locals>.handle_raw_string  s'    e,2215)%00r.   c                T    | | S  t        | t              r |             S |       S rI   )rA   r   )r   r   super_rps    r,   r   z'ARRAY.result_processor.<locals>.process  sA     = L  !%- &e,   r.   )r   r   r\   r   )r   r   r\   Sequence[Optional[str]])rC   r   result_processorr   recompile)rD   r   coltyper   r   r   r   r   s   `   @@@@r,   r   zARRAY.result_processor  s}     NN//8IIW
		'	+	 $$Hjj-G1+/ r.   )FNF)rC   z_TypeEngineArgument[_T]rl   r]   r;   zOptional[int]rm   r]   )r\   r]   )r   r   r\   z#Optional[_LiteralProcessorType[_T]])r   r   r\   z2Optional[_BindProcessorType[Sequence[typing_Any]]])r   r   r   objectr\   z*_ResultProcessorType[Sequence[typing_Any]])r^   r_   r`   ra   r=   r?   rB   r}   r%   comparator_factoryr   memoized_propertyr   r   r   r   rJ   r.   r,   rB   rB      s    ET $("1)*1) 1) "	1)
 1)f!NX^^..s3 !NF $	
 
	,(	;&**)/*	3*r.   rB   c                   d| vr*| r| j                  d      ng D cg c]  }|dk7  r|nd  c}S | j                  dd      }|j                  dd      }g }t        j                   d|      }d	}|D ]i  }|dk(  r| }|r"|j                  |j                  dd             0|j	                  t        j
                  d
|      D cg c]  }|dk7  r|nd  c}       k |S c c}w c c}w )N",NULLz\"z_$ESC_QUOTE$_z\\\z(")Fz([^\s,]+),?)splitreplacer   appendextendfindall)array_stringrtextresult	on_quotes	in_quotestoks          r,   r   r     s   
, 2>l((-2
 fA$&
 	
 7D<<t$DF&II #:%IMM#++os;< MM  ZZ< fA$. M7
,s   CC"
)r)   r[   r*   z_ColumnExpressionArgument[_T]r+   r   r\   r|   )r   r   r\   r   )6
__future__r   r   typingr   r[   r   r   r   r   r	   r
   r   r   r   r    r   r?   r   sqlr   sql.visitorsr   engine.interfacesr   sql._typingr   r   sql.elementsr   r   sql.expressionr   sql.operatorsr   sql.selectabler   sql.type_apir   r   r   r    r!   util.typingr"   r#   r%   eqr1   ExpressionClauseListr3   rB   r   rJ   r.   r,   <module>r      s   # 	 $        #   !    -,82-(/-1254*6# T$e:& '\\
(
(*
( 
( 	
(  '\\
(
(*
( 
( 	
(_J++B/ _DxHNN2 xvr.   