o
    8DiP                     @  s  d dl mZ d dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZmZ d dlmZmZmZ ejrEd dlmZ ejejeejf ZG d	d
 d
ejZG dd dZG dd deeZ			d;d<ddZd=d!d"Zd>d&d'Z 	d?d@d-d.Z!dd/dAd5d6Z"dBd9d:Z#dS )C    )annotationsN)expressions)Dialect)SchemaError)
dict_depthfirst)
TrieResultin_trienew_trie)DialectTypec                   @  s   e Zd ZU dZded< ej				d#d$ddZej			d%d&ddZej		d'd(ddZ			d'd)ddZ
eejd*dd Zed+d!d"ZdS ),Schemaz(Abstract base class for database schemasr   dialectNTtableexp.Table | strcolumn_mappingt.Optional[ColumnMapping]	normalizet.Optional[bool]match_depthboolreturnNonec                 C     dS )a  
        Register or update a table. Some implementing classes may require column information to also be provided.
        The added table must have the necessary number of qualifiers in its path to match the schema's nesting level.

        Args:
            table: the `Table` expression instance or string representing the table.
            column_mapping: a column mapping that describes the structure of the table.
            dialect: the SQL dialect that will be used to parse `table` if it's a string.
            normalize: whether to normalize identifiers according to the dialect of interest.
            match_depth: whether to enforce that the table must match the schema's depth or not.
        N )selfr   r   r   r   r   r   r   G/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlglot/schema.py	add_table       zSchema.add_tableFonly_visiblet.Sequence[str]c                 C  r   )a  
        Get the column names for a table.

        Args:
            table: the `Table` expression instance.
            only_visible: whether to include invisible columns.
            dialect: the SQL dialect that will be used to parse `table` if it's a string.
            normalize: whether to normalize identifiers according to the dialect of interest.

        Returns:
            The sequence of column names.
        Nr   )r   r   r   r   r   r   r   r   column_names,   r   zSchema.column_namescolumnexp.Column | strexp.DataTypec                 C  r   )a  
        Get the `sqlglot.exp.DataType` type of a column in the schema.

        Args:
            table: the source table.
            column: the target column.
            dialect: the SQL dialect that will be used to parse `table` if it's a string.
            normalize: whether to normalize identifiers according to the dialect of interest.

        Returns:
            The resulting column type.
        Nr   )r   r   r!   r   r   r   r   r   get_column_typeA   r   zSchema.get_column_typec                 C  s(   t |tr|n|j}|| j|||dv S )a  
        Returns whether `column` appears in `table`'s schema.

        Args:
            table: the source table.
            column: the target column.
            dialect: the SQL dialect that will be used to parse `table` if it's a string.
            normalize: whether to normalize identifiers according to the dialect of interest.

        Returns:
            True if the column appears in the schema, False otherwise.
        r   r   )
isinstancestrnamer    )r   r   r!   r   r   r(   r   r   r   
has_columnV   s   zSchema.has_columnt.Tuple[str, ...]c                 C  r   )zW
        Table arguments this schema support, e.g. `("this", "db", "catalog")`
        Nr   r   r   r   r   supported_table_argsl   r   zSchema.supported_table_argsc                 C  r   )z$Returns whether the schema is empty.Tr   r+   r   r   r   emptys   s   zSchema.emptyNNNTr   r   r   r   r   r   r   r   r   r   r   r   FNN)
r   r   r   r   r   r   r   r   r   r   NN
r   r   r!   r"   r   r   r   r   r   r#   
r   r   r!   r"   r   r   r   r   r   r   r   r*   r   r   )__name__
__module____qualname____doc____annotations__abcabstractmethodr   r    r$   r)   propertyr,   r-   r   r   r   r   r      s4   
 r   c                   @  sf   e Zd Z	d"d#ddZed$d	d
Zd%ddZed&ddZd'ddZ	d(d)ddZ		d*d+d d!Z
dS ),AbstractMappingSchemaNmappingt.Optional[t.Dict]r   r   c                 C  s8   |pi | _ tdd t| j |  dD | _t | _d S )Nc                 s  s    | ]	}t t|V  qd S N)tuplereversed).0tr   r   r   	<genexpr>   s    
z1AbstractMappingSchema.__init__.<locals>.<genexpr>)depth)r?   r
   flatten_schemarG   mapping_trierB   _supported_table_args)r   r?   r   r   r   __init__z   s
   

zAbstractMappingSchema.__init__r   c                 C  s   | j  S rA   )r?   r+   r   r   r   r-      s   zAbstractMappingSchema.emptyintc                 C  s
   t | jS rA   )r   r?   r+   r   r   r   rG      s   
