o
    YiL                     @   s  d Z ddl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mZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ edZeddZdd ZG dd dejZG dd dZG dd dZG dd dZ dd Z!dd Z"dd Z#G dd dZ$dS ) z
Various data structures used in query construction.

Factored out from django.db.models.query to avoid making the main module very
large and/or so that they can be used by other modules without getting into
circular import difficulties.
    N)
namedtuple)nullcontext)
FieldError)DEFAULT_DB_ALIASDatabaseErrorconnectionsmodelstransaction)
LOOKUP_SEP)tree)cached_property)make_hashabledjango.db.modelsPathInfozGfrom_opts to_opts target_fields join_field m2m direct filtered_relationc                 c   s(    | V  |   D ]	}t|E d H  qd S N)__subclasses__
subclassesclssubclass r   |/var/www/snowflake_co_dev_github/snow_flake_back_end_deploy/env/lib/python3.10/site-packages/django/db/models/query_utils.pyr   !   s
   r   c                       s   e Zd ZdZdZdZdZeZdZdeeefZ	ddd fd	d

Z
dd Zdd Zdd Zdd Zdd Z	d'ddZdd Zdd ZefddZdd Zedd  Zd!d" Zd#d$ Zed%d& Z  ZS )(Qze
    Encapsulate filters as objects that can then be combined logically (using
    `&` and `|`).
    ANDORXORTNF)
_connector_negatedc                   s^   || j vrddd | j dd  D }td| dt jg |t| ||d d S )Nz, c                 s   s    | ]}|V  qd S r   r   ).0connr   r   r   	<genexpr>7   s    zQ.__init__.<locals>.<genexpr>   z_connector must be one of z
, or None.)children	connectornegated)
connectorsjoin
ValueErrorsuper__init__sorteditems)selfr   r   argskwargsconnector_reprs	__class__r   r   r)   5   s   

z
Q.__init__c                 C   sb   t |dddu rt|| s| S |st|tr|  S | j|d}|| | ||| |S )NconditionalF)r#   )getattr	TypeErrorcopy
isinstancer   createadd)r,   otherr   objr   r   r   _combine?   s   z
Q._combinec                 C      |  || jS r   )r;   r   r,   r9   r   r   r   __or__L      zQ.__or__c                 C   r<   r   )r;   r   r=   r   r   r   __and__O   r?   z	Q.__and__c                 C   r<   r   )r;   r   r=   r   r   r   __xor__R   r?   z	Q.__xor__c                 C   s   |   }|  |S r   )r5   negate)r,   r:   r   r   r   
__invert__U   s   zQ.__invert__c                 C   s(   |j | ||dd|d\}}|| |S )NF)allow_joins
split_subqcheck_filterable	summarize)_add_qpromote_joins)r,   queryrD   reuserG   for_saveclausejoinsr   r   r   resolve_expressionZ   s   

zQ.resolve_expressionc                 C   s  |s| S | j | j| jd}| jD ]s}|}t|trx|\}}t|v r*|td\}}n|}d }t	|}	|	
| }
|	urw|d u rBd}|
| }d u r_|
| }d ur_||
}
d}|
|}|d u rn|dkrn|
d}d}|d urw||
|}n|
|}|j| q|S )N)r#   r$   r!   exactisnullT)r7   r#   r$   r"   r6   tupler
   rsplitr   Freplace_expressions
get_lookupget_transformappend)r,   replacementsclonechildchild_replacementlhsrhspathlookupfieldfield_replacementlookup_classtransform_classr   r   r   rU   j   sB   






zQ.replace_expressionsc                 c   sJ    | V  | j D ]}t|tr|d }t|dr| E dH  q|V  qdS )zg
        Recursively yield this Q object and all subexpressions, in depth-first
        order.
        r!   flattenN)r"   r6   rR   hasattrre   )r,   r[   r   r   r   re      s   


