U a@sddlmZddlmZddlZddlZddlmZddlmZddlm Z dd lm Z dd l m Z dd l m Z dd l mZdd l mZe dZdZdZe dZe dZe dZe dZe dZe dZddZddZGdddeZGdddeeZGdd d ed d!d"gZd#d$Z Gd%d&d&eZ!e!Z"Gd'd(d(eZ#Gd)d*d*e Z$e$Z%d+d,Z&Gd-d.d.e Z'e'Z(e )d/d0d1Z*Gd2d3d3e+Z,Gd4d5d5e e j-Z.Gd6d7d7e.Z/dS)8)deque) namedtupleN) operators)ExtendedInternalTraversal)InternalTraversal)utilinspect)collections_abc) HasMemoized)py37Z skip_traverseFTno_cacheZcache_in_placeZcall_gen_cache_keyZstatic_cache_keyZpropagate_attrsZ anon_namecKs*|ddrt}nt}|j||f|S)N use_proxiesF)getColIdentityComparatorStrategyTraversalComparatorStrategycompare)obj1obj2kwZstrategyrZC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\sql\traversals.pyrs rcCsFt|D]6}t|dr |t||jdt||jdq dS)N_traverse_internals#_generated_copy_internals_traversalZ!_generated_get_children_traversal)r Zwalk_subclasseshasattr_generate_cache_attrs_copy_internalsgenerate_dispatchr _get_children)Ztarget_hierarchyclsrrr_preconfigure_traversals#s r"c@sFeZdZeZdZeddZe dddZ ddZ ed d Z d S) HasCacheKeyrcCs|jdd}|r^t|dd}|dkrPz |j}Wntk rNt|_tYSXt||dS|jdd}|dkr|jdd}|dkrt|_tSt||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. Z inherit_cacheF_cache_key_traversalN_generated_cache_key_traversalr) __dict__rgetattrrAttributeErrorNO_CACHEr%_cache_key_traversal_visitorr)r!Zinheritr$rrrr7s>   z!HasCacheKey._generate_cache_attrssqlalchemy.sql.elementsc st|}|j}|kr"||fStj|<}jd7_z|jd}Wntk rl|}YnX|tkrdt<dS||f}||tD]b\}} } | dk r| t kr| j } | tkrdt<dS||| f7}q| t krt j j} t| | jr| } ||| f7}q| tkr2||| f7}q| r| tkrN||| f7}q| tkr||| d| dr|| dndf7}q| tjkr||j7}q| tjks| tjks| tjkr||tfdd| Df7}q|| || |7}q|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. rr%TNZcompile_state_pluginplugin_subjectcsg|]}|qSr_gen_cache_key.0elemanon_map bindparamsrr sz.HasCacheKey._gen_cache_key..)id __class__strindexr&KeyErrorrr)r*STATIC_CACHE_KEYZ_static_cache_key ANON_NAMEr preloaded sql_elements isinstance_anonymous_label apply_mapCALL_GEN_CACHE_KEYr.CACHE_IN_PLACEPROPAGATE_ATTRSrdp_annotations_key_annotations_cache_keydp_clauseelement_listdp_clauseelement_tupledp_memoized_select_entitiestuple) selfr3r4Zidselfr!id_ dispatcherresultattrnameobjmethZsckelementsrr2rr.bs            zHasCacheKey._gen_cache_keycCs0g}t}|||}t|kr"dSt||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. Nr3r.r)CacheKey)rKr4 _anon_mapkeyrrr_generate_cache_keys  zHasCacheKey._generate_cache_keycCs0g}t}|||}t|kr"dSt||SdSNrS)r!rPr4rUrVrrr_generate_cache_key_for_objects  z*HasCacheKey._generate_cache_key_for_objectN) __name__ __module__ __qualname__r)r$ __slots__ classmethodrr preload_moduler.rWrYrrrrr#3s * u)r#c@seZdZejddZdS)MemoizedHasCacheKeycCs t|SrX)r#rWrKrrrrWsz'MemoizedHasCacheKey._generate_cache_keyN)rZr[r\r Zmemoized_instancemethodrWrrrrr` sr`c@sXeZdZddZddZddZeddZd d Zd d Z d dZ ddZ ddZ dS)rTcCsdS)z7CacheKey itself is not hashable - hash the .key portionNrrarrr__hash__szCacheKey.__hash__csH|j|krt|||j<}n ||j}t|tfdd|jDfS)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|]}|j|jVqdSrX)rrVvalue)r0Z bindparam parametersrr 1sz-CacheKey.to_offline_string..)rVr8reprrJr4)rKZstatement_cacheZ statementreZsql_strrrdrto_offline_strings   zCacheKey.to_offline_stringcCs |j|jkSrXrVrKotherrrr__eq__8szCacheKey.__eq__cCst|g}t|g}||SrX)rT_diff)r!leftrightZck1Zck2rrr _diff_tuples;s  zCacheKey._diff_tuplesc cs|j}|j}g}d}||}}|D]}||}||}q"tt||D]d\}\} } ||kr^qH| | krHt| trt| tr||qqHdddd|D|| | fVqH|d}qqdS)Nrzkey%s[%d]: %s != %scss|]}d|VqdS)z[%d]Nr)r0rLrrrrfWsz,CacheKey._whats_different..) rV enumerater zip_longestr?rJappendjoinpop) rKrkZk1Zk2stackZ pickup_indexs1s2idxe1e2rrr_whats_differentAs.     zCacheKey._whats_differentcCsd||S)N, )rvr~rjrrrrm`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)Nrrr rz),rz()(z<%s object at %s>z rzCacheKey(key=%s) )rVobjectrwrur?rJlistr#typerZhexr6rgrv)rKrxoutputsentinelindentr1repr_rrr__str__cs.      zCacheKey.__str__cs&ddlm}|fdd|jDS)zused for testingr)prefix_anon_mapcsi|]}|j|jqSr)rVZeffective_value)r0brUrr sz1CacheKey._generate_param_dict..)compilerrr4)rKrrrr_generate_param_dicts zCacheKey._generate_param_dictcCs"ddt|j|jD}||S)NcSsi|]\}}|j|jqSr)rVrc)r0kvrrrrsz5CacheKey._apply_params_to_element..)zipr4params)rKZoriginal_cache_keyZtarget_element translaterrr_apply_params_to_elements z!CacheKey._apply_params_to_elementN) rZr[r\rbrhrlr^rpr~rmrrrrrrrrTs rTrVr4cKs|SrX)_clone)elementrrrrrsrc@seZdZeZZejZej Z ej Z ej ZeZZZZeZeZeZeZddZddZddZddZd d Zd d Z d dZ!e!Z"ddZ#ddZ$ddZ%ddZ&ddZ'ddZ(ddZ)ddZ*dd Z+d!d"Z,d#d$Z-d%d&Z.d'd(Z/d)d*Z0d+d,Z1d-d.Z2d/d0Z3d1S)2 _CacheKeycCstdd|DS)Ncss|]\}}|j|fVqdSrX__code__r0fnZc_keyrrrrfsz7_CacheKey.visit_with_context_options..rJrKrOrPparentr3r4rrrvisit_with_context_optionssz$_CacheKey.visit_with_context_optionscCs|t|||fSrX)r r.rrrrvisit_inspectablesz_CacheKey.visit_inspectablecCst|SrXrrrrrvisit_string_listsz_CacheKey.visit_string_listcCs|t|tr|||n|fSrXr?r#r.rrrr visit_multis z_CacheKey.visit_multics|tfdd|DfS)Nc3s(|] }t|tr|n|VqdSrXrr/r2rrrfsz-_CacheKey.visit_multi_list..rrrr2rvisit_multi_lists z_CacheKey.visit_multi_listcs$|sdS|tfdd|DfS)Nrc3s&|]}tfdd|DVqdS)c3s|]}|VqdSrXr-r/r2rrrfszA_CacheKey.visit_has_cache_key_tuples...Nrr0Ztup_elemr2rrrfsz7_CacheKey.visit_has_cache_key_tuples..rrrr2rvisit_has_cache_key_tuplessz$_CacheKey.visit_has_cache_key_tuplescs$|sdS|tfdd|DfS)Nrc3s|]}|VqdSrXr-r/r2rrrfsz5_CacheKey.visit_has_cache_key_list..rrrr2rvisit_has_cache_key_lists z"_CacheKey.visit_has_cache_key_listcCs||dd|D|||S)NcSsg|] }t|qSrr )r0orrrr5sz4_CacheKey.visit_inspectable_list..)rrrrrvisit_inspectable_lists z _CacheKey.visit_inspectable_listcCs||||||SrX)rrrrrvisit_clauseelement_tuplessz$_CacheKey.visit_clauseelement_tuplescs$|sdS|tfdd|DfS)Nrcsg|]}|qSrr-r/r2rrr5sz:_CacheKey.visit_fromclause_ordered_set..rrrr2rvisit_fromclause_ordered_sets z&_CacheKey.visit_fromclause_ordered_setcs,|sdSfdd|D}|tt|fS)Nrcsg|]}|qSrr-r/r2rrr5sz?_CacheKey.visit_clauseelement_unordered_set..rJsorted)rKrOrPrr3r4Z cache_keysrr2r!visit_clauseelement_unordered_sets z+_CacheKey.visit_clauseelement_unordered_setcCs ||jfSrX)namerrrrvisit_named_ddl_element sz!_CacheKey.visit_named_ddl_elementcs$|sdS|tfdd|DfS)Nrcs g|]\}}||fqSrr-)r0clausestrvalr2rrr5sz3_CacheKey.visit_prefix_sequence..rrrr2rvisit_prefix_sequences z_CacheKey.visit_prefix_sequencecs"d|ktfdd|DS)Nlegacyc3s|]\}}}r t|tr |n |r_CacheKey.visit_setup_join_tuple...)r?r8r.rJr)r0targetonclausefrom_r3r4 is_legacyrrrf&s$  z3_CacheKey.visit_setup_join_tuple..rrrrrvisit_setup_join_tuple!sz _CacheKey.visit_setup_join_tuplecs(|sdS|tfdd|DfS)Nrcs&g|]\\}}}|||fqSrr-)r0r dialect_nametextr2rrr5As  z3_CacheKey.visit_table_hint_list..)rJitemsrrr2rvisit_table_hint_list8s z_CacheKey.visit_table_hint_listcs|tfddtDfS)Ncsg|]}||fqSrrrrPrrr5Msz._CacheKey.visit_plain_dict..rrrrrvisit_plain_dictLsz_CacheKey.visit_plain_dictcs|tfddtDfS)Nc3s2|]*tfddtDfVqdS)csg|]}||fqSrrr)rrPrrr5Xsz=_CacheKey.visit_dialect_options...Nr)r0r)rrrfTs   z2_CacheKey.visit_dialect_options..rrrrrvisit_dialect_optionsOs  z_CacheKey.visit_dialect_optionscs"|tfddtDfS)Nc3s"|]}||fVqdSrXr-rr3r4rPrrrfgsz<_CacheKey.visit_string_clauseelement_dict..rrrrrvisit_string_clauseelement_dictbs z)_CacheKey.visit_string_clauseelement_dictcs.|tfddfddtDDfS)Nc3s0|](\}}|t|tr"|n|fVqdSrXrr0rVrcr2rrrfrs z4_CacheKey.visit_string_multi_dict..csg|]}||fqSrrrrrrr5ysz5_CacheKey.visit_string_multi_dict..rrrrrvisit_string_multi_dictms z!_CacheKey.visit_string_multi_dictcs|tfdd|jDfS)Nc3s|]\}}|VqdSrXr-)r0rcolr2rrrfszI_CacheKey.visit_fromclause_canonical_column_collection..)rJZ _collectionrrr2r,visit_fromclause_canonical_column_collection}s z6_CacheKey.visit_fromclause_canonical_column_collectioncCs d|t<dSNTrr)rrrrvisit_unknown_structuresz!_CacheKey.visit_unknown_structurecs|tfdd|DfS)Nc3s8|]0\}}t|dr |n||fVqdS__clause_element__Nrr.rr2rrrfs  z5_CacheKey.visit_dml_ordered_values..rrrr2rvisit_dml_ordered_valuess z"_CacheKey.visit_dml_ordered_valuescsptr"|tfddDfSddD}|r@dt<dS|}|tfddt|DfSdS)Nc3s8|]0}t|dr|n||fVqdSrrr0rrrrrfs z-_CacheKey.visit_dml_values..cSsh|]}t|dr|qSrrrrrr s z-_CacheKey.visit_dml_values..Trc3s"|]}||fVqdSrXr-rrrrrfs)rrJr)symmetric_differencer)rKrOrPrr3r4 expr_values str_valuesrrrvisit_dml_valuess   z_CacheKey.visit_dml_valuescCs d|t<dSrrrrrrvisit_dml_multi_valuessz _CacheKey.visit_dml_multi_valuesN)4rZr[r\rBvisit_has_cache_keyvisit_clauseelementrrGvisit_clauseelement_listrEvisit_annotations_keyrHvisit_clauseelement_tuplerIvisit_memoized_select_entitiesrC visit_string visit_booleanvisit_operatorvisit_plain_objvisit_statement_hint_listr; visit_typer<visit_anon_namerDvisit_propagate_attrsrrrrrrrvisit_executable_optionsrrrrrrrrrrrrrrrrrrrrrrsR     "rc@seZdZddZdddZdS)HasCopyInternalscKs tdSrXNotImplementedError)rKrrrrrszHasCopyInternals._clonercKsvz |j}Wntk r YdSXt||dD]@\}}}||krDq0|dk r0||||f|}|dk r0t|||q0dS)atReassign internal elements to be clones of themselves. Called during a copy-and-traverse operation on newly shallow-copied elements to create a deep copy. The given clone function should be used, which may be applying additional transformations to the element (i.e. replacement traversal, cloned traversal, annotations). Nr)rr(rZrun_generated_dispatchsetattr)rKZ omit_attrsrZtraverse_internalsrOrPrQrNrrrrs  z HasCopyInternals._copy_internalsN)r)rZr[r\rrrrrrrsrc@seZdZdZefddZefddZefddZefdd Zefd d Z efd d Z efddZ efddZ ddZ efddZefddZefddZefddZdS)_CopyInternalszmGenerate a _copy_internals internal traversal dispatch for classes with a _traverse_internals collection.cKs ||f|SrXrrKrOrrclonerrrrrsz"_CopyInternals.visit_clauseelementc sfdd|DS)Ncsg|]}|fqSrrr0rrrrrr5sz;_CopyInternals.visit_clauseelement_list..rrrrrrsz'_CopyInternals.visit_clauseelement_listc stfdd|DS)Ncsg|]}|fqSrrrrrrr5sz<_CopyInternals.visit_clauseelement_tuple..rrrrrrsz(_CopyInternals.visit_clauseelement_tuplec stfdd|DS)Ncsg|]}|fqSrrrrrrr5sz;_CopyInternals.visit_executable_options..rrrrrrsz'_CopyInternals.visit_executable_optionsc sfdd|DS)Ncsh|]}|fqSrrrrrrr szC_CopyInternals.visit_clauseelement_unordered_set..rrrrrrsz0_CopyInternals.visit_clauseelement_unordered_setc sfdd|DS)Ncs$g|]}tfdd|DqS)c3s|]}|fVqdSrXrrrrrrfszG_CopyInternals.visit_clauseelement_tuples...rr/rrrr5sz=_CopyInternals.visit_clauseelement_tuples..rrrrrr s z)_CopyInternals.visit_clauseelement_tuplesc stfdd|DS)Nc3s"|]\}}||ffVqdSrXrrrrrrfszA_CopyInternals.visit_string_clauseelement_dict..)dictrrrrrrsz._CopyInternals.visit_string_clauseelement_dictc stfdd|DS)Nc3s^|]V\}}}}|dk r"|fnd|dk r8|fnd|dk rN|fnd|fVqdSrXr)r0rrrrrrrrfs  z8_CopyInternals.visit_setup_join_tuple..rrrrrrsz%_CopyInternals.visit_setup_join_tuplecKs|j|||f|SrXr)rKrOrrrrrrr'sz-_CopyInternals.visit_memoized_select_entitiesc sfdd|DS)Ncs6g|].\}}t|dr"|fn||ffqSrrrrrrr5.s  z;_CopyInternals.visit_dml_ordered_values..rrrrrr*s z'_CopyInternals.visit_dml_ordered_valuesc sfdd|DS)Ncs4i|],\}}t|dr"|fn||fqSrrrrrrr9sz3_CopyInternals.visit_dml_values..)rrrrrr8s z_CopyInternals.visit_dml_valuesc s fddfdd|DS)NcsPt|ttfr"fdd|DSt|trDfdd|DSdsLtdS)Ncs&g|]}t|dr|fn|qSrr)r0rcrrrr5GszG_CopyInternals.visit_dml_multi_values..copy..csBi|]:\}}t|dr"|fn|t|dr:|fn|qSrrrrrrrNs zG_CopyInternals.visit_dml_multi_values..copy..F)r?rrJrrAssertionErrorr1rrrcopyEs   z3_CopyInternals.visit_dml_multi_values..copycsg|]}fdd|DqS)csg|] }|qSrr)r0Z sub_elementrrrr5_szD_CopyInternals.visit_dml_multi_values...r)r0sequencerrrr5^sz9_CopyInternals.visit_dml_multi_values..rrr)rrrrr@s z%_CopyInternals.visit_dml_multi_valuescKs|SrXrrrrrrcsz$_CopyInternals.visit_propagate_attrsN)rZr[r\__doc__rrrrrrrrrrrrrrrrrrrs2           $rcCs$t|dr t|dds |}q|S)NrZis_clause_elementF)rr'r)rrrr_flatten_clauseelementls  rc@seZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZddZddZddZddZd S)! _GetChildrenzqGenerate a _children_traversal internal traversal dispatch for classes with a _traverse_internals collection.cKsdSNrrrKrrrrrrysz _GetChildren.visit_has_cache_keycKs|fSrXrrrrrrsz _GetChildren.visit_clauseelementcKs|SrXrrrrrrsz%_GetChildren.visit_clauseelement_listcKs|SrXrrrrrrsz&_GetChildren.visit_clauseelement_tuplecKs tj|SrX) itertoolschain from_iterablerrrrrsz'_GetChildren.visit_clauseelement_tuplescKsdSrrrrrrrsz9_GetChildren.visit_fromclause_canonical_column_collectioncKs|SrX)valuesrrrrrsz,_GetChildren.visit_string_clauseelement_dictcKs|SrXrrrrrrsz)_GetChildren.visit_fromclause_ordered_setcKs|SrXrrrrrrsz._GetChildren.visit_clauseelement_unordered_setcksT|D]J\}}}}|dk r|Vt|ts2t|V|dk rt|tst|VqdSrX)r?r8r)rKrrrrrrrrrrs  z#_GetChildren.visit_setup_join_tuplecKs|j|f|SrXrrrrrrsz+_GetChildren.visit_memoized_select_entitiescks(|D]\}}t|dr|V|VqdS)Nrr)rKrrrrrrrrs  z%_GetChildren.visit_dml_ordered_valuescksNdd|D}||}t|D]}||Vq |D]}|V||Vq4dS)NcSsh|]}t|dr|qSrrrrrrrs z0_GetChildren.visit_dml_values..)rr)rKrrrrrrrrrs   z_GetChildren.visit_dml_valuescKsdSrrrrrrrsz#_GetChildren.visit_dml_multi_valuescKsdSrrrrrrrsz"_GetChildren.visit_propagate_attrsN)rZr[r\rrrrrrrrrrrrrrrrrrrrrus   rr+cKst|tjjjr||}|SrX)r?r r=r>r@rA)rrr3rrrr_resolve_name_for_compares rc@s eZdZdZddZddZdS)r3aUA map that creates new keys for missing key access. Produces an incrementing sequence given a series of unique keys. This is similar to the compiler prefix_anon_map class although simpler. Inlines the approach taken by :class:`sqlalchemy.util.PopulateDict` which is otherwise usually used for this type of operation. cCs d|_dS)Nr)r9rarrr__init__szanon_map.__init__cCs$t|j||<}|jd7_|S)Nr)r8r9)rKrVvalrrr __missing__szanon_map.__missing__N)rZr[r\rrr rrrrr3s r3c@sdeZdZdZddZddZddZdd Zd d Zd d Z ddZ e Z ddZ ddZ ddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Z d:d;Z!dd?Z#d@dAZ$dBdCZ%dDdEZ&dFdGZ'dHdIZ(dJdKZ)dLdMZ*dNdOZ+dPdQZ,dRdSZ-dTdUZ.dVS)Wr)rxcacher3cCst|_t|_dSrX)rrxsetr rarrrrsz$TraversalComparatorStrategy.__init__cCs ttfSrX)r3rarrr_memoized_attr_anon_mapsz3TraversalComparatorStrategy._memoized_attr_anon_mapcKs|j}|j}|dd}|||f|r|\}}||krDq&n"|dksT|dkrXdS||f|krfq&|||f|j} | |jkrdSt|d| d} | r| ||f|} | tkrdS| t krq&nd} t j |j |j ddD]\\} } \}}|s| dks|dkrq| |ks| |k rdS| | kr*q| | }t| |}t||}|dkrj|dk rdSq|| ||||f|}|tkrdSqq&dS) Ncompare_annotationsFz compare_%srNN fillvalueZ _annotationsT)rxr rrupopleftaddZ__visit_name__r'COMPARE_FAILED SKIP_TRAVERSEr rtrdispatchoperator attrgetter)rKrrrrxr r rnroZ visit_namerQZattributes_comparedZ left_attrnameZleft_visit_symZright_attrnameZright_visit_symrZ left_childZ right_childZ comparisonrrrrs        z#TraversalComparatorStrategy.comparecKs|}|j||f|SrX)r7r)rKrrrZ comparatorrrr compare_inner5sz)TraversalComparatorStrategy.compare_innercKs,||jdg||jdgkr(tSdSNrr)r.r3rrKrO left_parentrn right_parentrorrrrr9s z/TraversalComparatorStrategy.visit_has_cache_keycKs||dd|ddS)Nr,)rrrrrrrAs z1TraversalComparatorStrategy.visit_propagate_attrsc KsJtj||ddD]4\}}||jdg||jdgkrtSqdS)Nrrr)r rtr.r3r rKrOrrnrrorlrrrrrHs z4TraversalComparatorStrategy.visit_has_cache_key_listcKs|j||fdSrX)rxrurrrrrSsz/TraversalComparatorStrategy.visit_clauseelementc Ks.tj||ddD]\}}|j||fqdSNrr rtrxru) rKrOrrnrrorZlcolZrcolrrrrXszHTraversalComparatorStrategy.visit_fromclause_canonical_column_collectioncKsdSrXrrrrr*visit_fromclause_derived_column_collection^szFTraversalComparatorStrategy.visit_fromclause_derived_column_collectionc KsNtjt|t|ddD]0\}}||kr0tS|j||||fqdSr )r rtrrrxru) rKrOrrnrrorZlstrZrstrrrrrcsz;TraversalComparatorStrategy.visit_string_clauseelement_dictc Ks`tj||ddD]J\}}|dks(|dkr0tStj||ddD]\} } |j| | fq@qdSr r rtrrxru) rKrOrrnrrorZltupZrtuprrrrrrms z6TraversalComparatorStrategy.visit_clauseelement_tuplesc Ks.tj||ddD]\}}|j||fqdSr r!rrrrrwsz4TraversalComparatorStrategy.visit_clauseelement_listc Ks.tj||ddD]\}}|j||fqdSr r!rrrrr}sz5TraversalComparatorStrategy.visit_clauseelement_tuplecKsv|dkr|dkSt}|D]6}t||D]"}|j||f|r,||qq,qt|t|kopt|kSSrX)r  differencerrlen)rKZseq1Zseq2rZ completedrZ other_clauserrr_compare_unordered_sequencess z8TraversalComparatorStrategy._compare_unordered_sequencescKs|j||f|SrX)r&rrrrrsz=TraversalComparatorStrategy.visit_clauseelement_unordered_setc Ks.tj||ddD]\}}|j||fqdSr r!rrrrrsz8TraversalComparatorStrategy.visit_fromclause_ordered_setcKs||kSrXrrrrrrsz(TraversalComparatorStrategy.visit_stringcKs||kSrXrrrrrrsz-TraversalComparatorStrategy.visit_string_listcKs,t|||jdf|t|||jdf|kSr)rr3rrrrrsz+TraversalComparatorStrategy.visit_anon_namecKs||kSrXrrrrrrsz)TraversalComparatorStrategy.visit_booleancKs||kSrXrrrrrrsz*TraversalComparatorStrategy.visit_operatorcKs ||SrX)Z_compare_type_affinityrrrrrsz&TraversalComparatorStrategy.visit_typecKs||kSrXrrrrrrsz,TraversalComparatorStrategy.visit_plain_dictcKs||kSrXrrrrrrsz1TraversalComparatorStrategy.visit_dialect_optionscKs |r|r|j|jkS||kSdSrX)rFrrrrrs z1TraversalComparatorStrategy.visit_annotations_keycKs$tdd|Dtdd|DkS)Ncss|]\}}|j|fVqdSrXrrrrrrfszITraversalComparatorStrategy.visit_with_context_options..rrrrrrsz6TraversalComparatorStrategy.visit_with_context_optionscKs||kSrXrrrrrrsz+TraversalComparatorStrategy.visit_plain_objcKs |dkr|dk rtS|j|jkSrX)rrrrrrrsz3TraversalComparatorStrategy.visit_named_ddl_elementc KsFtj||ddD]0\\}}\} } || kr0tS|j|| fqdSNrrr#) rKrOrrnrrorZl_clauseZl_strZr_clauseZr_strrrrrsz1TraversalComparatorStrategy.visit_prefix_sequencecKsntj||ddD]X\\}}} } \} } } }| |kr8tS|j|| f|j|| f|j| | fqdS)N)NNNNrr#)rKrOrrnrrorZl_targetZ l_onclauseZl_fromZl_flagsZr_targetZ r_onclauseZr_fromZr_flagsrrrrs  z2TraversalComparatorStrategy.visit_setup_join_tuplecKs|j|||||f|SrXrrrrrrsz:TraversalComparatorStrategy.visit_memoized_select_entitiesc Kst|ddd}t|ddd}tj||ddD]P\\} } \} } | | krPtS|| | f|| | fkrptS|j| | fq0dS)NcSs|dj|dfSrfullnamerrrr zCTraversalComparatorStrategy.visit_table_hint_list..ricSs|dj|dfSrr(rrrrr* r+rr)rr rtrrxru) rKrOrrnrrorZ left_keysZ right_keysZltableZldialectZrtableZrdialectrrrrsz1TraversalComparatorStrategy.visit_table_hint_listcKs||kSrXrrrrrrsz5TraversalComparatorStrategy.visit_statement_hint_listcKs tdSrXrrrrrrsz3TraversalComparatorStrategy.visit_unknown_structurec Ks>tj||ddD](\\}}\} } |j|| f|stSqdSr')r rt_compare_dml_values_or_cer) rKrOrrnrrorlklvrkrvrrrr!sz4TraversalComparatorStrategy.visit_dml_ordered_valuescKs`t|d}t|d}||kr dS|r8|j||f|s8dS|sH||krHdS|j||f|s\dSdS)NrFT)rr)rKr.r0rZlvceZrvcerrrr,,s   z5TraversalComparatorStrategy._compare_dml_values_or_cec Ks|dks |dks t|t|kr$tSt|tjr^t||D] \}}|j||f|s:tSq:nt|tjrntStrt||D]@\\} }\} }|j| | f|stS|j||f|stSqnB|D]<} || }| |krtS|| }|j||f|stSqdSrX) r%rr?r Sequencerr,rr) rKrOrrnrrorr.r0r-r/rrrr:s*    " z,TraversalComparatorStrategy.visit_dml_valuesc Ksvtj||ddD]`\}}|dks(|dkr0tStj||ddD].\} } |j||| || f|tkr@tSq@qdSr )r rtrr) rKrOrrnrrorZlseqZrseqZldrdrrrr[s"z2TraversalComparatorStrategy.visit_dml_multi_valuescKsJ|j|jkrBt|jr:|j|j|jf|r4ddgStSqFdgSntSdS)Nrclauses)rrZis_associativer&r3rrKrnrorrrrcompare_clauselistks  z.TraversalComparatorStrategy.compare_clauselistcKs|j|jkrt|jrz|j|j|jf|r@|j|j|jf|sh|j|j|jf|rt|j|j|jf|rtddddgStSqddgSntSdS)Nrnegaternro)rrZis_commutativerrnrorr4rrrcompare_binaryys    z*TraversalComparatorStrategy.compare_binarycKs<|dd}|dd}|r"g}nddg}|s8|d|S)N compare_keysTcompare_valuescallablercrV)rwru)rKrnrorr8r9Zomitrrrcompare_bindparams   z-TraversalComparatorStrategy.compare_bindparamN)/rZr[r\r]rr rrrrrrrrr"rrrrr&rrrrrrrrrrrrrrrrrrrrrr,rrr5r7r;rrrrrsXO         !rc@s.eZdZd ddZddZddZd d Zd S) rTrcKs\|f}|r ||kr |||}|D]2}|r>||r>tSt|t|kr$tSq$tS)zCompare ColumnElements using proxies and equivalent collections. This is a comparison strategy specific to the ORM. N)unionZshares_lineagerhashr)rKrnrorZ equivalentsrZ to_compareZothrrrcompare_column_elements  z4ColIdentityComparatorStrategy.compare_column_elementcKs|j||f|SrXr>r4rrrcompare_columnsz,ColIdentityComparatorStrategy.compare_columncKs|j||f|SrXr?r4rrr compare_labelsz+ColIdentityComparatorStrategy.compare_labelcKs||kr tStSrX)rrr4rrr compare_tablesz+ColIdentityComparatorStrategy.compare_tableN)Tr)rZr[r\r>r@rArBrrrrrs  r)0 collectionsrrrrrqrZvisitorsrrr Z inspectionr r r rsymbolrrZCOMPARE_SUCCEEDEDr)rCrBr;rDr<rr"rr#r`rTrrr*rrrrrr r_rrr3Z MemoizedSlotsrrrrrrsZ                  [5"{ G B