zAbstractMappingSchema.depthr*   c                 C  sh   | j s1| jr1|  }|st | _ | j S d|  krdkr*n ntjd | | _ | j S td| | j S )N      zInvalid mapping shape. Depth: )rJ   r?   rG   rB   expTABLE_PARTSr   )r   rG   r   r   r   r,      s   z*AbstractMappingSchema.supported_table_argsr   	exp.Tablet.List[str]c                 C  s   dd t |jD S )Nc                 S  s   g | ]}|j qS r   )r(   )rD   partr   r   r   
<listcomp>   s    z5AbstractMappingSchema.table_parts.<locals>.<listcomp>)rC   parts)r   r   r   r   r   table_parts   s   z!AbstractMappingSchema.table_partsTFraise_on_missingensure_data_typest.Optional[t.Any]c           	      C  s   |  |dt| j }t| j|\}}|tjkrdS |tjkrKt|}t|dkr2|	|d  nd
dd |D }|rItd| d| d	dS | j||d
S )aW  
        Returns the schema of a given table.

        Args:
            table: the target table.
            raise_on_missing: whether to raise in case the schema is not found.
            ensure_data_types: whether to convert `str` types to their `DataType` equivalents.

        Returns:
            The schema of the target table.
        r   NrM   z, c                 s  s    | ]}d  |V  qdS ).N)join)rD   rU   r   r   r   rF      s    z-AbstractMappingSchema.find.<locals>.<genexpr>zAmbiguous mapping for : rZ   rW   )rV   lenr,   r	   rI   r   FAILEDPREFIXrH   extendr[   r   
nested_get)	r   r   rW   rX   rU   valuetriepossibilitiesmessager   r   r   find   s   

zAbstractMappingSchema.findrU   r   dc                 C  s(   t |p| jgt| jt|R d|iS )NrW   )rb   r?   zipr,   rC   )r   rU   rh   rW   r   r   r   rb      s   z AbstractMappingSchema.nested_getrA   )r?   r@   r   r   r5   r   rL   r4   )r   rQ   r   rR   TFr   rQ   rW   r   rX   r   r   rY   )NT)rU   r   rh   r@   r   rY   )r6   r7   r8   rK   r=   r-   rG   r,   rV   rg   rb   r   r   r   r   r>   y   s    