z	Q.flattenc              
   C   sJ  ddl m}m} ddlm} ddlm} ddlm} |d}|	 D ]\}	}
t
|
ds/||
}
|j|
|	dd	 q"||d
d t| }|jjrV|t|| d| d n||  |j|d}|jrjtj|dnt }z| ||duW  d   W S 1 sw   Y  W dS  ty } ztd| | W Y d}~dS d}~ww )z|
        Do a database query to check if the expressions of the Q instance
        matches against the expressions.
        r   )BooleanFieldValue)Coalesce)Query)SINGLENrO   F)selectr!   _checkT)output_field)usingz.Got a database error calling check() on %r: %s)django.db.modelsrg   rh   django.db.models.functionsri   django.db.models.sqlrj   django.db.models.sql.constantsrk   r+   rf   add_annotationr   featuressupports_comparing_boolean_expradd_qr   get_compilerin_atomic_blockr	   atomicr   execute_sqlr   loggerwarning)r,   againstro   rg   rh   ri   rj   rk   rJ   namevalue
connectioncompilercontext_managerer   r   r   check   s8   

(zQ.checkc                 C   sf   d| j j| j jf }|dr|dd}t| j}i }| j| jkr'| j|d< | j	r.d|d< |||fS )Nz%s.%szdjango.db.models.query_utilsr   r   Tr   )
r1   
__module____name__
startswithreplacerR   r"   r#   defaultr$   )r,   r_   r-   r.   r   r   r   deconstruct   s   



zQ.deconstructc                 C   sb   |   \}}}|g| }|D ]}t|tr'|\}}t|}|||f q|| qt|S r   )r   r+   r6   rR   r   rX   )r,   r_   r-   r.   identityr[   argr   r   r   r   r      s   
z
Q.identityc                 C   s   t |tstS |j| jkS r   )r6   r   NotImplementedr   r=   r   r   r   __eq__   s   
zQ.__eq__c                 C   s
   t | jS r   )hashr   )r,   r   r   r   __hash__      
z
Q.__hash__c                 C   s    ddl m} dd || D S )z
        Retrieve all base fields referenced directly or through F expressions
        excluding any fields referenced through joins.
        r   )rJ   c                 S   s   h | ]
}| td d qS )r!   r   )splitr
   )r   r[   r   r   r   	<setcomp>   s    z+Q.referenced_base_fields.<locals>.<setcomp>)rr   rJ   get_children_from_q)r,   rJ   r   r   r   referenced_base_fields   s   zQ.referenced_base_fields)NTNFF)r   r   __qualname____doc__r   r   r   r   r2   r%   r)   r;   r>   r@   rA   rC   rO   rU   re   r   r   r   r   r   r   r   r   __classcell__r   r   r0   r   r   '   s4    

'$
r   c                   @   s*   e Zd ZdZdd Zd	ddZdd ZdS )
DeferredAttributez
    A wrapper for a deferred-loading field. When the value is read from this
    object the first time, the query is executed.
    c                 C   s
   || _ d S r   )ra   )r,   ra   r   r   r   r)      r   zDeferredAttribute.__init__Nc                 C   sr   |du r| S |j }| jj}||vr5| |}|du r1| s&| jjr&td|j|gd || S |||< || S )zx
        Retrieve and caches the value from the datastore on the first lookup.
        Return the cached value.
        Nz4Cannot read a generated field from an unsaved model.)fields)__dict__ra   attname_check_parent_chain
_is_pk_set	generatedAttributeErrorrefresh_from_db)r,   instancer   data
field_namevalr   r   r   __get__   s   
zDeferredAttribute.__get__c                 C   s6   |j }|| jj}| jjr| j|krt||jS dS )z
        Check if the field value can be fetched from a parent field already
        loaded in the instance. This can be done if the to-be fetched
        field is a primary key field.
        N)_metaget_ancestor_linkra   modelprimary_keyr3   r   )r,   r   opts
