o
    8Di;                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
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jrcd d	lmZ d d
lmZmZmZ d dlmZ d dlmZ e dZ!ej"dd Z#e$dZ%G dd deZ&G dd de'Z(dddZ)dd"d#Z*ej+dd'd(Z,ej+dd*d(Z,ej+dd,d(Z,d-d( Z,ej+dd.d/Z-ej+dd0d/Z-d1d/ Z-d2d3dd6d7Z.	8ddd>d?Z/	dddGdHZ0ddJdKZ1ddQdRZ2ddUdVZ3ddYdZZ4edd^d_Z5ddcddZ6ddgdhZ7ddidjZ8ddmdnZ9ddqdrZ:ddudvZ;	wddd{d|Z<dd}d~Z=dddZ>dddZ?dddZ@dddZAdddZBdddZCdddZDh dZEdddZFeGdZHeGdZIG dd dejJeHeIf ZKdS )    )annotationsN)
CollectionSet)contextmanagercopy)get_close_matches)Enumcountexp)AET)DialectType
Expressionz(?<!^)(?=[A-Z])   sqlglotc                   @  s   e Zd ZdZdd ZdS )AutoNamez
    This is used for creating Enum classes where `auto()` is the string form
    of the corresponding enum's identifier (e.g. FOO.value results in "FOO").

    Reference: https://docs.python.org/3/howto/enum.html#using-automatic-values
    c                 C  s   | S N )name_start_count_last_valuesr   r   G/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/helper.py_generate_next_value_$      zAutoName._generate_next_value_N)__name__
__module____qualname____doc__r   r   r   r   r   r      s    r   c                   @  s   e Zd ZdZd	d
ddZdS )classpropertyzB
    Similar to a normal property but works for class methods
    Nobjt.Anyownerreturnc                 C  s   t | jd | S r   )classmethodfget__get__)selfr%   r'   r   r   r   r+   -   s   zclassproperty.__get__r   )r%   r&   r'   r&   r(   r&   )r    r!   r"   r#   r+   r   r   r   r   r$   (   s    r$   kindstrwordpossibilitiest.Iterable[str]r(   Nonec                 C  sF   t ||dd}t|dpd}|rd| d}td|  d| d	| )
N   )nr    z Did you mean ?zUnknown z 'z'.)r   seq_get
ValueError)r-   r/   r0   close_matchessimilarr   r   r   suggest_closest_match_and_fail1   s
   r;   seqt.Sequence[T]indexintt.Optional[T]c                 C  s    z| | W S  t y   Y dS w )zVReturns the value in `seq` at position `index`, or `None` if `index` is out of bounds.N)
IndexError)r<   r>   r   r   r   r7   ?   s
   
r7   valuet.Collection[T]	t.List[T]c                 C     d S r   r   rB   r   r   r   ensure_listG   r   rG   t.Listc                 C  rE   r   r   rF   r   r   r   rG   K   r   r   c                 C  rE   r   r   rF   r   r   r   rG   O   r   c                 C  s(   | du rg S t | ttfrt| S | gS )z
    Ensures that a value is a list, otherwise casts or wraps it into one.

    Args:
        value: The value of interest.

    Returns:
        The value cast as a list if it's a list or a tuple, or else the value wrapped in a list.
    N)
isinstancelisttuplerF   r   r   r   rG   S   s
   
c                 C  rE   r   r   rF   r   r   r   ensure_collectione   r   rL   c                 C  rE   r   r   rF   r   r   r   rL   i   r   c                 C  s.   | du rg S t | trt | ttfs| S | gS )z
    Ensures that a value is a collection (excluding `str` and `bytes`), otherwise wraps it into a list.

    Args:
        value: The value of interest.

    Returns:
        The value if it's a collection, or else the value wrapped in a list.
    N)rI   r   r.   bytesrF   r   r   r   rL   m   s   