"r>   c                      s   e Zd ZdZ				d?d@ fddZedAddZ	dBdC fddZdDddZ				d?dEd!d"Z				dFdGd%d&Z
		dHdId*d+Z		dHdJd,d-ZdKd/d0Z		dHdLd1d2Z			dMdNd7d8ZdO fd:d;ZdPdQd=d>Z  ZS )RMappingSchemaa!  
    Schema based on a nested mapping.

    Args:
        schema: Mapping in one of the following forms:
            1. {table: {col: type}}
            2. {db: {table: {col: type}}}
            3. {catalog: {db: {table: {col: type}}}}
            4. None - Tables will be added later
        visible: Optional mapping of which columns in the schema are visible. If not provided, all columns
            are assumed to be visible. The nesting should mirror that of the schema:
            1. {table: set(*cols)}}
            2. {db: {table: set(*cols)}}}
            3. {catalog: {db: {table: set(*cols)}}}}
        dialect: The dialect to be used for custom type mappings & parsing string arguments.
        normalize: Whether to normalize identifier names according to the given dialect or not.
    NTschemar@   visibler   r   r   r   r   r   c                   s`   || _ |d u r	i n|| _|| _i | _d| _|d u ri n|}t | jr+| | d S | d S )Nr   )r   ro   r   _type_mapping_cache_depthsuperrK   
_normalize)r   rn   ro   r   r   	__class__r   r   rK      s   &zMappingSchema.__init__mapping_schemac                 C  s   t |j|j|j|jdS )Nrn   ro   r   r   )rm   r?   ro   r   r   )clsrv   r   r   r   from_mapping_schema   s   z!MappingSchema.from_mapping_schemaFr   rQ   rW   rX   rY   c                   s:   t  j|||d}|rt|tr fdd| D }|S )N)rW   rX   c                   s*   i | ]\}}|t |tr |n|qS r   )r&   r'   _to_data_type)rD   coldtyper+   r   r   
<dictcomp>   s    z&MappingSchema.find.<locals>.<dictcomp>)rr   rg   r&   dictitems)r   r   rW   rX   rn   rt   r+   r   rg      s   
zMappingSchema.findc                 K  s,   t di | j | j | j| jd|S )Nrw   r   )rm   r?   copyro   r   r   )r   kwargsr   r   r   r     s   zMappingSchema.copyr   r   r   r   r   c           
        s   j | d}|r(js(t|j kr(td|jjd d  d fddt|	 D }j
|dd	}|rD|sDd
S |}	tjtt|	| t|	gj d
S )a  
        Register or update a table. Updates are only performed if a new column mapping is provided.
        The added table must have the necessary number of qualifiers in its path to match the schema's nesting level.

        Args:
            table: the `Table` expression instance or string representing the table.
            column_mapping: a column mapping that describes the structure of the table.
            dialect: the SQL dialect that will be used to parse `table` if it's a string.
            normalize: whether to normalize identifiers according to the dialect of interest.
            match_depth: whether to enforce that the table must match the schema's depth or not.
        r%   Table r   z( must match the schema's nesting level: rZ   c                   s"   i | ]\}}j | d |qS )r%   _normalize_name)rD   keyrc   r   r   r   r   r   r}   '  s    z+MappingSchema.add_table.<locals>.<dictcomp>Fr]   N)_normalize_tabler-   r^   rU   rG   r   sqlr   ensure_column_mappingr   rg   rV   
nested_setr?   rB   rC   r
   rI   )
r   r   r   r   r   r   normalized_tablenormalized_column_mappingrn   rU   r   r   r   r     s    

zMappingSchema.add_tabler   rR   c                   sb   | j |||d}| |}|d u rg S |r| jst|S | | || jp'g   fdd|D S )Nr%   c                   s   g | ]}| v r|qS r   r   )rD   r{   ro   r   r   rT   F  s    z.MappingSchema.column_names.<locals>.<listcomp>)r   rg   ro   listrb   rV   )r   r   r   r   r   r   rn   r   r   r   r    5  s   

zMappingSchema.column_namesr!   r"   r#   c           	      C  s   | j |||d}| jt|tr|n|j||d}| j|dd}|r:||}t|tjr.|S t|tr:| j	||dS tj
dS )Nr%   Fr]   r   unknown)r   r   r&   r'   thisrg   getrO   DataTyperz   build)	r   r   r!   r   r   r   normalized_column_nametable_schemacolumn_typer   r   r   r$   H  s   

zMappingSchema.get_column_typec                 C  sN   | j |||d}| jt|tr|n|j||d}| j|dd}|r%||v S dS )Nr%   Fr]   )r   r   r&   r'   r   rg   )r   r   r!   r   r   r   r   r   r   r   r   r)   `  s   zMappingSchema.has_columnt.Dictc           
   	     s   i }t |}d}|D ]r}t|gt||R  }t|ts/t|d|dd t|d |s@tdd|dd  dtt	|
 tr^t|d|t |d  t|d  fdd	|D }| D ]\}}	t|| |g |	 qkq
|S )
z
        Normalizes all identifiers in the schema.

        Args:
            schema: the schema to normalize.

        Returns:
            The normalized schema mapping.
        z3Table {} must match the schema's nesting level: {}.rZ   Nr   r   z must have at least one columnc                   s   g | ]	} j |d dqS )T)is_tabler   )rD   r   r+   r   r   rT     s    z,MappingSchema._normalize.<locals>.<listcomp>)rH   rb   ri   r&   r~   r   formatr[   r^   r   valuesr   r   r   )
r   rn   normalized_mappingflattened_schema	error_msgkeyscolumnsnormalized_keyscolumn_namer   r   r+   r   rs   p  s0   

&zMappingSchema._normalizec              	   C  sf   |p| j }|d u r| jn|}tj|tj||d}|r1|jD ]}t|tjr0|t	||d|d q|S )N)intor   r   Tr   r   r   )
r   r   rO   maybe_parseTablerU   r&   
Identifierreplacenormalize_name)r   r   r   r   r   rS   r   r   r   r     s   

zMappingSchema._normalize_tabler(   str | exp.Identifierr   r'   c                 C  s,   t ||p| j||d u r| jdjS |djS )Nr   )r   r   r   r(   )r   r(   r   r   r   r   r   r   r     s   zMappingSchema._normalize_namerL   c                   s"   | j s| jst  d | _| jS )NrM   )r-   rq   rr   rG   r+   rt   r   r   rG     s   zMappingSchema.depthschema_typec              	   C  s   || j vr<|p	| j}t|j}ztjj|||d}|| j |< W n ty;   |r.d| nd}t	d| d| dw | j | S )aH  
        Convert a type represented as a string to the corresponding `sqlglot.exp.DataType` object.

        Args:
            schema_type: the type we want to convert.
            dialect: the SQL dialect that will be used to parse `schema_type`, if needed.

        Returns:
            The resulting expression type.
        )r   udtz in dialect  zFailed to build type ''rZ   )