link_fieldr   r   r   r     s
   z%DeferredAttribute._check_parent_chainr   )r   r   r   r   r)   r   r   r   r   r   r   r      s
    
r   c                   @   s    e Zd ZdZdd Zdd ZdS )class_or_instance_methodz
    Hook used in RegisterLookupMixin to return partial functions depending on
    the caller type (instance or class of models.Field).
    c                 C   s   || _ || _d S r   )class_methodinstance_method)r,   r   r   r   r   r   r)   &  s   
z!class_or_instance_method.__init__c                 C   s$   |d u rt | j|S t | j|S r   )	functoolspartialr   r   )r,   r   ownerr   r   r   r   *  s   z class_or_instance_method.__get__N)r   r   r   r   r)   r   r   r   r   r   r      s    r   c                   @   s   e Zd Zdd Zejdd Zdd ZeeeZ	e
eZdd Zd	d
 Zedd Ze
dd ZdddZdddZeeeZe
eZdddZdddZeeeZe
eZdS )RegisterLookupMixinc                 C   s   |   |d S r   )get_lookupsget)r,   lookup_namer   r   r   _get_lookup1  s   zRegisterLookupMixin._get_lookupc                 C   s   dd t | D }| |S )Nc                 S   s   g | ]	}|j d i qS )class_lookups)r   r   )r   parentr   r   r   
<listcomp>6  s    z9RegisterLookupMixin.get_class_lookups.<locals>.<listcomp>)inspectgetmromerge_dicts)r   r   r   r   r   get_class_lookups4  s   
z%RegisterLookupMixin.get_class_lookupsc                 C   s(   |   }t| dd  }ri ||S |S Ninstance_lookups)r   r3   )r,   r   r   r   r   r   get_instance_lookups;  s   z(RegisterLookupMixin.get_instance_lookupsc                 C   N   ddl m} | |}|d u rt| dr| j|S |d ur%t||s%d S |S )Nr   )Lookuprn   )django.db.models.lookupsr   r   rf   rn   rV   
issubclass)r,   r   r   foundr   r   r   rV   D     
zRegisterLookupMixin.get_lookupc                 C   r   )Nr   )	Transformrn   )r   r   r   rf   rn   rW   r   )r,   r   r   r   r   r   r   rW   N  r   z!RegisterLookupMixin.get_transformc                 C   s    i }t | D ]}|| q|S )z
        Merge dicts in reverse to preference the order of the original list. e.g.,
        merge_dicts([a, b]) will preference the keys in 'a' over those in 'b'.
        )reversedupdate)dictsmergeddr   r   r   r   X  s   zRegisterLookupMixin.merge_dictsc                 C   s   t | D ]}|j  qd S r   )r   r   cache_clearr   r   r   r   _clear_cached_class_lookupsc  s   z/RegisterLookupMixin._clear_cached_class_lookupsNc                 C   s4   |d u r|j }d| jvri | _|| j|< |   |S )Nr   )r   r   r   r   r   r`   r   r   r   r   register_class_lookuph  s   

z)RegisterLookupMixin.register_class_lookupc                 C   s,   |d u r|j }d| jvri | _|| j|< |S r   )r   r   r   r,   r`   r   r   r   r   register_instance_lookupq  s   

