NWdZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z dd l m Z dd l mZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddlm"Z"ddlm#Z#ddlm$Z$ddlm%Z%ddlm&Z&d d!lm'Z'd d"lm(Z(e(j)*e#j+d#Z,d$Z-d%Z.d&Z/d'Z0 dEd)Z1d*Z2d+Z3d,Z4d-Z5d.Z6d/Z7d0Z8dFd2Z9d3Z:d4Z;d5Z<Gd6d7e=Z>Gd8d9e>Z?Gd:d;e>Z@d<ZAdGd>ZBd?ZC dHd@ZDGdAdBejEZFGdCdDeFZGd=S)Iz;High level utilities which build upon other modules here. )deque)chain) operators)visitors)_deep_annotate)_deep_deannotate)_shallow_annotate) _from_objects) ColumnSet) sort_tables)_expand_cloned) _find_columns)_label_reference)_textual_label_reference) BindParameter) ColumnClause) ColumnElement)Grouping)Label)Null)UnaryExpression)Column)Alias) FromClause) FromGrouping)Join) ScalarSelect) SelectBase) TableClause)exc)utilz.sql.util.join_conditionctt|}g}t|D]4\}}|D],}||r||-5|S)aGiven a list of FROM clauses and a selectable, return the first index and element from the list of clauses which can be joined against the selectable. returns None, None if no match is found. e.g.:: clause1 = table1.join(table2) clause2 = table4.join(table5) join_to = table2.join(table3) find_join_source([clause1, clause2], join_to) == clause1 )listr enumerateis_derived_fromappend)clausesjoin_to selectablesidxifss /srv/buildsys-work-dir/castor/build_node/builder-2/WGSG1/unpkd_srcs/cloudlinux-venv-1.0.6/venv/lib/python3.11/site-packages/sqlalchemy/sql/util.pyfind_join_sourcer13sz"}W--..K C'""1  A  ##  1   Jctt|}g}t|D]6\}}|D].}||r||n/7t |dkrkg}|D]b}||}|D]U}t t|t|r||nVc|r|S|S)zGiven a list of FROM clauses and a selectable, return the indexes from the list of clauses which is derived from the selectable. r) r%r r&r'r(lensetsurface_selectables intersection) r) join_fromr+ liberal_idxr-r.r/conservative_idxr,s r0#find_left_clause_that_matches_givenr;Ms,}Y//00KK'""  1  A  ## ""1%%%  ;!  C A   *1--..;;'**%++C000E   $# # r2c g}tt|}tdkr|d}t|}nd}d}t D]\}}||gD]} |rWt|j| j|r| |n0[tj || s|| |nt|dkr/ttdD fd|D}|s|ttS|S)a Given a list of FROM clauses, a selectable, and optional ON clause, return a list of integer indexes from the clauses list indicating the clauses that can be joined from. The presence of an "onclause" indicates that at least one clause can definitely be joined from; if the list of clauses is of length one and the onclause is given, returns that index. If the list of clauses is more than length one, and the onclause is given, attempts to locate which clauses contain the same columns. rNTFc6g|]}t|jS)r _hide_froms).0r.s r0 z1find_left_clause_to_join_from..s"CCCaN1=11CCCr2c(g|]}|v |Sr>r>)r@r-r)toremoves r0rAz1find_left_clause_to_join_from..s'<<>!#&&112BCCJJqMMME1%% )= 1 *> 3xx!|| CC7CCC D  =<<<<#<<< 8'S\\""" r2cRgfdt|ddS)aProduce a traversal of the given expression, delivering column comparisons to the given function. The function is of the form:: def my_fn(binary, left, right) For each binary expression located which has a comparison operator, the product of "left" and "right" will be delivered to that function, in terms of that binary. Hence an expression like:: and_( (a + b) == q + func.sum(e + f), j == r ) would have the traversal:: a q a e a f b q b e b f j r That is, every combination of "left" and "right" that doesn't further contain a binary comparison is passed as pairs. c3Kt|tr|VdS|jdkrtj|jrd||jD](}|jD]}d||) d| D] }|dSt|tr|V| D]}|D]}|VdS)Nbinaryr) isinstancer__visit_name__r is_comparisonoperatorinsertleftrightpop get_childrenr)elementlrelemefnstackvisits r0raz#visit_binary_product..visitsf g| , , MMMMM  #x / /I4K  5 5 / LLG $ $ $U7<(( ' 'w}--''ABuQxA&&&&' IIaLLL,,..  d   '<00  ,,..  tAGGGG  r2N)r%)r_exprr`ras` @@r0visit_binary_productrcsQF E, t EEEr2Fcgi}|rjx|d<|d<|r j|d<|r j|d<|rfdx|d<x|d<|d<|r fd }||d <j|d <tj|d d i|S)z1locate Table objects within the given expression.selectcompound_selectjoinaliasc8|jSNr(table)enttabless r0zfind_tables..s ci00r2rUupdatedeletec<|jdSrjrk)columnrns r0 visit_columnz!find_tables..visit_columns MM&, ' ' ' ' 'r2rsrlcolumn_collectionsF)r(rtraverse) clause check_columnsinclude_aliases include_joinsinclude_selects include_crud _visitorsrtrns @r0 find_tablesr~sFIK=C]J (i(9:*"M &+#] '1 1 0 0 0 1 ( 1i1I 5 + ( ( ( ( (+ (Ig f3U;YGGG Mr2ctj}g}t|g}|rO|}t |t rt |t rtj|j st |trSt |j ts9|j }t |tr|j }||t |tr|j }t |t r||vr*||||n,|D]}|||O|S)zqBreak up an 'order by' expression into individual column-expressions, without DESC/ASC/NULLS FIRST/NULLS LAST)r# column_setrpopleftrQrrris_ordering_modifiermodifierrrZrrr(rraddrY)rwcolsresultr`trEs r0unwrap_order_byrsg ?  D F 6(OOE  MMOO a ' ' 1o.. 1!*== !U## J <-- Ia**" A Q!-.. I!688 }}  a   ^^%%   Q5  6 Mr2c4d}tj|i|S)NcLt|ttfr|jSdSrj)rQrrrZ)r]s r0replacez'unwrap_label_reference..replace8s- d-/GH I I <   r2)rreplacement_traverse)rZrs r0unwrap_label_referencer7s(     ("g > >>r2ctd|Dttd|D}fd|DS)zGiven the columns clause and ORDER BY of a selectable, return a list of column expressions that can be added to the collist corresponding to the ORDER BY, without repeating those already in the collist. c.g|]}|j|jn|Srj)_order_by_label_elementrZ)r@cols r0rAz4expand_column_list_from_order_by..Gs6   6BCKK   r2c,g|]}t|Sr>)r)r@os r0rAz4expand_column_list_from_order_by..Ms DDDaq11DDDr2cg|]}|v| Sr>r>)r@rcols_already_presents r0rAz4expand_column_list_from_order_by..Os$ J J JC#5I*I*IC*I*I*Ir2)r5r%r)collistorder_by to_look_forrs @r0 expand_column_list_from_order_byr?sn     uDD8DDDEFFK J J J J; J J JJr2c<t|D] }||krdS dS)zGiven a target clause and a second to search within, return True if the target is plainly present in the search without any subqueries or aliases involved. Basically descends through Joins. TF)r6)rwsearchr]s r0clause_is_presentrRs7$F++ T>>44 ur2c#Kt|tr8t|jD]}|Vt|jD]}|VdSt|t rt|jD]}|VdS|VdSrj)rQrtables_from_leftmostrVrWrrZ)rwrs r0rrbs&$ %fk22  AGGGG%fl33  AGGGG   FL ) )%fn55  AGGGG   r2c#K|g}|r|}|Vt|tr"||j|jfn/t|t r||j|dSdSrj) rXrQrextendrVrWrr(rZrwr`r]s r0r6r6os HE 'yy{{ dD ! ! ' LL$)TZ0 1 1 1 1 l + + ' LL & & & '''''r2c#K|g}|r|}t|ttfr|Vt|tr"||j|jfnrt|tr| |j nBt|tr'|j | |j n |Vn||V|dSdSrj) rXrQr rrrrVrWrr(rZrrlrs r0surface_selectables_onlyrzs HE yy{{ d[%0 1 1 JJJ dD ! !  LL$)TZ0 1 1 1 1 l + +  LL & & & & l + + z% TZ((((  JJJ r2Tc# Ktf}|s |tfz }t|g}|rY|}|V|D](}t ||r||)|WdSdS)ztraverse and yield only outer-exposed column elements, such as would be addressable in the WHERE clause of a SELECT if this element were in the columns clause.N)rrrrrYrQr()rwinclude_scalar_selectsfilter_r`r]subs r0surface_column_elementsrs oG !!J=  6(OOE }} $$&&  C#w''  LL     r2cttt|t|S)z:Return True if left/right have some overlapping selectable)boolr5r6r7)rVrWs r0selectables_overlaprsA   % %&&334G4N4NOO  r2cFgfd}tj|id|iS)zReturn an ordered list of "bound" values in the given clause. E.g.:: >>> expr = and_( ... table.c.foo==5, table.c.foo==7 ... ) >>> bind_values(expr) [5, 7] c<|jdSrj)r(effective_value)bindvs r0visit_bindparamz$bind_values..visit_bindparams %&&&&&r2 bindparam)rrv)rwrrs @r0 bind_valuesrsD A''''' fb;"@AAA Hr2ct|tjr|dd}d|zSt |S)N'z''z'%s')rQr# string_typesrrepr)rZs r0_quote_ddl_exprrsA'4,--//#t,,G}}r2c$eZdZdZdZdZdZdZdS) _repr_baserrr!) max_charsct|}t|}||jkr.|jdz}|d|d||jz zz|| dz}|S)Nr!rz# ... (%d characters truncated) ... )rr4r)selfvaluereplenrepsegment_lengths r0truncz_repr_base.truncsx5kkS DN " "!^q0NAn$%9.0 ~o&&' (  r2N)__name__ __module__ __qualname___LIST_TUPLE_DICT __slots__rr>r2r0rrs7 E F EI     r2rc$eZdZdZdZddZdZdS) _repr_rowzProvide a string view of a row.)row,c"||_||_dSrj)rr)rrrs r0__init__z_repr_row.__init__s"r2c|jddfd|jDt|jdkrdnddS)N(, c3.K|]}|VdSrjr>r@rrs r0 z%_repr_row.__repr__..s+99ueeEll999999r2r,))rrgrr4)rrs @r0__repr__z_repr_row.__repr__s^  II9999999 9 9 9tx==A%%CC2 - -  r2N)r)rrr__doc__rrrr>r2r0rrsB))I####     r2rc0eZdZdZdZd dZdZdZdZdS) _repr_paramszProvide a string view of bound parameters. Truncates display to a given numnber of 'multi' parameter sets, as well as long values to a given number of characters. )paramsbatchesismultirNc>||_||_||_||_dSrj)rrrr)rrrrrs r0rz_repr_params.__init__s"   "r2c &|j||jSt|jtr|j}n^t|jt r|j}n.(sD!!9?!!&)44!!!!!!r2r[%s]z(%s)) rQr%rrrrrtyperg)r multi_paramsrelementsrs` @r0rz_repr_params._repr_multis  ,q/400  J LOU33  K LOT22  J 9a))uyy!!!!!CO!!!HHH $*  H$ $H$ $r2cb|j||jur6ddfd|DzS||jurK|]\}}|d|VdS)z: Nr>)r@keyrrs r0rz,_repr_params._repr_params..7sN"U!$UU5\\\2r2rc3.K|]}|VdSrjr>rs r0rz,_repr_params._repr_params..>s+;;5%%,,;;;;;;r2rrrrrc3.K|]}|VdSrjr>rs r0rz,_repr_params._repr_params..Bs+&H&HuuU||&H&H&H&H&H&Hr2)rrrgitemsrr4)rrrrs @r0rz_repr_params._repr_params3s  $*   &,llnn  DK    ;;;;F;;;;;;6{{a''R//  TYY&H&H&H&H&H&H&HHHI Ir2)rN) rrrrrrrrrr>r2r0rrsk/I#### 777<%%%0JJJJJr2rc>fd}tj|id|iS)zWgiven criterion containing bind params, convert selected elements to IS NULL. ct|jtrQ|jjvrC|j|_t |_t j|_t j |_ dSt|jtrE|jjvr9t |_t j|_t j |_ dSdSdSrj) rQrVr_identifying_keyrWrris_rTisnotnegate)rPnullss r0 visit_binaryz-adapt_criterion_to_null..visit_binaryKs v{M 2 2 , ,55!,FK66FL'mFO%OFMMM v|] 3 3 , -6666FL'mFO%OFMMM  , ,66r2rP)rcloned_traverse)critrrs ` r0adapt_criterion_to_nullrEs8 ,,,,,$  #D"x.F G GGr2Nc||S|dfg}t|}d}|r|\}}t|trh||urd|}|||j|_||j |fn||}|||_ ||}||Srj) ClauseAdapterrXrQr_clone_reset_exportedrvrJr(rV)rVrWstop_onr`adapterret prevrights r0 splice_joinsr `s | T]OED!!G C  "YY[[ eT " " ,uG';';LLNNE  ! ! # # #$--en==EN LL%*e, - - - -$$U++E  "IN ;C   Jr2cz |dd}|dd tjtj D]}t d|jDD]~}D]y}||ur |j}n+#tj$r|rY#tj $r|rY6wxYw| |r) r|j |j kr |nz|r& fd}|D]} | tj| id|it S)aCgiven a list of columns, return a 'reduced' set based on natural equivalents. the set is reduced to the smallest list of columns which have no natural equivalent present in the list. A "natural equivalent" means that two columns will ultimately represent the same value because they are related by a foreign key. \*clauses is an optional list of join clauses which will be traversed to further identify columns that are "equivalent". \**kw may specify 'ignore_nonexistent_tables' to ignore foreign keys whose tables are not yet configured, or columns that aren't yet present. This function is primarily used to determine the most minimal "primary key" from a selectable, by reducing the set of primary key columns present in the selectable to just those that are not repeated. ignore_nonexistent_tablesF only_synonymscg|] }|j Sr>) foreign_keysr@rEs r0rAz"reduce_columns..s@@@Q!.@@@r2c|jtjkrtjt dD}|j|vrf|j|vr_tD]Q}| |jr/r|j |jj kr |dSLdSdSdSdS)Ncg|] }|j Sr>) proxy_setrs r0rAz8reduce_columns..visit_binary..sJJJAAKJJJr2) rTreqr#rrrDrVrWreversedshares_lineagenamer)rPrrEcolumnsomitr s r0rz$reduce_columns..visit_binarys),..JJ1C1CD1I1IJJJK;$&&6<4+?+?%g..""++FL99" -"126;;K1K1K HHQKKK!EE/.'&+?+?""r2NrP)rXr#ordered_column_setrrrrsr"NoReferencedColumnErrorNoReferencedTableErrorrrrrrvr rD) rr)kwr rfkrEfk_colrrwrr s ` @@r0reduce_columnsr ys(!#'BE J JFF?E22M%g..G ?  D@@#-@@@A  B  88YFF21 11  ((++%)*38););HHSMMME1 4H " " " " " " " H HF!!&"x.FGGG W''-- . ..s?BB/ B/ -B/ crrtjddfd}gtj|id|iS)z9traverse an expression and locate binary criterion pairs.zSCan only specify one of 'consider_as_foreign_keys' or 'consider_as_referenced_keys'c,||Srj)compare)abs r0col_isz"criterion_as_pairs..col_issyy||r2cs|jtjurdSt|jt rt|jt sdSr|jvrB|j|js |jvr#|j|jfdS|jvrB|j|js |jvr%|j|jfdSdSdSr|jvrB|j|js |jvr#|j|jfdS|jvrB|j|js |jvr%|j|jfdSdSdSt|jtrt|jtr|j |jr#|j|jfdS|j |jr'|j|jfdSdSdSdSrj) rTrrrQrVrrWr(r references)rP any_operatorr&consider_as_foreign_keysconsider_as_referenced_keyspairss r0rz(criterion_as_pairs..visit_binarys y| C C F&+}55 Z L-> >   F # >{666v|V[117<'??? flFK899999!999v{FL11:;&>>> fk6<899999 :9>>) >{999v|V[11:<'BBB fk6<899999!<<<v{FL11=;&AAA flFK899999 =<AA&+v.. >: f44 >;))&,77>LL&, !<=====\,,V[99>LL&+v|!<=====  > > > > >>r2rP)r" ArgumentErrorrrv) expressionr*r+r)rr&r,s ``` @@r0criterion_as_pairsr/s  $?  ,   %>%>%>%>%>%>%>%>%>N E j"x&>??? Lr2c>eZdZdZ ddZejfdZdZdS)ra5Clones and modifies clauses based on column correspondence. E.g.:: table1 = Table('sometable', metadata, Column('col1', Integer), Column('col2', Integer) ) table2 = Table('someothertable', metadata, Column('col1', Integer), Column('col2', Integer) ) condition = table1.c.col1 == table2.c.col1 make an alias of table1:: s = table1.alias('foo') calling ``ClauseAdapter(s).traverse(condition)`` converts condition to read:: s.c.col1 == table2.c.col1 NFc|g|d|_||_||_||_t j|pi|_||_dS)N)ranonymize_labels)__traverse_options__ selectable include_fn exclude_fnr# column_dict equivalentsadapt_on_names)rr4r8r5r6r9r2s r0rzClauseAdapter.__init__sX#| 0% % !%$$+K,=2>>,r2c:|j||}|O||jvrF||vrB|j|D]4}|||||g}||cS5|jr&|$|jj|j}|S)N)require_embedded)r;_seen) r4corresponding_columnr8_corresponding_columnrFr9rEgetr)rrr;r<newcolequivs r0r>z#ClauseAdapter._corresponding_column1s55 "26   >cT%555#U:J:J)#. " "33%5++se,,4 %!MMM&   56>_&**3844F r2c@t|tr!|j|r|jSt|tsdS|jr||sdS|jr||rdS||dS)NT)rQrr4r'rr5r6r>)rrs r0rzClauseAdapter.replaceDs c: & & 94?+J+J , , 9? "C// 94 _ 9T__S%9%9 94 _ 9!5!5 94--c488 8r2)NNNFF) rrrrrr# EMPTY_SETr>rr>r2r0rrsm:----(,0>& 9 9 9 9 9r2rcteZdZdZ d dZGddeZdZd ZeZ e j Z d Z d Zd ZdS) ColumnAdapteraExtends ClauseAdapter with extra utility functions. Key aspects of ColumnAdapter include: * Expressions that are adapted are stored in a persistent .columns collection; so that an expression E adapted into an expression E1, will return the same object E1 when adapted a second time. This is important in particular for things like Label objects that are anonymized, so that the ColumnAdapter can be used to present a consistent "adapted" view of things. * Exclusion of items from the persistent collection based on include/exclude rules, but also independent of hash identity. This because "annotated" items all have the same hash identity as their parent. * "wrapping" capability is added, so that the replacement of an expression E can proceed through a series of adapters. This differs from the visitor's "chaining" feature in that the resulting object is passed through all replacing functions unconditionally, rather than stopping at the first one that returns non-None. * An adapt_required option, used by eager loading to indicate that We don't trust a result row column that is not translated. This is to prevent a column from being interpreted as that of the child row in a self-referential scenario, see inheritance/test_basic.py->EagerTargetingTest.test_adapt_stringency NFTc  t|||||||tj|j|_|js|jr |||j|_||_ ||_ d|_ dS)N)r5r6r9r2) rrr#WeakPopulateDict _locate_colrr5r6_IncludeExcludeMappingadapt_requiredallow_label_resolve_wrap) rr4r8rJr5r6r9rKr2s r0rzColumnAdapter.__init__rs    !!)-    ,T-=>> ? Kdo K66tT\JJDL,#6  r2ceZdZdZdZdS)$ColumnAdapter._IncludeExcludeMappingc"||_||_dSrj)parentr)rrPrs r0rz-ColumnAdapter._IncludeExcludeMapping.__init__s DK"DLLLr2c|jjr|j|r&|jjr?|j|r%|jjr|jjj|S|S|j|Srj)rPr5r6rLr)rrs r0 __getitem__z0ColumnAdapter._IncludeExcludeMapping.__getitem__s & /3{/E/Ec/J/J +( -1[-C-CC-H-H ;$;,4S99J<$ $r2N)rrrrrRr>r2r0rIrNs2 # # # % % % % %r2rIc(|j|j}|j|j||_t j|j|_|j s|j r | ||j|_|Srj) __class____new____dict__rprLr#rGrHrr5r6rI)rracs r0wrapzColumnAdapter.wraps ^ # #DN 3 3 4=)))*2>:: = EBM E44RDDBJ r2c|j|Srj)r)robjs r0rvzColumnAdapter.traverses|C  r2ct||}|jr|j|}||}|jr||urdS|j|_|Srj)rrvrLrHrJrK_allow_label_resolve)rrrEc2s r0rHzColumnAdapter._locate_colsh  " "4 - - : ''**B~   1884!%!9r2c>|j}|d=|S)Nr)rVcopy)rds r0 __getstate__zColumnAdapter.__getstate__s! M    iLr2cv|j|tj|j|_dSrj)rVrpr#rGrHr)rstates r0 __setstate__zColumnAdapter.__setstate__s1 U###,T-=>> r2)NFNNFTF)rrrrrobjectrIrXrv adapt_clausercopy_and_process adapt_listrHrardr>r2r0rErESsB 8 % % % % % % % %!!!L/J  ?????r2rE)FFFFF)Trj)NNF)Hr collectionsr itertoolsrrrr annotationrr r baser r ddlr rrrrrrrrrrrrschemarr4rrrrrrr r"r# langhelperspublic_factory_join_conditionjoin_conditionr1r;rMrcr~rrrrrr6rrrrrrerrrrr r r/ReplacingCloningVisitorrrEr>r2r0rts&&&&&&(((((())))))$$$$$$######&&&&&&......######""""""######%%%%%%""""""$$$$$$$$$$$$""""""######!004 4'''T111h<<<B %%%%P"""J???KKK&      '''&&   *.        "UJUJUJUJUJ:UJUJUJpHHH62H/H/H/Z" $ <<<<~M9M9M9M9M9H4M9M9M9`q?q?q?q?q?Mq?q?q?q?q?r2