rp   r   r   get_or_raiseSUPPORTS_USER_DEFINED_TYPESrO   r   r   AttributeErrorr   )r   r   r   r   
expression
in_dialectr   r   r   rz     s   


zMappingSchema._to_data_typer.   )
rn   r@   ro   r@   r   r   r   r   r   r   )rv   rm   r   rm   rk   rl   )r   rm   r/   r0   )
r   r   r   r   r   r   r   r   r   rR   r1   r2   r3   )rn   r   r   r   )r   r   r   r   r   r   r   rQ   )NFN)
r(   r   r   r   r   r   r   r   r   r'   rj   rA   )r   r'   r   r   r   r#   )r6   r7   r8   r9   rK   classmethodry   rg   r   r   r    r$   r)   rs   r   r   rG   rz   __classcell__r   r   rt   r   rm      sJ    	
,
)rm   FT
identifierr   r   r   r   r   r   r   r   exp.Identifierc                 C  s:   t | trtj| |d} |s| S || jd< t|| S )Nr   r   )r&   r'   rO   parse_identifiermetar   r   normalize_identifier)r   r   r   r   r   r   r   r     s   

r   rn   Schema | t.Optional[t.Dict]r   t.Anyc                 K  s   t | tr| S t| fi |S rA   )r&   r   rm   )rn   r   r   r   r   ensure_schema  s   
r   r?   r   r   c                 C  sp   | d u ri S t | tr| S t | tr#dd | dD }dd |D S t | tr/dd | D S tdt|  )Nc                 S  s   g | ]}|  qS r   striprD   xr   r   r   rT     s    z)ensure_column_mapping.<locals>.<listcomp>,c                 S  s.   i | ]}| d d  | d d  qS ):r   rM   )splitr   )rD   name_type_strr   r   r   r}     s     z)ensure_column_mapping.<locals>.<dictcomp>c                 S  s   i | ]}|  d qS rA   r   r   r   r   r   r}     s    zInvalid mapping provided: )r&   r~   r'   r   r   
ValueErrortype)r?   col_name_type_strsr   r   r   r     s   


r   rG   t.Optional[int]r   t.Optional[t.List[str]]t.List[t.List[str]]c                 C  s   g }|pg }|d u rt | d n|}|  D ](\}}|dks#t|ts,|||g  q|dkr>|t||d ||g  q|S )NrM      )r   r   r&   r~   appendra   rH   )rn   rG   r   tableskvr   r   r   rH      s   rH   r]   rh   patht.Tuple[str, str]rW   rY   c                G  sR   |D ]$\}}|  |} | du r&|r#|dkrdn|}td| d|  dS q| S )aH  
    Get a value for a nested dictionary.

    Args:
        d: the dictionary to search.
        *path: tuples of (name, key), where:
            `key` is the key in the dictionary to get.
            `name` is a string to use in the error if `key` isn't found.

    Returns:
        The value or None if it doesn't exist.
    Nr   r   zUnknown r\   )r   r   )rh   rW   r   r(   r   r   r   r   rb     s   
rb   r   rc   c                 C  sh   |s| S t |dkr|| |d < | S | }|dd D ]}||vr'||i }q|| }q|||d < | S )aG  
    In-place set a value for a nested dictionary

    Example:
        >>> nested_set({}, ["top_key", "second_key"], "value")
        {'top_key': {'second_key': 'value'}}

        >>> nested_set({"top_key": {"third_key": "third_value"}}, ["top_key", "second_key"], "value")
        {'top_key': {'third_key': 'third_value', 'second_key': 'value'}}

    Args:
        d: dictionary to update.
        keys: the keys that makeup the path to `value`.
        value: the value to set in the dictionary for the given key path.

    Returns:
        The (possibly) updated dictionary.
    rM   r   Nr   )r^   
setdefault)rh   r   rc   subdr   r   r   r   r   *  s   
r   )NFT)
r   r   r   r   r   r   r   r   r   r   )rn   r   r   r   r   r   )r?   r   r   r   r1   )rn   r   rG   r   r   r   r   r   )rh   r   r   r   rW   r   r   rY   )rh   r   r   r   rc   r   r   r   )$
__future__r   r;   typingrE   sqlglotr   rO   sqlglot.dialects.dialectr   sqlglot.errorsr   sqlglot.helperr   r   sqlglot.trier   r	   r
   TYPE_CHECKINGr   UnionDictr'   ListColumnMappingABCr   r>   rm   r   r   r   rH   rb   r   r   r   r   r   <module>   s6    gN  