z, )separgsrN   c                 G  s   |  dd |D S )z
    Formats any number of string arguments as CSV.

    Args:
        args: The string arguments to format.
        sep: The argument separator.

    Returns:
        The arguments formatted as a CSV string.
    c                 s  s    | ]}|r|V  qd S r   r   .0argr   r   r   	<genexpr>   s    zcsv.<locals>.<genexpr>)join)rN   rO   r   r   r   csv~   s   rU   r   module_nameclassest.Type | t.Tuple[t.Type, ...]excludet.List[t.Type]c                   s&   dd t tj|   fddD S )ac  
    Returns all subclasses for a collection of classes, possibly excluding some of them.

    Args:
        module_name: The name of the module to search for subclasses in.
        classes: Class(es) we want to find the subclasses of.
        exclude: Class(es) we want to exclude from the returned list.

    Returns:
        The target subclasses.
    c                 S  s   g | ]\}}|qS r   r   )rQ   _r%   r   r   r   
<listcomp>   s    zsubclasses.<locals>.<listcomp>c                   s   t | ot|  o| vS r   )inspectisclass
issubclass)r%   rW   rY   r   r   <lambda>   s    zsubclasses.<locals>.<lambda>)r]   
getmemberssysmodules)rV   rW   rY   r   r`   r   
subclasses   s   re   thisexp.Expressionexpressions	t.List[E]offsetdialectr   c                 C  s   |rt |dkr
|S |d }ddlm} ddlm} ddlm} | js)|| |d t	|j
| jj|j
jj|j
jjfvr>|S |jsG|||d t	|j
|jj|j
jv rctd| ||| }|gS |S )a  
    Applies an offset to a given integer literal expression.

    Args:
        this: The target of the index.
        expressions: The expression the offset will be applied to, wrapped in a list.
        offset: The offset that will be applied.
        dialect: the dialect of interest.

    Returns:
        The original expression with the offset applied to it, wrapped in a list. If the provided
        `expressions` argument contains more than one expression, it's returned unaffected.
    r3   r   r   )annotate_types)simplify)rk   z Applying array index offset (%s))lenr   r    sqlglot.optimizer.annotate_typesrl   sqlglot.optimizer.simplifyrm   typetcastDataTyperf   TypeUNKNOWNARRAYINTEGER_TYPESloggerinfo)rf   rh   rj   rk   
expressionr   rl   rm   r   r   r   apply_index_offset   s(   r|   r   c                 C  s   t d|  S )zDConverts `name` from camelCase to snake_case and returns the result.r[   )CAMEL_CASE_PATTERNsubupperr   r   r   r   camel_to_snake_case   s   r   r{   r   funct.Callable[[Expression], E]r   c                 C  s   d}	 |du rt t|  D ]}t||_qt| }|| } t|  }t |D ]
}d|_t||_q)t| }||krG|D ]}d|_q>	 | S q)z
    Applies a transformation to a given expression until a fix point is reached.

    Args:
        expression: The expression to be transformed.
        func: The transformation to be applied.

    Returns:
        The transformed expression.
    N)reversedrK   walkhash_hash)r{   r   end_hashr4   
start_hashexpression_nodesr   r   r   while_changing   s$   r   dagt.Dict[T, t.Set[T]]c                 C  s   g }t |  D ]\}}|D ]}|| vrt | |< qq| rJdd |  D }|s,td|D ]}| | q.|  D ]}||8 }q:|t| | s|S )z
    Sorts a given directed acyclic graph in topological order.

    Args:
        dag: The graph to be sorted.

    Returns:
        A list that contains all of the graph's nodes in topological order.
    c                 S  s   h | ]\}}|s|qS r   r   )rQ   nodedepsr   r   r   	<setcomp>  s    ztsort.<locals>.<setcomp>zCycle error)rK   itemssetr8   popvaluesextendsorted)r   resultr   r   depcurrentr   r   r   tsort  s$   


r   	file_namet.TextIOc                 C  sb   t | d}|ddk}W d   n1 sw   Y  |r*ddl}|j | dddS t | d	dd
S )zSOpen a file that may be compressed as gzip and return it in universal newline mode.rbr   s   Nr   rtr5   )newlinezutf-8)encodingr   )openreadgzip)r   fgzippedr   r   r   r   	open_file%  s   r   read_csvexp.ReadCSVr&   c                 c  sz    | j }t| j}d}tdd |D }t||D ]
\}}|dkr#|}qzddl}|j||dV  W |  dS |  w )z
    Returns a csv reader given the expression `READ_CSV(name, ['delimiter', '|', ...])`.

    Args:
        read_csv: A `ReadCSV` function call.

    Yields:
        A python csv reader.
    ,c                 s  s    | ]}|j V  qd S r   r   rP   r   r   r   rS   A  s    zcsv_reader.<locals>.<genexpr>	delimiterr   N)r   )rh   r   r   iterziprU   readerclose)r   rO   filer   kvcsv_r   r   r   
csv_reader2  s   
r   takent.Collection[str]basec                 C  sH   || vr|S d}| d| }|| v r"|d7 }| d| }|| v s|S )z
    Searches for a new name.

    Args:
        taken: A collection of taken names.
        base: Base name to alter.

    Returns:
        The new, available name.
    r   r[   r3   r   )r   r   inewr   r   r   find_new_nameN  s   r   textboolc                 C  
   t | tS r   )is_typer?   r   r   r   r   is_inte     
r   c                 C  r   r   )r   floatr   r   r   r   is_floati  r   r   target_typet.Typec                 C  s$   z||  W dS  t y   Y dS w NTF)r8   )r   r   r   r   r   r   m  s   r   prefixt.Callable[[], str]c                   s   t   fddS )zTReturns a name generator given a prefix (e.g. a0, a1, a2, ... if the prefix is "a").c                     s     t  S r   nextr   r   sequencer   r   ra   x  s    zname_sequence.<locals>.<lambda>r
   )r   r   r   r   name_sequenceu  s   r   r%   t.Dictc                 K  s   i dd t |  D |S )z9Returns a dictionary created from an object's attributes.c                 S  s,   i | ]\}}|t |d r| nt|qS r   )hasattrr   )rQ   r   r   r   r   r   
<dictcomp>~  s   , z"object_to_dict.<locals>.<dictcomp>)varsr   )r%   kwargsr   r   r   object_to_dict{  s
   r   Tmin_num_wordsfill_from_startt.List[t.Optional[str]]c                 C  s:   |  |}|rdg|t|  | S |dg|t|   S )a  
    Perform a split on a value and return N words as a result with `None` used for words that don't exist.

    Args:
        value: The value to be split.
        sep: The value to use to split on.
        min_num_words: The minimum number of words that are going to be in the result.
        fill_from_start: Indicates that if `None` values should be inserted at the start or end of the list.

    Examples:
        >>> split_num_words("db.table", ".", 3)
        [None, 'db', 'table']
        >>> split_num_words("db.table", ".", 3, fill_from_start=False)
        ['db', 'table', None]
        >>> split_num_words("db.table", ".", 1)
        ['db', 'table']

    Returns:
        The list of words returned by `split`, possibly augmented by a number of `None` values.
    N)splitrn   )rB   rN   r   r   wordsr   r   r   split_num_words  s   
r   c                 C  s(   ddl m} t| dot| tt|f S )aF  
    Checks if the value is an iterable, excluding the types `str` and `bytes`.

    Examples:
        >>> is_iterable([1,2])
        True
        >>> is_iterable("test")
        False

    Args:
        value: The value to check if it is an iterable.

    Returns:
        A `bool` value indicating if it is an iterable.
    r   r   __iter__)r   r   r   rI   r.   rM   )rB   r   r   r   r   is_iterable  s   r   r   %t.Iterable[t.Iterable[t.Any] | t.Any]t.Iterator[t.Any]c                 c  s.    | D ]}t |rt|E dH  q|V  qdS )a  
    Flattens an iterable that can contain both iterable and non-iterable elements. Objects of
    type `str` and `bytes` are not regarded as iterables.

    Examples:
        >>> list(flatten([[1, 2], 3, {4}, (5, "bla")]))
        [1, 2, 3, 4, 5, 'bla']
        >>> list(flatten([1, 2, 3]))
        [1, 2, 3]

    Args:
        values: The value to be flattened.

    Yields:
        Non-iterable elements in `values`.
    N)r   flatten)r   rB   r   r   r   r     s   r   dc                 C  sB   zdt tt|   W S  ty   Y dS  ty    Y dS w )a  
    Get the nesting depth of a dictionary.

    Example:
        >>> dict_depth(None)
        0
        >>> dict_depth({})
        1
        >>> dict_depth({"a": "b"})
        1
        >>> dict_depth({"a": {}})
        2
        >>> dict_depth({"a": {"b": {}}})
        3
    r3   r   )
dict_depthr   r   r   AttributeErrorStopIteration)r   r   r   r   r     s   r   itt.Iterable[T]c                 C  s   t dd | D S )z=Returns the first element from an iterable (useful for sets).c                 s  s    | ]}|V  qd S r   r   )rQ   r   r   r   r   rS     s    zfirst.<locals>.<genexpr>r   )r   r   r   r   first  s   r   t.Optional[str | bool]c                 C  s:   t | ts	| d u r| S |  }|dv rdS |dv rdS | S )N)true1T)false0F)rI   r   lower)rB   value_lowerr   r   r   to_bool  s   r   rangest.List[t.Tuple[A, A]]c                 C  sj   | sg S t | } | d g}| dd D ]\}}|d \}}||kr+|t||f|d< q|||f q|S )z
    Merges a sequence of ranges, represented as tuples (low, high) whose values
    belong to some totally-ordered set.

    Example:
        >>> merge_ranges([(1, 3), (2, 6)])
        [(1, 6)]
    r   r3   N)r   maxappend)r   mergedstartend
last_startlast_endr   r   r   merge_ranges  s   	
r   c                 C  s(   z	t j|  W dS  ty   Y dS w r   )datetimedatefromisoformatr8   r   r   r   r   is_iso_date     r   c                 C  s(   z	t j |  W dS  ty   Y dS w r   )r   r   r8   r   r   r   r   is_iso_datetime  r   r   >   dayweekyearmonthquarter
year_montht.Optional[exp.Expression]c                 C  s   | d uo
| j  tv S r   )r   r   
DATE_UNITS)r{   r   r   r   is_date_unit)  s   r  KVc                   @  s8   e Zd ZdZdddZdddZdddZdddZdS )SingleValuedMappingz
    Mapping where all keys return the same value.

    This rigamarole is meant to avoid copying keys, which was originally intended
    as an optimization while qualifying columns for tables with lots of columns.
    keyst.Collection[K]rB   r  c                 C  s"   t |tr|nt|| _|| _d S r   )rI   r   r   _keys_value)r,   r
  rB   r   r   r   __init__9  s   
zSingleValuedMapping.__init__keyr  r(   c                 C  s   || j v r| jS t|r   )r  r  KeyError)r,   r  r   r   r   __getitem__=  s   
zSingleValuedMapping.__getitem__r?   c                 C  
   t | jS r   )rn   r  r,   r   r   r   __len__B  r   zSingleValuedMapping.__len__t.Iterator[K]c                 C  r  r   )r   r  r  r   r   r   r   E  r   zSingleValuedMapping.__iter__N)r
  r  rB   r  )r  r  r(   r  )r(   r?   )r(   r  )r    r!   r"   r#   r  r  r  r   r   r   r   r   r	  1  s    


r	  )r-   r.   r/   r.   r0   r1   r(   r2   )r<   r=   r>   r?   r(   r@   )rB   rC   r(   rD   )rB   r2   r(   rH   )rB   r   r(   rD   )rB   rC   r(   rC   )rB   r   r(   rC   )rO   r.   rN   r.   r(   r.   )r   )rV   r.   rW   rX   rY   rX   r(   rZ   r   )
rf   rg   rh   ri   rj   r?   rk   r   r(   ri   )r   r.   r(   r.   )r{   r   r   r   r(   r   )r   r   r(   rD   )r   r.   r(   r   )r   r   r(   r&   )r   r   r   r.   r(   r.   )r   r.   r(   r   )r   r.   r   r   r(   r   )r   r.   r(   r   )r%   r&   r(   r   )T)
rB   r.   rN   r.   r   r?   r   r   r(   r   )rB   r&   r(   r   )r   r   r(   r   )r   r   r(   r?   )r   r   r(   r   )rB   r   r(   r   )r   r   r(   r   )r{   r  r(   r   )L
__future__r   r   r]   loggingrerc   typingrr   collections.abcr   r   
contextlibr   r   difflibr   enumr	   	itertoolsr   TYPE_CHECKINGr   r   sqlglot._typingr   r   r   sqlglot.dialects.dialectr   sqlglot.expressionsr   compiler}   version_infoPYTHON_VERSION	getLoggerry   r   propertyr$   r;   r7   overloadrG   rL   rU   re   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  TypeVarr  r  Mappingr	  r   r   r   r   <module>   s    


	

0

)
"





	







	