z,RegisterLookupMixin.register_instance_lookupc                 C   s"   |du r|j }| j|= |   dS )zn
        Remove given lookup from cls lookups. For use in tests only as it's
        not thread-safe.
        N)r   r   r   r   r   r   r   _unregister_class_lookup~  s   z,RegisterLookupMixin._unregister_class_lookupc                 C   s   |du r|j }| j|= dS )zs
        Remove given lookup from instance lookups. For use in tests only as
        it's not thread-safe.
        N)r   r   r   r   r   r   _unregister_instance_lookup  s   z/RegisterLookupMixin._unregister_instance_lookupr   )r   r   r   r   r   cacher   r   r   r   classmethodrV   rW   staticmethodr   r   r   r   register_lookupr   r   _unregister_lookupr   r   r   r   r   0  s2    








	


	r   c                 C   sd   | j sdS t| j ddrdS |s| j S | j|vrdS |r0| |vr0td| jjj d| j ddS )a  
    Return whether `field` should be used to descend deeper for
    `select_related()` purposes.

    Arguments:
     * `field` - the field to be checked. Can be either a `Field` or
       `ForeignObjectRel` instance.
     * `restricted` - a boolean field, indicating if the field list has been
       manually restricted using a select_related() clause.
     * `requested` - the select_related() dictionary.
     * `select_mask` - the dictionary of selected fields.
    Fparent_linkzField .zM cannot be both deferred and traversed using select_related at the same time.T)remote_fieldr3   nullr   r   r   r   object_name)ra   
restricted	requestedselect_maskr   r   r   select_related_descend  s   
r   c                 C   sL   t dt| d D ]}t| d| }||r#|| |d f  S q	dS )z
    Check if the lookup_parts contains references to the given annotations set.
    Because the LOOKUP_SEP is contained in the default annotation names, check
    each prefix of the lookup_parts for a match.
    r!   r   N)Nr   )rangelenr
   r&   r   )lookup_partsannotationsnlevel_n_lookupr   r   r   refs_expression  s   
r   c                    s,    fdd}||pt |ddo||jjS )z
    Check that self.model is compatible with target_opts. Compatibility
    is OK if:
      1) model and opts match (where proxy inheritance is removed)
      2) model is parent of opts' model or the other way around
    c                    s&    j j| jkp| j j jv p | jv S r   )r   concrete_modelall_parents)r   r   r   r   r     s
   z-check_rel_lookup_compatibility.<locals>.checkr   F)r3   r   r   )r   target_optsra   r   r   r   r   check_rel_lookup_compatibility  s   r   c                   @   sH   e Zd ZdZe dddZdd Zdd Zd	d
 Zdd Z	dd Z
dS )FilteredRelationz7Specify custom filtering in the ON clause of SQL joins.	conditionc                C   s:   |st d|| _d | _t|tst d|| _d | _d S )Nzrelation_name cannot be empty.z*condition argument must be a Q() instance.)r'   relation_namealiasr6   r   r   resolved_condition)r,   r   r   r   r   r   r)     s   

zFilteredRelation.__init__c                 C   s4   t || jstS | j|jko| j|jko| j|jkS r   )r6   r1   r   r   r   r   r=   r   r   r   r     s   

zFilteredRelation.__eq__c                 C   s4   t | j| jd}| j|_| j }d ur| |_|S )Nr   )r   r   r   r   r   rZ   )r,   rZ   r   r   r   r   rZ      s
   
zFilteredRelation.clonec                 C   s"   |   }|j }r|||_|S r   )rZ   r   relabeled_clone)r,   
change_maprZ   r   r   r   r   r     s   
z FilteredRelation.relabeled_clonec                 O   s(   |   }|j| j|ddddd |_|S )NTF)	can_reuserD   rE   update_join_typesr   )rZ   build_filterr   r   )r,   rJ   rK   r-   r.   rZ   r   r   r   rO     s   z#FilteredRelation.resolve_expressionc                 C   s   | | jS r   )compiler   )r,   r   r   r   r   r   as_sql  s   zFilteredRelation.as_sqlN)r   r   r   r   r   r)   r   rZ   r   rO   r   r   r   r   r   r     s    	r   )%r   r   r   loggingcollectionsr   
contextlibr   django.core.exceptionsr   	django.dbr   r   r   r   r	   django.db.models.constantsr
   django.utilsr   django.utils.functionalr   django.utils.hashabler   	getLoggerr|   r   r   Noder   r   r   r   r   r   r   r   r   r   r   r   <module>   s6    
 M-g&