U kf @sddlmZddlZddlmZddlZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZej rtddl!m"Z"ddl!m#Z#ddl!m$Z$ddlm%Z%dd l&m'Z'Gd!d"d"eZ(Gd#d$d$ej)Z*e*j+Z+ed%ee*j+edfZ,Gd&d'd'ej)Z-e.e-\Z/Z0Z1Z2Z3eee4eeed(eed(ffe-effZ5Gd)d*d*Z6Gd+d,d,ee6Z7Gd-d.d.e6eZ8Gd/d0d0e6ej9Z:Gd1d2d2e Z;d3d4d5d3d6d7d8ZdS);) annotationsN) zip_longest)Any)Callable)Dict)Iterable)Iterator)List)MutableMapping) NamedTuple)Optional)Sequence)Tuple)Union)anon_map)HasTraversalDispatch)HasTraverseInternals)InternalTraversal)prefix_anon_map)utilinspect) HasMemoized)Literal)Protocol) BindParameter) ClauseElement) ColumnElement)_TraverseInternalsType)_CoreSingleExecuteParamsc@seZdZddddddZdS)_CacheKeyTraversalDispatchType HasCacheKey_CacheKeyTraversal$_CacheKeyTraversalDispatchTypeReturn)selfvisitorreturncCsdSN)sr&r'r*r*H/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/sql/cache_key.py__call__.sz'_CacheKeyTraversalDispatchType.__call__N)__name__ __module__ __qualname__r-r*r*r*r,r"-sr"c@seZdZdZdS) CacheConstrN)r.r/r0NO_CACHEr*r*r*r,r13sr1r c@s eZdZdZdZdZdZdZdS)CacheTraverseTargetrrrN)r.r/r0CACHE_IN_PLACECALL_GEN_CACHE_KEYSTATIC_CACHE_KEYPROPAGATE_ATTRS ANON_NAMEr*r*r*r,r3?s r3.c@seZdZUdZdZeZded<dZdZ dZ ded<dZd ed <e d d d dZ e dddddddZdd ddZe dddddZdS)r#apMixin for objects which can produce a cache key. This class is usually in a hierarchy that starts with the :class:`.HasTraverseInternals` base, but this is optional. Currently, the class should be able to work on its own without including :class:`.HasTraverseInternals`. .. seealso:: :class:`.CacheKey` :ref:`sql_caching` r*_CacheKeyTraversalType_cache_key_traversalTNzOptional[bool] inherit_cacher_generated_cache_key_traversalzCUnion[_CacheKeyTraversalDispatchType, Literal[CacheConst.NO_CACHE]]r(cCs|jdd}t|}|rt|dd}|dkrfzt|ts>t|j}Wntk rdt |_ t YSX|t k s~td|dt ||dS|jdd}|dkr|jdd}|dkrt |_ |dkr|j rtjd|jd d t St ||dSdS) zgenerate cache key dispatcher for a new class. This sets the _generated_cache_key_traversal attribute once called so should only be called once per class. r=Nr<zclass zK has _cache_key_traversal=NO_CACHE, which conflicts with inherit_cache=Truer>_traverse_internalsaClass %s will not make use of SQL compilation caching as it does not set the 'inherit_cache' attribute to ``True``. This can have significant performance implications including some performance degradations in comparison to prior SQLAlchemy versions. Set this attribute to True if this object can make use of the cache key generated by the superclass. Alternatively, this attribute may be set to False which will disable this warning.Zcprf)code)__dict__getboolgetattr issubclassrAssertionErrorr@AttributeErrorr2r>_cache_key_traversal_visitorZgenerate_dispatch_hierarchy_supports_cachingrwarnr.)clsr=inheritr<r*r*r,_generate_cache_attrss\          z!HasCacheKey._generate_cache_attrssqlalchemy.sql.elementsrList[BindParameter[Any]]zOptional[Tuple[Any, ...]])r bindparamsr(c s|j}|\}}|r ||fSz|jd}Wntk rJ|}YnX|tkr`dt<dS||f}||tD]v\}} } | dk rr| tkr| j} | tkrdt<dS||| f7}qr| t krt j j } t | | jr| } ||| f7}qr| tkr ||| f7}qr| rr| tkr(||| f7}qr| tkr`||| d| drV| dndf7}qr| tjkr|jr||j7}n||7}qr| tjks| tjks| tjkr||tfdd| Df7}qr|| || |7}qr|S)aBreturn an optional cache key. The cache key is a tuple which can contain any series of objects that are hashable and also identifies this object uniquely within the presence of a larger SQL expression or statement, for the purposes of caching the resulting query. The cache key should be based on the SQL compiled structure that would ultimately be produced. That is, two structures that are composed in exactly the same way should produce the same cache key; any difference in the structures that would affect the SQL string or the type handlers should result in a different cache key. If a structure cannot produce a useful cache key, the NO_CACHE symbol should be added to the anon_map and the method should return None. r>TNZcompile_state_pluginZplugin_subjectcsg|]}|qSr*_gen_cache_key.0elemrrQr*r, Osz.HasCacheKey._gen_cache_key..) __class__Zget_anonrBKeyErrorrNr2rIr8Z_static_cache_keyr:r preloaded sql_elements isinstanceZ_anonymous_labelZ apply_mapr7rSr6r9rdp_annotations_keyZ!_gen_static_annotations_cache_keyZ_annotations_cache_keyZ_gen_annotations_cache_keydp_clauseelement_listdp_clauseelement_tupledp_memoized_select_entitiestuple) r&rrQrLid_found dispatcherresultattrnameobjmethZsckelementsr*rWr,rSs           zHasCacheKey._gen_cache_keyOptional[CacheKey]cCs<g}t}|||}t|kr"dS|dk s.tt||SdS)apreturn a cache key. The cache key is a tuple which can contain any series of objects that are hashable and also identifies this object uniquely within the presence of a larger SQL expression or statement, for the purposes of caching the resulting query. The cache key should be based on the SQL compiled structure that would ultimately be produced. That is, two structures that are composed in exactly the same way should produce the same cache key; any difference in the structures that would affect the SQL string or the type handlers should result in a different cache key. The cache key returned by this method is an instance of :class:`.CacheKey`, which consists of a tuple representing the cache key, as well as a list of :class:`.BindParameter` objects which are extracted from the expression. While two expressions that produce identical cache key tuples will themselves generate identical SQL strings, the list of :class:`.BindParameter` objects indicates the bound values which may have different values in each one; these bound parameters must be consulted in order to execute the statement with the correct parameters. a :class:`_expression.ClauseElement` structure that does not implement a :meth:`._gen_cache_key` method and does not implement a :attr:`.traverse_internals` attribute will not be cacheable; when such an element is embedded into a larger structure, this method will return None, indicating no cache key is available. NrrSr2rGCacheKey)r&rQ _anon_mapkeyr*r*r,_generate_cache_key[s   zHasCacheKey._generate_cache_key)rhr(cCs<g}t}|||}t|kr"dS|dk s.tt||SdSr)rl)rLrhrQrnror*r*r,_generate_cache_key_for_objects  z*HasCacheKey._generate_cache_key_for_object)r.r/r0__doc__ __slots__r2r<__annotations___is_has_cache_keyrJr= classmethodrNrpreload_modulerSrprqr*r*r*r,r#\s   H}*r#c@s eZdZdS)HasCacheKeyTraverseN)r.r/r0r*r*r*r,rxsrxc@s$eZdZdZejddddZdS)MemoizedHasCacheKeyr*rkr?cCs t|Sr)r#rpr&r*r*r,rpsz'MemoizedHasCacheKey._generate_cache_keyN)r.r/r0rsrZmemoized_instancemethodrpr*r*r*r,rysryc@seZdZdZddddZdS)SlotsMemoizedHasCacheKeyr*rkr?cCs t|Sr)rzr{r*r*r,$_memoized_method__generate_cache_keysz=SlotsMemoizedHasCacheKey._memoized_method__generate_cache_keyN)r.r/r0rsr}r*r*r*r,r|sr|c@seZdZUdZded<ded<dddd Zd d d d dddZdddddZdddddZe ddd dddZ dddddZ dd dddZ d dd d!Z d"dd#d$Zed%dd&d&d'd(d)Zd*S)+rmzThe key used to identify a SQL statement construct in the SQL compilation cache. .. seealso:: :ref:`sql_caching` Tuple[Any, ...]rozSequence[BindParameter[Any]]rQz Optional[int]r?cCsdS)z7CacheKey itself is not hashable - hash the .key portionNr*r{r*r*r,__hash__szCacheKey.__hash__zMutableMapping[Any, str]rr!str)statement_cache statement parametersr(csn|j|krt|||j<}n ||j}|jsJtfddtD}ntfdd|jD}t||fS)aGenerate an "offline string" form of this :class:`.CacheKey` The "offline string" is basically the string SQL for the statement plus a repr of the bound parameter values in series. Whereas the :class:`.CacheKey` object is dependent on in-memory identities in order to work as a cache key, the "offline" version is suitable for a cache that will work for other processes as well. The given ``statement_cache`` is a dictionary-like object where the string form of the statement itself will be cached. This dictionary should be in a longer lived scope in order to reduce the time spent stringifying statements. c3s|]}|VqdSr)r*rUrorr*r, sz-CacheKey.to_offline_string..c3s|]}|j|jVqdSr))rCrovalue)rUZ bindparamrr*r,rs)rorrQrbsortedrepr)r&rrrZsql_strZ param_tupler*rr,to_offline_strings   zCacheKey.to_offline_stringrrD)otherr(cCst|j|jkSr))rDror&rr*r*r,__eq__szCacheKey.__eq__cCs|j|jk Sr))rorr*r*r,__ne__szCacheKey.__ne__)leftrightr(cCst|g}t|g}||Sr))rm_diff)rLrrZck1Zck2r*r*r, _diff_tupless  zCacheKey._diff_tuplesz Iterator[str]c cs|j}|j}g}d}||}}|D]}||}||}q"tt||D]d\}\} } ||kr\qF| | krFt| trt| tr||qqFdddd|D|| | fVqF|d}qqdS)Nrzkey%s[%d]: %s != %scss|]}d|VqdS)z[%d]Nr*)rUrcr*r*r,rsz,CacheKey._whats_different..)ro enumeraterr]rbappendjoinpop) r&rZk1Zk2stackZ pickup_indexs1s2idxe1e2r*r*r,_whats_differents.     zCacheKey._whats_differentcCsd||S)N, )rrrr*r*r,r szCacheKey._diffcCs|jg}g}t}d}|r|d}||krL|d|dd|d8}qt|tr|sv|d|dddq|d7}t||g|}|d|ddqt|trd t|j t t |f}nt |}|d|dd |d qd d |fS)Nrr rz),rz()(z<%s object at %s>z rzCacheKey(key=%s) )roobjectrrr]rblistr#typer.hexidrr)r&routputsentinelindentrVrepr_r*r*r,__str__ s.      zCacheKey.__str__zDict[str, Any]cstfdd|jDS)zused for testingcsi|]}|j|jqSr*)roZeffective_value)rUbrnr*r, /sz1CacheKey._generate_param_dict..)rrQr{r*rr,_generate_param_dict+szCacheKey._generate_param_dictrOzColumnElement[Any])original_cache_keytarget_elementr(cCs,|js||kr|Stjj}|||j|jSr)) _is_immutablerr[r\Z_OverrideBindsrQ)r&rrrjr*r*r,_apply_params_to_element1sz!CacheKey._apply_params_to_elementN)r.r/r0rrrtrrrrrvrrrrrrrwrr*r*r*r,rms  $rmr~z'Iterable[Tuple[str, InternalTraversal]]z Iterable[Any])tokens traverse_argsargsr(c Csg}t}|}t||D]\\}}}|j} | dd} |dkrL||df7}qtt| } | tkrl|||f7}q| ttt t fkrt d| dq|| ||d||7}q|S)z;a quick cache key generator used by reflection.flexi_cache.Zdp_visit_NzHaven't implemented symbol z for ad-hoc key from args) rzipnamereplacerErIr6r7r8r:r9NotImplementedError) rrrrQrntuprgsymargroZ visit_keyrir*r*r,_ad_hoc_cache_key_from_args>s.    rc@seZdZeZZejZej Z ej Z ej ZeZZZZeZeZeZeZdddddddddZdddddddd d Zdddddddd d Zdddddddd dZdddddddddZdddddddddZ dddddddddZ!dddddddddZ"dddddddddZ#dddddddddZ$dddddddddZ%dddddddddZ&ddddddddd Z'dddddddd!d"Z(dddddddd#d$Z)dddddddd%d&Z*dddddddd'd(Z+dddddddd)d*Z,dddddddd+d,Z-dddddddd-d.Z.dddddddd/d0Z/dddddddd1d2Z0dddddddd3d4Z1dddddddd5d6Z2dddddddd7d8Z3d9S):r$rrrrPr~)rgrhparentrrQr(cCstdd|DS)Ncss|]\}}|j|fVqdSr))__code__)rUfnZc_keyr*r*r,rsz@_CacheKeyTraversal.visit_with_context_options..rbr&rgrhrrrQr*r*r,visit_with_context_optionsxsz-_CacheKeyTraversal.visit_with_context_optionscCs|t|||fSr))rrSrr*r*r,visit_inspectablesz$_CacheKeyTraversal.visit_inspectablecCst|Sr)rrr*r*r,visit_string_listsz$_CacheKeyTraversal.visit_string_listcCs|t|tr|||n|fSr)r]r#rSrr*r*r, visit_multis z_CacheKeyTraversal.visit_multics|tfdd|DfS)Nc3s(|] }t|tr|n|VqdSr)rrTrWr*r,rsz6_CacheKeyTraversal.visit_multi_list..rrr*rWr,visit_multi_lists z#_CacheKeyTraversal.visit_multi_listcs$|sdS|tfdd|DfS)Nr*c3s&|]}tfdd|DVqdS)c3s|]}|VqdSr)rRrTrWr*r,rszJ_CacheKeyTraversal.visit_has_cache_key_tuples...Nr)rUZtup_elemrWr*r,rsz@_CacheKeyTraversal.visit_has_cache_key_tuples..rrr*rWr,visit_has_cache_key_tuplessz-_CacheKeyTraversal.visit_has_cache_key_tuplescs$|sdS|tfdd|DfS)Nr*c3s|]}|VqdSr)rRrTrWr*r,rsz>_CacheKeyTraversal.visit_has_cache_key_list..rrr*rWr,visit_has_cache_key_lists z+_CacheKeyTraversal.visit_has_cache_key_listcs$|sdS|tfdd|DfS)Nr*c3s |]}|jr|VqdSr))rurSrTrWr*r,rsz>_CacheKeyTraversal.visit_executable_options..rrr*rWr,visit_executable_optionssz+_CacheKeyTraversal.visit_executable_optionscCs||dd|D|||S)NcSsg|] }t|qSr*r)rUor*r*r,rXsz=_CacheKeyTraversal.visit_inspectable_list..)rrr*r*r,visit_inspectable_lists z)_CacheKeyTraversal.visit_inspectable_listcCs||||||Sr))rrr*r*r,visit_clauseelement_tuplessz-_CacheKeyTraversal.visit_clauseelement_tuplescs$|sdS|tfdd|DfS)Nr*csg|]}|qSr*rRrTrWr*r,rXszC_CacheKeyTraversal.visit_fromclause_ordered_set..rrr*rWr,visit_fromclause_ordered_set s z/_CacheKeyTraversal.visit_fromclause_ordered_setcs,|sdSfdd|D}|tt|fS)Nr*csg|]}|qSr*rRrTrWr*r,rX#szH_CacheKeyTraversal.visit_clauseelement_unordered_set..rbr)r&rgrhrrrQZ cache_keysr*rWr,!visit_clauseelement_unordered_sets z4_CacheKeyTraversal.visit_clauseelement_unordered_setcCs ||jfSr))rrr*r*r,visit_named_ddl_element-sz*_CacheKeyTraversal.visit_named_ddl_elementcs$|sdS|tfdd|DfS)Nr*cs g|]\}}||fqSr*rR)rUclausestrvalrWr*r,rXEsz<_CacheKeyTraversal.visit_prefix_sequence..rrr*rWr,visit_prefix_sequence7s z(_CacheKeyTraversal.visit_prefix_sequencecstfdd|DS)Nc3sh|]`\}}}||dk r,|nd|dk rB|ndtfddtDfVqdS)Ncsg|]}||fqSr*r*rflagsr*r,rXaszG_CacheKeyTraversal.visit_setup_join_tuple...)rSrbr)rUtargetZonclauseZfrom_rWrr,rTs z<_CacheKeyTraversal.visit_setup_join_tuple..rrr*rWr,visit_setup_join_tupleLsz)_CacheKeyTraversal.visit_setup_join_tuplecs(|sdS|tfdd|DfS)Nr*cs&g|]\\}}}|||fqSr*rR)rUr dialect_nametextrWr*r,rXts  z<_CacheKeyTraversal.visit_table_hint_list..)rbitemsrr*rWr,visit_table_hint_listfs z(_CacheKeyTraversal.visit_table_hint_listcs|tfddtDfS)Ncsg|]}||fqSr*r*rrhr*r,rXsz7_CacheKeyTraversal.visit_plain_dict..rrr*rr,visit_plain_dictsz#_CacheKeyTraversal.visit_plain_dictcs|tfddtDfS)Nc3s2|]*tfddtDfVqdS)csg|]}||fqSr*r*r)rrhr*r,rXszF_CacheKeyTraversal.visit_dialect_options...Nr)rUr)rr,rs   z;_CacheKeyTraversal.visit_dialect_options..rrr*rr,visit_dialect_optionss  z(_CacheKeyTraversal.visit_dialect_optionscs"|tfddtDfS)Nc3s"|]}||fVqdSr)rRrrrQrhr*r,rszE_CacheKeyTraversal.visit_string_clauseelement_dict..rrr*rr,visit_string_clauseelement_dicts z2_CacheKeyTraversal.visit_string_clauseelement_dictcs.|tfddfddtDDfS)Nc3s0|](\}}|t|tr"|n|fVqdSr)rrUrorrWr*r,rs  z=_CacheKeyTraversal.visit_string_multi_dict..csg|]}||fqSr*r*rrr*r,rXsz>_CacheKeyTraversal.visit_string_multi_dict..rrr*rr,visit_string_multi_dicts  z*_CacheKeyTraversal.visit_string_multi_dictcs|tfdd|jDfS)Nc3s |]\}}}|VqdSr)rR)rUkcol_rWr*r,rszR_CacheKeyTraversal.visit_fromclause_canonical_column_collection..)rbZ _collectionrr*rWr,,visit_fromclause_canonical_column_collections z?_CacheKeyTraversal.visit_fromclause_canonical_column_collectioncCs d|t<dSNTr*r2rr*r*r,visit_unknown_structuresz*_CacheKeyTraversal.visit_unknown_structurecs|tfdd|DfS)Nc3s8|]0\}}t|dr |n||fVqdSZ__clause_element__NhasattrrSrrWr*r,rs   z>_CacheKeyTraversal.visit_dml_ordered_values..rrr*rWr,visit_dml_ordered_valuess  z+_CacheKeyTraversal.visit_dml_ordered_valuescs|tfddDfS)Nc3s8|]0}t|dr|n||fVqdSrr)rUrrr*r,rs  z6_CacheKeyTraversal.visit_dml_values..rrr*rr,visit_dml_valuess  z#_CacheKeyTraversal.visit_dml_valuescCs d|t<dSrrrr*r*r,visit_dml_multi_valuess z)_CacheKeyTraversal.visit_dml_multi_valuesN)4r.r/r0r7Zvisit_has_cache_keyZvisit_clauseelementrr_Zvisit_clauseelement_listr^Zvisit_annotations_keyr`Zvisit_clauseelement_tupleraZvisit_memoized_select_entitiesr6Z visit_stringZ visit_booleanZvisit_operatorZvisit_plain_objZvisit_statement_hint_listr8Z visit_typer:Zvisit_anon_namer9Zvisit_propagate_attrsrrrrrrrrrrrrrrrrrrrrrrrrrr*r*r*r,r$csJ        r$)? __future__renum itertoolsrtypingrrrrrr r r r r rrZvisitorsrrrrrrrZ inspectionrrZ util.typingrr TYPE_CHECKINGrjrrrr Zengine.interfacesr!r"Enumr1r2r;r3rbr6r7r8r9r:rr%r#rxryZ MemoizedSlotsr|rmrr$rIr*r*r*r,s                              :%A