JFIFC   %# , #&')*)-0-(0%()(C   (((((((((((((((((((((((((((((((((((((((((((((((((((" ,.Fh Ch@ 10D``DBB h4 @dX bD iD ІI$TBB'$"`I)Eb`(m9@0hb&!1114  b` Dh "lTH)TAiN  A" hf%n£!aY4hcC"5J2#Tզ@ #(a`QI+JHB8h@!!!hSMNhC4$11SB!`&2Dc(p*`"XE b!IJ&0C41 b `hL0JHLi1L -XX`ݚb% )*Cp& ! $40)!b䜢hC@D 6JJቨ4B!`b `0@ b`&ё^IÆ LO7dX h@)A "I`6H !L'@ DQ B!Bj4  L@ @hb&%$ D LQ~7ҜtZ&pӘ b `&)F؆` 7DBB&qI:LVF2B1 5iL4$ mj4 @ @ b`0b iS` 14V1l˦I7 @` L&ȒB[lC!FlIY +@!"!%$  HX J00CبDE18! L r2ϳ>Tس:=8Ӓb  & !`) "0$EMSIAL6D$B`&BBX&1C CT4h! @@4 0Yf |,tCE\T}nn` b$1AN&$ &IS`0118` 4  9_^8B14yꞿ3wlK 7 &@ 0@ @ `Ȓ b( +$2DR:]Z3cqcAȴNb11@#@18b`!upyt|z8lZ+]}3:zKcwA9SUU5AJ   2LUp*HR+EUEvF2qIW8)-JYDUQ  b `16!B& n$I9y~yntpX"QE,m[&C44 b ``@  BQ0&:Qud J7*"S-5(J7U@`  b1n.2/| ZrJY]3~ڕyצ1Ͳʬ3}[9NΨWVun}Tc~g6g=Mq6}GKsx b``L!nu"6ڬQ}_4 4IMtSҫ(610 b`],k4r:\_GOn骻q[,C*ͳԖzhUݐ9w L01 L& hQm(4d]nNiF wfG&ܱx*uθIbBʤSnܢaFj(@`8箄Ꝿ&IltgxgɻM%Mږ{z)]vSqUټ& b`0CT 8&`% '** -L/(4$cךRjp.h @1b!  0n7ʮB Kt}UF˞tr\7Jϖ~%Ҹ[!hUqp!&7Č1] *O4צN.Ǽt0!J%S101CC&1 Lh b bey ?fW7Ƨ,ʒ2t}֚m[PzvvF@ʀ  hb @%(#!!bBâM4BF=x Pցdd'YS̷ͬ 118h`bSv\>}Ux/ޝ7UI5h,pܞ^[U9=&v8@I!(XjaS,S3]av(KWP4j` -#ݒ7Jն&W"1t!^0 ! &X2y=yomNz.zVwfKݚж26ϗMa5L0C]q$8EQTl;yj]\U:znT62U f%uLb!  o7Q/{jyϣCJgS[oޮOO>_W6O~oC,2T`44\3zc(B A\cuݛU4컗AK2B6vǷ\n9WXQ,y:Bz` `4 @C&r_'RdxyNu <SQUM+#S⎬7v㦩K]Jy:KX5b`!!)*d 1RYn+έӚKUJX7U3˟EA}lŪe6@@  b b4x2\>|z^WvB{3^S׺Np^kέ㜅VզhW6rw{xz=)@h+ !daYZC.~mQniڲ7|0Qgj_J}l;8Po)Ά>4 @dtsNqОgͷ>ǻ \T`ыfNf7(pu9|]͙c{#(h1 @ @}6yn;*SHI*Bj"9̻&{y]4գ7>Wf~םZ0niMRsTH/NL` @ `/9ywVY-tkZJ~sGCz|z[cV-KX+csSTWu6kK2"2QiM b6y֝^]k׍ʻK=U**MVK2R.ZE9}v6{i1m]jZҌRUJ)De%dR*K~eS>-у$eͮsuκh%lGNl8#~:n5Yߎqf?L'@ @ojȲ*d.ܴn3q$ngլNKbS%{ߓ\qM(zOk=R͕zX_~=hE'J]\YA&]ƣLk4>5tdUFm8ʋ+7T+K-%3oU]kRKV=cNjkCiGY)s󝧂뫟CX=na\^ RgOA5F|-P_ew9jWM;暜Q}rUh;p_>|+ng<%̙uӧ>phss.SE67FH[W+8sc<=3Z_FJ^Mz('.Rǖ=<}<=hr7Z6v"pV-:jS٩}vf2UeYN\K JN*|y.!~O{ k#;1rt݃:>8sVL]*gs*-dY*Wdnb b&@?=1Ms*|ZW3VY.+ӋcSZg EWfgvZNDeSBWʋ$ӟLu?CԎvܚ/\hُR]zu3&UWZRvj^l[֢3u[ةZ2=Ox]wԥΛbyu͝p뚫3UsaVX;I>7~xgpa;_կM5yĔ1dD׳<K}*D&P&@18{N]n)E=Mg_811YGE) "J cMQ]e3>_Q=:f]IzTQS US-izΛ$Iv3Q]]JM$[VT *N5-eBHJO<侴euRVzseOv--m(JƬi`jKڹW+n}1Z^.sLyq9}4/sw@ZH!]M&y،l-nq沯Ets'mi9E: Q"Z 5ֽC^mkV[ʝ>]3n2,#\B `T(U6-N,gF~&[bB^w*<=UÎ+mBePW:IPڪ7䫲anm J0 Pg=iQpڎz\~-kRqXl9]O.w}Ku&kSuHS $BRee:̢r fnYmSE9Hr3PQuVE 6AM "vty|yU.Y!nm4kqB.N4UdF鶫,qLں[e ⒅kYknpwBϓU>^Ѳ+214E8,:"=YվٛG\N{UǭJ1؆( -Rd [ۏͣ1f^6%fF$sB̠YUӲs]0 &\Z\_dL)f{!f7}6_w5SYŵUUYe]=73uԌybv#3]ё+fXx?ί'jĪZ'KZCOmVg ٚ5![omjbїxue ؒuU̔g5ziW:7':]Uˎ:ur;ês솅Dq#$BGVQ}cWQd.ŋZ5yrhgg^1ʎxGo|u?=%[V63fH41ӿFBwwnlӯǵ*vp$FJdi::qӏ^|{sF5skb+b;+ɳǽy9mIAJ1ɚz9j]<+htU!lNZ`tafcʍ4⁳G/LJ|TZ5%TͲBLSd-.ط%ؓ5ˡæRdĉV bc@$::v֋oV\fwtr~.V:2.8n.YX͎hk1.Jvտ}ڸm볧-%\s^Lݾ}fƥ<;9 o-^,/B9T,ųXҬ o,4 hxiӛfR-zlFfR&oSG/G=fl"#o %$4W٫#1e;Y(62+W4:lt#:;1[G3YfzseN8dًI8Oy@ԉ``&!#8Hs3_OFRثRulvth;Ì:dl @TqVR* ˣnsuX4%y:f2h]KƣVi%:f'w?LkU?,iÑIg]B%6aUiUg&>zuƧM_5^^Z役:stNg\Y+6ٞEֹgZγV5vkD-d=y55(&: F%`Ȏ-@ 9}l|dNPGDWmp%܍=mbZFlӺ23jqъuپY|| FxiP+$'*싶M+oEșPBf x8O;)3:!319t5!K kϥ:o 鞖3;=QY٣ܘ0JCM`I5f|֭sb)[b6xe8Ne!Bq2c8&(Nv񺭁TmdB6AI"^OOA(D#4o,i󶞼 ^ϯɽEz{κչ  J2# J0lewn~̚!)N(џLbU9:x}qҲ6m~/LmҘ>F蛖޿q]V FbRF|qV]ب5ltO՜&e\u5N\&\تP ʕ^dKN}!F'3ԌIT-!Ќ\%||&zcy].:yٿ,n㨍vL1I"5I4ЇJ+y_4t[Aݦ>f:i2\2eP۱kqED1g۟NxǫOMJ4uH\EūB ]I!["IHl>GW t0peEN]2_g:nm#7S{qR7.ŲAVL,qhJ A$n,iօ7>]0g3MiKkK^#PJ8@LjVD,kU yz̪|NKυI@.v}5wy}~cLIWw!o )E(JT1RjґW{!#4}g(CD%bJ+WKO+ &3doFtr걤Zabb!ͫ7%ѯךU-Ăj*ÿУTҷ=|<=X[q6*iC"(d'"$- yyTnh-|z]fSn'dZ1Ky} />u_3\8 Nz8~GLP;iHvL@`SM"1`8x`q/mAI}E9qOןơ^r2U`JP,cBkW!$I)d+bܩir+уXJ-)~tc>&ĂVB-K_?z$. h0R)F@9"ʑe>\z\;5P:M9u9ɮsaOz{qҬsq6ȦN@gm ;\$8' #R#%M_28ІU[j,#"˟P=++| g!4n^䪶 i5P$ϮYCc`Wr^010#Њr3$H ۀ29# ?ӯ ,q=ی;G0O,, 4A@83s3o !<5-׼ 1?430D$a ;8cO4 ̲9G&o4 1ͫ?8<3w>9? 6 8E Ǡ~ߙs,< ,/1\O8<:Հn:,ӽDb.4'8+Jr<<9]+rˑ0 <8"CP/ < s c?2<O;x7}000 Á(N5M0ϯFo<Q!w0 # L4Ҏ +1`=LѨAuM 8 @h  Ϊg0[8d_o|n00 8 whhtS/-ŸsC8 0 07o8$ڍ"ʘq{ T2ѱa0sFsrљu[ ?Nz2"8fɒ{Oc1+3vzM|"D:I}KYaLω` 0 G+(+f?)ŖR+}0q@{1'7#:w4VO0 $βէFS4LBer JeN*/ =A1=$l\Ӯ@j.檄kz%eqe^PU콹4x=3` X?Rʺn.Z׍x)y"ř?21l6oW5O䐘eނ͠@{B2y^%kZ*ogxBVW`h9mh]zXX,нP,ۍ44&}=fJ4E6~JC 06}+n'Ui1᠗$ClLE՝)[T@Ub̶&R3[gXPB =J(B41|xs}Px蒲@[5"J۲syo#$;X#L z\,;tEfwҸ,=ěeӽ'O (7=u~*"x(Q$I0Nm5ͬz hEb0?%0+l2ͻXl RH#rA/TmXb̪?>޻|P:}f}Sb*QnW4{5\@9I{;MWjMxs1;1dY~>r[WRlW2 UսKzrIv6G'1gglOrm"(zLfo`Tx0fbhmNW= [c3 $'4jy32`$^vԩWW|[|{TFg4CPaڝ {X6]0[Ö4W`'LqϊJ.,3U[1[v Q!!FuZe$ eQw?ieg]TL-N @X-nqBٸGV'd H- 47O3y=Q ,swwF%"wXMhO{5! p:;K(o;1O6`.9I~hŶͱ]Yqưpmaƾk^'y; S!",`8t侑5qGZw)Ayw/<^?Oz1tӪ($S]n91#T2yJφ |R|3sJ(]U+G{a&Pd>i6ClR|2Ռ7Cgخurڛgs.3uo=p,!5bh-?KM)UzUk81ְ` ZIy6 qJN-ե5ymχ7cl,iX .CR oz⯫y/R褻kPp20%˄c`6HapC[q7C(Dz0DG ϴu{m[˯Ac" i;?vGms$יg,h?(sc}^?Z׼s8&IGhDm?Kosy[r)| Cq{د}4} /{ePE4]s։* -?ۉ붻]:+m'Wum}njj(l*J }mKVT~ 5o|YYLPK,"jC*6i<}}mg*ޏ<2cs|㐓bI/v}Hvw gM$YQm<}}}}ڡ, 5`na%mv}]}UhQۼu,0<2}5uSU[-3lMUQ }d[a-9qLԻƥŻIu<<}g}mD#͓[}3qԗq[\^|+ (ŵP }qqe5=߷ (Bt597=#a*8^ȁ 2y`Åqi}<887w]Գ=xQD\}Dr)XI 1ϻ( cK<u6YqJ|4tu<o0[$-| 4&'=M}R&ʨLs.Uij M\_҂B!wh,o3g]o4Q7u ?o.\o(iˣ&CpLTz7ʙqoyv1 ԄajAĕ]ȘYB1/&aжiv1$J]I1ڂ#y ہ+-AiVmmRYY̺}S*_އ #׭qrBv YR̿XB=kqYH8Dvq%=j1 PUjץ0,#>!Tף,8Ns|i,:$BWpہ0NNʼTrJkY?4@K_oYa @1沩(SgaA4Q6HwF!J`7pVhָe"֬jO>$,JdLTf9BV;(L\ h7 6: /[)+R1.?`2UM|r*Mѫ/-?H@l!M*"% d͖<HbģHo몯H^nTG[-9#%9I"9MԾtd%yhGN Z`˿LJܘ1 3Zޥ0ږ[z hfɎ$X览N7a./m ՖG]8_:)]`9xw(F.&n$6NJ?[^F GYdn΄΋9>z nf`~@lֽL&".qj'1q8hWݎ's@;B ;fdBy|q=S$`RD>]F ig ^%"MHt4SIK+fe Tnf/޳tdy%[1!Jdx'@^PMoxMS{TPfB|^*}'sUC-JA!AFx(i؟.C` \nx<졆|nxYPd(n`/fL#2t>#DũE^?кq OmNkoȚ6Y?7*&-BA0QRj`鋘LϡL61O{˗&T܊TΛ7 q5tfԯ09mKxt\6j0"4x/\ҙ UL}%jXƄ QYgк87d]G#aPJHrCN\xKg 3]Jy1`\` Ә![MͅX\ΖABn %̃rd@fL*tf]>]x*G~|ˀ`1|>;;_`GEqIؔ嚜 o3TrUsqǣĭ`FC1No}~`?52%f o5P  B楩I<$̙G.4v|ͬa,U+)7v1yP&_6WcBa1g$љWx5G!TxHRbL>}UȈ26KNV_OAk-eT~0 ""3›O1Pg(>L<^F,hF㘘ټËlauVGW5$Švչ6b.3N?/4Ow!~& <~0"1rvb Qf0U5Ax=Fo3S1z9f|1/&E(q3dq1&F #(Ua<DM@Af.gI똏fnD$;2?05(B A) >0Kp|~ED6EFZFv癩>Pڥ0 ӛf. Tk3mGVc0Qf;,ƥT`B"ߖ7*s iN*3("U FbqBbZ - ma_\X5 3.(drb;R`@58q@T&bfj\|{Tӹ$4AهB9itbĪہ̮D{ud\%jc5Ɍw,Le"m̠\xꙮkC ʔLD鷕x*D1(~?P& f&3Y1[c`J LzARspa\|t(TWJlKT"z 3 +ɨ80&]>Mg;0Ll&Ll61Z { MRSn(-=:fP& 8]!ryI'U,ynX\ n?sB9$̈́ u6`6/Y3Sd%1)w< 54QO8nYSMd&@k&<[DkcQ>&\ [%N:VA g08AyG淟R4qډswD:AOyDm<*\Mg3zA0c"țDɄf. ,jH#U6;U}1M 83y|kcBk889?Lچpd4L\W 2g&SLue~2-2!¦"Ӗ]:)&m;4bA?0k8d?)}AkV,&E(hڅ۸2S5Aq0F"UbYө䉗JF:6ry.6CMw> b&'5M{P|]T}8_3P,X Bc{A(7g9кӅr(55HDRiS~I:M_Ǐ  ZÕZ-k54ZV3Mg2/̹ڢiYԊD͐c]#6чu>Lv"pAFaJh]Q,MFfܢ&)>@CG(X%ߒhF(m.U?i.q.مw2c('kXIcbZkXD&#lGu g\)KlP#B`P[y}sR(UpAn%MW>fqԳM/|5FOm?ٷbx*ٚ-X9BP16ճ0ԲPP^cuyLF*e Ù­ -Ar8ybf&l$>!WQHQ.TIL ,?y"zmճ65Vq|L_"Sgϸ 72Ϸ#5Rܾb{["R>#9&e0Nf|6s5 ]?3:`"Γm@'gfLyybXq #=7VsE2%ĠG,y,n~"T~ _eXt^Q70ٝA7%ÑAf%3Vr(ij7@{_a_}od橶bdgGGɈlw˜' u.fYRh96i[9!>2p@*1&ELf`B~TM3F᱂\N`J AAH |e0sPJ|1>'L1L t nLQ cqsLUIQu4^a )u; о`vNbJP!1&Œ,.Rݳe(Gb}ޠ06mŒ`Q5ܙ#[`hP 6 cu 36`־& :3>SmxuxNMFdԐ9$G 4;++!>L(bdGRG pgʟ)3cܻ ~e3Hdiѷ)"T??ŋU"aENbw .SP@@_&l*1<8arcj/POܰ!48v ˊ|w3PrՄmCju594"~Q:LA[&-ϊc:f#YQ)="T{ajW><>D8[ǃz ExF6IOb"/"e֜965 &x&c̍h ~X9|K`01gm; 0md<Ӏ*3 >%]%Ӷ>4\AC85LY|@(vu{]:d5c::VzjzF]g.1dM3]bQn* "'6Vӯ28 e? Lu3IcaZ|T؉fm5:gyd9Rq:nǗ0:6ZvsB`G˘Lh8Oèf^Jk깠kMԸ~"nCop&. mS̹p{3b\ML;1|op܍l~_~&7<+\4g a+2 k_ߙ[ S7"ĚU@ѬGP&=7]=(!>cdːa,:~\r?i>ij28̵=<vm<)pc `1CهX õ{0t91 _`'cQf(\ehP" #YA>Q>yzS7Jy 1X Bp8s,v|G";_1+ks7#LZpڐ ?81|+fB\OB8<aMf*ȃϻo~5yֻ$ïb91LA1{xU5") E`+byg<\_lZ3aE c`;O0f,KNDd0XHN3tW3 OlHCaoUܒ&"Pه[2 FZW0'KWOt/ A δ 㹇E5L,JJ6DmZcdtRf w'1h_bc|ith\h/{XWfg`r#v=s<\ĻlkRkaٚţO:[鿿ogʡ<|h1TqNau3.,Y`c! Di3qۙaVh~ˆE<4бWf A{g2rL>8ljocMCAMO ';Q|Tv8&h5nqW IUdO\9P6y<fG&OT|8А&-22fp\tl~4zllCq] L9wB tiX\Fܠo~h?y/~AP*~ OãR(q` SfKN gfE]4hɈ6c Bkܮ3p=; DBAg0? =ˁS|Kt2ci4F3gJpee˪*~qwՐۏa4b1}S55 Cs EbE˸Q#4yCv{L^%XЈN6 ǭª&H*qsWv+gFuAƢy)MfhB2@PC '%}k"Lϑ9"z]BUΝ5@9&5';\>%H;u tۄ8V`zo3{@>'_l6dG+f:;A]BM;@D87"u@r2}t[ ¥4ll&>r!\O6&}n0!=`8'pftؾ=k1Yf(|uOrZn4(cuQɞ /L - T؊ۅ<ZEb*~&vߐ%+Fa*YSFM7/n&d5&i\>0@c"h#h n` `8 >=Ȍ(u`RǑ46`4{&R(H``7 abo"`ݻ5,('7j =5f\ '``g1|L˜"Vi[3HbT1g>`|č米?5_r~IjY 2p=kX0L4jLP-!Pr/gQm37}魻N}Ri`C4ŋ6,]R=ӷL#)(eF'%i&0L| 2UOULjliIP|b:}Bd_]vjvSCWe5$Q0>6!1A "0Q2@a#PqBR$%3?l/;?(g=T3iMm#D =>J~¿h,%_\rB>Q_qSMi3*:t(h{TR|aYR[oϧESFZ5`ܿ07a_8")&])5cbzԯF7KGz(JHP(F3X>?T6ʄJJޞJ dͰp&a)x]R~7NɘY18hHRĝL|2~#갢Sn<ً1ѓr]ٴq'>[\LoQ`צeBTf[ٌxmcgr`_ؾ!ݐ660-EQ  Ɂg@SC^&\z'Q8B= a?)?P:U?N@*>4}BrgX:;\N7jМ QK&ZNܯT6a6oa㸍練0d8E+`rVuhhhD3q=x멯oݙQfg<x?ӦÉV2?=`͟H$DXt`?TEeS'5g !{Aw~O2k'%8?6 1bmxls48>Hx55T[|G"0~{L`KPT4oU1c6|OF. >"De? FasQ^ʬrMne@3`d4tDDn8?2VC+VxHLeV748M* qU?M7& r g.Ѵ'o&\̀]` MqF*D,hA14l"\"@&T.f<r.2)&}0i#Qdƃ&nD3L@|@r"&#ɍs Eړ:cHfvd"G*fA\YB@S\X Fngt&,Yr*E!CDf mbiwd49Аc2uPr%&PCLlw\EP?1BSO(7#(☎B V0h@0SQrfn!kv?uw5LT!E "+2%}eAv`@Wc͒30+26Tc>fn<RT(9ֱO+n&W˦?UDZJAdQ`ZBAq0e*`"㈊Ld0X36fR@, #aJ?a 00GQ B% jfe WώE7iF ӏ(2}1:&e3A:%E]DPT A(DF=YTUm%d EPy<@ k mF^ft *Gs\DmšmAK列N2?gI8.0#%0 Fb. .f(FqV&P:vhtCwb-& ˇ#Lώ&#E!Rp'Og( xXX%,[V`Y LX!65mG],|Y*> i )4wdDs\f44M5Al|J8 f 3ןfyeSl"3]1X̸O+s"saWqR)yTccLCP, ;qh 4}y!IɴEv{9T2EXٚlG&@&W,j 3ǽ@j&zG&bLTno'cƘ<OLx=?(ؙȵʴRZ/R<֝Mq, nTյ$Yk] e`.u'V-w!h cOc4Y61&Rǁ1)4bG ,Cs 3'B@+1bg[Q4‰'˽&, o'"T5=`UvOj?BrC 8C XP ɤ:kȌMԻ1&ogG[@@aQp34_B QP_ hVbb C:c-h.!A ω 81J[ل'&)(ۣ,'X)\A 8D=Bo]7[{1QCP3&#Ez/gܻc~]q`QRf,eT ͤL=5#MC:.1\PT-8w Gan|c"%Y0LMٛ&L rsSd8u+W/Rè@E\\٦զ}1zQ,b~;"k6)F:YWc2TLnjb6ۓ9.><~1,NEn '74o_(*lD+u wӜٕDƼ@G3(e&lQзd@l. ȪjÓlUٔHn!:l"fL9v5hIu ǍL-o7:7EK.crmը௙ u3c]XGȘS2}#XZ?dO)f!ɐAbfG8T3OfpiNrfX)4cN2"F4!ʕL֠]ZŇLɷ%~e3܄E؈a/D>zzc=5V>L[i'b 'C>R#I( eR@9修euaFt`ŊSN]#bqk 3 j75lU*n}jOMWfUT0nf"!%zːc&gڥJ*i؜BV n|@7:0}bf\7M@9@gPМ`i 4j&p1m5?Qfk!ְcd luR>L'м̄&*}?툊怇J 0MfM) NՎs;)rlT=" (?9ɅZul@;%R&}: ^yVԛ# g-@@PRLg94^C>`&\.G7gйUL1 *: QDsAjqDl2-4u7Eox`܌c˼/*'fd*9㱆 D ;da:K2gbeh4{FҡgL |v3 }P ?tz`Ț&&o"{preLB$5fl L6وAn &3za)ϑŴ(ϩɄMQ\ޣ 3>=v~n ԐVPTWLĹnt̛3W=ØuqyYؿp}:O?g'ŷY(vf ,gQ9AL^?1!+n$֢&*`հ3$Ծ &5)\\@:&0E!iS3y7/URA<~"1e0YFNioIB;?Lpl=1V1w0`Nd`$C#O-ϙp!vkZ˹.fn|NɁOBdԽ(݇_-l3i0FԢ7+fLe9*D h;Ob`F1<"ڑح(E`Owֻc(VUlY{slc5UGESowѹ oy0Q{v剷 lsI6 FƖ8cimJIΓ 7TQsQ9F $h1"U/]Ps2+7s73YO|U|ΠS vcB=Tǘ>aۧjN3(côRƣ){Z;_@\P#؜gK=2͸1-qs:"1+*~`Ρ r"6b&mη$j 6>aTPŚ#1`R FD֔My$fI`ʻC3. >aӱ*1%g'i1lJfxjPðvېnk_%8 Q)RY4SLoɧ>lhđ&*&"ϑWj 8f_Xv3#B:;116&@caS0?`1sR37-b!q7Fa+4cE;S&Z3t;rq34)jQAJ!}c]@>`E3w]ҳ/8pÌe\I›, "1!cjTfb[if_i~ߨ4=ndY(L5cGQ ̣!5l=S2w,π-Fk6&wľ͆,UCJgP9cswbPݍ&ǰq0o*`C ȕ cF+/@B˩5fU #62‰(h۩2b`m4xm1V/lZo}VjiT/n 05w2Ʃ7b`<> 5٠%z"wv.n,LYWjfJ3wBm(w@\D|)d=Yqs?=f} s}&W4&Ĵ Cj}34s\m 0 &, &Lm3 % LTʶ.<x>FTLP"u-8 x (@QJy̨ʂT7?1}?n (6u^#>eh@Nnf*I<)aaԛ{}֊c]f{ UGT;,ͦʠyӌr1#nZE标80a+`DT\˘O(ٔa7`N[#6H#[YIU>'͙(M:.e/ONfRk޿> aٿ`G?~!^a£SP)cPD"l& 6ȇ)1t&zn|0dAc#'Calumb 4 ֩L=fݸ2oy.2I$\@=%?.$γc.U' &6yhc4~DžYz<fc@X~è81]K n DRk Ž &QbƣP pэZ:ljX3ʕ?ݎѲ(G` (z(PԅB~`kS6xM,bmwQ_ 6rMp{CdСG՝K cmؓG'ӲTnTM4k#Q{1O\GeN(QbsDO{h:Kihc'\?3(PBgmA)g 9aTq%#8N0m^T\cXQ%…^(/au9羳:o=3 =n-~Q~މs>0f' dΟ?n:cW=vKCiREd]|E9=(faݹ[9d* 8۳ݣeJ0}BKtLdIPGcGTıa+6M/" e'af[:^ 03~z?7*TqG Px{e`Q+yh'*94omJ(1W/Ɠ^+LJӓNJy-_$^kS h&fn!fusB'j9pV!8 0(蹦*9U4Xgc{ZUVӧw=Wf8TXңe\we7D ;>@SZ;VjgqHjP9 z#"bȯpcv)(et+w4gQ ,{ Ži$5EX:m/\ntXG\Frv~,Ԩp5! cL%O*Lx yŦqdGh 7cnSz L mgZl0G\dSݼ.UiVm FVcNH9dעlUe^,.I&Q&] mѝL/賀A5aS4s|CQqpoIH;|e_ -!Rb}/2tu #r@Uy6Tܻ0Phu]Ļٹ_@lrLдt#T1OS76~uwliΧ[L}LLiM9!7_O? IuZuNv,/!P25䷴CrwhcVI *U5ϢDiYLtaUvp}:'{?]fmst' LzMVrMMʮ0uFS naW7Ԃe Fk;B>Ƕ5D7w2&dK~ُƂڴ,;2Z{CX S5Mh?-$JfID£&x,-q#DQO2tj@GI @!Sv.2JvY*d &V`~#=27Z,TrdBCdFW K Tz;x5qTæʙ`;*kHQ&\JyݳKBt fL :|zt^c;`3 +ɀ-V;t)>au?7Xw`GRwAWHSnNeII*pU)ai0i8i9ͧPѥfcXUV6zy4Hg]NJ<-=֪xbS3fYOC. Py֩+kYZylg 9j:D3d\އoipwa6@nbq#\A}#R5Bl p2U]& %QΓ~3TLG]BbIU MӒcl*T&t9c=eC'~:;6x5@M4 [BnդM0I>򫅨VOt525j=wS1 0b L{mkEUm O *c T̸AiD? N;Ӛ`s^ǀ檓N|sPL:6HI?Eޙ'sf2M}'TjhhwL)? 煨 J Nu'䎉 ԅB4NU|)Tm<8B0k{2`i &KCe~Mޚx!%OA!Wk|!;T$S%L;kiTxG ײ4AL&ТJ.#4hmGhZ$4LtUeˡK*r{:s^D\TwPnQ[t\5ee=UG7˞je0GC,T8|P}(lsjhvwdOWgUtr;\DM)eEOHM >Rxs|BM:M}6aFbD eQ1[߽?P 9ke6N|hyD:9jpj6?ڎ-Kz*sDKay %^цAoyK)4nj]ˮ78uXjz5"汲!QQI=75iͳu}Ձ;V*}!TKC8nys]0etPmaS`CT*Tvb:ױ9*g<L0ʧU|!&eaL'϶DM$g53ZLk)#-S'wDcwE{0G;Ii#6?CrnC +Ϟp$puC=2oY4t 4FC9/Q:~'ET\t?T󯺰u8{C3B+'^XdamZZM<:}imް׎D+rKanUi*e"ςZs2潤CsS]sNRζqFHh4asۍaxJG9 ̕"ks7u)ѽLOE>>.suU?&hTUy}T!@& ?%̣| K]yoU#p#ZUDdNl9!R hNNg0[[o&O@p/ݯC3ȦRf+9إM)džA:J7@ˌqOK y]^3cNDѠqkXX~Z*AW,&קk*qglamFtqJ-'B|m>hwk!6!S)yBcW NmUZUIˈ.Ϫj܌~vFG$Ba;fVm:k x]^GN 1t /Tۓ@h+¼rW2gOݗ.Jxl"y%MzE1[uy,s-p,MTo8xʯ k $1Y:ȉ&̨;ÃVߧi dˠ "9BOȧ訸; i]c-{p ԉZ°1gif2nv2ZCW5[Pup|i ԜRʨX}I4w@Mny'K):\全9O%KxA Fn_٪*&i {%.*È*m &gR$Le" .$8OTT\*H:~F_ 5BF1ͱNrk Und*.|sޓ=Ld*6x2 v@)I/S5=%_ACFTثZ.xÒכxfd']%J܈#Ul4:({.|uꦵ'j{a~0r9#U4!apAd@ȣ190&hM_Ē)UUmsM%d 3o8ɵ=k:T*qLwu]h]chʓK9:_ө41{y.n|-@Wgl(:\D4cm:d Ow<_T8biS{d.ڃ(!UߴUMo7LԨ}mp:O: ^5*|MSK~`zSm\T ]& Mq+HTK YQR`s3΋ "'NߚܷunKv2/o㖍`vl&iA:VmE,9zg`̞>G^IwyTШzOM%4&@*O4; ˾*=}Bk?BaoA6 Csns M`Yy,"=S3{qn*'ڵrrՊ||LUHnJC) ve1/-ѣ@U[Uȵb*omx`n.Ӵ>*SLUZ *Ea6L\UR\w{g6Dhk[g)LdeW02BV5U6U,— cG `LOU8}~ K op|4q9(\~_=m7CdxH9eMl*ᕉ1Թa2D(܏TaBTUՄf EPC ?Obu'5Hk8G$y*cCrՅrM9Nyk>GTXdnoh4Xj;]9#YM­2ڲ3*joEARzeh@rküOWwZoU^69)'Xی;kߒcN ]< s'{lp Vi3R[ T`LE^ GS: P L}} (႘Ӫ}AlwEZzev#޳)Ȯq}C{bSֻ;IT}6s]:y)\ֻ{`L;%{zFKO}Uv-oHhQ2һK Y~LeڻPrDMwbby'rcTL$Z\2ǸT+*8Qt8]R)cAsdxDz6CDagXܩvk̦uQsdPqa|2ۏ`V w u6Fzho]m&wtX|>!<]Q1Z\ӡ݀ aȄ[qasUM>XrN ~LJ 0H}&ɨj=ʿı ^_> us{39+Z~%iv#03uO_תUeq| f}eR:,E ۗ.{`U\@ dgM04c6cj R3Xl@{n5X1-fࠉïNg~~wsDR:(rJ"\yŻ_o=ʼnZ*ѻ.4a*1uaouُ$I,)c[F@^ TGR&Mbnc\wMw*vVS6yL8džjvU ԅ@Mvy{D3=rYSkC@V@3QbP!q|Vڎ#Pf2{F2}!pT{M7T{F\L_0[5ZtTgi]97Y.ըfJf,s'D:6Yt}U4q-4cB>+ cmƲpvmh:ZGf32'k#o<'' _Bcd'CM#fp5k,;OV=G3Muj\eԕA-e1 ʬ4l9l)hÏUITk- y޻PŹ}ڸ50yQ'U2O@!T<SF6/H z7?XN3 BS)0-9s!SiTUw.HҚL~)\eT{Fly*.,Qp:gy. h-O`]}1ZPkP t:rXϧ^⏉8CM2c-&,y9MvXމCp8fmJuY,tHS]k:&x`!ۊ`r)lKS».R~~J9iuuވK{лO]W ?"Nh(uBJm췍܀sToKM.Cyho6{`CCvYpv9be0U??D *X~ӡ_4T'"ԤX㪥JjtđIu)w犏aT @{6X|Ml.rGf!V3+UȔ %Z|Ujze0ֹ^1OT>0 %2HX'vN+Ҝ!7'hp8+v.,R=Qѻjxѧ'dMH?HnX\=3AuĻ>^G_m 8\K@XAAk" +YsUt5vi?cLhI_5 <)JC /Ak\6,0;&)s h&q9SKU@^5_,ͱ$&nȷOݷڧ 7u^G89y m _,Rg/pjǘҫu0\?J]#\w"b=G%γX7l8a-[QU}r=B$h MUJLƦGS3@*\"B4E /VnͩNw,**Z[V.p9gpXgյ̧kc)ou7Bh 5U@FJ&,~t7)%37 S@sns)YMtn w4'xisWXa>o%kV}G'TU0vg J~lp*D$&vgkTwU%Yi^!b\xF+' ! 3\:G5iDWhGO*iЫwMwD|qvc*5C-aDjp^k V5 (7kKi7ywYoTʨ,B9rriL]60QR *`mVaY.e1R뾩Yn5c/k{xuﵤhCFjپ冤Vh zPab4^eRbgB 4]+_񓪜SC9[QG:Q`Y+Qw̬ v@ R,^,. 짖W _yDu๲-b>.$ )'}^'. {jWR9hb(6IVh ӬxI6Z1U Nm.ޣ4E@f>Ues-)*3 u=UJna 8:~K M-ܰm̧wd+I*imw Ri&Uh>VysnԳ>"2yNv%Pb:T.a5T=\S({*G^EhZ>G5هع өrU 4XC_Ul8 o5 Vو|uDasuDO%-0n5XgUpK+#2UiR6N 3G uBײa5u9gIN+*7O$H0Tn{qla_4O@RÅkXItEGqpyjihOͭ'>IUQu6,vg)Qc~ùh=Ή*}Wq ~ձ|UEYTqW.-y&Sxl_%in&v_y{oTG#%xy,E==ځ}C -oRHxuk L%昦A(qf|N7%Li-+ j#柕O4a_n!'(o9wK{ UOV絽:wbsAbUq5˟$r uL '*75n MB- /u:܈Xj&QNMyNH0TOUJ U0u[$o__ 9hqftY'J8; ?A2F2\dYtWh^ke*ƅp^j +|+Z>DmH B]Ty,#<=s ֛MٔZHsPF\8TiK˹NӅ:h(H\Jc&tJ}jnlo}CI!::<5\wBQK"3Qp51:eZ=Ät*# [)ܺ֙Jߴ?6hӒTkZ*zu|8GSktN|62f'3FOڵҝSH0ZKnj=ڰr֕!U|`1è?-ph >Jr: ~M`ۼwC%(Nn{ h ht]\0tL|~Knhø.q7D G  jANt#EO.`89跜1isCUkATiSkq#O^L@y2E x',(3 JpM9,Q蟲aC1L dWg{x|;vbkd杈uVaT׫knK ˭h,q&VEPf3RygbP2rjS]G>I"AG&$.ϧ$Yk/r{s4ւO c&5 h[(u!7x*5&89?>wu$2CR5F_[>u*=QΥiH=f.4l@-}#54@ ΉO0 l2?ҝ#0iO̩>. L ~X[`L_iAAx[XbuY8GЪT&gp9X٦:&yh 5%pRG%8&jS&LTXvjyn`{<5x4Â\9kچ4Laa^֜X.M4íf%;`G2~s ƛ;aRWm7 y"b0,hSmggԬ\>X:~kVGftRGyoᕼc|װezER4GUFPě.WX he< Z>NO85L5Uꖵx9amٻE$9 PH7~JmLtJӣZUS*FEauV.9+hȧze&73#^yg 4ˮh"7k {af ?ȉ[tZ<-XTʹ q,YXurr=L#iӺj~fL--jkRDwGkRѧUFe+w/E+ O_ XXQ|韆Dh Uw S=2 X[IRL1a.V"lxXZFWQZ] Ht9:uGV5U1oJ0Ktb:2~v:ջ6;Իv4O5 pfts\78S)fD+y놚A' (դ$2YC*9Tu*bXG \/<P hWejgiemmf<5@u 2Uud4i# dm;03 y/SA@L1-Uh0sGDse:CYV͵̭p;Rqꁹ->#Ś)wn(X!^UfL.ȧxx*7Cx,%?*|T Ҥ zͻFJM5?򫦣ˀp>{aЅyzMZbmn4 QʂZV; pKNTr@*bJgFDd7Soxuf>eb 9`\ZM;; 1.NCCs>KXiLW=G1g-q Ku[<|a'U9fF){DU*ݝg+HeJdazDiZu1P /GCD=ե{G%"oCJm*!B."J D>J"ᜅO8ےy͟{@~C R\rS=!0ѧK#yT!(tE"hF$y J.*X\1{ySjATZAy*7,I-p/ ȱkH^U 0<5?6g.7,'{]?!°檃!c/uLko#]"3թSi{8F)u6{QRrjh^e`mQ.k nBZ.Сu wcoVm4+ԫj}793 wz|,;3!'a\4+}X OC:V: v&ʐܚj2$ƫ 75Nmi"K}eLC |fD?LZ DHQ-YLA t2tj81br`yp٢d*9pNLɎmAeUUmFSk9D,Vm+vMN +߽hsC~jMu f^7%xSkO|K`&[%G 25 pH*:xOUP 2ElЎרּ`AzAne%By&O2N~JfsЧ*urJk*}"O>ES9,8;zhUs-$Z*\ ᒢw"3Nmi.D[*jUBրT8wM#Q‹]}HzK]rWf^v4:j[}\5ge7M; ʁN\f2|YaZLĪJ5y$E9 a);҅[kKwFs|tXO>"%od.wXi TV+Y= YI瓳w*.اR=5V u DHIMl&G޽s3~S XpZ,N3.+NCϢ6)TkUCK/y[~ɞhb*Y!֓:}\;OTЈUܟe?Hȷ3AS0 OHd8c^e/+zK]N*0}BDDfh ҷ7u0Ч!5i9gT}hUˋTeg)T?#x,h$xD4MHj]hBT M~ z7Jm':[96K ;o-Ӝa-)BfM'5W(;iWR4*Zs\YեUeGR9*g!y5DqNx}{MZS{IM7G$Ԟ8Vlߛ5V#JSPĿLp22X?mLx7fsM&%vJMߝVq3&"u+i<\$'^cg-@緸<x[:5 i>iЧa̔Ǵ) ei.:+U:cȦ֋DѪh>iL}8N}\ BVΑ$!s44^hwW>:xpY[gPp:*ױ||y[we4d4ٜ±sM9@Jz$cPee>nMSԂn\Lڊ/S57ky-s ADn 57}`.7-J^x)eArW,۫mVHUi,EKDTWf;ܘ@b< @ve`m';Xu:02޷{[PTe@$$4[jqGhy'g@QRx,> O&BgdӦ$U,)؆9 f(*f?־\ڔTMʡZ|0V0]:A5 ǻNjnaSΙi'h26Vo5I3dpH' 쎬*K^ZǫM!6e 2FɏU(Xch'-e`0SшżDesFt \52䫋*} >)o\Wm)0ŷyD41akUK'MVّs'!S\tE[F\&b2Lg iJ{p橐Y颖FSFDt 0N!>yPi) j0P (TELW%  OB{u<0oJ״Nf+#%a⒨Pm4¹M0aC۟А_wUUgaw, 4wE q g$BV;eӪҗi晢J*)t'876x`8uL1˄B$nOC^ Ѱ` ^5.)o/erlRۏtn3oBegTc̷{1ZdWg*WԈ FTo?!Ҭ]0px*,j2SCT+E0%9‡bwaSӼCrsm0sG<UҘB9ܴ6ho!&!UC/e[=*UamVEa`p۷zEIM֞+TtpX8yLaJQr]\OT0 peCDw-k{߂Ԇ* fn0حŶePi{h9L&؀ByVSlpJq98[19*!Uwӵf,R mv3 AY -%i)UTCa4dcc{ydZ8\UnU>O9?v7k!kw]!aiT{ƖP[K|]TYXxzsLT2=.e=Z\;v9 Oc]rW^ ΩR;PLIsX^*-k2Ui1%R@˪uWI]PڦRH'1>OӚCȏ /rQq,cSjwIғbpQ$[O9se; ӣ[ao^hP%Fj'?%/|*FnwWt=>LZ(妨TyVLNl>.ᕏ;CMZTAkcf]QQn傘3 ohdKO|rXJ]Iܴ 8Z+\Vl/a, ³bIWɐ\3GhEmrU|DuԢiRBmUtmrjԫW1H](˻q.s_{ɓ0u4Tj?OfA:a&_&\<=Pi0{5*Lx^4oq: xUuwM@I\Fқ1iz%Ps olUsbӏSM9AT/ʂq%RDStt鳆 ]} }ZdIaM"JaW`gtF3$Ð9x+̆Ɠ@ˉJp,6Qu>]Sh#Lp  UTS#7yP&zǗX9.VsG4LTmHnAE0HP̭knp6p*w901qE5Bvlvj3Q2\z8L!'9+F߳ly'CQwݪ'޺X;iOS\l v-Yn!uXhiϚb|d%bu'2x&ccyJ-aOjwU ;)9BJ*fLseP4fn/U-dG ƈlysR_=*¹5o$8jT#^J{x5CڲJ *MDD:SD+Sp W{U3s'䯜<x!59[7ИCEVRᓪ[ӢX3> 9o)/]/" M`qچqopS\hQwo,Ȫnm~JSdnNtHY57_|Sʬ{rΪH1$+ʛYCFaSi/rMw77NeuFF\uR 1QO-9!9ʧLn'5S: uTE&G&T%ZR9yu'HPiקCZC ȂE;6-_s-ks `Q)6!KZ\yM8-b 4fߺw,Zv؍&Gka WFBteb[Ҍ@sXb7`~(" qqOڌ{@sWw=[k XSsia^O-7:}REĽ%֋bMXGT N\wqf_lh ~zdW 35cNH^- m~^J%Li U*=h*99 dNי m'4 =^ . gU,})H-2=\qvQBiܲ-TNSk槌5jA`v] ƔSl\nƗD Dp˞cU:&Gsfc0ċ[2+[ leUstO0+Mw,M9җOY~Ik,|k UAg*ė.W,M  ]jaҜrȭNU= W$2FP8H,8L;J" M~92~RhoO"2P a0Y!b ơӉt*FNe[48Sʁ#00!„uN!B%JjNS` fm<[L X]u6=murq ) HCŒuV?wݴz*2tM*Tis=ѥ1HSܖDo(yOsH*o1O(CLӜ-v{ˍ̢skU:z+`G$O g/?Z5Maf^0o v̑™d1Ls I|,[%ZrWDJ*خ.>ISME6sT%V͍ UIU5c龠]nssa eisne9w'D 璥y!N;NkF\]uE"lY%1!;@Fn赘9jNV$"5:c)d+FY&gT~#%Vg+[ {<ˉ4JB6ۡe0 #67'i"sa$oz-vy8ndYRyT4 ?ֹ/oSV>U8e &2s޷-p,NAnV ՍCy2skþisx ϼSZ2o S\`<t9"I俁Nvd֟MJFن>*R Sj Zŧz@]Y^wPYZO9ALr~MYsT(Ѷe5. X~*8+-CSih]#H,*=֪n-R4PsGBTE=i'(Md2Sv:mҟ{@DCT`ys*d3*38JwB9'l/v* WpƥS~jwCvVzQEPlrofyFI5<&Qu٫S\Ot#j"'gJZfUzuTkK}+_^ jnq7wS:bGIW&O%yuBC( ؎!U(L vRӞQSgRK%We4ܮlQ'V3r` M,SN5`^ MpR'`*TJ\RXzTMVΪ-<{ȈJim뾉棄{f曊#\kǂJ%BoEwR匩;Uk|r@iV ''Z-'#0eIg;U'dNÇ!hPUFj])Nb&TOlL> V]᧽,8mVĹT8+XִHh:'2m uAµRT*WRz&419tKP8dUVXF7yhGvy/]R(aB eU"ntLl:k}a4Ʃ97~ =IWtF\NM+To$é7@T$ocZ eW]Nn5淘iXBo&HE{JJEك\i,>6uH) ND&} r^S_&*Gk訷wE,gz 7xEu "M*Y OIr*`yU5r^TAQP*+Xp 몴oBuѣOMU570莫z,嘒\5 _CA8g$3PcJ!90V"s`}|2M[f p9YUpYF\Z/ԫ{9J;UYCZ9v7gOk9ͤ*oI̪o:j}1u^L]MډT=}ٜh~r͒ʬUJu@2{MIw sn*,IW0vxO+HtUM:cD2s䍆hr4ө5\"~ix鰦SW!9R)ٷg&)T{LL*$#;lz|Ka{KQ{Y=Rxie}Bc n2X иsrVku1~j)\w! 8rꯦ3sHTa>IvF״r5wODi <&4 S[̑MBtԩb+:QȕBduqU ^o//lt+zL;,ް=NY"%E)FHx&rN 2U M-m2fJLBf LtswŎ ijUo;MÒ0zQĨ;;D^rr_(duty-}Ӓjb~ٽZfa uE2=9F>J/en|?p$Z69;ܿ5%O}Jgx9qpRz]a>jCi>ͪKG;+°&ꆫZQ@dUVdi)Akp{ ENо.l`)W) %hMb~ xvU٧~k E$^NlIth1NkɸTs6RՍD4*nžpN&DHPEc*7xE1D(vFS*Ԩ[żAAJO)>2d?OOvz6~jj2Y rw\RG{!ba-=OagQy"XSs#+v?6rN ouT5c4V7*'s)ﵤԞM9s0uIR$~0LFY}U;iGXU:#2:"DTd*dR{8\Ce \Z b~yަ~mGxћ] ufb}nG%@ BNNl#]5S+D禊Ri><>f\^zrMhh:(VR$ǂ'6jaVUDGUwltU;E7x-6E4Vtk#6SHjR.DgR}:&Ϣ;Ng%15n7\(maiញԞM@t7{ \;C^HB2kS97 fBe+5G2WխRi.{Qh=G0 ,‘vAN$:W35W7U#z쪔Lw__:d*] O%~Sp5^[bhlQs2/)z;5iBq.Ъ}Xݐ7؆7VT, Io8}GnTZ> hXpXv统2TF4hiS{-tX|S4ƆC%jЂ湠>J@@X;6 _4>US6YFY咎0Sja$O##$ /4W4\Nj)r@N e8l+Mkipo~d'5{ajw^9m&M♘3bknYN/x,FWv޺WeaSRc0%7uXLs[L%f|4!n)wFeTQֶe'G u(ӧ<ƪu3LjKIbZp 0oi>ebnT(!4 U*m8 K2Dv%:Xz6.rprn'z.h-JɍXی9> LZ%awj# m26l'DFK٢Uz4m> Ana ھ|+轌&g.i'[ ^Is# LjeW3B&Ys'ՍO N i-2GEA tR⃏vSpd+<G=CSi6*r]6V|%Xs)-M7`l] a&e;CkOC#AYiXk 89љ j NB;=.yTR,7{\rv(U#019?-$NS0=ػ{f::AkI 0|D61.:}3rM|D˺ǒrBU|"}DڜUZ+u3+w=C -Dvnlޙ*e$4ݪ4(lg,NY >8y.-mrjpvbvJC$*gCaC(Or2`Ach&.U{xf6X;a,Bu?X7$O8Uq>ʙ u`Ԯs .7. $stnvpgM<􅀾7{+}]֗d2uh_Vv%E&Lu32lXaMsT7o{IwlߖʂXSgx0Ϻ83PܜUkR~G J\iʣ"|s>AT3=>JȊtۉ [FϚ̔GM}(rA \sC]-eaj8Sk^-QB%5 fsu%]"NjRITxl9,}FcWg׃roŰ_.iuNU{&-N?못OF3F&i4UټMdHtU sȬ%}rjmQ%B*(PBjjZVHżOD:W8s{Wd2EUnL)%6Ub,Y==9'ɐtld\!P֖˓qL!hAdN nmV2= ִ 3 Vnג Dq#T{aꂵ BÚ3eSWxM祖תv 3d-B. Xa;CmXSaUa*yM I=Zݮns|FjDfs@?UfYP^mSLU;mpӲ %5?Ui!a9Z׺ R֑~G)X"ThwsR=Ld7K@]a:g%b(U^915 A'xm$|kZ^i } sN{r懚U reZd4 tZl(hOU0O"4Ҫwµ̔@s|Tҏ{: koV!3r&ZnU}Wd}u.qz#Q !4!s@~~UЧv}Ou#;_"֛ޑ桽Uܙ|kN¯sT #Ԉ]J%=vTe S&9f,Pky1Z r6$?6)%Fi=Rw& L1؆C'4.h0>h_dSB&sxjNܼhahC[5T\Cs|M'-|wfL/7UPjI?W4*HwQĵǝ:UZoHt41 } wB%ak4`v T4f9ʕa9}wBZ2V:$5EbL>tO>˧jkʕAQw?%<_3"LB=#Ȧ,{f]$;kxО\:Cs#=`?]NkHeyhi҃2VB r\i<7FIĺteZhRXU.ͱ)aMa=&ӱ^շ=ӏZJqZWx&TU4DTЪjMKWiWsD(ŚIUAȝ=L..cs/Ɨ݀g'e&:>9oX4.n;pcSt-DHF[7 VW\Z4^X& m h@JWS(_4{6%bnCÚzrXVRa{X*"X=1 d^2(ves̯֗&}j=א⪁.>U80IgHT]}6A٠Z e;ӕZE:O8TϮ;FliCϼZgW mrźOS-ہn碝]TyܧLWqƆ3h>j/ 'bg,=[LǠޛBz)D<5G0}j̀B{H>\JjQUhTTi~ .mQ]u<7;Oo3)w\-FJ g`ZoD)x)9#s.i$w^a9X߆oHj6v\:Ueg7LFp/n\6g}jRCi#ԕ x,3s(ViNf*Ҡ*E혒R%FkLֹn nR):]ҪDCQM-yJ!qCp#CITm[!ScZchvjv75O;WeN|әMIn'{jpdHdQ.YAavlz Wn:'8#>ΛUJ֍tySCfnW6T#)we@(-i@V_ ?6P7 | ķyftx {FJv,sbp? #.5 R/5%4Gf8wBKxMzmNצT.oߪkq M8OZ_)~OK?/~[R⭯_U?]OS<U[E7˹t*r }\= xk+Ѷd VNhZNIxfۂk- sc< jՇKG4h:Tzʺ]tD>aO5lMk/!T3ƎMD0uw5ID*uYXCr(3iSwy9pQ_JNFEnb&2u]>jKFlgihEcYלx.h=Pc]*uNWJH+{L9/9*X~j`溵7̥N:vs)4O3_ُ5]ի'+O%rQLsWeL9'"B| 4 jA @6y*[ʏ n+qWe)c\k9gaSAѸj` <̗@3UO<; N qDCG4uz5/ShQPTSOQL`J>HY:\VEd tVΪ DL(CvMkG=Sapzc C mV6&zKsMt8N})i§!P:sDv^V'kwZgMT}'3HJ7QnP" zJTY2O%Ul @ ,c:mZT fB##`ZuPŴQt0BR:Xw @,fQć8>< f"Y49&fgeU~5^]:e`7':u,S\Y[1ⷕ(5j? |G#.|gzefx8ukB?i|X:#A([:FY;1 j-ϒ,{-O'-P3£e'Q06-ZG%IkTꝘ[[S[w3fٵ)B jhh@#cJM*T䝢MJi~i |3& תcZ4().ˬ*iS>P4ʡ2<¤׹+| .m@AM2ܑ;2Pa -Lw.+0!krK[iڴd}L vТgEKMU vasyƂ:ibiu\C1qUjƊW8{IO ݖQµ=:/@:Eu'f#U DʬᄤrzØ_uW[!zUPQ2m%vχ[cZτB2[ݟig4l[MZ [Fgލ ˸Jϓ^#{?U$1RŗU+L E%4{QŞuV=h{E5 EBSD>aǪ:.ĶTve4vB湁j4RUèR:UxWh>^4k @<9JFD#/0 rThv@)Z<iDɘPB2nav=3z_U|0U.l6Mit}5yoT;2?D;63{;ٍX:Peʥ0Z֋O*0>;]Й__CtE>s`\@N*q2F6hJK ^\ײ59(kNcz*"sr~ Ɩ "Tq[>}"|!n? ^Z]2|jW^+FJ(^ժߺj|@~[Y nqG^_ .+?g:Q؃zwRvD3qP~mLj+UDi4ieg:ފ"ȡ =QԔ@lm0S"v#Ѩ]Tc G*g'?S5s,4 C pOuMaΌ;\c]6MNwBJզXNuЅu,{90@>6㩕O Q[aT ->K?(#jM+z}nޡNm-<|dJ)^2\uL'*:Ҏ)ky(wTtxX_ItOJ8*cʂu+N-{rPA6i $CBn`p2U,F\\^2sAŎu>aqշ8wxTj ԘVsYEvM[t(EQ71Qy-E^S02Oe}ۺ5k=l%3ۢk5脑Fa= qtQ&;HC~%wGl>Hf5*3n~'r#[S#p02ۊl{@'(!f:#gʔwBO0SXV[fRZ%> L;NSfZW~ZJq4pqO5Zl+ Zk:m#qʻJ9BsI1FX snXogU!JvA(ӞIB+w6=T:XG=y\; R(s1f<=2@Ts](/P 6l;P5rR,LYV״ N4[4tN:X29UUN.}E,7>V1f%We,óy^:'CD a9>IτriK HFYl-uԴǩ 6J' Mͣc!=[̑Aˎy,vy#vR$Ss^L(ex{>6TSo)nYڭvu <[ .K~uG[y4%Ti܋2VG S堟 MG{sx;Y+kD OԢ2)ۄxڏQ.UZg,1('8eVX`KNzme[gS3MWyPUKtWgϥJ~ 17T^`d 'xRbI(=:nrpmo/Wdjk 7ef՝S]|DmV4R O4V)T/K9B5hѩikgO5%Nxy]Xcc*K4E܁i"-/$7lȢ@Q(#]|zq,daQ]Zg&ʻƏNXmPzT Q\HBm>(*7_, niGTiyx#De@MdO܁sO"@UO n#YAVoS^oǺy=dmi=q;SLWhewO|dn7mi*$ !5vJ^OiVh> lfuLIkD\xZ#6Hٸiin B^:L8OĆtFѭMq23T+==Jcԩ[ﻗU|p^J޿L/ɡ2{xA{gf@EG0\>9a˪K:Y#FӔs+-kE>\â8rz#D̦Sr\6́Xwq H-czϨTi>Jn\*j%sTܱ}E>J!Jķgc4Rö=IOe\JOY *?YXe?Sm ŸQ#O8o uHBwOG;=p SE6ZV'Z7ڿ̫r[*frD5+:ֹ*6l:x'9O;yu ?VUJUjS1nV5۷wg?lj0NDѬ#pU=Gj٨FBZrMAuC4Ji$D\Ni}z-T65ZV2*2+a麩68QiVgQ>"sRk"AL&*Ew֤s@:V xF$3 lA. hԮѪk /SMJG)O3(z)_$S7JJvO%g\@lڻLN}oq޳z}~~TfSNKS8"&ssP`cIB\G23Nhx!E[ta ,~6ia֕ڮ`jğl=iPlt~OɅ)J gfkS䫙x~}'dZ ݵnPbwڬKNGW0Sƒp,5Kvb^@BgogvӓSmw5jZUxty*bicXV_SCZ^~kxOwz%ժa&qmG谴i vchS mJv> -Leτlے_iĠe:簎FY N~W1q2VWa^#I޷?'o=m]vdB#ll$aooX'=<^ݟ߳ǧ/Oُ,jL=[ڟ)TK/\Q=/M]9 'UN&閫g JۿمʋUTuW0拭nj~A>V>ϟT)%4jUnr@,q2LftB 2d45'SkA5:ըiG)P>^)nwU  >4r $ ٔYk {Y8 sd7.J؟5E ]z#P8z!fT _4l)ԣj+jVJNBJrMRRj:tg/#%%wTP*V$P੘jWsF[v*3Uqg5T2ghpp*t5 WFU].m60]9O%ӻ8&sXvW8eĪ6ʎoC4V AD%T' ȢP7.kPw6Wl ܲV({a䩙` gَ~y>K5_F}@'ŧ}Kyo-?]OG'/Ysf>c|eLϑ> !7~  q脲\isSu> 0_B}E.[9gD.)Á̎$KLiR۞qJd^hV'*o$2%`"S Vj:ݍQCdeqdV;5jX[oSs΍`_Gn7hG캎s 7FĈapwL6AiT3!xI˒kČh OǾ|SqfPs DӁb!kD<q4؉k>W"F7_tQ0Q i꣢ᖪG"@o!o|ܚ#5],"Lpea>zɥj|ef4֎gԍ(F']MOoK]d inmȐ &юMyq@Ore_P, wzY&NtOUjS(CC"ouF\ Ag?(>4V z"SG4LS fs觢>/V%ًXnN+ RkT!W͖Q1]>O F(XoKmi~JFl:l"u m-k:h4Ph`6yf 2uD-LDSIaez.ਚtYhAKg%9ׯD5ѦFڬwB pGX_e//o;4^}܂VKEMRM,~v5=JƉ)}V^t2sӮjeTL.`,5Bg4doa*l}Gg2-:Ӓ&T8ŭ*t)Nt\ch戹nNJ '0z-lوL}.tG⩹|&dBu OA [q=%bg5 2!S{s69Ǫi%FQM}` *a c<pz S l:eRC$jUkEk8^܎[FpCVWihϚi FO{5s_ZZr7K\~m01K/`6EW@ EHwq;zpS2PKt(憋aX'~QQ%S9&Fg%sA4ӈUrnPV'V˧E!s]vL6BqP T6YQmkd=3i{X@Я{=eTeBr0+~Ti> d>m9I^!-?4j1úQ"mKX[mvk6 Dw3g }"~p&h6WqfU!i1: ǩnp[t`ٟrhsn-AZ*:´R.k]uIXnZUk3P{k6C:,V-ӺQH:tҦA7waaXvqqT60 Tk~4#":S,jù~F]7KXnqs`&"KXJ)ucg/P(Cdz`z`/͞MT1~s]/@r *-xcF'w% 5kC1;E@_Z@p!YW.yT:>a,U">%aulp8jqyu$Th~9*ȯLwEڎ=#[B~c jsV25C5$I/FK9xXa_ C搏Y2YHk k񚅏yL!QbX ;)TɹZNPĹjZr̦3ؓwąs:N9@Bn9Ŭs.M=o ]e\h4+=U3P(N e"MFl:,ڀO9 =76QPB!Fzt^=G jiw=!s|=NK IvxRcVKꏪ*Ylkn#6Pe&9uVs{܏Dw ̂{.XOrtw%OxSۙ'w^{NcT67˞9,!zӛKb|SiXB32Ng5V/cɸ]5iZvv/l'Nw M㫑mџuW4Ѹ'H@TWkv7R<KLKxHXw5ָ"i .]ƦsO5Ru_5GT0{1憐-vl(*Ttb)0xpiNPwPThiC|s)=f765x'8O-\ A9ce4xf)aȻX*)9SCEsRI$a'`^ݽj*1GcrUmqZrbiT47gjxl#UVT0C8Ӣ5 Ou{9rٮ4r*6I樄Ջz#IYQR ҡz=C9h门=q9 KaVeMt$ꛃ5#!apo5*ln5nchx˸}+K .szeU?86!cs^C K|psnnm*2eȾ26xFkgT hAiU1vIyק*x%# c(SvB1)j+EFWyW{g/dvBW*Y^iվ[)eT*;aoGs.qxqm-nz.4o:?xZsEUs5nOS^hQ tO*i0N(cIy'c@ آS<W#SPMny#5}ymw~Y*Ns.q19Q b|"dJZ=Hl5(}AN=HGc̹(u9M%*LiRDs cJ@{]@Wg*T)CM3G9&ϦMᎰ993:Pv"Bu0Ak9d`Y iR1ڂ}Ȋ̔D;1⭈s/oUw@ڔ\eBF8UB'ZySk|O Kď }IO]cdm:-T"9&^?Tlq0JnAv)g+m3ncU7|>ypmpSS+JohmkG Y5=Z14x("bUJUh+]T6x-dHkd4%Z.r)Xu2S h)7UzSsog7vzmHTm,> `4zXc5; lxNȠ!"%ǒrUS Xr%,%?[ 2~}-Cռ붅Vs`94N~g۱,6Pj4l.)9aRR(Z@Ca|@U<{"v 182*x8;w~yKOXSd\GQ)6VjԼc\s1RF}sAUw2+X37ѫU5hOd| uR`-3/F7 | Zb*ꅃ,iQBpU W yUl ;lzNUoe%¦q0n2h'\A iq^=BaG v=9k@U:' (b\cR'l+VKU!BQɡVw ~+TӤ7sUDt' Qq4.\1cZp194v"'N֟%OsV6:䱔ǫNg0<,}cy^is`8qb0Ŕ!#%P\ ṖRQf[7㘔ݐdl!T 8u`PB}z/7ʄju9l5ͧV p!qƣ" A&faL$&ytB'eM!"}HQjJ%\٪D"!{dj)5ֺ+vPg-[SuA n6g$pޅvk!ȃ$ϬK6{ksY(QȊm^s;ޘXjK\Rܲ@`1M4)]HAI$=*WYRC+c~}Uz>u_lмz4=c'g_~T._ @!ڷa@"U<^z_~~/@*0G~iF\n_?K_Ex$ ZUY>緈w~X\~z+^6#7~z5z]M0dܭhOAՍ_櫽K/1A .JT^z'Hѷ~VЊGp\Ki>?Uz\"EJIRz1as~'Mz>3юo ryBw6?1 >"[NE_/KYCRJ~?/1;r߸&ehk1;r)*ܗа oWԌ}.\r=JE~RT}ULFW[lsbp&low._EJr+֥~ z?c0{.RV&*[^(Korn>w kftbʑ??g2J5^*TQ%z+ֽ.z GzxQzo_ 4a*fg8éf2#wT|Ns>m!GЊٷϪ*GV R>Wj쎫Uo7/>WtQ]4??rEܹr2C>RpޜD:Bݦfrs2J5ϭJ^%7j.nja$8QF; +fh #>cLEޅ6鸍a ?螧JeIHM+ٔj`b*tB`gHpZ <²MvE87ԇii7gңY8cb2d+Xß iGv} 53m@Cu~/YhXq;???bjU?NvVyG3N& mVsTJ2u>gѝNNs؈<,U1(*yNDU8NI\.j3 OF&my+oqڑݛ@|5;F6mmχգf=JYcxiP.+,E+vlWE:qU3<>*e.Gac/߻ .^ڥC͌?'藔T"yϜN2m֝Oah6W^"9!Ҫ{2y%L"c/@ s JqnqҪ8.Pi)J.eB%qiҖ2=lXoy!Jvmy4\?O?Lyf_&+i9gn!T ,]$ZXtw 4vN_RU<`q63TT*@ͭ2>=?賘YrKhGC yC;D"ݮ3\4Yt!kEt4D*Ǣmlf!H2ҾOmW3Lh7+;z=L:̱حFf}fplhHW(Rp=L`Oa2vوe(  >|eN9)%Snoq}״"=&]0*ovK;Lg̳rwmԽ[]]"hT[Sa|%{bDlıF!)vy/>6t32j#+LmZ=c&F.[9vR&p`U [x8579;s1Q)q803cb.7n|SfmyBHIv?0PusNjq8bQC/2Q<\7=sn[+5ۙrQ:tvE2}c=೩Z_/IkYQ0ޥ⧺tY,c5<J4jzjp0į< 6oLx,E\;\y0#U3Xf2:/?ybs"@W5 -BPȘ$;P)pep+-@E ۱h ]616_,*s0}MojDbKTP/RlN!8rNEXS }}u,u7^w/>#a-x0z DG&_hX`AaP+؋|G!gh;AWAn&sKPҍq*%q:ypzvs@Ydv b\S?8Gt,ra g#TBcؼkOc˯HrIGf#LLJd,N<gTBsWCA0ےqX_?y1|\3PZg?f9\yGtCL6q:',& -ܼ{pmy{\ARk<^Sľ(HK-qRg107R> IЋ^[+\שjHkIot@-⧴7V,*9 R\UyTVuaBbƿ1 dQ`v= @WX3RSٙAkXZ~IZ*4a.iC6T,wlJnGDKu.j+FRlg3r;.mSyx{WgQ*Yt{1op0/b3M>YMj:-ffA3 p#_qa!-kCSLxyByn#Ek~. ⏴ ֈ RnOyxM w͌0ΰ[ܭB%ׂ__B&x..lDJDZh[l +5F:x;K+ʲ\yW_@?ISo[i<ՀܤWvFe? جck-وj([ݿf06]I/]dUT&8/4/_3+2GRj*AM O9bur*),% o}L20~5L}(~xِ!8l܋ßxfʍbt5ůKK=ԼjnmdDϢT3ݧDmLΑlMu2W*0Dqc%a" iEi¸Ut0A/vcEyx@} *ΪQ^ﳬWsbdNC=EFf5xmoȔCWib(4ЧZ[փ0)FA+t>ʽyN1lƯ>0x8gAl+lA2FI=C(3G1S48?쳵 1!g-j7wnT,rlN u㙀#_ beĪ`e-?t;xoq^[7y*srnR13kOeG ەKsDG0TgIm&"*.|x]y{҅즾"&X :F Z;/ZVrusx/%zwV[{5^E0PTo]{]|LLM  חS  6(~g1*ҹpmE _SpZ{և-5 ¿ܯ; d9Έk$i TR&~ȣCL;1u ݹv`! \c~%{u}1^2͐5VƢKuMJ)PցcE bX_%3^<ŠeQniGyJW_ΊbcgCg'Ɇ8\UJpz,C/ ;ڊe*p}eԷ s̭l0*Rw (J2V7dSY,\^D,YcS^^cP@n@ l?(ljivþ[RTcm,x C qz^ h5)okѴL@lk^pi03sfR!W{ruE0޽P7WF*pFS' qa#kɰ }u'T 2rxѾV /5i7Ra"ԦkSn DS @ߺjNf >=̅vfeԍƱ(]g/i\Ӌz@}ӦXiP&N 3Gr7v-h;AA08Het;@TldM7Ѯ8Vhׇ"t-_.#e PglqAvR~IV|_JU)wmF"rU*B(ڷ v `j)?Kf:+R˗P*>ڞX & iӨyzAn?L*vʺq:g!ZbF+Jx9eLьF``R\',xҜ% k^ 4,j8L3r8(b(d̥]UgT/E.AX7X< L¹8z] >&Өyc/u?h5SD#x.+y`tvB4 %{,”fǥC} ܣG ԏo X$wgYeCPa)D!pP=H !P_(w:x״Vf%F_/(J> 0 X0Aw {17drn򍣱8N58or=C\eTs\F*.iZ/""NCƠ6b=Y fFp'_1Fa,~^ѹvL%NZ;Ҹj6^Y]NKQ9jZy .[;i euʸf0S߿IN{KCg\(-~ fA`9ka.`:]bRl~nMw^ n)*,/@rA^rGJ"SwXT&Qi?X9d\zeDzE@濾 ™)uɴ=_i\;]>k#~7,b75tStpyMn%OG3⢪y~hLcah3veÈnV꾦0/y}fwf h{`r{ΜRq&HMɸ?|i4(, saky4 =LX`10̂^|GBM;(3O,Mnd,C|)4VD3l@v!`(')il"++(cXcJۓ,z@ Mw!RَCh9J- ϓlP|[.lxD(XcP!Z A* -;G1*̳Es+̶yS=:"ʻLjoe(#b[ ϼn:Nx(cWeK^)=9v 阱YU{͙;R=it%İw1&˃L+e nkcɺ5W_{]X73E)cNO[?׬~y3]pP9v')@P܍+y:L}v_ R9iCغ1l&MP9 3.ؖO0ipo;u12ͣ-l4W4Dte_aX#>ޱQ!YW{JþiN7eȩ2 \P]XI\ y[Z#s{KmM)%<ܬumf:Fߙ7uh&(RPlr8͜)rۆe&<`Ru6cY@]piX`!RH֎ =P;n=\3" AH\5'M GP*pF"_Dv8ʑ 59w6Cv uc`N,eBݢlS>`-zSG0+US_`INk(O#[X5n58|T[2蘜)> Rl*FI>:]zinwOMu_-R՘8 LZ4S(̞|J^eC8ԶMj80 kb:#䍥t?x Mijz"y4)RKHŦ\T2X4#ڱ݄۳n,'vY"mx5 ;+(}k ˿lJpo#/(lUQp8S5NC/-76j%+Lps0iS i:<@h}UӞbĠ~߃aQ7#*v}}7GGGQ$X֥reۥuqC1ʧk/X7pJuVo3Ji%FפZ:VR 8Vdeu-o=k@-.E~D~9j 2ccT2+fR-*myqnLeTEn9˔,5b] N(Q 2ݞXmxNqf/-WT3,LQa|.:-Ws&1BJKUUQu/ Xqc̰ K(uf UkHL~ "YYƷaSa3jÒn3908#_X4@5α}pt; q *m\AZ8r2ƫEهR> pza=75{Ģ2W*:@Z KoX%k~􉉧P@5RI 6UET_vN{7dfk_!N9%PY7ۤu!PSTBUroA%-H"2XVGIsIQP|п rB5.p}`!riC&n tKzL˘DF55+;O러DYElA -grl= 91Q+.%JSS2ӯՌ/^1!􂥀ٞ+hc^Ng>pdu9:M37+5g,EEkAy*lFQnZ~C}!WpwU7*k f6fQQjȝ扺:ڟȧ l kmAp@fC#ˡLqs/$;uu; ^S7+M:Cдۊ ;&ic.CgMU}'\!{%z5X:55\CQTW8fk>0  w,yB9<v1{ܪb6ǴW\thP c|z |6|qqgM9V:B ?FT9ה(7G N8 iw rx! jϡ(ݙxX2ʶcK5}i=u5Cs+Eqhj׈EU_)!_mK xb珙@r̍l2{9C,T(r\rCb\S'J[';K#؊!*UŠ jcuD5)ia*c̷muoAd`@k Kb1קoN`DR¸ , zb%骻AϤtλ4Q,|acEyuYֹ-|A9/iV^jTF/LOvpOc9C=?빉Pfrzw Ɋ<Z.˗>ފfM;Fh3V% P',-+a] KgDZZVq9D+f=f RK|7 1eQGwt9T'i˓ԏ ^O9Qt0 Jĕkkc:>[~q Dh<=&`{dJΠ BxWPt%T~{i(vnPF 5KC"H2\Wi'ٹ|8P 3 ĸ1$t} P3g.%{n{ -*k$OA<@k^{VF rŴo=wίhT 2v)itsrK)0RQ&̩[tg\k YmZ "gdIPљiӣ=}fgl8l}c.ǘ4*`fj\/ъAg̤pO35B_2G7QsʨhRၥI{푱at\{h![LJhcu>D׵L@3([|Fq<ĺq4#L^jA8}9#ѷA% 1K_V`菊j`JsZ, n5|DX t.}%ٜK^ p7+2TPjffn&b..`HԏJ6kI*hVSe+j>ePɖW (prCo8W"8"eXΐYMaˮE5\0QX#q1A/!~ϛ"BfAyc]!N ^ٍve(YA3CvьMҔ\4 i8HNPeLk^1,a. =!'V2r^XK֫`!*AǼ!u# -:@׹ Z_׏JE%1S-naNefdK;ezd 4')6;Wr˅)Sw٨ w {JuxB/fL=Jd2ڰဿq*1ײj0lX:jMޥ59=a_~%x/`=vf]VWY`VHhkTy?ݽo +,D6Kޘ:Bڕ ‚S$93k7WU|fiD5|2ߔGRӻvw !2'<WEo{lK!hvz[e1}fo~¥3 _1S_蓏*mR:Vp8qvo@ 8CVK@;$ eBs̛\AC #K䎉fU>&p*X/tpD\"X Jd,2e h-W0ֹW0-!;%.D!uԱo Geѭӓ MRPe/*%̴u89Umt'U*avC]ʼn6}JB GKU+xtu_tE,Wԕ_N1Tq1T}?NOw0  WlPKtK!*]He|ͽGl)cMÓ")KŐzEas>*O:h4Bg+/ DhlٰykY̺f.HJAH9rDWq2tb6Se۪K*,gC@%U0tWȻAD|Gg˒0qbY VZ0:V]Z")}Y4ltNyqQM13D 9ZΦbG&nҠÉg\$p3&%UI}J8ޓ( N}ҙfIc26w@z+S2sc,?Xg^c$FIqUl {_&Tͷ̺z۪_އ+D1b^gCpA\m>]+1`R_T ;sa IZ|[9s1"n 5CJ(auqݭP:O4.s+=rgЎ2v< HPn/O8sbA|0<%8^FtA9԰Zw4*s,r8@ hpgBU+o7NEq @w ѾoNd\W2oa0sI"'Ml)S30f5o,nQLBk84:i)LxodPkg\ L/wK./t k}BV%7kC7eÇ$h! xGZ6 &z?+LcgrԩUӴLgC1sӦmdh:N'W~-LLsT|z%-X9h[|%%Ur)Q:l+͗|CQC qRx; tJ 4_Y͘|fep;@ KcL '|z852w& 0&QڽY(EI#7ˈ[K Կ|c?R4ωe3)G Y2q) ?XVx|L`QMavMҀ YQX%mpg3M`x J+oˊ-0_k?_n:1-# n*vjs/jxO[U :_R{C|S5IpV E[ tDxALZ22FAܹ§KPv,B FNVp?E}f$;L; K_\w۲sS>n:^W3DsMʲ/OB$Zt=|L"~Yrkl@BO p1R¾H0M ڨA+mħ荆qJPz8PJ@59" C QIT6yn.v#\φmmQj ^s/Ky#*"!6C |J&֘2%ӈeK%0y[x5ᙅK"!^b2Z2i˙˟ e)Eݯeqȥ5j,3]lVN2ƫ5bo11u)~gz~"r_I{( =sɃT{˼u~)9g%.XE)Lf |XI~R3/WI!=#)):J^.Zqܑ[@aGfiޏUYvNndE䧳LTTJ^qPY%'A8b㼩WM?1%V^.Q%{mpSC;#0$ƈWmTˑ5.ԡ7QU~R,\6R!:]A V @x=}fơLy#=pSW A&h>LQ,VY"u9[v)̣j2xf'a'Zy23#v} ݡs"l=m9(&%q*VT N%x[~&%~Sx%x X[^#ӹz̫S4dv:CGPy마NYНۀ.VVD`r }%z~ ahr1b ~GRSvJݵs2>t2q՗z9ˎ𣈬ll_(JzrӨ>!R2z03gY>Ъ]61.5Xeݩ(/ӈZΦK7q,Ctu3 hQn}2)eJTfp)Й+x#3_fMƷeU{%T;·B!$3bkhr{w+'94d]NAx=j S+* m9-`u8Ҿ%Er|D5 O̓){]0T8@<[F?5@r⯷]"-X!O \`b5Y6lZc`&rbanK?@FrE a[D6_M4 JLq3+yQy=">龡+'%G70j*eHs=X2Y]~ muYH}‹28^Sb8QT՟hL#x9Zxk~!¨|\6$p }%7tK' ̎YU3rzO6Jۙ3P ү@f YY޸] a2uC,hs ;,wcmcP}cNC A0[qK?(bYiy 8G8{xѴ+ߙ*@k6^N\cqEB0 ![4švKWvPR\b-WB}Eܶu<ǰO*O7ַ+fvؖ0 FkSb^ }n͋ףFN5dPNY(/-VT#oըfImn6Ʀd@B_ISў+:Ni]Z2^.`Kex?)J2uM%b yFXf%D g)k1!jwGO*usn7S2wI@ʢ1fs 2RJ6R 7)?Mbfzn'L"&E 1'z!R^FK!}Iӊ ]bZ@Jt$6^.v3+ PIJ)2FsYi+OUVMyDK_dǰˡq9Кa va-de`ģ|Z:=yo`Xw1緘δJqYr^4|t乱G,X)X,S \PGb_I`cv&H9%V `&6ʼ so꒩ 1CAo,))>,Ez-OA g0] aK֞GШ1yd[T6&؏q ,t`G_&s19Pg!'7 9 fwg3I.eDc>F)ΉLWY Y4xL &,m2weN!ĽgTh仪LqZMd&Xad\1243+q 0H)}QJE* Fk"G>m>ӓa!"{ѝ}i  pLXQ\< /o߿݈L 1 !y 6`dӻ2nX)^,ZU2F'2q}rTAaVUNжYje\=]fFYږ\/3$}.Yr.kCNh ;Z~k%-.;!Ny"}W&#y.s(=/wؘ>VO#jiЇ 6kTE ETu4,}AGXo/uܕ9+r8+ a!eM1$p0>"Pe F\g_5QQN;C [m3 ee_pg‡SZ|[?dfVl8-mJ{2G\־g'mSM;1M%ҹz' Omkn`/ӆ?D:ԡCyͺd -f/Qx_aZuJi.WlDR=/*EcnTL}!=WXoC|-v3u9k5"y&|X,\;8`<,GCkDܨ)v@XfEL-"\*s([߫}gC2E%:*3iPX9ݶf27ԗ6@4*c!ŘOɣa _s+8秆i<6|\(y_)a{,'78;[ O{\4.(BQ<!/oio.ml)2b!q d˿MbfT0j[he]hyD`/3w~I\^(&,ےÇ'C QLЩӿĻe<& `1/ PwQp=YY|ŝa1nZa~sh혠IkԻW YYu\J.uqa).A+sS)Z"7u.!ʤ y{Lyt˭}Z>k)2:21yu7K;83Ծrena4zz1s/G$̻Q#AX%te}"Ef51s3[T/j n6n*g5*+iNP.Q" ʳGf;Fgf6Z7*ӯM!y6d37K0JƠVvgkk kgK5\R]w2_s,}Ha5V(ԀYyS%_ MIB=XP,p'#l%QuSN}FTZ`A\p}s*TɆdٿYf<ޮekΆ$AϼQa)_R`~ܰ5gl0 0=_V(^@|Po3,s}HfWf}|Yf!~ l#"eHg蜲AkѦ98B2D+R et3p2IbSal˼04#7qljۼ@}%,m^rÔ5 ^&pkњFJ0@ -_/_#Gt=ߥ&*z&~Wa\תvj[3|g'̹,a73ƜC:u3b[q&P;3n٤~f4l#h0;eN$.\׭Ds_nI[L($S#jG1:e[[a :Mߍ9sKG1fJ"T/H?TJeB:lqIbgpWl>pd9VѿD 0FZ\8L_iOyuTՇٍ̽`c6#ӬxhT~s-Yؕq3n2J`M3*?b }#GeVyFof<.0˩YcÈ0[N"Id9뼭urK.˲[)A=Rs9Mq2#|ͿO7~ʂh1_mk#~o05 D6Q+_8h0TA8~!In߹+sWJt:mg}љ=xVfe{9N_Z0a!b2uO/CzMl+c*Xbά>@ĥ ÝJ+ҏ~p[s 5pY͉OɹQƊ 1fj|Ҍ bz<.;:Cp8<ǡQCmjqL ܱKG J/B+W2x3e uw5'ZY@;ObGAylz˸oG,_+MarV|E f\}e}B,tg>'򏥱{YC@;OCs&q(Yٹlʬ@]IONv2^j , ^tF%/JO-6F]JD!n5۔5̱ooS,_ghe;ןJN zX%t/֏T$+g/zCP5V xP/5wpVj㯩o512]-#\6u0BqWXegEom|EuS"J-Z&k/gLp2ZMYNs,F: r/w}6l[xunU6D62#]R-n+"bS۷SϠg៊4CJl_ Ŷ*=SV#|33"9pva7U&,-JjncG\5GflXruE 0[ \<^~YSe-qybX5/\?tI*o\X*efؿB[]#dOywNgR#Srňs%0?(, M3W_i|c]H;} PsSj$|ɣm+ y>ψSs(:z;j=G5yFTZ^ 0WxYL@PTIR3#oWaGy'b.\\cޅMS\0S1pŸ~?lLfX/?eMw ߂ozhu#g`z.,0ј NB 0f<0S~+@nj癖J'i+9en1:fjcё0Sƥ-L{Dys. vzJW̪Z2M2hG&68F,hseCGej]89V]X[2E~_> 2؜dr]B ۼx)܃Ŷ:ܲ ecĢi{\G<aIȕ/+q.q*N!O"V$1}Y7>VܚeGcuocBV0jwcmh,By16Uvv< 5BXLy)ĽVx' Fr0XwaN.20vgcQc4H>&ǙytKH/_2,]#-ݼ̉g)Ei71w4Gn)_ $J޻MGNf-SamڋE3NqU>鈀PƥF-i=EvVF9-U<7*~Ia-ku21O ڐs#Z5qc1B+9n1@=tӆqʩAyw,ZÍ`+os)"/%@ Jή%^L6/yA,iT&rSrwܥGgICבLOgfg&0E d4;Sg2@5fSAD:Wyn zX#y~U7f̸X1G\U{k7=$vCATDw7q1ü;1 T'RX0;S>^.' %pZ>aH:i*q?}=Q J.:J(OCܔf#I 0TKHY۩-e; ިL՗A7.We20tv:ٝ~g0*ߖZ1!LqiC.gb+70p`UjGh9G[ q:yr,d|Զ 㙞 ?=sq&Y=>O-n0JaADj~uMIk.vDsS&Еq閇0Ic^f)q^f9B\fu q 1+܉TvJ{&r`擴^U~s0Bf nTEEwԵ2;/~p:]~Rƻ"#:OKq^%s Tc{ʰ~띟SЇiv G9obvche\3;@-n=#_g̹Ri)}=ƍP_!uNn{[KW|JHXv1)fC]MGw ޠ]ǫ|1С\,xX]cu /9Q; v2qb^%Sat);3Me|Cr9*a`3^nwz.g̥qԮӡLG? LRcge8άܢVxR/y%<}Q==Z6c楛8L<@ k=c9 %)%Ǧ'3~ g>˧4coO9"s7ـvXwgt#ɡFJҳF0І2C9d¬wjAϏI2B.(+)Ybbnc+3G0X;ͣN"`]7ܞݝLЅ(>DžʶQ{NjS]S]B:4x%,U0:Ϣ>=KVF}陔X+ai3a7yvZ4 )ڃ[NDwO^~#ѣP2:Kc-k.Ȋ^k%2\˄szjLL1&qqʻ3dt;MADP+c{jh ^&Z^ +%{âh-bծe~#5[PFcB2-0%n2{LѼb,~aSqȫU6ī6ʋQϻO>'N% '1y}<¼L!bopsb\?hz4WzQb{ b'<]#kUQz9+-+Q! :1MOE\el_&wYMGImOV?812zƹ'ȷgg3LՓ` 5R"7틤.`NS%ʆ=9 wrzns9ۜ_[/iVcF-oXm0MR <>Dqǎ=Ftxϙ]5s^~gs4+7RmPV~jq (P+<1#0Q vD܎J`ZV{5I5h/9$sQ6(;kSdeivJQbssmi~c8Ks~==" L32cxr-LLgN`2Ѭ0)JDt}*d.Rs0q]%T-hJ tjLtOi nvo:6A/Z8Snڥ=xiޱ7,F 8gZICلmKY܍PܳWȈM!ꌚ/1q^;9h= SQ̒R,NW~T6޾ed1~]x: +]438=Ǡw cQTucqb2[zIk˰B.D37(wvy*3g/K9xeJ; zY{J[*.)^%~Ck8ZW%刱m3!0CX/LOĻ,>J}(J%Td~H}ѱCf/a'S vm GInw bs-ǟS!d۝RG>5Īnc!vaX xYUJu\o-;17K{x/ea}NJLf lN*4#| ]f_uwswĿ 3Vlpg΃!B4%,Of}7 Ny%ܓwR/ѯ^/5 jsң屪˞ۨ$+2f]RN/9~+PN*@sLĠ~Bʀʥ ݾƥYUoZ5,6TgUBW jU[۟H*Ú0 &.1p#ڠWAiB]~0}+db ]vEgh):͈I(`|?tcQXDLwgNɨzae>S718w h}Y3T W:?Ƭ{況}0lpao$t6C6}fW_9DIg^LgP S!h?skZ `{|5P{ m!g:"MLC= Y}q+SF22R(Ļōyo"&Ne|+-7a5 48ӿ_ގe GH˸+q`'Bgz6{~=XY 'tD=1OdN7AeTR'3^YdNDy&} z-S Д3{eG {"[.o;QxkT#fMf+g0|*KXās^Cܖ3~bm { ]=u8z)ܠh+1]]ݏGc(ؚ51@iLx0f\RseHɁ͞bX㈻"Z;$X(:89O;b/>}'髠> $-%TuY#MXbep pFpƝb")<^.eq ON\)}!3p {:VX Por=4Q؎=As X(^3<̪L,}ĵ% `勸<@z^2Ma(-lG׫X'BVu/XqT[IQ0&UNV#/f$kxzzkIe724yzo2Wa4@ vt c$hY9ε7%w% Aٞ`H8'()%u3.~4py;.Sxk՗fSobѤ̡ 萯 (gs˙YzC lp@daLYnk{f1vnK\YL:K) *K&,ρ~gmR/KdQ=WчCT\Ks238vp#Ib-c>P@a&h%Fos~"s"Am1L#,D𘾒`do&fqQA4I{ē$*@Uڍ8qK[-j z mtq+0flHg9pL )݄v`c>#<х}@p%ncџi"T1+u.+d^*P1n}y#SL9G_eu=݋1}aD>X6:[;YzOОIwl;AHxرQ-r ӇYi3Lt^20E3znsL0i[rvwNc}7\Tj|ٽ ǥ?2S!2ƙ]#fK^BO1,KJ}-W傰xJ1 秴/i 0Y-}3-(h-N_.W!ZU0UҎ(s,50u3(ryl k? ; {,AؤyW_>wij .k hNҜe8/ܞDvҷ/ C6 e1h/T2n!0_ޑj"*ܗ*-Tfx+`-7D.w*_Ϫߤ12ޥ9ͶOy 89yv &&q4b"wR%Lm_7U(2  2F̺AvT8ZT`)92ֶ̠w 7r].XPm79A3"~浘 }(<#['M X-̙U3Q^дP Sh9>m|])5JhTuIPY-& s49ΦLŲ yi/c%C}fZzz2_K=cu7Eyֽ1Ms;&,[UQl-o%T؆ ;J`'0pԾ:Jke{TJ;s`5(<] J ߈^wV%<{\ʧG \2|Jo%f(c~&r,W5Oiǘ`M Ûo%h !pA(`1 (CEch,_i5Lc8O*Q`M B 2BW(Uz$0&w˳` 8 k3EH\u1̫W FڎT蟑ƫ76Bf~4kq5ƿmX4jR`)rU&Kd5_hMlalLD&~pr$zj8g%z Me\eFFiӏFopz03]3ǥF %PJi/^s|"4Q.bb.1V1j1rCzЍ5g)}a'I1ݧ[L0 `T,};jf#; *uC*5`ORܑuҥ, 5X(s(1}Kg@QPSL/\Muxj%fbtnKჸktXQaW `)!_ 'e@%#6pfd,'w-"* uIpaMv*rf.9"eB5ǰu! _J+9^&FS̽4>/?J>Y|jjcY(pMosuj˴"<: }BzMO1ǯ2#؏} <z&Sy(VJ踄N%WWĪg!JMs9y#pplЕ¿4dǙm۴\Kc)xU@(F>C\xZjc2AcW-t3aќG.9EW 5 3bi2rܻTeeЗJXBU60"Kݱ`?/7>҈"1sZu{nb wipt{ʑ1Nc*Ѡ/rfE=b^950 ]Y* pq@}e${"QI4cw#~ص~7rfQeoDNefjԫ~!cN.fp_F%W9fs*gʢ@:Mn Ö9>!Zi_AwsQJ3̊Cz0Lquwc$ aԮ '%̹ ֮Q` XLjJ?;1)rzX_2^&&aRu#hwacΌD,%Ĭ-aB;-L Ś#E"d^gmeu"Ըe[M'0uVBb& (Oe|&ԮRW-~7%M,;8`:pJgH:8\ L5u Hu5ƒGJ+vk{RbQK{eCw@^(Ꙧ9D}e&ۇg9ɂ:!G0)f}.{C tq.4@0g zF0f;.C`Qn7:FRʲl ` ΄]Mb--2Hx"NyaUѬq3pwCi~!fsG63E{ť="[~AzNO5D 8*ݟ cKs=<Hi L_ڗ >`Z\ 90Q.C<AN8 4@rcw_lu,>{?M"򹒍x ͬJ2a3̵,Û,S"YmJQ+3SҽN`9ԋ1hz*i2fxf(&ebpT?V X>f/<]j1^#JFGBmn1`.U #k *?Pmx<gH7C ʷj26_#3D_KF8f#cҨ'hdI^TJb1 v&&Z͕ ip5;tPTXqslFi#9jg̨w&& d{N!sewk~_$ Ji#YrPUb;f"/Kc9i z5Z=<55ʢl @|,3*>铄,9L$! ϡkѿ]>5˛Hϣ~YjQ1T?uۊdڹ2^͗bc"S''dNMxA͹ _hP|qEcPlT jϰe!.-;yҭi ]r\Acۜ 5g&Suh>uc3}jvBb`.zi G702gP̪bY/=QLh0 d:KkY|3cI!\j+2,GXvc$!8^J:A^3:B5DrK<2=BPXJC8RрIoG'P eep]y _#9=C߬2F 6i J.g/Emr>:=(ff,tZ,C3ZoE)I@~4@fHĢOX8|DBɾrDe_X9 7! CC}>"TR@ Yߢ\KĪ7d73}bw>YFRS*(=sa}a8lje}XR`7M9/Ҩ_yd..k d֘ W^0,%J :_XY`C/A+Sp34#Bimeqś*醥0yk:53b* ǘ=Jv2GieR$\QS}c(ێ,`)ŸH<@nJV(.sA4u7٣B\oLs*THzWTR\3} Lښh|]hk,4*k>hNg EKzi~Ie@W@/Ó@`gcѴJL ~\lZmm[򩢧91;s;u(-re^]18"WA,oi%·lF+zv\T,J0I>JNJc9%WZ=22*ehZE=AUxQɿi}Y\E!$վT'DycmpVly3( FKt40bS<:* 535 ]~[:8=>2Lec^ԩY|76^)1u/ "WT*.UI% o3 rɛ9f~Rnl6̪-;N{6&-Q>%t59 =SD} =35aAy5*Bh+mX7q/.:S8 n[9oPw+טp)`]_3c7)'9әUܰWŌh!f&G"^L2ZhДMZD:y!:?4Z[{gK~9 v>O%7|K_XGYYLCO}X=e*!1AQaq 0@P?/TR ҿ}B.\ ./B.\r.\HAGqcYKH:8Z- ^ r˗/+.\peƢtr/~\aU@˗t(0Eȸ.C \(HL :?rѹr˗`˗\ yʉ 8?ĹqK?}<=1[3=P@:J333a!/_\r_K.__a6 uG=02/aHtFTRt*S:$r˗*ErTJ+ tW򨒥tN+RJRQb躃^eAX._*T}oYR W&[`UiQCfU|dNL#Ѓܹ}.\}_}/*J\qbqܸ *U[]ZS]@5T*TAper˃.?Q%tu ~@6&B1s_n\Yrˋ/(zBTI_en-q!c ҄_*T\/*TR}n\}n\Yrآ+miHrM%JTQ%u*.qt#lhtCۡab=0ƒK#$u\2չrοJ+/qa O)D8f՟~~%uRu.\} _CsGAp /u]rUꌾ K.\Zҥtj$a0^J`Dfaf#% ;ch[$]#|oM*!P%J/lJJ+e1_ٔʘrԯ}.\r\}*T+ + l|B涞 2#ԓ.5io_edͶYr˗JRq ˗._\QǢ e"G>BQ(*$p`˗.}C*;.\r\}jWa:nΠbi{x* +u/K -(,wF* ވLڮMsX[n\r.\rR'f/6XvkLJ< n㺪eOF A* M\a2X\uV+d4U!"`w2yFXZLPr .CGt%n;]*B `[ekIܴ(䟿撿rӹ0z;T0Q8HTAi,splXUo+L`Bj|ےpӎ^vAUTUr@ ݩxF- ҉6X`JVt*422tr˗_r J*_NB|gh6 fc ANs%$5& 2]FE\`awt$K.`=//]W{rXIPHͰ]/l h4גBlHƱ#߿ig~0)#Q^B}~/1~isX(ϘK? O)׼ǩœ| F":_*W0e9꧜ف!NsSUKB:0 !JoRv00B#< dSxKY/d`y Ц^‹c^/ e88)Ef!PӃ{0I9!npHW .,y贝0rǟ5r` P{ioPw8B4)ōj*k+LvS2riʆT =o3#Vf ;+ODA, B!n=Ņxq9MBϓ=cf%n7-o%[*ϙV Ru}@+E?\rѹUnTJDK1V9F$yQ! ՕbdaR8+V-)9KHHW>yuhw$%5˗._r.\W*\+}vEzd(l0(LZ>_T0A r|m,%Zd:Jk#s{|22%baizIf; R[*r9>0m5V򚔆C~f YuӮ 7 BhrԿ.\rɨof);`S# " X' 1.Xq ]S!qr#?SdHrX^ ̏:5QtuS&Gi/v/99IsXr?/B082Y_Әjg?Ws[O*j]460T/:=e4XX-yJIv쵨<̮r I<1K˿}wLx)P!osAոm;:QPJ)^׵6OD*& $NJ_E4^ ljRҹr$RPG"DzcUn W]JRU[J*7 q!k~JU7.ԫFv)ح@%괡_.;3yY7CՓ.J pS~KCβJݝ[ Bo_*TIRWST\z,<Ϳ;#i}=o+o"L*Y\ޞC-eeuIyW*j& cvsA-koG ZP&>.(14ODVwwwzV>+ @ ү?#P ZDHqV2ŔN!S-_C8xn$_w.\_wy`堨5SP=[]Uhߨ+%Iʺ!^d"-r׹R=Ve}t#TWM} Ǚj'kLPY1P1 #c{j0{B|l2s0e?Tf4ypwFoʵ 65D"_ '%. C@mcǍy~&mR{ 7J/H N_rr%J#/^zmm^4Lny%Q3''=8MAoklJFNפx-e˭+R[Ÿ.Uq 7.\"UmIP`̺֋UAZ&K8! |sr'ĻN**WG~0UxCoAMrR)Q 1ejleϭTZ\ L RԡV( %r7(򐥗FJk&ْ+l;nT "^6Al? QEB7i3NU z Jkk0ч㔙f}X=+E| =Cf⮾kC?5JӰnJM$q 77)RV9Db;g{3jø ^ M!{J&ST8b0|}n\KrkM ᙪg`N%fi)nX\Bh*~An?79^,雔? 2˵`f+ 5Pmu;[26aB[*z2,!MI2p9WBmc,tzWr˗/L[)+ZvsCڊٓ:EXJcjnݔCrw _L܌ؽH)ݧ=@;pU/%QvS98㜭q?wrSO8L]aY#;wѥKiK)c7)c@L"/[1JXP`h[y!EboeZqO{C#\_._/(4rRJ3ʸ"9b5De]l"I))?v2ª#bu+'E`⇵k{ݒ)ǿ`BW9\%V, ݕajk*O*WQ̹D׶:G{D|Lcx| |Z u;yϠQ)2❘V0Z%>' ¥={9 J^rl!,!߸2, JN-`!b`D[QYvcf`2`)q77gSjB6>!ݼk˗/r%]*k#rf7ӈ4$57,`B4#*e)G?,1̺"ިʇSk-tTݨX hEs%%==u<8c;y$Iڢ_O37`|& *u}HTj;?bielU<dHcC,sD$&651ah-`ERJjXh` 2_D}Zu> Ha# ʸƔ6?}ʘG$KKK< r,1 r^2 1â!:^qm̗zi~!ME{=OVHv2Y._}oQ2T66R^}H?~lEk9S }eƕ=O If¢0bXb7sv<.\zy"C5olLD\!6 Kr}o\r+øj&ʣbxZr66.0h#M`킣UNQ,9 7ZEZhri-,QU-_!b_r~LEN% Y8Vˢ\˗/w-eD dv>'iዀ6"C=/SP3Co?ք׾n6'{A*ntf.ܼfg[h4ݧ?n豎!}X4Z!)J7fdg3pc+}ށTN8M{d0n䲂csΧm>"[Sߊ.ϧw r˗._J7/tPiI_ ɦxc d5c0O5Jk$BVe!M[FwׄX1 bCzeӫ@څa pd瑗y.pT>Q9H˓u}ru/jW}.\˗/_[k r ÿc3d0EoUKh0֯f*|b:neоY ʚQMN#ZbJ||b#1!b#IYb8a&£0Uo!J^7zG+"+B1vP/Sʌ_JVRY~S+vy!TiBɸ|[2%Ɏ^ kJ;[C;pTX:ZWbam4ps}53c2g[xh0(bP+g>f~#j3m Y2BT1Wous<L4~Xu *~be˗/\"i&)㝻9_k'e3l-a8/ A._^,&wRHϘ+ z3b@LTz&^G{jig鸎ځM/o+3 ԳRrd4BM :nI++Њ+~(D,)\Gn<:e1w8~f7\2}La_bm5 U8#22OUM=хJ*A.U{\+-ێ5L?.L9mJ0TJw?WՍ]^UM^Xy{6(w," Ev ;QB|`X7 ֘|{JzW|2W.\r ev~ }?|:Vb<8}~*)q Rӽivj $2pTh @}e0w~=Ȥso!SyvCq~? ," v{':#&jr Q}3c6 6'j-MرSJR&tt<^RT>gץ -GDqKƭЪqUqy !pʏ"ݱk{Q5,?f~茗U]߃xbݯ!T U?uL7LI!n$ϯw/u@sɳFpb:(ٜ&v<-!Ji5]ahj|NpqG7īf-gzWXp.FX}TD嵍/\< lwA-R]ц7NX- i>%tB!rls%;.rRJ޵*_|U$WoJ])yM3cOi8BG &)t"J6K* ^pk$%+Px}Pp+ T&IQpς ئ$c+i v0Ơ.܌bW!Zq4y!YrC"b6VHJsv\?BG3v<6b ؀g!|0GXɹ&\  C?8drSl͓fGo$e)cZ5'ҩO M[RRw3ȳ+x7e8EsaqUeFEApJE$Ko }o$z*hsk|gs(J.f!E ὏ `,yC}J"ӤKxNA.=]мɦTӲv34=(+ T1k)L`XR* (+[_c3%UJ][%s+?ځ t(4MɬnMe=̻@a@Ƽt T's>F½ɞ?L.U}FE[%y8T NrDB QH @m$ +xȕZ3@f"3 &11T31&tX#ζ4d 5/C"i UKɖ/0P_{k _o,8y^1nx˲1f,u+VDt5߀)C@<:g`pBVicАѷ]ku._lwe[""mƛȝcpg[}(S`ԯn&N3ɃFgusf#0eqY 0 NnuƬ^Y9 P( lL@N Өy8M<8pJMn 036S4\9u-g CWkU˗._KЮ͙0mCE %ak+>M]1~bs,vCΎ dx=8LZ00ො^o |=تUDϴ^)7V\^Sұm (> bjŽ3 1k'#Y2'FNQP9P'?&zԩ_.=YkіU#s_H&L(szf3ty5`'Qs4$4ld|cU+w F1Qq3ev0KȌn y ZjF>X{ X5EuƠ/wHnͷK7%$U33U|f6cPaM{ƹn)7Vþ+/m`3N tݚs~ N`?*`rU'(Y.Ԥ1#،aYGm) X%,j*v~ێNQ{[W(!| Ǭ Co5W1Q3HsX<]AgT6?K*OOWm!23ow=NB/CR[%L_ aB˖K",Dl4oX}Ec{+NC_ <}#цH22ҊPB EW )X 1b X- XD p3v"adv%j ¹ca-Kޣl;Wg/ F/Y&Wj+8lßlq2N*YN0_7‚lՙ> ͋!&צ,[L R>Pq%I/P'ǤXc0I?셞*/aXA PŶ im>J4PdZŔpOP[,߄Y@+UeeIYbSukQ3`e#Cp4ªddcMU2VKa.Wc Ԧg]7Byxo>=h~6~|j#W%.15Uo_㾗/꿃SWt=_/10)tx ˥e?T ^~FE b ž'.lT<69հVDhoL4nk_-Id`66s^t+ )Z4i 5`[dޠ~Ț[jA1uNTSBhƫs1/&cSMiLpKxqV>+aRp!/?bA6ʬh [1gNDZg?_V5N4jpq;|E=WR F_'/g_1 Vo\Ꮏ&W7J '-UhTAC/"FemyBdMe®3p/Zb?Qn6a@$2Nl8#@9le#.!9pzPXIS +q*z4kjs?8.Rv0.Pa]438gI@8 mfh<4T$݈^/A(/mmyTXmeI{KfnԗUf%aܐ[-N*YK c'x녮gljbqw`wr *C[cpɗ7lӫy X0̉oR^U]2 k8[aOTk./ByBllNDǢ zr힇_ORkǘY,J;MQ*˗6S 4nɥbR0K];*y<b,WQ36 ]=t|v `ÃMxC Ac@J3{UԢStcU 9=gT9S 2I?C2]ciiBhFfnb[bml65rexLULY>8(j.l\1UZDsue ,MkEBƞU_%kbvqQ&j^,y82ZFh"-d N`0;lmr wREE0k`, b8:Z%ĻPklN;c+8e_[wc8ߗe;AsGvW඲_dG¿~12[ǨZudҥ}]+p؏@ 0j_cVgٙc:W}XF6W JSpߎ*[Tp*RKr܊%xnʐ,N3_b| D4 Xp C" \iż FypMd&Yj` q4t%*ʇp_`j9Xv-FQlee~ tlbCXZL)DҳErj-<8\N&9cx`51F\YcWGtn_5ÕL+JB;aB hdI|vJHgjbQDG9ya`pfzFԿt 5Zu,4Ŭ5z׹Ah!Bj)V4h$vn+%L2grI(Ҷcɗ& 9sPagI{@T)(xuZj'8 uݩ{@XBȮh9HX ^E k0,- `J?-R#1FU<{U'h4@ x@̢ͫ>(s {Q= Ѻ qIW`RgRPR эoe4GMQ«k:iݟ0A@!\mB/ٍEaEFy&]}7 fMxaBw/9_-ƗOy mf*gB'Nj#/rղ&e0`*#bz^K Ib}(ow rH y\RІfҲ0m KTFRx‡vfPw}60he Wn IJaE1Klp*6?K@ݷ4'Bt )DNOnvBrPxizI WEoq3_;edx旒3Yj^NVvޛ:Ra34鴅Ijͮ$M[WX{"7堂W;Ɓ`8X@+eBPbOk֪hKuhYWʦX[0X+u)\ؼ*˭AbRႋ78#~ H19r\jk_eheB[4LD9F(KYnuĽC燹Eu`m?ilpt_vT`L_ ewXAXq$ե>X*v=H ,HU5pXRW\]2SD#BXt)صr*3Gyc_/e]z^a_)A>)1MATi&*-ʋdٞ[< ׅѦ0 3^EIP21|\ Mבw2xܸm j~EcwKu8D \&<%.-2z4(F^ ^"ʽT@Rv!!m9~g;n-YQq+ U:ז&ZY#T;1KE3ZOoGیO,C~~;_^o4D'LJ%ƈ@C1EH_^C߃hN܁i}.b_P5DEKϙA8DYMiZ̪ruX@CIZzKds X.Ȳ1峼m1L-n YE(k+P\Ns` g5* whYfa}Rռ9,  o^m|,CTc4B*۫?@ qC^~+pbA1X[ "98z6w u ט[39:{wB<,_>ŦNx8}3F{oL}:φʳ)| .HA/*%)[Q^gWjZ(Ⳙd6^9dEٶx ?8Pq~nYH54n!7Z/,%O J:vZkl]=einRVJ%^V5I, f)I! [  Y.aC"cuF%+ڥUi4NDcsPG{9*YAv9p"` ~3)$L~tB֒kno0缩-Ear =t Ҹgh n g 2:*Urb#IG'r ,b_;JSP"#PET`5ⸯ)2,/cYc/L3h@P _r3z>5b]XXW֢ڣ`g#RF@Xp ԡanԘ!U@b--Ӧ̀A򈣹c0ѷ@p9WBAF!k)"Få۟rK.K$jŀvVJ#] n"3sD*̠74Ns) 蔭SWd$o <Կ vJn{1Er_Ob 2vCcp{V".yb_[`j0ૂ9fOӦ7h+ǔ{Lr dlu˵>l|&<1;Sa2`+54qBn|XmVë;QjsX @LSVDolJ5}a\=x͐x?.ގa.ʍ^fIR-E* gf`uD0B` ."Oz(K֭P#$雄R.+W>e7]-O-*PY)36\(\J:=(sr*"3p."rTw)6`F1r /Oirso=ATډ)wOhP_ aevPN`՛ٍXچÑ S^, i@j ;ucgDV ,3 Qp=Owq`,s$.42? G"vƍRryʖS]$DWQ0ȞA`Bn{z$Xza[Ь), L{q XE/3F2c ^'g_$շL(fjw nf)lD b#~e}U lgdm2W Eh\ybB[VD.KeoK(X ̝)/hb6Xskx_1Uu&4TbXUwtx&\Lr o9 jɄ"zk j2 4AAZr鵹!#'S08mM׉)ŵUǡ!)nO1-n\5(ܟTG>TZ\czTv 0@W1 @0mRvRtdJܼR@F2"54BA6(gLkBiNfRQݼ*0<,805 g>=2R/m/5Ev7;"79n 32 %5Щ3Qƻ ȿ "WյGU QSN-·.{ʞm.WjN'Ԍ,(ڰ`Q%,.@|B O[igOx,(cQs*8!A@!Z\"ɲd vvM(hM#$=Stϑ׷8cZvF#SOLِb!: U|P*VZb֡O+SK/cPx r {/"ٽc30a,KTBf{|Ӵ3Cee\[a0ivQ0PZl3\ҳFc Pg VJ.`Uyq=xu+46\h+ m{]xϰf@>#v㰖)^V.1I퀘 [XٖuZ)`&l{٪9kGA(Uut@]T+y_*\p=fZS*X~p܅m9m* u3oԷ+m!Ig7L_buRXj}Pϸ's7 b ObK#~b-(b\sLD, dҏtfR/;ui%^qb to!PggkXAScNC}ojHb1:fKF qN?.e? qPi|v" &bKq tf"0b]>#V.QpswMcz,@[~b~Q骸U&6 [!+/}azHe2f-K8q1N֪UNSe.,7pDh>z%w497a*Ulmh"sb k75{bP]Q'Ee5wO+uUDwfljE0[w!,чɘY+[؊A}/~]hj?eAgQ<35V' ;o/,lEe. Q6pY2 X 7*S;.+־ɚAՌO.YV\3^<#;(F奱O~Q򧐝vX׳*1v0# M)FhFfDfY~߷NGi'AKq 8Ɛl}V;B&񕯍"D(Ͳ|BEN އ/t$e[CvdCL MYmƎ.TWp =xүew@c%h̨UJ5@Ҧ)pneYJ0P-"aq`7oi,!bZ+q( y9Y̻q8R e8I46eY"[RsHhز4A…o^p^7ܢrg2ݟ\;.ị% l%B`QyG\F[[\% Ơ ^8DUzUl*D5'1EW y;p56b( :7v~(MmSVn`:VB+l"o-;̸ՋL:D, fw~rF#: ߴbΘ%&ILdJq \4m.qv*ٵcDW,3,ᭅFBh@f y7Vr1-qU@!yWn-ET%hY6S2ĭR(Kl.8n4 'l#ԸF.c>cVhj#( 9v>nS(ޮ+ L>B,6:Uj,LS^@fP֕ y,he*5dȇvQbr#SAu0Z{̿ĭLV(6/zeо%r8r4#-%Rsi̳<_/CY2 >ks28{K"\1l^Ɲ&b|i!X\H`j+,B >a* l׻.pJr@-¥Uo-SXR7[d3b5CXams2}43اDF2𜟨KwEƍ/Z1Nd2n'޻NTd|Mx)?fm][~ɗv% Hߒ Ar‡1iмX4X&ʓA~.Z.GI^v|BUɘ_4Kڲ,!A;( (`Sd+GuWtq rZSW5UCMRPXL1m8|@g8̡tlm,]ʪe.4M1}v2rITĭ9~PH߆qdhFܙ7M@yUanEE1lZZ0Pq@uK^W gWA1gx-S%n}Y" "3;'0h[Co-("@}b_mANvNo࿹_wCINvGL슕h?/v|~ S~?a-XҲ+?0TZFfN/E?r1Jⱏ*{ؽ1.U.0s*xw|ᘤ$~I&]C=K0]'ܴ 9}x2i4Xd<&Ƞ6)|d3c .&N{\UԶ6]V aшPA]&ͭZsSg򷃛2*M%^M&u 7bV@/rQMfDQÇV1q8"Emw+_{&$J+;@4gO̲ ˳߁>D/ &Z;GVV^m)|R5H&6=`~ѨnYdzR`M".Eb]R}EBoo`Z&Jx ߙfj5=E" | !Y3&p ι"$g;˪$D4,5M]HJ&X`6,FTE ]+CYV]7Y]a .lͱE 4#1b3 h],tby bpX%%su[f Qnh&Q|D \HoA;`4؇!7AnKa3guBpL(o}K'Wq F \PK$̬qIN},?07)-iܳq5 m2Y (#k|gXR'?#QBo Հ!m}@.˚Arr%-]Y<ȋz&L&{[ÿ2zLc : 3-:4/}iwPch#|Vh|ƹ5rGwmf:w2RL+QqnY4شuD Vv Wj1򺶧kAR+egb*ཏK÷7@4%1M]%T%VX@$l{fvsօ ^W9~V{%S$<"; #6_=΄w}RAbV*bGSR\c4;Lf%DqKswᘀKsMF;BGt뗣 2*qVfh6_lr+$GDwv_'<{)cy9qpV\Uj=ʙlRZA"Φs_;#Hbe&!%> Pԡ!4xҔ”_DTÚnT E]7W%"휆Tv.ͿE€8)e*]{FexĶedTƝFH[Lbv @tTC|Z\pJaAVjZ;cT*)n_!%ў26Θow&f,o `,Z8+ g S78n+$.L/"k}{ Jah*Q~q7|ef+ł1Ʉ2[$c,eAiZhU}$s,G/ TYj"AbweCB̓=ux]Cl&l|4ZrPX45ah  y5`=;9e 4A ئ`yk&XQc C5M0ԳA!o*!0e68GLb` –/(\U˥%b'f bVDI>*)|2C5q!/4=[LH6%i!abEVjU2D~X/UQz>Pܾs6*bes XF ኹJ>lb8鋯A:'"xS!MT%(WB {DAn7oy\GGZ!d}Bh %A*(QG{j:d n -,$f [Bqm)"Lh UP5X[. ~+ 3׮ oaߕhTL,E"c@U]h,נcKpro2t[&y3gzK}F^$mUj1}#wcU1˿1Ífo'VdzIH[tL)ipN9Z*dآiZeQxã'fgyO] jRq To(Xٖ`2)⩑1cx< ٘z0A H򙋖g*C_A,(7!@0@[0I&уTVtNnWN ٘,.'m_*un֠q-%j6f)R ^{K+UF6T/q>6QVeUq3-D%VW[weoUM7ž#f@UZ 5(/$ei+loqi Ւ֮i5J;a3VŸW*[ZUPH8&;$4%a|lq@&oD8@oo/.R.^,?WIBgeЗ< 򦒺NT=2c!ڲ@?XcK xaV]> Lb}SjI4q9LRan}(:Ȍdy1Q0)뙈c7yn*FQ[``mf5{ &hes3=j]RYwjR)4QT*WiVhSl9bʁXj! fkLJ0;wKnT,hyBk>heWK)7=<Wjp*9 eXj7r|aPzv5vq{tS<@*!E2P ^pA6QIGgYvHKxgf!nw+LDVdWzdw ֗=HK0W^ yYww P1߷UKGmoiYNe-=n9sEJxǖ`97'NG EU8ݙƕe C 1J-pDIh%Z x?'a97}O64@tLR|G&theԔ B("d&a.Hee.q~h [0>FV/x -mt@4Z)dEY[fc?2LSASM )6ALU#$sNPZx9qnŸ4#c 4@wt0_JؓU;18#[ SFVXcyNM;*)*̷KGvA "0Kҭ,J"xӏ(jaYŘ7+\ ɔLQa2ih ;TstTD丘 Gf@{Љ?r zVفQ9n_׆v)wڋXaS|۽],q|E0!:RS= Zd/89^+kb uDWl)v8 Af{4(Yyn̰䯍{ {Z6DkRQ@  C^&jD!6q~ _@zH|FZ ՗0Qq{I|"Pz-AC6L-D)4spq`b0^c Kv,(U|EAnp6xށ\.c ^#(1TeLO%bR >JS 0eAH6ʄiWQ4;eTw}xD7 3;'%s~Ҟhܫx};&2}יnnљP+, qe)O0C men6Zl çDRT2|nʎg~ s~`/QUa_{Nߘ3 ADD] 5w `N AV(Ķi5NۻBO'~mt1(\BPM7uF!md ,rlآ^WF'v52PZ܈~'0ZV6P3,K">6[?b/s;vr^QK ZU;xT^LKg,n4/Ҋ(I9 V wC֠*Zp #O5zn@[`)w*K5͙nBK0k9̍5ey.~>b zqZC|Oٖg[3h |3n|Jpnr>ʝ?+*7VPLMb[Qݍ2,e ^ 7:$Di-I:{ڢRS`ʭݞd?]U/ Y8G+}٪Ke ɮPGI"ɭ `4Ɇn8`wlH3% l=V]$0B#N_c/aDĠS4J3z`WeCEwTb9|o1E/bw"v=q7:i.CCheEŰ('sMr֮4"`d{ogԣj7b kR@b/u0(f&ں7ĺ3wQ4y%,4_I[MKS#' K;#;a(:ebJs~WCIxVa]O7o8 Id +/۰'`nMO1I\> 79{Nu7@IPttn,4qW@UZ" v@{>c)u|MȽWI [N"#V>"AKS!vfzK8Cؗɦ[xBRaa5ŹLs`˖!PÝQK'AwCݧs&j)[Y}ٖ2O1jA%:*eKP^}sƎ* + =Rh(}"!>l Zw>e#Er+,Os|^RF A/-=$g,ݡ~1l40Bd)m'Aߚ1J,.kL>E' c~o o0\d{_$טd'\N f@U@{$X 8{'5?hcn5чJ>e/D{6U;fW9XG}[!q13a@,6W3whdy!fQiw*XEx_XfM A`̢\Y,qzc,}{&vndv˫ۂTļbŃ._E˗J2~^b8e203E@EA@.Y'&_]i< qy|a8z#6HRŜc#4/xPJyy7`1t=UCkaϸZpfDpG?A2$h(A5v67 NUocEUy{m%Mȗg0^<%"Ҹķ0UhUe;ZqqF$n}s9J(tV(a9\;I 7p:1vkYFmf:+w)N٥v/V+Lʿ3ATo&>IH&f誶*\sY;k[Yг1"& `Y{pK|EWe;%V4Z*Tۇ1b/"pA AKja q͌.j9U1[BG8#,d- sZLpt`oiU> )&Y9!.,RwRYPXC"FXlxln9۩3Y< je,e+6"v]۸6V>p#q7M|Z& M'i4xѭExq1PѵʉQ6hN&OeӦA"hd0ea1 mҎZk %j=Wt RR? G"b*Km~hW1/e9|sNnOZy UQV8_ʃQ['y$1,A98`rUX~܍@A,AAsYVjߘ7.i\L˩+e"HBhQh*{֫{/Yj*SM!dQzc:0ˌ9`~^ 56e&HVaX*uor;M*, hYi̻*0^a#ܫDފN: 8!x+k Xc*8>S0{\ Zô6.XP. B`sCZ?(ca K0K 1:ZE[.1,^;&:x*2{%; robTohV+g>zCNbmeawU+K0b8|=g*d4=ĨTRG~bj*) oAi0\EK 6"Tþ"l 4- vN>LA*{%ADXPDwao0Y}r0GȏZfw?Mܰ.iw.( S& 9UPo.sٜKo/><$UFx%071>F6KHq Dz\pC厭w% .*%`x8nұ,݌tTBext.rE.1vS UdA z4\k*LA.h{?IGDt)4XnBlĺvg},UܼKn̽^tgLnxJ9^3l"$aȁ LM/h;ʦz+%l5 ۫( ӵ8 z[.1uW8^ZoKswXKLb/ q"D= xD\b^}VWYL+dV̦h /p/,BDwTzo{!՝o苓f#kf࠱>ABl](ɨ' CfjhYi5aB A/1q )E(o2?Ɗ`{>6"Vdlt֮*x:Q`6dіZĿDW3z]#`4q*O䕝:i@Pr4xw-^+\9yA̴Y9&܉t +U_XPhq J dœ[_:Lo|!գ)kO4/2z0?!wO8o [>(jbT7/GcdGEc Md75!v BF<1,!*"3LtJK%NzBu OYG1bH{Kpeo%o a ʼney06&Lp5 hP^cXU{?1qLeÊ#}0[͑XWT<#+%K\SH0_I$UMҷAt#5<߆t >J=%SG#A>Jt*#m/D0O ހ~п ,W_P#H`.%-ۿL _+%7/*dZgYA~N|,H+3ƩO7~na0aWZZӱ>.6w@ TVm }BGDx%)dV4&0 f,4Khulpb\ӱ 3*Q0iUO([FO;NIED BII0_r1%l%o1v"09.!pkj4XRXpѝ|+6prŘn] n^R# U<!#(8Hiem - [N`J.T҉S" ROhk %8 u >)geQx`.q,qZ"i/e0>UqNJ\x @+rհnahG7yB!(D(̳-X'4f9[6;YP̦t35<]*%[ɇ]@nOD6#Nҽ^0yE^oh0`e;&-@yd(tx)1p'`R^E-5{Ga[_-9TեxL+m8ipV\rXqxE.ձwNupܶ9ycu)فR9:ҨMވj1Yj*!u]$\-l /£y\1i撬=Ls>Qiw`fT0dШimiX&e8TUv"( Eȯ#cpN,z0n2ZwYZP*A oga`@ Q/i -@蝪FZDM©_0 :\ΦuM\ E6V8ք GB@l|ah+Ȱ*Q'lE^fop] sYsnarX" CR%8h 䔥neIp3F0?0 hyv!^fji4eNK[x8Gj f%af/?c/ZK mW?K9A]!fvq-{h4(Q @+ZG嗟v\*,fEl^&8q[LP"rlj4 XZ;B"US l>).&. \P{)pfx2>/¬r/xx/F%Q_L|?!Fc|U_ n](N|B#P86Y蛁#agAEA18A)QxJGr.0T3W*̣]땊)*W IV]w"]Y .VS.9yT(հe3[ķc wTQ!|Nڌ\ZKxE :'v"ۊkUE3F\ g'uk,Q{45JᎾp*4J7rCe./5.a–-OlNF#+Ǹ*Ih+4{ 1%zhS<˛--,[9=S1q12˷`Hsc0S\ U}Y>X.Q)(7+5)Jw3eRkAv`s[@8weg\@5 -L@ o /1pV{Vrhde &Z b{.uu(Ec 72ؖdHg&4S-Ūyfd܊hhrܸw !ouZюoU2;`ٕX+rJRZ=Մُh6\@vąMψ:C0qIP"X9 5~.YT#DS_4\ :|8"OEs; Z*ٰ(G6gBPKߐ|{FdP3JI^ OxfeMܮG@oQ?vnR (cH ؐXm@~@Ǡ¶!EL7=VPUwx `/~1ZsL+F^* (t$SDKXwQ!aPM zŗvpj%=!h8%2FfzEiYBzO &bt hUñ#\+*d/+?nPap!N@F.ɖ{ a(%Ǚ B\b&t}gii[lG&6h<D;~.LӔ|dQ,;X4^kQl̉@5sXv0\#c!(mjYJB<76ŵ1U|. ZKffx3HD9) Icc.#H1e) ֡ܬ$]|O!x3r6c.m&88Hܗ+Dj@о&{0EQJiT8E QM/&g[oFO.[(jX$w$ݰ9:XMҸ!n%U-A@ ƒ6@~ |1H06T^ҎKGh ʦx~ݡ(]Z-Vbfod0'ZWlsC*4)8ahP#I%D\m=4 +>VM'ZHUFKwy](BQk - .2ϔT axUvz.YWX9ʨsacnC@385)_#ꇡNB0]Aġ,=&40 `'qolø ~+ R-]Q*OG4)!⢓B`= JwSU}پ,Xbcn\Me7'VL)bōm!>,ߊ_TA99P)Uce\STF=KpA FB,Xk[.qfgҟqݸjj: >b2m& [;z,0a;b D?3xhX7bʗ%p4{;#._15߷.T;oQq"'kaP^HװE#]F]V=t[)l=%e 3qnz/4; Uh JtFĺS[fV*,XF3Z@Rk4!ayr?˨9.ha a Jހb7<_اH ,uQ2y ;֭C\wz!106,F{y!ώP7D*w+bzIrOܵqK}6dDLO %,Sz')a SK2+%Ĥ7 *%5AЇ k EP8hdR[8-5Ƃ#d:dإJ卛{:[s{O":(d+ R]d] %Up7(EGs]#dǁ%7B›Hdp/w_ kjnY N1򂶷xH׶0 ɿy.W^y px{>!֤mmzT.wuM©!r xw^ݒKUT.5V0Ʌ aq w%Fyfj 7mK Kt'3UL.5,ɿ~mbĜMͳNp=1+f5Chbw\LȆ%$RRM#..9R炇?E!Db(;ɛٹ+x~ѱ&f#׉IND40JD[|/ /N V5T>%4k&]YcnR\,2p+QcK2<nW,̡RȬI6ylu$ |DmfK)-МSeA_æi;?iq&Vjterxc]q,YP\K`'Ld"&l~N +9uCaRmލR&oFpTFW١Z`]۟$uen"e~MYu}@{PmB\:B5( SDgR..)soc`"fy)^P!P:f3%`^J1jwHQ@*a _snpl>eCT S+'{.V U(1PXl@2AZ-|9yiW #O %w3k6afjJ;cM0yJ>FlQAPVS-賠86ja@$Z7eKf:?!k * xB cs̽UJ%+d|M,@ 8{scmÈW-65 KufrԸ K"(!^y?FeW@`lf~zYSg[T3f7@nez]C.0@]r,vX*w2 fj+tUC1^x{Ǹb;OB qG,ޣDEzj-`&lwءy ?gAĴ Cp゠#l 7g1{XU0.m7;0U\.RβUU0 [[Fp\"9@QqAlLveL兘-a+X ~O$Kdǖ:n!WhL؈-֏ܻ/\qR͌ÌZ8}I-jƘ`eK07!% /UɚnT",o(p~P-г&.~cJ#"@&_, ̂°ަe FT 9L o2p 2P+d`hg{vo_1-~cO1TOw K,L栂ޕ&D@u.٬ƊU.}ȚV4dU[pJ|ҖU dX¨̧Yȷ-UhDvѳaR0Y%obQT^pGȈ-K(Jdv -` ûw+D^ NϕR!M_IWGRЂ{ M%jNkFR[;G3 PwZ +/aEu>E#dyVf xXov7$%)ڹG)0zj#AjY mxFū D.2#"vp/p6=s(ܮQ悆X`m7XJȇgq`Ӄmka ̶M)RB`[ &-%kTӪ10q6 0z+#+f#A|$o%C?؏TWLXx؎TY6|Ԫa0@HH0Td ZVeArQ|m"4 >me,5; +DB(lR[̯$ P )BCD\`Mwa97b(&3h[tԁeQx(\$b#Bs 095BEуnWS8)|D=tЕPKh]-MXP2f#Rp:V's0vx<&=uiو# mm  s7M16` KdV(`ef<^ҸL[\"]1ޠ|0<^UycG$9?bˈXrbjhx @RsWKޭ6ЃW,pWf|j KU;\Y^a! M(.Xc*86 er+U'F_<]=q\30C Ҍ9.,Bs 2R͌J4 ǵHÃFYPGÌ3^̗`z3n l I4m̃v7Ohdr5* E& 5`_Mie3%hɉp1Z(k@*E'^<+uɉ]pCL[Y%TlDUt ;V']kp0]& \D(:&iu瘿Hmy/%^& ei-V,))> Z?e[4!ݓb)" W{+eӕ5y2,w,W9zK/B{f­|6 F&p+z{P鵗Rl<3{z*Ux+qa|"ysBu@zYD,9^K5K}P-艔K>f躋y/#2Gdqn` ^ )Kaǔ) \WB-90 ys2[Lfc|H*̭@IK95!t'4L2EM!21 kj92 @L̕ͅv0ӄ11|UpQ79En`1,g'yx (K k!0ґ:ROҞ{Ѐ0md=jEdۮ1 B%j Utn]^cmԤL5,‹cl5Z muzZ wK7uX 1mBO+k0q6L7V` sNa=HC:a4BÁCݿeͿ)y-4F@ H9Y,ړ!|  ,ض\j`(Ja}NNQ t,@q]EBPF.ES-ҡFF4{1-GSIjfuQz|3#3j.Fc8z1hGst옩(.UU 3xc v%,&UxC +B6=ܾOd802›KnnAo}XgF͢cϽ/N?1R>-+u^ ȍxUnC`UQvCw;_pT-0|~ 85[r>V7Jm{>(Ÿ%DSfŨ~ Dq$@ ˂pG8eU&6 xcbC6Y%%%0p!mh+G@a-P2-=ڵ+Mvek,H!*gy3ʀ2r% 3^B6(wP= 4)G4TZEH3V<[A@#!@>)vxa'/cmJ(Pa8^c7}" ʯ+9[/P\@@#PV]QmObC)`ܡ'}PŏiQ'6;h4kY%̳1"![18eq`áYi.D>yFg.Z?aIu`}B_yeVA 7UKA9ؠΎuN.a! *iAM-*F LiĬvܵ~vm>NH`KeSFY3B*cN2F#sw˖䬹AeYZ R\KX{׬v$.k ʿ3Ef֦'W=0T_Kck^n-ZB0\RJ ReA%u5P ɫ ߃ kɹ_l m p,edgS{m{s ,hzki͡y-7͑ m+=)xSp{gG`XJcU9fhbL@4. ng\fgţl~&,&6E-n,&B LejQ Fy4TZ6_RR`t^5 4i棣}9鰘"O,f?LYA˜y]) ]+0gQBI FqU/]ыx0zL)%P3Ig̼.) 12W%\j~JٚK mZal٧a @jWC/71 L+eU,<L5dR,69ơ+Zn? rȌ.+)2CAR#;25< @;=1O67:Y"~5I%]8UċBk0ǥv&Wj8PXJ,68HY;U~SGJ~dꩤyEL֒T/yd ŰǴh18\Rf$Ӝ~V 4l֌*6é<}"u(c xavf ۹:%% %؏sf1#1!oZ_8\`T֮Xg&lC`ULP9MLFt}lk\@+Mʈ1x(K3b-&Ҕj6@`!QV.Xl4>Ax啇6URLD6r7KkԲM/u TDA/k6@Q5QY a*6Xg +nԠ">pK3Q.8qMl.*/G0O`jyߋF[W.<\Tqh8MHY#7]ŀi4"a;qG Nw;%F6FXSWuf1_ht+X9IzJNjS`H+meyb7 1^I_ Zns/ ;-2 Jlo.30.w=_5R(Wph袹L:/1_k6h-# &4@s?PF0R(s'"8NLq5TSHMʱV ᴄ Zv%8jxQ*E,(9EjhةH m7x'.L@lpZ`\Qa,Y,65k6g^ˤe`K>'.Vrfq LJ М6isV*}0Q;Eo)W̒jзm wJ-0%w?A tj7S$q^if.LF  Ma!0ۺOИtèXZ$)g v}m? *>e\Ee>3V>PU߂)v0]ַ0#L9WٌTBq[m_|{㢚Jȵ T[e 8VܬjR^ TF4 hdlcdp b[j^^%L7pzfQ>udAc~tPc3TA¯n{Q2q~ 9VK:T@aL/pL0,L:eo!* Jh.jR󽌤n@>%%%TA.23<Ŏ Vn?fHm1dSLüe^Ⱥ+p2(cظ4myaaZh^:CI䀛unr4$6֌;FXuBzc?3FǵyHr=6?*=Vd'## =1 JeB[oJ(Pji&ܥ[dFTyDP!:S:[Hp@t!?drߕJnʌÍ1=Qh'Q>VXj":ˇTXd@HfX Q7+!~:'J1Fd̞` )hӥ%* )fO  ,%j\-~Fzad3/KYEky'.˦4%\/.<U*4)enlX..>hip&Y@ɔ+TUƌqTńܭm xauyn8ͽ՚fƽRiO7cN <N\O*R\W剪6S^;p+G33FEb{YXU|ehG<" v(T¥1J]!w"81FjUN#-;́?U 2Ytw&#)` $I.@4\JhʔpVXN&Ռ!~ C MC}+
Linux 4gvps.4gvps.com 3.10.0-1127.18.2.vz7.163.46 #1 SMP Fri Nov 20 21:47:55 MSK 2020 x86_64
  SOFT : Apache PHP : 7.4.33
/proc/self/root/usr/share/mysql-test/suite/ndb/t/
38.135.39.45

 
[ NAME ] [ SIZE ] [ PERM ] [ DATE ] [ ACT ]
+FILE +DIR
bug36547.test 0.377 KB -rw-r--r-- 2021-01-05 10:19 R E G D
clusterj.test 1.8 KB -rw-r--r-- 2021-01-05 10:19 R E G D
clusterj_jpa.test 2.461 KB -rw-r--r-- 2021-01-05 10:19 R E G D
disabled.def 0.896 KB -rw-r--r-- 2021-01-05 10:19 R E G D
have_ndb_dist_priv.inc 0.837 KB -rw-r--r-- 2021-01-05 10:19 R E G D
have_ndb_error_insert.inc 0.909 KB -rw-r--r-- 2021-01-05 10:19 R E G D
have_ndbinfo.inc 0.802 KB -rw-r--r-- 2021-01-05 10:19 R E G D
loaddata_autocom_ndb.test 0.096 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_add_partition.test 6.777 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_addnode.cnf 0.648 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_addnode.test 2.176 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table.test 9.604 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table2.test 1.313 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table3.test 1.474 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table_backup.test 1.526 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table_error.test 0.931 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table_online.test 21.472 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table_online2.test 4.824 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_alter_table_online_multi.test 1.92 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_auto_increment.test 11.595 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_autoinc.test 0.627 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_basic.test 20.682 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_bitfield.test 6.332 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_blob.test 17.696 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_blob_big.cnf 0.345 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_blob_big.test 1.618 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_blob_partition.test 4.28 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_bug26793.test 0.823 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_bug31477.test 2.126 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_bug31754.test 0.201 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_bulk_delete.test 3.922 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cache.test 7.92 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cache2.test 11.052 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cache_multi.test 1.888 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cache_multi2.test 4.3 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cache_trans.test 4.643 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_charset.test 6.411 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_column_properties.test 4.484 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_condition_pushdown.test 80.538 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_config.test 3.527 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_config2.test 0.338 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_create_table.test 0.776 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_cursor.test 0.896 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_database.test 2.993 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dbug_lock.test 1.941 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dbug_tc_select.test 3.811 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dbug_tc_select_1.inc 1.835 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dbug_tc_select_2.inc 1.908 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dbug_tc_select_3.inc 2.064 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_alter.test 7.874 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_basic.test 20.168 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_bug12581213.cnf 0.108 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_bug12581213.test 0.361 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_ddl.test 7.37 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_disk2memory.test 10.017 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_dump.test 10.579 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_restore_compat.test 0.927 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dd_sql_features.test 16.136 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_ddl_open_trans.test 2.538 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_disconnect_ddl.test 1.313 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_discover_db-master.opt 0.042 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_discover_db.test 1.878 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_dist_priv.test 7.086 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_gis.test 0.206 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_global_schema_lock.test 3.508 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_global_schema_lock_error.test 1.528 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_grant.later 10.979 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_hidden_pk.test 2.552 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_index.test 11.897 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_index_ordered.test 15.464 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_index_stat.test 9.91 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_index_stat_enable.inc 1.176 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_index_unique.test 14.633 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_init_schema_locks_count.inc 0.221 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_insert.test 36.318 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_join_pushdown.test 110.529 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_jtie.test 0.967 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_limit.test 2.252 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_load.test 2.121 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_loaddatalocal.test 2.43 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_lock.test 5.688 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_lock_table.test 0.277 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_mgm.inc 0.127 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_mgm.test 3.377 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_minmax.test 1.277 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_multi.test 5.786 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_multi_row.test 1.783 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_native_default_support.test 25.474 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_optimize_table.test 2.441 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_optimized_node_selection.test 0.887 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_error.test 1.835 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_error2.test 0.36 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_hash.test 1.529 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_key.test 6.849 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_list.test 2.674 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_partition_range.test 7.905 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_read_multi_range.test 14.601 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_reconnect.test 1.759 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_rename.test 0.838 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_replace.test 3.952 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restart_nostart.inc 0.144 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restart_start.inc 0.127 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_compat_compression-master.opt 0.045 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_compat_compression.test 0.575 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_compat_downward.test 3.991 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_compat_endianness.test 6.68 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_conv_lossy_charbinary.test 16.864 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_conv_lossy_integral.test 22.531 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_conv_padding.test 9.087 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_conv_promotion.test 12.709 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_discover.test 1.717 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_misc.test 23.182 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_print.test 6.817 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_schema_blobs.test 4.263 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_schema_partitions.test 14.934 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_schema_rewrites.test 16.265 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_schema_subsets.test 10.973 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_schema_tolerance.test 6.552 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_restore_undolog.test 16.525 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_row_count.test 2.953 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_row_format.test 1.886 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_schema_locks_count.inc 0.204 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_select_count.test 0.355 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_share.cnf 0.637 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_share.test 9.383 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_short_sigs.cnf 0.166 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_short_sigs.test 2.495 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_show_tables_result.inc 0.55 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_single_user-master.opt 0.031 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_single_user.test 4.758 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_sp.test 0.888 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_sql_allow_batching.test 1.122 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_statistics.inc 3.328 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_statistics0.test 0.227 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_statistics1.test 0.226 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_subquery.test 2.531 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_temporary.test 1.083 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_tmp_table_and_DDL.test 0.384 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_transaction.test 5.763 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_trigger.test 8.771 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_truncate.test 0.775 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_types.test 2.694 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_update.test 2.739 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_update_no_read.test 16.906 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_view.test 0.593 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_wait_nostart.inc 0.101 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_wait_started.inc 0.082 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndb_waiter.inc 0.145 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbapi.test 1.978 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbinfo.test 6.854 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbinfo_cache.test 0.775 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbinfo_create.inc 0.378 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbinfo_drop.inc 0.124 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ndbinfo_dump.test 0.611 KB -rw-r--r-- 2021-01-05 10:19 R E G D
ps_7ndb.test 0.877 KB -rw-r--r-- 2021-01-05 10:19 R E G D
show_attributes.inc 0.648 KB -rw-r--r-- 2021-01-05 10:19 R E G D
show_primary_keys.inc 0.595 KB -rw-r--r-- 2021-01-05 10:19 R E G D
show_varpart.inc 0.744 KB -rw-r--r-- 2021-01-05 10:19 R E G D
strict_autoinc_5ndb.test 0.143 KB -rw-r--r-- 2021-01-05 10:19 R E G D
test_mgmd.cnf 0.227 KB -rw-r--r-- 2021-01-05 10:19 R E G D
test_mgmd.test 0.19 KB -rw-r--r-- 2021-01-05 10:19 R E G D
test_ndbinfo.test 0.224 KB -rw-r--r-- 2021-01-05 10:19 R E G D
REQUEST EXIT
-- source include/have_ndb.inc ######################################## # Define two connections as we want DDL to use its own connection # in order to keep DDL statistics counting out of the way # of the SPJ testing ######################################## connect (spj,localhost,root,,test); connect (ddl,localhost,root,,test); --disable_warnings connection ddl; drop table if exists t1,t2,t3,t4; --enable_warnings ####################################### # Enable ndb$info counters for SPJ block. connection ddl; --source ndbinfo_create.inc connection spj; # Remember all SPJ conters when test started. # Will report and compare the diff. at end of entire test create temporary table spj_counts_at_startup select counter_name, sum(val) as val from ndbinfo.counters where block_name='DBSPJ' group by counter_name; # Save old counter values. let $scan_count_at_startup = query_get_value(show status like 'Ndb_scan_count', Value, 1); let $pruned_scan_count_at_startup = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); let $sorted_scan_count_at_startup = query_get_value(show status like 'Ndb_sorted_scan_count', Value, 1); let $pushed_queries_defined_at_startup = query_get_value(show status like 'Ndb_pushed_queries_defined', Value, 1); let $pushed_queries_dropped_at_startup = query_get_value(show status like 'Ndb_pushed_queries_dropped', Value, 1); let $pushed_queries_executed_at_startup = query_get_value(show status like 'Ndb_pushed_queries_executed', Value, 1); let $pushed_reads_at_startup = query_get_value(show status like 'Ndb_pushed_reads', Value, 1); # Use this table and the two queries below to turn of meassuring # SCAN_ROWS_RETURNED for certain bushy scan queries. The reason for this is # that growth of this counter is platform dependent for these queries. There # are two reasons for this: # 1. Distribution hashing (partitioning) of tables is endian dependent. This # may cause data to be more skewed on some platforms. This again requires more # batches to scan the table and thus more repeats of repeatable scans (i.e. # those that will be repeated for each batch of the other branch of a bushy # scan). This increases the overall scan row count. # 2. If a timer expires in LQH after receiving SCAN_FRAGREQ, LQH may decide to # send SCAN_FRAGCONF immediately, even if more tuples could fit in the batch. # As above this causes more repeats of repeatable scans. create temporary table spj_save_counts like spj_counts_at_startup; insert into spj_save_counts values ('SCAN_ROWS_RETURNED', 0); # Record current counter value. let $save_scan_rows_returned = update spj_save_counts set val = (select sum(val) from ndbinfo.counters where block_name='DBSPJ' and counter_name='SCAN_ROWS_RETURNED') where counter_name='SCAN_ROWS_RETURNED'; # Update spj_counts_at_startup to compensate for counter increments since # running save_scan_rows_returned. let $compensate_scan_rows_returned = update spj_counts_at_startup set val = val + (select sum(val) from ndbinfo.counters where block_name='DBSPJ' and counter_name='SCAN_ROWS_RETURNED') - (select val from spj_save_counts where counter_name='SCAN_ROWS_RETURNED') where counter_name='SCAN_ROWS_RETURNED'; ############## # Test start set @save_ndb_join_pushdown = @@session.ndb_join_pushdown; set ndb_join_pushdown = true; connection ddl; create table t1 ( a int not null, b int not null, c int not null, d int not null, primary key (`a`,`b`) ) engine=ndbcluster; connection spj; insert into t1 values (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4), (1,2,5,1), (1,3,1,2), (1,4,2,3), (2,1,3,4), (2,3,4,5), (2,4,5,1), (3,1,1,2), (3,2,2,3), (3,4,3,4), (4,1,4,5), (4,2,5,1), (4,3,1,2); explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c; # Check that we do not push an operation if this prevents us from using # 'join buffer'. explain extended select straight_join count(*) from t1 as x1 join t1 as x2 on x1.d > x2.a + 1000 join t1 as x3 on x1.c=x3.a and x1.d=x3.b; select straight_join count(*) from t1 as x1 join t1 as x2 on x1.d > x2.a + 1000 join t1 as x3 on x1.c=x3.a and x1.d=x3.b; # Check that we do not push an operation if this prevents us from using # 'join buffer'. explain extended select * from t1 as x1 join t1 as x2 on x1.a=1 and x1.c=x2.a and x1.d=x2.b join t1 as x3 join t1 as x4 where x4.a=x3.c and x4.b=x1.d; --sorted_result select * from t1 as x1 join t1 as x2 on x1.a=1 and x1.c=x2.a and x1.d=x2.b join t1 as x3 join t1 as x4 where x4.a=x3.c and x4.b=x1.d; explain extended select * from t1 left join t1 as t2 on t2.a = t1.b and t2.b = t1.c; --sorted_result select * from t1 left join t1 as t2 on t2.a = t1.b and t2.b = t1.c; explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b; explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c left join t1 as t3 on t3.a = t2.a and t3.b = t2.b; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c left join t1 as t3 on t3.a = t2.a and t3.b = t2.b; explain extended select * from t1 left join t1 as t2 on t2.a = t1.b and t2.b = t1.c left join t1 as t3 on t3.a = t2.a and t3.b = t2.b; --sorted_result select * from t1 left join t1 as t2 on t2.a = t1.b and t2.b = t1.c left join t1 as t3 on t3.a = t2.a and t3.b = t2.b; set ndb_join_pushdown=true; explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d procedure analyse(); explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3 order by t1.c; select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3 order by t1.c; set ndb_join_pushdown=false; explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 2 and t1.b = 3; set ndb_join_pushdown=true; explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; set ndb_join_pushdown=false; explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; select * from t1 left join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a = 1 and t1.b = 1; ## Join as 't1 ALL' -> 't2 RANGE' -> 't3 EQ_REF' ## Possibly joinable starting with 't2 - RANGE' as root. ## However t3's join condition 't3.a = t1.c' refers t1 which is ## outside the scope of current queryplan. The equality set ## should be consulted in order to replace 't1.c' with 't2.a' ## inside the scope set ndb_join_pushdown=true; explain extended select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t1.c and t3.b = t2.b; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t1.c and t3.b = t2.b; ## Join as 'x ALL' -> 'y ALL' -> 'z EQ_REF' ## As Scan vs. scan is not pushable, only y,z is pushed ## However join cond on z refer x which is a ## (pseudo constant) paramValue wrt. the pushed join. ## As we have a dependency on previous rows these ## should not be join cached (ref. HA_PUSH_BLOCK_JOINCACHE) explain extended select straight_join * from (t1 as x cross join t1 as y) join t1 as z on z.a=x.a and z.b=y.b; --sorted_result select straight_join * from (t1 as x cross join t1 as y) join t1 as z on z.a=x.a and z.b=y.b; ## Some variants of the above where t3 has a join conditions in t1 ## where t1 is outside scope of pushed join (as above). However, in ## these tests t3 is also linked with t2 through another join condition. ## This makes t3 join pushable by specifying the value of t1.c as a ## paramValue() explain extended select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 and t2.b = t1.c straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b; --sorted_result select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 and t2.b = t1.c straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b; explain extended select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 and t2.b = t1.c straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b where t1.a=1 and t1.d=1; --sorted_result select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 and t2.b = t1.c straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b where t1.a=1 and t1.d=1; explain extended select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b; --sorted_result select * from t1 straight_join t1 as t2 on t2.a = t1.b+0 straight_join t1 as t3 on t3.a = t1.b and t3.b = t2.b; ## Create a non-ndb table used as a tool to force part of ## a query to be non-pushable. connection ddl; create table t1_myisam ( a int not null, b int not null, c int not null, d int not null, primary key (`a`,`b`) ) engine=myisam; connection spj; insert into t1_myisam values (1,1,1,1), (2,2,1,1), (3,3,1,1), (4,4,1,1); ## Optimizer will use the equality set to replace 't2.a' ## in the term 't3.a = t2.a' with 't1.c' (as 't2.a = t1.c'). ## Furthermore the MyIsam table t1 is const table optimized making ## 't1.c' a const_item. This constant value has not yet been materialized ## into the key_buffer when the definition for the linked query is ## created. However, it is always available through the ## Field defining the KEY_PART of this JT_EQ_REF. ## set ndb_join_pushdown=true; explain extended select * from t1_myisam as t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.a and t3.b = t2.b where t1.a=2 and t1.b=2; --sorted_result select * from t1_myisam as t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.a and t3.b = t2.b where t1.a=2 and t1.b=2; connection ddl; drop table t1_myisam; # # Test scans with filter. These should be pushed as linked operations # where the root operation is a scan *with* a (pushed) filter and a # primary key lookup child operation. # connection spj; set ndb_join_pushdown=true; # Table scan explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.d = 3; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.d = 3; # Ordered index scan explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a > 2 and t1.d = 3; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.a > 2 and t1.d = 3; # Sorted scan of ordered index. explain extended select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.d = 3 order by t1.a; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d where t1.d = 3 order by t1.a; # # Test index scan w/ equal-bounds (low == high) # NOTE: There used to be temp restriction of not allowing ordered # index scans to be pushed. (Has later been lifted) # SQL stmt. are therefore written with pushable JT_REFs from table 2 -> # set ndb_join_pushdown=true; explain extended select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c left join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; --sorted_result select * from t1 left join t1 as t2 on t2.a = t1.c left join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; set ndb_join_pushdown=false; explain extended select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; --sorted_result select * from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; explain extended select * from t1 left join t1 as t2 on t2.a = t1.c left join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; --sorted_result select * from t1 left join t1 as t2 on t2.a = t1.c left join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t1.a = 1 and t1.b = 1; # JT_REF as root operations is now supported as pushed joins set ndb_join_pushdown=true; explain extended select * from t1 as t2 join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t2.a = 1; --sorted_result select * from t1 as t2 join t1 as t3 on t3.a = t2.c and t3.b = t2.d where t2.a = 1; # Test multiparent pushed joins where it is not possible # to find a single common parent by using the equality set # # NOTE: We should take care to join the multiparent linked # table on field refs. not also being refered from other join expr. # as this will make them candidates for equality set replacement. # set ndb_join_pushdown=true; # t3 refer both t1,t2 as parrent. # t1 should be identifed as a grandparent available # through its child t2. explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t2.c and t3.b = t1.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t2.c and t3.b = t1.c; # t4 is pushable iff we force an artificial parental dependency between t2 & t3. explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.c; # t3 is a child of t2 and grandchild of t1 # t4 is a child of t3 and grandchild of t2 explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t2.d join t1 as t4 on t4.a = t3.c and t4.b = t2.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t2.d join t1 as t4 on t4.a = t3.c and t4.b = t2.c; # t3 is a child of t2 and grandchild of t1 # t4 is a child of t3 and grandgrandchild of t1 explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t2.d join t1 as t4 on t4.a = t3.c and t4.b = t1.d; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t2.d join t1 as t4 on t4.a = t3.c and t4.b = t1.d; # Some testcases where t4 is not directly pushable, but # may be made pushable by equality set replacement. # # BEWARE: mysqld optimizer may do its own replacement # before ha_ndbcluster_push analyze the AQP. We therefore # provide multiple similar testcases and hope that # some of them will trigger the replacement code in # ha_ndbcluster_push :-o explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.a and t4.b = t2.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.a and t4.b = t2.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.b and t4.b = t2.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.b and t4.b = t2.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.a; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.a; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.b; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t2.b; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t1.c and t4.b = t2.c; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t1.c and t4.b = t2.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t1.b; --sorted_result select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t4 on t4.a = t3.c and t4.b = t1.b; # Added more multidependency tests; # explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t3x on t3x.a = t3.c and t3x.b = t3.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d join t1 as t3x on t3x.a = t3.c and t3x.b = t3.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; # 't3' is not referred as ancestor and should not be # included in the forced dependencies # (Depends directly on 't1' and can be bushy wrt. to # the other tables) explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d join t1 as t3 on t3.a = t1.c and t3.b = t1.d join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; # 't3' is still independent - see comment above. explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t2x on t2x.a = t2.c and t2x.b = t2.d join t1 as t3 on t3.a = t1.c and t3.b = t1.b join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; ## It should not be possible to force grandparent dependencies ## via a previously outer joined table: explain extended select straight_join * from t1 left join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.c and t3.b = t1.d left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b left join t1 as t3 on t3.a = t1.c and t3.b = t1.d left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; explain extended select straight_join * from t1 left join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.a left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b left join t1 as t3 on t3.a = t1.a left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; explain extended select straight_join * from t1 left join t1 as t2 on t2.a = t1.a and t2.b = t1.b join t1 as t3 on t3.a = t1.a left join t1 as t4 on t4.a = t3.c; explain extended select straight_join * from t1 join t1 as t2 on t2.a = t1.a and t2.b = t1.b left join t1 as t3 on t3.a = t1.a left join t1 as t4 on t4.a = t3.c; # Test a combination of pushed table scan (x, y) # & pushed EQ-bound (indexScan) (z, t1) # This used to give incorrect results with random result for last table (t1) set ndb_join_pushdown=true; explain extended select * from t1 x, t1 y, t1 z, t1 where y.a=x.d and y.b=x.b and z.a=y.d and t1.a = z.d and t1.b=z.b; --sorted_result select * from t1 x, t1 y, t1 z, t1 where y.a=x.d and y.b=x.b and z.a=y.d and t1.a = z.d and t1.b=z.b; # Pushed scanIndex() with (multi-)range: explain extended select * from t1 x, t1 y where x.a <= 2 and y.a=x.d and y.b=x.b; --sorted_result select * from t1 x, t1 y where x.a <= 2 and y.a=x.d and y.b=x.b; explain extended select * from t1 x, t1 y where (x.a <= 2 or x.a > 3) and y.a=x.d and y.b=x.b; --sorted_result select * from t1 x, t1 y where (x.a <= 2 or x.a > 3) and y.a=x.d and y.b=x.b; # 'open' range: explain extended select * from t1 x, t1 y where (x.a >= 2 or x.a < 3) and y.a=x.d and y.b=x.b; --sorted_result select * from t1 x, t1 y where (x.a >= 2 or x.a < 3) and y.a=x.d and y.b=x.b; # Combination of range and 'in' list explain extended select * from t1 x, t1 y where (x.a <= 2 or x.a in (0,5,4)) and y.a=x.d and y.b=x.b; --sorted_result select * from t1 x, t1 y where (x.a <= 2 or x.a in (0,5,4)) and y.a=x.d and y.b=x.b; # Combination of range and 'in' list with exact match # NOTE: Due to simplification in pushed mrr, exact matches are also # executed as range scans explain extended select * from t1 x, t1 y where (x.a <= 2 or (x.a,x.b) in ((0,0),(5,0),(4,3))) and y.a=x.d and y.b=x.b; --sorted_result select * from t1 x, t1 y where (x.a <= 2 or (x.a,x.b) in ((0,0),(5,0),(4,3))) and y.a=x.d and y.b=x.b; # Test ORDER BY expressons # Filesort on pushed joins are not possible as the # read of rows to be filesorted will also prefetch rows from pushed child # operands. These are not cached by the filesort buffer mechanisnm and are # effectively lost. # With pushed joins we either has to: # 1) find a suitable ordered index which we can create an ordered indexscan on # (-> joinType() -> JT_NExT, or type: 'index' w/ explain) # or: # 2) Use a temporary result file for the result, which is then filesort'ed # (-> 'Using temporary; Using filesort') # # Comment1: As 'order by' correctness is part of what we want to test, # '--sorted_result' is *not* specified. Instead we aim at # specifying a deterministic sort ordering in order by list. # # Comment2: 't1.a, t1.b' is appended where required to the order by spec # to get a deterministic sorting order wo/ '--sorted_result' # ## pushed join w/ 'simple order' on non_PK - Need temp table + filesort explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.c,t1.d, t1.a, t1.b; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.c,t1.d, t1.a, t1.b; ## pushed join w/ non-'simple order' on non_PK - Need temp table + filesort explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.c,t2.d, t1.a, t1.b; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.c,t2.d, t1.a, t1.b; ## pushed join w/ 'simple order' on PK - Should use ordered index scan explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a,t1.b; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a,t1.b; ## pushed join w/ non-'simple order' on PK - will need temp table + filesort explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a,t2.b, t1.a, t1.b; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a,t2.b, t1.a, t1.b; ## Descending ordering on PK - use reversed ordered index scan explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a desc,t1.b desc; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a desc,t1.b desc; ## PK column in incorrect order, -> filesort to tempfile explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.b,t1.a; #--sorted_result select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.b,t1.a; ## Explore other permutations of PK columns in ORDER BY clause ## Don't care about the results here.... # Subset of first part of PK -> ordered index scan explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.a; # PK columns not including first part -> filesort to tempfile explain extended select * from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b order by t1.b; ## Similar tests for GROUP BY expression ## PK grouping (or subpart) may be optimized ## by ordered index access. ## explain extended select t1.a, t1.b, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.a, t1.b; --sorted_result select t1.a, t1.b, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.a, t1.b; explain extended select t1.a, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.a; --sorted_result select t1.a, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.a; explain extended select t1.b, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.b; --sorted_result select t1.b, count(*) from t1 join t1 as t2 on t2.a = t1.b and t2.b = t1.c join t1 as t3 on t3.a = t2.a and t3.b = t2.b group by t1.b; explain extended select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 and t2.b=4 group by t2.c; --sorted_result select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 and t2.b=4 group by t2.c; explain extended select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 group by t2.c; --sorted_result select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 group by t2.c; explain extended select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 and t2.b=4 group by t2.c order by t2.c; --sorted_result select t2.c, count(distinct t2.a) from t1 join t1 as t2 on t1.a = t2.c and t1.b = t2.d where t2.a = 4 and t2.b=4 group by t2.c order by t2.c; connection ddl; create table tx like t1; connection spj; insert into tx select x1.a+x2.a*16, x1.b+x2.b*16, x1.c+x2.c*16, x1.d+x2.d*16 from t1 as x1 cross join t1 as x2; # Test of outer join with scan child. # This query should not be pushed. Doing so would produce lots of extra # [.NULL] rows, since the x1.d=x2.d predicate cannot be pushed. explain select count(*) from tx as x1 left join tx as x2 on x1.c=x2.a and x1.d=x2.d; select count(*) from tx as x1 left join tx as x2 on x1.c=x2.a and x1.d=x2.d; connection ddl; drop table tx; # Test bushy join with pruned scan. connection ddl; alter table t1 partition by key(a); connection spj; eval $save_scan_rows_returned; explain select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t1.c; select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t1.c; # Test bushy join with pruned scan and larger result set. connection ddl; CREATE TABLE tx ( a int NOT NULL, PRIMARY KEY (`a`) ); connection spj; delete from t1; insert into tx values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); insert into t1 select 1, x1.a * 10+x2.a, 1, 0 from tx as x1 cross join tx as x2; explain select count(*) from t1 as x1 join t1 as x2 on x2.a = x1.c and x1.b < 2 join t1 as x3 on x3.a = x1.c; select count(*) from t1 as x1 join t1 as x2 on x2.a = x1.c and x1.b < 2 join t1 as x3 on x3.a = x1.c; eval $compensate_scan_rows_returned; connection ddl; drop table t1; drop table tx; # pushed mrr does not yet handle multiple PK operations in same transaction # Need 6.0 result handling stuff to simplify result handling # *** join push is currently dissabled for these **** # connection ddl; create table t1 (a int, b int, primary key(a) using hash) engine = ndb; connection spj; insert into t1 values (1, 2); insert into t1 values (2, 3); insert into t1 values (3, 1); set ndb_join_pushdown=true; explain extended select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b; --sorted_result select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b; connection ddl; drop table t1; # Same case when there is an ordered index on PK connection ddl; create table t1 (a int, b int, primary key(a)) engine = ndb; connection spj; insert into t1 values (1, 2); insert into t1 values (2, 3); insert into t1 values (3, 1); set ndb_join_pushdown=true; explain extended select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b; --sorted_result select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b; ## Adding and 'order by ... desc' trigger the usage ## of QUICK_SELECT_DESC which somehow prepares a ## pushed join as indexscan but ends up executing it as ## primary key access. This (auto-) disables the pushed ## join execution (EXPLAIN still says 'pushdown') which ## should test handling of this in ha_ndbcluster::index_read_pushed() explain extended select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b order by t1.a desc; select * from t1, t1 as t2 where t1.a in (1,3,5) and t2.a = t1.b order by t1.a desc; connection ddl; drop table t1; set ndb_join_pushdown=true; connection ddl; create table t1 (a int, b int, primary key(a)) engine = ndb; create table t2 (c int, d int, primary key(c)) engine = ndb; create table t3 (a3 int, b3 int, c3 int not null, d3 int not null, primary key(a3, b3)) engine = ndb; create table t3_hash (a3 int, b3 int, c3 int not null, d3 int not null, primary key(a3, b3) using hash) engine = ndb; connection spj; insert into t1 values (0x1f, 0x2f); insert into t1 values (0x2f, 0x3f); insert into t1 values (0x3f, 0x1f); insert into t2 values (0x1f, 0x2f); insert into t2 values (0x2f, 0x3f); insert into t2 values (0x3f, 0x1f); insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); insert into t3_hash values (0x1f, 0x2f, 1, 0x1f); insert into t3_hash values (0x2f, 0x3f, 2, 0x2f); insert into t3_hash values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y, t1 where y.a3=x.d3 and y.b3=x.b3 and t1.a = y.d3; --sorted_result select * from t3 x, t3 y, t1 where y.a3=x.d3 and y.b3=x.b3 and t1.a = y.d3; explain extended select * from t3 x, t3 y, t3 z, t3 z2, t1 where y.a3=x.d3 and y.b3=x.b3 and z.a3=y.d3 and z.b3=y.b3 and z2.a3=z.d3 and z2.b3=z.b3 and t1.a = z2.d3; --sorted_result select * from t3 x, t3 y, t3 z, t3 z2, t1 where y.a3=x.d3 and y.b3=x.b3 and z.a3=y.d3 and z.b3=y.b3 and z2.a3=z.d3 and z2.b3=z.b3 and t1.a = z2.d3; # Table expressions wo/ parent-child linkage should *not* be executes as a pushed join: explain extended select straight_join * from t1 x, t1 y where y.a=0x1f and x.b = 0x1f; select straight_join * from t1 x, t1 y where y.a=0x1f and x.b = 0x1f; # NOTE: Due to constValue replacement in equality sets, query below are # effectively the same as the one above. -> Don't push either explain extended select straight_join * from t1 x, t1 y where y.a=x.b and x.b = 0x1f; select straight_join * from t1 x, t1 y where y.a=x.b and x.b = 0x1f; # Tests usage of unique index connection ddl; create unique index t3_d3 on t3(d3); create unique index t3_d3 on t3_hash(d3); commit; connection spj; # Use an unique key to lookup root in pushed join: explain extended select * from t3 x, t3 y where x.d3=31 and y.a3=x.d3 and y.b3=x.b3; select * from t3 x, t3 y where x.d3=31 and y.a3=x.d3 and y.b3=x.b3; # No data-found on unique key lookup root explain extended select * from t3 x, t3 y where x.d3=0 and y.a3=x.d3 and y.b3=x.b3; select * from t3 x, t3 y where x.d3=0 and y.a3=x.d3 and y.b3=x.b3; # Use an unique key to lookup joined child tables explain extended select * from t1 x, t3 y where y.d3=x.b; --sorted_result select * from t1 x, t3 y where y.d3=x.b; # Unique index used both for root lookup and child linkage. explain extended select * from t3 x, t3 y where x.d3=31 and y.d3=x.b3; select * from t3 x, t3 y where x.d3=31 and y.d3=x.b3; # No data-found on unique key lookup child explain extended select * from t3 x, t3 y where x.d3=31 and y.d3=x.c3; select * from t3 x, t3 y where x.d3=31 and y.d3=x.c3; # 'index_merge' between PRIMARY and index t3.d3 # NOTE: currently unhandled explain extended select * from t3 x, t3 y where ((x.a3=0x2f and x.b3=0x3f) or x.d3=0x1f) and (y.a3=x.d3 and y.b3=x.b3); # No 'sorted_result' required as index merge itself sort on PK select * from t3 x, t3 y where ((x.a3=0x2f and x.b3=0x3f) or x.d3=0x1f) and (y.a3=x.d3 and y.b3=x.b3); explain extended select * from t3_hash x, t3_hash y where ((x.a3=0x2f and x.b3=0x3f) or x.d3=0x1f) and (y.a3=x.d3 and y.b3=x.b3); # No 'sorted_result' required as index merge itself sort on PK select * from t3_hash x, t3_hash y where ((x.a3=0x2f and x.b3=0x3f) or x.d3=0x1f) and (y.a3=x.d3 and y.b3=x.b3); # Any ordered index may also be used to scan a 'range' explain extended select * from t3 x, t3 y where x.d3>=31 and y.d3=x.b3; --sorted_result select * from t3 x, t3 y where x.d3>=31 and y.d3=x.b3; # handle "null" key insert into t1 values (0x4f, null); --sorted_result select * from t1 left join t1 as t2 on t2.a = t1.b; connection ddl; drop table t1,t2,t3, t3_hash; ############################### ## Test Primary key and unique key defined 'out of order' ## wrt. the order in which columns was defined in 'create table' connection ddl; create table t3 (a3 int, b3 int, c3 int, d3 int, primary key(b3, a3)) engine = ndb; create table t3_hash (a3 int, b3 int, c3 int, d3 int, primary key(b3,a3) using hash) engine = ndb; create table t3_unq (pk int, a3 int not null, b3 int not null, c3 int, d3 int, primary key(pk) using hash, unique key(b3,a3) using hash) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); insert into t3_hash values (0x1f, 0x2f, 1, 0x1f); insert into t3_hash values (0x2f, 0x3f, 2, 0x2f); insert into t3_hash values (0x3f, 0x1f, 3, 0x3f); insert into t3_unq values (1001, 0x1f, 0x2f, 1, 0x1f); insert into t3_unq values (1002, 0x2f, 0x3f, 2, 0x2f); insert into t3_unq values (1003, 0x3f, 0x1f, 3, 0x3f); ## Table scans (ALL) as pushed root explain extended select * from t3 x, t3 y where y.a3=x.d3 and y.b3=x.b3; --sorted_result select * from t3 x, t3 y where y.a3=x.d3 and y.b3=x.b3; explain extended select * from t3_hash x, t3_hash y where y.a3=x.d3 and y.b3=x.b3; --sorted_result select * from t3_hash x, t3_hash y where y.a3=x.d3 and y.b3=x.b3; explain extended select * from t3_unq x, t3_unq y where y.a3=x.d3 and y.b3=x.b3; --sorted_result select * from t3_unq x, t3_unq y where y.a3=x.d3 and y.b3=x.b3; ## Lookup (eq_ref/const) as pushed root explain extended select * from t3 x, t3 y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; select * from t3 x, t3 y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; explain extended select * from t3_hash x, t3_hash y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; select * from t3_hash x, t3_hash y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; explain extended select * from t3_unq x, t3_unq y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; select * from t3_unq x, t3_unq y where y.a3=x.d3 and y.b3=x.b3 and x.a3=0x2f and x.b3=0x3f; connection ddl; drop table t3, t3_hash, t3_unq; ########### connection ddl; create table t3 (a3 int, b3 int, c3 int, d3 int, primary key(a3), unique key(d3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); insert into t3 values (0x4f, 0, null, null); explain extended select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.d3 left outer join t3 as t3 on t3.a3 = t2.d3; --sorted_result select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.d3 left outer join t3 as t3 on t3.a3 = t2.d3; ## Test usage of nullable unique key column in where clause on pushed parent node explain extended select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 = 47; --sorted_result select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 = 47; explain extended select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 >= 47; --sorted_result select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 >= 47; explain extended select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 is null; --sorted_result select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 is null; explain extended select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 is not null; --sorted_result select * from t3 as t1 left outer join t3 as t2 on t2.d3 = t1.a3 left outer join t3 as t3 on t3.a3 = t2.d3 where t1.d3 is not null; connection ddl; drop table t3; ####### Composite unique keys, 'const' is part of EQ_REF on child nodes #### connection ddl; create table t3 (a3 int not null, b3 int not null, c3 int, d3 int, primary key(a3), unique key(b3,d3), unique key(c3,b3), unique key(c3,d3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); insert into t3 values (0x40, 0, null, null); insert into t3 values (0x41, 0, null, null); insert into t3 values (0x42, 0, 4, null); insert into t3 values (0x43, 0, null, 0x43); ## Baseline: Not pushed as only one of the columns in unique indexes are REF'ed explain extended select straight_join * from t3 as x join t3 as y on x.b3 = y.b3; --sorted_result select straight_join * from t3 as x join t3 as y on x.b3 = y.b3; ## Extend query above with 'where ' explain extended select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f; --sorted_result select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f; explain extended select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.d3 = 0x2f; --sorted_result select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.d3 = 0x2f; explain extended select straight_join * from t3 as x join t3 as y on x.d3 = y.d3 where y.b3 = 0x2f; --sorted_result select straight_join * from t3 as x join t3 as y on x.d3 = y.d3 where y.b3 = 0x2f; explain extended select straight_join * from t3 as x join t3 as y on x.d3 = y.d3 where y.b3 = 0x20+0x2f; --sorted_result select straight_join * from t3 as x join t3 as y on x.d3 = y.d3 where y.b3 = 0x20+0x2f; ## Not pushable as 'not null' is actually not a single const value explain extended select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 is not null; --sorted_result select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 is not null; ## Neither 'is null' pushable as uniqueness is not defined for null ## ... and null's are not present in the unique index explain extended select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 is null; --sorted_result select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 is null; explain extended select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.b3 = 0; --sorted_result select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.b3 = 0; ## As 'b3' is defined as 'not null', this query will optimized as 'Impossible WHERE' (No push) explain extended select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.b3 is null; --sorted_result select straight_join * from t3 as x join t3 as y on x.c3 = y.c3 where y.b3 is null; ## Will break up query in 2 pushed joins. ## Last join (join t3 as y2) refer x1.c3 which will ## be handled as a constant paramValue wrt. scope of the ## second pushed join. explain extended select straight_join * from t3 as x1 join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3 join t3 as x2 on x2.b3 = y1.b3 join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3; --sorted_result select straight_join * from t3 as x1 join t3 as y1 on x1.b3 = y1.b3 and x1.d3 = y1.d3 join t3 as x2 on x2.b3 = y1.b3 join t3 as y2 on y2.b3 = x2.c3 and y2.d3 = x1.c3; ########################### ### Prepared statments #### ########################### prepare stmt1 from 'select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f'; #execute multiple times execute stmt1; execute stmt1; # Execute after drop expected to fail drop prepare stmt1; --error 1243 execute stmt1; # Multiple prepare of same stmt should silently discard prev prepared stmt prepare stmt1 from 'select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f'; prepare stmt1 from 'select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f'; drop prepare stmt1; #Prepare explain'ed statement and execute it prepare stmt1 from 'explain select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = 0x2f'; execute stmt1; execute stmt1; #survives commit; commit; execute stmt1; # Drop index used by query -> Query plan should change to unpushed join connection ddl; drop index b3 on t3; connection spj; execute stmt1; # Then recreate it -> original query plan connection ddl; create unique index b3 on t3(b3,d3); connection spj; execute stmt1; drop prepare stmt1; ### Prepared stmt with dynamic parameters ('?') ### prepare stmt1 from 'explain select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = ?'; set @a=47; execute stmt1 using @a; set @a=0; execute stmt1 using @a; set @a=null; execute stmt1 using @a; prepare stmt1 from 'select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 where y.d3 = ?'; set @a=47; execute stmt1 using @a; set @a=0; execute stmt1 using @a; set @a=null; execute stmt1 using @a; prepare stmt1 from 'explain select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 and x.d3 = y.d3 where x.a3 = ?'; set @a=47; execute stmt1 using @a; set @a=0; execute stmt1 using @a; set @a=null; execute stmt1 using @a; prepare stmt1 from 'select straight_join * from t3 as x join t3 as y on x.b3 = y.b3 and x.d3 = y.d3 where x.a3 = ?'; set @a=47; execute stmt1 using @a; set @a=0; execute stmt1 using @a; set @a=null; execute stmt1 using @a; connection ddl; drop table t3; connection spj; # Execute after table dropped should fail set @a=47; --error 1146 execute stmt1 using @a; #################### # test index scan disguised as JT_ALL connection ddl; create table t1 (a int primary key, b int, c int, index(b,c)) engine = ndb; connection spj; insert into t1 values (1,null, 2); insert into t1 values (2,1, null); insert into t1 values (3,2,2); insert into t1 values (4,null, 2); insert into t1 values (5,1, null); insert into t1 values (6,2,2); set ndb_join_pushdown=false; --sorted_result select * from t1 join t1 as t2 on (t2.b = t1.b or t2.b = t1.a) join t1 as t3 on t3.a = t2.a join t1 as t4 on t4.a = t3.b; set ndb_join_pushdown=true; explain extended select * from t1 join t1 as t2 on (t2.b = t1.b or t2.b = t1.a) join t1 as t3 on t3.a = t2.a join t1 as t4 on t4.a = t3.b; --sorted_result select * from t1 join t1 as t2 on (t2.b = t1.b or t2.b = t1.a) join t1 as t3 on t3.a = t2.a join t1 as t4 on t4.a = t3.b; ## Test subquery execution where 'Full scan on null key' strategy requires ## table scan execution in addition to the key lookup which was prepared ## as part of the pushed join NdbQuery explain extended select * from t1 where b in (select x.a from t1 as x join t1 as y on (y.a = x.b)) xor c > 5; --sorted_result select * from t1 where b in (select x.a from t1 as x join t1 as y on (y.a = x.b)) xor c > 5; ############## ## Subqueries with EQ_REFs in subquery containing an outer referrences ## to 't1.b' should not be pushed as outer referrences are outside ## the scope of our JOIN_TAB's ############## explain extended select t1.a, (select straight_join x.a from t1 as x join t1 as y on x.a=y.b where y.a = t1.b) from t1; --sorted_result select t1.a, (select straight_join x.a from t1 as x join t1 as y on x.a=y.b where y.a = t1.b) from t1; connection ddl; drop table t1; # mixed engines connection ddl; create table t1 (a int primary key, b int) engine = ndb; create table t2 (a int primary key, b int) engine = myisam; connection spj; insert into t1 values(1,1), (2,2), (3,3), (4,4); insert into t2 values(1,1), (2,2), (3,3), (4,4); explain extended select * from t1, t2, t1 as t3 where t2.a = t1.b and t3.a = t2.b; --sorted_result select * from t1, t2, t1 as t3 where t2.a = t1.b and t3.a = t2.b; connection ddl; drop table t1, t2; # Tables with blob, but not in the selected columns: connection ddl; create table t1 (a int primary key, b int, c blob) engine = ndb; create table t2 (a int primary key, b int) engine = ndb; connection spj; insert into t1 values (1,1, 'kalle'); insert into t1 values (2,1, 'kalle'); insert into t1 values (3,3, 'kalle'); insert into t1 values (4,1, 'kalle'); insert into t2 values (1,1); insert into t2 values (2,1); insert into t2 values (3,3); insert into t2 values (4,1); set ndb_join_pushdown=true; explain extended select t1.a, t1.b, t2.a, t2.b from t1, t2 where t2.a = t1.b; --sorted_result select t1.a, t1.b, t2.a, t2.b from t1, t2 where t2.a = t1.b; explain extended select t1.a, t1.b, t2.a, t2.b from t1, t2 where t2.a = t1.b and t1.a = 2; --sorted_result select t1.a, t1.b, t2.a, t2.b from t1, t2 where t2.a = t1.b and t1.a = 2; explain extended select t1.a, t1.b, t2.a, t2.b from t1, t2 where t1.a = t2.b; --sorted_result select t1.a, t1.b, t2.a, t2.b from t1, t2 where t2.a = t1.b; explain extended select t1.a, t1.b, t2.a, t2.b from t1, t2 where t1.a = t2.b and t2.a = 3; --sorted_result select t1.a, t1.b, t2.a, t2.b from t1, t2 where t1.a = t2.b and t2.a = 3; # # result sets contain blob # i.e no push explain extended select * from t1, t2 where t2.a = t1.b; --sorted_result select * from t1, t2 where t2.a = t1.b; explain extended select * from t1, t2 where t2.a = t1.b and t1.a = 2; --sorted_result select * from t1, t2 where t2.a = t1.b and t1.a = 2; explain extended select * from t1, t2 where t1.a = t2.b; --sorted_result select * from t1, t2 where t2.a = t1.b; explain extended select * from t1, t2 where t1.a = t2.b and t2.a = 3; --sorted_result select * from t1, t2 where t1.a = t2.b and t2.a = 3; connection ddl; drop table t1, t2; ## Test usage of a constValue() as part of the EQ_REF key relating a child operation ## with its previous parents. ## All datatypes are tested in the section below ## connection ddl; create table t3 (a3 int, b3 tinyint, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3="63"; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3="63"; connection ddl; drop table t3; create table t3 (a3 int, b3 tinyint unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 smallint, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 smallint unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 mediumint, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 mediumint unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 int, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 int unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 bigint, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 bigint unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=(60+3); connection ddl; drop table t3; create table t3 (a3 int, b3 boolean, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0, 1, 0x1f); insert into t3 values (0x2f, 1, 2, 0x2f); insert into t3 values (0x3f, 0, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=1; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=1; connection ddl; drop table t3; create table t3 (a3 int, b3 float, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 2.71, 1, 0x1f); insert into t3 values (0x2f, 3.00, 2, 0x2f); insert into t3 values (0x3f, 0.50, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0; connection ddl; drop table t3; create table t3 (a3 int, b3 float unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 2.71, 1, 0x1f); insert into t3 values (0x2f, 3.00, 2, 0x2f); insert into t3 values (0x3f, 0.50, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.0; connection ddl; drop table t3; create table t3 (a3 int, b3 double, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 2.71, 1, 0x1f); insert into t3 values (0x2f, 3.14, 2, 0x2f); insert into t3 values (0x3f, 0.50, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; connection ddl; drop table t3; create table t3 (a3 int, b3 double unsigned, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 2.71, 1, 0x1f); insert into t3 values (0x2f, 3.14, 2, 0x2f); insert into t3 values (0x3f, 0.50, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; connection ddl; drop table t3; create table t3 (a3 int, b3 decimal, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=63; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=63; connection ddl; drop table t3; create table t3 (a3 int, b3 decimal(12,4), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 2.71, 1, 0x1f); insert into t3 values (0x2f, 3.14, 2, 0x2f); insert into t3 values (0x3f, 0.50, 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3=3.14; connection ddl; drop table t3; create table t3 (a3 int, b3 date, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, '1905-05-17', 1, 0x1f); insert into t3 values (0x2f, '2000-02-28', 2, 0x2f); insert into t3 values (0x3f, '2000-02-29', 3, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28'; connection ddl; drop table t3; create table t3 (a3 int, b3 datetime, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, '1905-05-17 12:30:00', 1, 0x1f); insert into t3 values (0x2f, '2000-02-28 23:59:00', 2, 0x2f); insert into t3 values (0x3f, '2000-02-29 12:59:59', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28 23:59'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='2000-02-28 23:59'; connection ddl; drop table t3; create table t3 (a3 int, b3 time, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, '12:30:00', 1, 0x1f); insert into t3 values (0x2f, '23:59:00', 2, 0x2f); insert into t3 values (0x3f, '12:59:59', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='23:59'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='23:59'; connection ddl; drop table t3; create table t3 (a3 int, b3 char(16), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 'Ole', 1, 0x1f); insert into t3 values (0x2f, 'Dole', 2, 0x2f); insert into t3 values (0x3f, 'Doffen', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; connection ddl; drop table t3; create table t3 (a3 int, b3 varchar(16), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 'Ole', 1, 0x1f); insert into t3 values (0x2f, 'Dole', 2, 0x2f); insert into t3 values (0x3f, 'Doffen', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; connection ddl; drop table t3; create table t3 (a3 int, b3 varchar(512), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 'Ole', 1, 0x1f); insert into t3 values (0x2f, 'Dole', 2, 0x2f); insert into t3 values (0x3f, 'Doffen', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; connection ddl; drop table t3; create table t3 (a3 int, b3 binary(16), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 'Ole', 1, 0x1f); insert into t3 values (0x2f, 'Dole', 2, 0x2f); insert into t3 values (0x3f, 'Doffen', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; connection ddl; drop table t3; create table t3 (a3 int, b3 varbinary(16), c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 'Ole', 1, 0x1f); insert into t3 values (0x2f, 'Dole', 2, 0x2f); insert into t3 values (0x3f, 'Doffen', 2, 0x3f); explain extended select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; select * from t3 x, t3 y where x.a3=0x2f and y.a3=x.d3 and y.b3='Dole'; connection ddl; drop table t3; ## Joins where the datatype of the EQ_REF columns are not identical ## should not be pushed ## connection ddl; create table t3 (a3 int, b3 tinyint, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values (0x1f, 0x2f, 1, 0x1f); insert into t3 values (0x2f, 0x3f, 2, 0x2f); insert into t3 values (0x3f, 0x1f, 3, 0x3f); explain extended select * from t3 x, t3 y where y.a3=x.b3 and y.b3="63"; select * from t3 x, t3 y where y.a3=x.b3 and y.b3="63"; connection ddl; drop table t3; ## ## Testing of varchar datatype as part of lookup key and index bounds. ## Need special attention due to the 'ShrinkVarchar' format used by mysqld. connection ddl; create table t3 (a3 varchar(16), b3 int, c3 int not null, d3 int not null, primary key(a3,b3)) engine = ndb; connection spj; insert into t3 values ('Ole', 0x1f, 1, 0x1f); insert into t3 values ('Dole', 0x2f, 2, 0x2f); insert into t3 values ('Doffen', 0x3f, 2, 0x3f); # Varchar is lookup key explain extended select * from t3 x, t3 y where x.a3='Dole' and x.b3=0x2f and y.a3=x.a3 and y.b3=x.d3; select * from t3 x, t3 y where x.a3='Dole' and x.b3=0x2f and y.a3=x.a3 and y.b3=x.d3; # Varchar as hi/low bound explain extended select * from t3 x, t3 y where x.a3='Dole' and y.a3=x.a3 and y.b3=x.d3; select * from t3 x, t3 y where x.a3='Dole' and y.a3=x.a3 and y.b3=x.d3; connection ddl; drop table t3; connection ddl; create table t1 (k int primary key, b int) engine = ndb; connection spj; insert into t1 values (1,1), (2,1), (3,1), (4,1); ## Pushed join driven by a scan, with cached row lookups: ## (Note: We force the Scan to not be pushed as the parent op ## by making the join condition on t2 a non-FIELD_ITEM ('t1.b+0') ## As all column 'b' has the same value (1), the scan will refer ## the same t2 (parent) row in every access. This will trigger the ## row caching in join_read_key() where we eliminate redundant lookups ## where 'next row == current row'. In order to work for linked operations, ## the value and status for all linked tables should be kept unaltered. explain extended select * from t1 straight_join t1 as t2 on t2.k = t1.b+0 straight_join t1 as t3 on t3.k = t2.b straight_join t1 as t4 on t4.k = t1.b; --sorted_result select * from t1 straight_join t1 as t2 on t2.k = t1.b+0 straight_join t1 as t3 on t3.k = t2.b straight_join t1 as t4 on t4.k = t1.b; ## Similar example as above, except that access to 't2' is made ## a const table access explain extended select * from t1 straight_join t1 as t2 on t2.k = t1.b+0 straight_join t1 as t3 on t3.k = t2.b straight_join t1 as t4 on t4.k = t1.b where t2.k = 1; --sorted_result select * from t1 straight_join t1 as t2 on t2.k = t1.b+0 straight_join t1 as t3 on t3.k = t2.b straight_join t1 as t4 on t4.k = t1.b where t2.k = 1; connection ddl; drop table t1; ## # Try with higher row-count to test batching/flow control # connection ddl; create table t1 ( a int not null auto_increment, b char(255) not null, c int not null, d char(255) not null, primary key (`a`,`b`) ) engine=ndbcluster; connection spj; let $1=1000; disable_query_log; while ($1) { eval insert into t1(a,b,c,d) values ($1, 'a', $1, 'a'),($1, 'b', $1+1, 'b'),($1, 'c', $1-1, 'c'); dec $1; } enable_query_log; explain extended select count(*) from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.c and t3.b = t2.d; select count(*) from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.c and t3.b = t2.d; explain extended select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d; select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d; explain extended select count(*) from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.c; select count(*) from t1 join t1 as t2 on t2.a = t1.c and t2.b = t1.d join t1 as t3 on t3.a = t2.c; connection ddl; alter table t1 partition by key(a); connection spj; explain extended select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d; select count(*) from t1 join t1 as t2 on t2.a = t1.c join t1 as t3 on t3.a = t2.c and t3.b = t2.d; connection ddl; drop table t1; # Pushed join accessing disk data. connection ddl; create logfile group lg1 add undofile 'undofile.dat' initial_size 1m undo_buffer_size = 1m engine=ndb; create tablespace ts1 add datafile 'datafile.dat' use logfile group lg1 initial_size 6m engine ndb; create table t1 (a int not null, b int not null storage disk, c int not null storage memory, primary key(a)) tablespace ts1 storage disk engine = ndb; connection spj; insert into t1 values (10, 11, 11); insert into t1 values (11, 12, 12); insert into t1 values (12, 13, 13); connection ddl; create table t2 (a int not null, b int not null, primary key(a)) engine = ndb; connection spj; insert into t2 values (10, 11); insert into t2 values (11, 12); insert into t2 values (12, 13); # Disk data in projection of first op. explain extended select * from t1, t2 where t1.c = t2.a; --sorted_result select * from t1, t2 where t1.c = t2.a; explain extended select * from t1, t2 where t1.a=11 and t1.c = t2.a; select * from t1, t2 where t1.a=11 and t1.c = t2.a; # Disk data in projection of second op. explain extended select * from t2, t1 where t2.b = t1.a; --sorted_result select * from t2, t1 where t2.b = t1.a; explain extended select * from t2, t1 where t2.a=11 and t2.b = t1.a; select * from t2, t1 where t2.a=11 and t2.b = t1.a; # Disk data in predicate but not in projection explain extended select t1.a, t1.c, t2.a, t2.b from t1, t2 where t1.b = t2.a; --sorted_result select t1.a, t1.c, t2.a, t2.b from t1, t2 where t1.b = t2.a; explain extended select t1.a, t1.c, t2.a, t2.b from t1, t2 where t1.a=11 and t1.b = t2.a; select t1.a, t1.c, t2.a, t2.b from t1, t2 where t1.a=11 and t1.b = t2.a; connection ddl; drop table t1; drop table t2; alter tablespace ts1 drop datafile 'datafile.dat' engine ndb; drop tablespace ts1 engine ndb; drop logfile group lg1 engine ndb; connection spj; # Store old counter values. connection ddl; create temporary table old_count select counter_name, sum(val) as val from ndbinfo.counters where block_name='DBSPJ' group by counter_name; connection ddl; create table t1 (a int not null, b int not null, c int not null, primary key(a)) engine = ndb; connection spj; # We use key values that have the same representation in little and big endian. # Otherwise, the numbers for local and remote reads may depend on endian-ness, # since hashing is endian dependent. insert into t1 values (1, 2, 2); insert into t1 values (2, 3, 3); insert into t1 values (3, 4, 4); # Run some queries that should increment the counters. select * from t1 t1, t1 t2 where t1.a = 2 and t2.a = t1.b; select count(*) from t1 t1, t1 t2 where t2.a = t1.b; select count(*) from t1 t1, t1 t2 where t1.a >= 2 and t2.a = t1.b; # Get new counter values. connection ddl; create temporary table new_count select counter_name, sum(val) as val from ndbinfo.counters where block_name='DBSPJ' group by counter_name; # Compute the difference. --sorted_result select new_count.counter_name, new_count.val - old_count.val from new_count, old_count where new_count.counter_name = old_count.counter_name and new_count.counter_name <> 'LOCAL_READS_SENT' and new_count.counter_name <> 'REMOTE_READS_SENT'; select 'READS_SENT', sum(new_count.val - old_count.val) from new_count, old_count where new_count.counter_name = old_count.counter_name and (new_count.counter_name = 'LOCAL_READS_SENT' or new_count.counter_name = 'REMOTE_READS_SENT'); connection ddl; drop table old_count; drop table new_count; drop table t1; ### Test that scan filters are used for pushed operations. connection ddl; create table t1 ( a int primary key, b int, c int) engine = ndb; connection spj; insert into t1 values (1, 2, 3); insert into t1 values (2, 3, 4); insert into t1 values (3, 4, 5); # Find the total number of lookups issued by the SPJ blocks. let $spj_lookups = query_get_value(select sum(val) as Value from ndbinfo.counters where block_name='DBSPJ' and (counter_name='LOCAL_READS_SENT' or counter_name='REMOTE_READS_SENT'), Value, 1); # Root scan should give only one tuple if scan filter is pushed. # Therefore only one lookup on 'y'. explain extended select * from t1 x, t1 y where x.b=y.a and x.c=4; select * from t1 x, t1 y where x.b=y.a and x.c=4; --disable_query_log --eval select sum(val) - $spj_lookups as lookups from ndbinfo.counters where block_name='DBSPJ' and (counter_name='LOCAL_READS_SENT' or counter_name='REMOTE_READS_SENT') --enable_query_log # Lookup on y should only give one result tuple if filter is pushed. # This should give 3 lookups on 'y' and 1 on 'z', 4 in all. explain extended select * from t1 x, t1 y, t1 z where x.b=y.a and y.c=4 and y.b=z.a; select * from t1 x, t1 y, t1 z where x.b=y.a and y.c=4 and y.b=z.a; --disable_query_log --eval select sum(val) - $spj_lookups as lookups from ndbinfo.counters where block_name='DBSPJ' and (counter_name='LOCAL_READS_SENT' or counter_name='REMOTE_READS_SENT') --enable_query_log connection ddl; drop table t1; # Test and server status variables (i.e. mysqld counters) connection ddl; create table t1( a int not null, b int not null, c int not null, primary key(a,b)) engine = ndb partition by key (a); connection spj; insert into t1 values (10, 10, 11); insert into t1 values (11, 11, 12); insert into t1 values (12, 12, 13); # First query against a new table causes an extra scan (of a dictionaty table??) # so adding an extra scan here to make results from the following part easier # to interpret. select * from t1 t1, t1 t2 where t1.a = 10 and t1.b = 10 and t2.a = t1.c and t2.b = t1.c; # Save old counter values. let $old_scan_count = query_get_value(show status like 'Ndb_scan_count', Value, 1); let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); let $old_sorted_scan_count = query_get_value(show status like 'Ndb_sorted_scan_count', Value, 1); let $old_pushed_queries_defined = query_get_value(show status like 'Ndb_pushed_queries_defined', Value, 1); let $old_pushed_queries_dropped = query_get_value(show status like 'Ndb_pushed_queries_dropped', Value, 1); let $old_pushed_queries_executed = query_get_value(show status like 'Ndb_pushed_queries_executed', Value, 1); let $old_pushed_reads = query_get_value(show status like 'Ndb_pushed_reads', Value, 1); # Run some queries that should increment the counters. # This query should push a single read. select * from t1 t1, t1 t2 where t1.a = 11 and t1.b = 11 and t2.a = t1.c and t2.b = t1.c; # This query should push a sorted scan (and three reads). select * from t1 t1, t1 t2 where t2.a = t1.c and t2.b = t1.c order by t1.a; # This query should push a pruned scan (but pruning must be fixed for # pushed scans.) select count(*) from t1 t1, t1 t2 where t1.a = 11 and t2.a = t1.c and t2.b = t1.c; # Get the new values; let $new_scan_count = query_get_value(show status like 'Ndb_scan_count', Value, 1); let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); let $new_sorted_scan_count = query_get_value(show status like 'Ndb_sorted_scan_count', Value, 1); let $new_pushed_queries_defined = query_get_value(show status like 'Ndb_pushed_queries_defined', Value, 1); let $new_pushed_queries_dropped = query_get_value(show status like 'Ndb_pushed_queries_dropped', Value, 1); let $new_pushed_queries_executed = query_get_value(show status like 'Ndb_pushed_queries_executed', Value, 1); let $new_pushed_reads = query_get_value(show status like 'Ndb_pushed_reads', Value, 1); # Calculate the change. --disable_query_log --eval select $new_scan_count - $old_scan_count as scan_count --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count --eval select $new_sorted_scan_count - $old_sorted_scan_count as sorted_scan_count --eval select $new_pushed_queries_defined - $old_pushed_queries_defined as pushed_queries_defined --eval select $new_pushed_queries_dropped - $old_pushed_queries_dropped as pushed_queries_dropped --eval select $new_pushed_queries_executed - $old_pushed_queries_executed as pushed_queries_executed --eval select $new_pushed_reads - $old_pushed_reads as pushed_reads --enable_query_log connection ddl; drop table t1; # Test scan pruning connection ddl; create table t1( d int not null, c int not null, a int not null, b int not null, primary key using hash (a,b)) engine = ndb partition by key (a); connection spj; insert into t1(a,b,c,d) values (10, 10, 11, 11); insert into t1(a,b,c,d) values (11, 11, 12, 12); insert into t1(a,b,c,d) values (12, 12, 13, 13); let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); # Should give pruned scan. connection ddl; create index i1 on t1(c,a); connection spj; explain extended select count(*) from t1 t1, t1 t2 where t1.c = 12 and t1.a = 11 and t2.a = t1.d and t2.b = t1.d; select count(*) from t1 t1, t1 t2 where t1.c = 12 and t1.a = 11 and t2.a = t1.d and t2.b = t1.d; connection ddl; drop index i1 on t1; connection spj; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log # Should give pruned scan. There is a one sided limit for t1.b, but this is # after the partition key prefix. connection ddl; create index i2 on t1(a,b); connection spj; explain extended select count(*) from t1 t1, t1 t2 where t1.a = 11 and t1.b<13 and t2.a = t1.c and t2.b = t1.c; select count(*) from t1 t1, t1 t2 where t1.a = 11 and t1.b<13 and t2.a = t1.c and t2.b = t1.c; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log # Should give pruned scan. Upper and lower bounds for t1.a are the sane. explain extended select count(*) from t1 t1, t1 t2 where t1.a >= 12 and t1.a<=12 and t2.a = t1.c and t2.b = t1.c; select count(*) from t1 t1, t1 t2 where t1.a >= 12 and t1.a<=12 and t2.a = t1.c and t2.b = t1.c; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log # Should not give pruned scan. Upper and lower bounds for t1.a are different. explain extended select count(*) from t1 t1, t1 t2 where t1.a >= 11 and t1.a<=12 and t2.a = t1.c and t2.b = t1.c; select count(*) from t1 t1, t1 t2 where t1.a >= 11 and t1.a<=12 and t2.a = t1.c and t2.b = t1.c; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log # Should not give pruned scan. There will be two sets of bounds that have # different distribution keys (t1.a=10 and t1.a=12). explain extended select count(*) from t1 t1, t1 t2 where (t1.a = 10 or t1.a=12) and t1.b<13 and t2.a = t1.c and t2.b = t1.c; select count(*) from t1 t1, t1 t2 where (t1.a = 10 or t1.a=12) and t1.b<13 and t2.a = t1.c and t2.b = t1.c; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log # Should give pruned scan. There will be two sets of bounds, but they have the # same distribution key. explain extended select count(*) from t1 t1, t1 t2 where t1.a = 10 and (t1.b<11 or t1.b>11) and t2.a = t1.c and t2.b = t1.c; select count(*) from t1 t1, t1 t2 where t1.a = 10 and (t1.b<11 or t1.b>11) and t2.a = t1.c and t2.b = t1.c; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log connection ddl; drop table t1; create table t2( d int not null, e int not null, f int not null, a int not null, b int not null, c int not null, primary key using hash (a,b,c)) engine = ndb partition by key (b,a); connection spj; insert into t2(a,b,c,d,e,f) values (1, 2, 3, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (1, 2, 4, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (2, 3, 4, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (3, 4, 5, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (4, 5, 6, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (5, 6, 7, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (6, 7, 8, 1, 2, 3); insert into t2(a,b,c,d,e,f) values (7, 8, 9, 1, 2, 3); connection ddl; create index i2_1 on t2(d, a, b, e); connection spj; # Should give pruned scan. The index prefix containing the distribution key # has a single possible value. explain extended select count(*) from t2 x, t2 y where x.d=1 and x.a=1 and x.b=2 and y.a=x.d and y.b=x.e and y.c=3; select count(*) from t2 x, t2 y where x.d=1 and x.a=1 and x.b=2 and y.a=x.d and y.b=x.e and y.c=3; connection spj; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count let $old_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --enable_query_log connection ddl; drop index i2_1 on t2; create index i2_3 on t2(a, d, b, e); # Should give pruned scan. The index prefix containing the distribution key # has a single possible value. connection spj; explain extended select count(*) from t2 x, t2 y where x.d=1 and x.a=1 and x.b=2 and y.a=x.d and y.b=x.e and y.c=3; select count(*) from t2 x, t2 y where x.d=1 and x.a=1 and x.b=2 and y.a=x.d and y.b=x.e and y.c=3; --disable_query_log let $new_pruned_scan_count = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); --eval select $new_pruned_scan_count - $old_pruned_scan_count as pruned_scan_count --enable_query_log connection ddl; drop table t2; connection ddl; create table t1 (a binary(10) primary key, b binary(10) not null) engine = ndb; connection spj; insert into t1 values ('\0123456789', '1234567890'); insert into t1 values ('1234567890', '\0123456789'); explain extended select count(*) from t1 join t1 as t2 on t2.a = t1.b where t1.a = '\0123456789'; select count(*) from t1 join t1 as t2 on t2.a = t1.b where t1.a = '\0123456789'; connection ddl; drop table t1; # Tests for some bugfixes which have been cherry picked from 5.1 main # Not necessarily test of SPJ functionality, but may test optimizer # behaviour which we depend on when doing RQG testing # We can remove these testcases when fixes - and propper MTR testcases - # Have been merged from 5.1 main branch. connection ddl; create table t1 (pk int primary key, a int unique key) engine = ndb; connection spj; insert into t1 values (1,10), (2,20), (3,30); set ndb_join_pushdown = false; # Bug#53334: # Join should be optimized as 'Impossible On condition' # ... *not* 'Impossible WHERE' explain extended select * from t1 as x right join t1 as y on x.pk = y.pk and x.pk = y.a and x.a = y.pk where y.pk = 2; select * from t1 as x right join t1 as y on x.pk = y.pk and x.pk = y.a and x.a = y.pk where y.pk = 2; set ndb_join_pushdown = true; explain extended select * from t1 as x right join t1 as y on x.pk = y.pk and x.pk = y.a and x.a = y.pk where y.pk = 2; select * from t1 as x right join t1 as y on x.pk = y.pk and x.pk = y.a and x.a = y.pk where y.pk = 2; connection ddl; drop table t1; ######################################### # Test section for scan-child operations ######################################### # Test scan-lookup-scan query (see http://lists.mysql.com/commits/115164) connection ddl; create table t1 (pk int primary key, u int not null, a int, b int) engine=ndb; create index ix1 on t1(b,a); connection spj; insert into t1 values (0,1,10,20); insert into t1 values (1,2,20,30); insert into t1 values (2,3,30,40); explain extended select * from t1 as x join t1 as y join t1 as z on x.u=y.pk and y.a=z.b; --sorted_result select * from t1 as x join t1 as y join t1 as z on x.u=y.pk and y.a=z.b; connection ddl; drop table t1; # Test sorted scan where inner join eliminates all rows (known regression). connection ddl; create table t1 (pk int primary key, u int not null) engine=ndb; connection spj; insert into t1 values (0,-1), (1,-1), (2,-1), (3,-1), (4,-1), (5,-1), (6,-1), (7,-1), (8,-1), (9,-1), (10,-1), (11,-1), (12,-1), (13,-1), (14,-1), (15,-1), (16,-1), (17,-1), (18,-1), (19,-1), (20,-1), (21,-1), (22,-1), (23,-1), (24,-1), (25,-1), (26,-1), (27,-1), (28,-1), (29,-1), (30,-1), (31,-1), (32,-1), (33,-1), (34,-1), (35,-1), (36,-1), (37,-1), (38,-1), (39,-1), (40,-1), (41,-1), (42,-1), (43,-1), (44,-1), (45,-1), (46,-1), (47,-1), (48,-1), (49,-1), (50,-1), (51,-1), (52,-1), (53,-1), (54,-1), (55,-1), (56,-1), (57,-1), (58,-1), (59,-1), (60,-1), (61,-1), (62,-1), (63,-1), (64,-1), (65,-1), (66,-1), (67,-1), (68,-1), (69,-1), (70,-1), (71,-1), (72,-1), (73,-1), (74,-1), (75,-1), (76,-1), (77,-1), (78,-1), (79,-1), (80,-1), (81,-1), (82,-1), (83,-1), (84,-1), (85,-1), (86,-1), (87,-1), (88,-1), (89,-1), (90,-1), (91,-1), (92,-1), (93,-1), (94,-1), (95,-1), (96,-1), (97,-1), (98,-1), (99,-1), (100,-1), (101,-1), (102,-1), (103,-1), (104,-1), (105,-1), (106,-1), (107,-1), (108,-1), (109,-1), (110,-1), (111,-1), (112,-1), (113,-1), (114,-1), (115,-1), (116,-1), (117,-1), (118,-1), (119,-1), (120,-1), (121,-1), (122,-1), (123,-1), (124,-1), (125,-1), (126,-1), (127,-1), (128,-1), (129,-1), (130,-1), (131,-1), (132,-1), (133,-1), (134,-1), (135,-1), (136,-1), (137,-1), (138,-1), (139,-1); explain extended select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk); select * from t1 as x join t1 as y on x.u=y.pk order by(x.pk); connection ddl; drop table t1; # Test query using "scan -> unique index lookup -> index scan". connection ddl; create table t1 (pk int primary key, u int not null, a int, b int) engine=ndb; create index ix1 on t1(b,a); create unique index ix2 on t1(u); connection spj; insert into t1 values (0,0,10,10); insert into t1 values (1,1,10,10); insert into t1 values (2,2,10,10); insert into t1 values (3,3,10,10); insert into t1 values (4,4,10,10); insert into t1 values (5,5,10,10); insert into t1 values (6,6,10,10); insert into t1 values (7,7,10,10); insert into t1 values (8,8,10,10); insert into t1 values (9,9,10,10); insert into t1 values (10,10,10,10); insert into t1 values (11,11,10,10); explain extended select count(*) from t1 as x1 join t1 as x2 join t1 as x3 on x1.a=x2.u and x2.a = x3.b; select count(*) from t1 as x1 join t1 as x2 join t1 as x3 on x1.a=x2.u and x2.a = x3.b; explain extended select count(*) from t1 as x1, t1 as x2, t1 as x3 where x1.u=x2.pk and x1.a=x3.b; select count(*) from t1 as x1, t1 as x2, t1 as x3 where x1.u=x2.pk and x1.a=x3.b; # Regression test for commit http://lists.mysql.com/commits/116372 # (missing rows in left join query with multiple result batches). insert into t1 values (12,12,20,10); explain extended select count(*) from t1 as x1 left join t1 as x2 on x1.a=x2.b; select count(*) from t1 as x1 left join t1 as x2 on x1.a=x2.b; set ndb_join_pushdown=off; select count(*) from t1 as x1 left join t1 as x2 on x1.a=x2.b; set ndb_join_pushdown=on; # Test left join with mix of scan and lookup. explain extended select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b; select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b; set ndb_join_pushdown=off; select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b; set ndb_join_pushdown=on; explain extended select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b left join t1 as x4 on x3.u=x4.pk left join t1 as x5 on x4.a=x5.b; select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b left join t1 as x4 on x3.u=x4.pk left join t1 as x5 on x4.a=x5.b; set ndb_join_pushdown=off; select count(*) from t1 as x1 left join t1 as x2 on x1.u=x2.pk left join t1 as x3 on x2.a=x3.b left join t1 as x4 on x3.u=x4.pk left join t1 as x5 on x4.a=x5.b; set ndb_join_pushdown=on; ############################ # Testcase for 'Got error 20002 'Unknown error code' from NDBCLUSTER' # Caused by failure to identify AT_MULTI_PRIMARY_KEY as a lookup operation. # This in turn caused a pushed 'lookup-scan' query to be produced - which we don't support # Should not be pushed (lookup-scan query) explain extended select count(*) from t1 as x1 join t1 as x2 on x1.a=x2.b where x1.pk = 1 or x1.u=1; select count(*) from t1 as x1 join t1 as x2 on x1.a=x2.b where x1.pk = 1 or x1.u=1; ############################ # Testcase which forced us to ditch using the 'global cursor' # on the NdbQuery result set from mysqld. # # As the global cursor will fool mysqld into handling the resultset # as a result from a scan - n*lookup query, incorrect cardinality on the # parent operation was perceived. Which caused extra null-joined outer rows # to be emitted in this testcase. # # Refactored handler interface and SPJ API use subcursor on each operation # which correctly preserves the dependency between the parent subscans # and its child(s). set ndb_join_pushdown=on; explain extended select straight_join * from t1 as table1 left join (t1 as table2 join t1 as table3 on table2.pk = table3.b) on table1.pk = table2.b; --sorted_result select straight_join * from t1 as table1 left join (t1 as table2 join t1 as table3 on table2.pk = table3.b) on table1.pk = table2.b; ############# # Testcase for 'sledgehammer' fix for scan -> outer join scan: # Pushing of outer joined has to be dissabled as incomplete child batches # may cause the parent row to be returned multiple times: # Push scan-scan when inner joined explain extended select straight_join * from t1 as x1 inner join t1 as x2 on x2.b = x1.a; # Outer joined scans are not pushed. explain extended select straight_join * from t1 as x1 left join t1 as x2 on x2.b = x1.a; explain extended select straight_join * from t1 as x1 right join t1 as x2 on x2.b = x1.a; # If there is a lookup operation(s) inbetween the scans # pushing is disabled if any of these are outer joined # inner joined lookups, push allowed explain extended select straight_join * from t1 as x1 inner join (t1 as x2 inner join t1 as x3 on x3.b = x2.a) on x2.pk = x1.a; # Even if x3 is inner joined with x2 (lookup) # push is dissabled as x2 is outer joined with embedding scan operation # which makes join relation between the scans on x1 & x3 an 'indirect' outer join explain extended select straight_join * from t1 as x1 left join (t1 as x2 inner join t1 as x3 on x3.b = x2.a) on x2.pk = x1.a; ############# # Test bushy-scans: # These should be allowed to be executed in 'parallel', depending on # only the root operation # eval $save_scan_rows_returned; explain extended select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=off; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=on; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; # A really bushy scan - would take almost forever to execute if # we had to force the child scan to be non-bushy (serialized by # adding artificial parent dependencies) # explain extended select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.a join t1 as x4 on x4.b = x1.a join t1 as x5 on x5.b = x1.a join t1 as x6 on x6.b = x1.a join t1 as x7 on x7.b = x1.a where x3.a < x2.pk and x4.a < x3.pk; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.a join t1 as x4 on x4.b = x1.a join t1 as x5 on x5.b = x1.a join t1 as x6 on x6.b = x1.a join t1 as x7 on x7.b = x1.a where x3.a < x2.pk and x4.a < x3.pk; eval $compensate_scan_rows_returned; ############# # If we have an outer join, we can't create an artificial dep. 'through' the outer join. # In this case the child scan can't be part of the pushed query. # explain extended select straight_join count(*) from t1 as x1 left join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=off; select straight_join count(*) from t1 as x1 left join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=on; select straight_join count(*) from t1 as x1 left join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.b = x1.b; ############ # However, When the scanchild itself is an outer join, we *can* push that scan operation # explain extended select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a left join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=off; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a left join t1 as x3 on x3.b = x1.b; set ndb_join_pushdown=on; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a left join t1 as x3 on x3.b = x1.b; ############## # If we have a bushy lookup, with scandescendants depending on these lookups, # the query is 'scan-bushy' through these lookups. # # Bushy execution is expected for these scans (x2 & x4) wrt. root (x1) # eval $save_scan_rows_returned; explain extended select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.pk = x1.a join t1 as x4 on x4.b = x3.a; set ndb_join_pushdown=off; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.pk = x1.a join t1 as x4 on x4.b = x3.a; set ndb_join_pushdown=on; select straight_join count(*) from t1 as x1 join t1 as x2 on x2.b = x1.a join t1 as x3 on x3.pk = x1.a join t1 as x4 on x4.b = x3.a; eval $compensate_scan_rows_returned; ############# # Test bushy lookups + 1scan, # (Regression test for previous commit: http://lists.mysql.com/commits/117571) # Repeatable child rangescan with same parent should be allowed to be in # 'm_iterState != Iter_finished' if the child row didn't exist (outer join): explain extended select straight_join count(*) from t1 as x1 left join t1 as x3 on x3.b = x1.a join t1 as x2 on x2.pk = x1.a; select straight_join count(*) from t1 as x1 left join t1 as x3 on x3.b = x1.a join t1 as x2 on x2.pk = x1.a; # Modify rows to force null rows from outer join update t1 set b=b+10; select straight_join count(*) from t1 as x1 left join t1 as x3 on x3.b = x1.a join t1 as x2 on x2.pk = x1.a; #Undo update update t1 set b=b-10; ############## # Testcase for: http://lists.mysql.com/commits/118917 # There used to be a bug in SPJ API resulthandling of incomplete # child batches where we tested for incomplete fetch for any # childs (in a bushy scan) instead if this particular child batch # being incomplete. # # In this testcase (x inner join y) will have incomplete # childbatches, while (x left join z) will be complete. # Modify rows to force null rows from lookup(z) below update t1 set u=u+100; set ndb_join_pushdown=on; explain extended select straight_join count(*) from (t1 as x join t1 as y on y.b = x.a) left outer join t1 as z on z.u = x.a; select straight_join count(*) from (t1 as x join t1 as y on y.b = x.a) left outer join t1 as z on z.u = x.a; #Undo update update t1 set u=u-100; ############## connection ddl; drop index ix2 on t1; create unique index ix2 on t1(a,u); connection spj; set ndb_join_pushdown=on; explain extended select straight_join * from t1 as table1 join (t1 as table2 join t1 as table3 on table3.a = table2.a) on table3.u = table1.u where table2.pk = 3; --sorted_result select straight_join * from t1 as table1 join (t1 as table2 join t1 as table3 on table3.a = table2.a) on table3.u = table1.u where table2.pk = 3; ############## connection ddl; drop table t1; ############## # Test that branches of a bushy scan are correctly reset. connection ddl; CREATE TABLE t1 ( a int NOT NULL, b int NOT NULL, c int NOT NULL, d int NOT NULL, PRIMARY KEY (`a`,`b`) ) ENGINE=ndbcluster; connection spj; insert into t1 values (1,1,1,1), (1,2,1,1), (1,3,1,1), (1,4,1,2); connection ddl; CREATE TABLE t2 ( a int NOT NULL, PRIMARY KEY (`a`) ) ENGINE=ndbcluster; CREATE TABLE t3 ( a int NOT NULL, b int NOT NULL, PRIMARY KEY (`a`,`b`) ) ENGINE=ndbcluster; connection ddl; insert into t2 values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); connection spj; # Make t3 so big that it takes multiple batches to scan it. insert into t3 select 1, x1.a * 10+x2.a from t2 as x1 cross join t2 as x2; explain select straight_join count(*) from t1 as x0 join t3 as x1 on x0.c=x1.a join t1 as x2 on x0.c=x2.a join t3 as x3 on x2.c=x3.a join t1 as x4 on x0.d=x4.a and x3.b=x4.b; eval $save_scan_rows_returned; select straight_join count(*) from t1 as x0 join t3 as x1 on x0.c=x1.a join t1 as x2 on x0.c=x2.a join t3 as x3 on x2.c=x3.a join t1 as x4 on x0.d=x4.a and x3.b=x4.b; eval $compensate_scan_rows_returned; connection ddl; drop table t1; drop table t2; drop table t3; ############################################# # Test pruned index scan: connection ddl; create table t1( d int not null, e int null, f int null, a int not null, b int not null, c int not null, primary key (a,b,c)) engine = ndb partition by key (b); connection spj; insert into t1(a,b,c,d,e,f) values (1, 2, 3, 1, 2, 3), (1, 2, 4, 1, 2, 3), (2, 3, 4, 1, 2, 3), (3, 4, 5, 1, 2, 3), (4, 5, 6, 1, 2, 3), (5, 6, 7, 1, 2, 3), (6, 7, 8, 1, 2, 3), (7, 8, 9, 1, 2, 3); # Find the total number of pruned range scans so far let $pruned_range = query_get_value(select sum(val) as Value from ndbinfo.counters where block_name='DBSPJ' and counter_name='PRUNED_RANGE_SCANS_RECEIVED', Value, 1); let $const_pruned_range = query_get_value(select sum(val) as Value from ndbinfo.counters where block_name='DBSPJ' and counter_name='CONST_PRUNED_RANGE_SCANS_RECEIVED', Value, 1); set ndb_join_pushdown=on; explain extended select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; connection ddl; alter table t1 partition by key (a); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; connection ddl; alter table t1 partition by key (a,b); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; connection ddl; alter table t1 partition by key (b,a); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; ######### # const pruned testcase ######### connection ddl; alter table t1 partition by key (b); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=2; connection ddl; alter table t1 partition by key (a); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=1 and y.b=x.e; select straight_join * from t1 x, t1 y where y.a=0 and y.b=x.e; # Non-const pruned as both partition keys are not const connection ddl; alter table t1 partition by key (a,b); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=1 and y.b=x.e; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=2; ########## # Test pruned scan using an index: # Declaring PK as 'using hash' will prevent that PK is used as index # Declare PK / ix1 with mismatching column order will test correct # usage of NdbRecord::distkey_indexes[] ########## connection ddl; alter table t1 drop primary key, add primary key using hash (d,b,a,c); alter table t1 partition by key (b); create index ix1 on t1(b,d,a); connection spj; explain extended select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; ########### # Partition keys may evaluate to null-values: ########### insert into t1(a,b,c,d,e,f) values (8, 9, 0, 1, null, 3), (9, 9, 0, 1, 2, null); connection ddl; alter table t1 partition by key (b); connection spj; --sorted_result select straight_join * from t1 x, t1 y where y.a=x.d and y.b=x.e; # Verify pruned execution by comparing the NDB$INFO counters --disable_query_log --eval select sum(val) - $pruned_range as pruned from ndbinfo.counters where block_name='DBSPJ' and counter_name='PRUNED_RANGE_SCANS_RECEIVED' --eval select sum(val) - $const_pruned_range as const_pruned from ndbinfo.counters where block_name='DBSPJ' and counter_name='CONST_PRUNED_RANGE_SCANS_RECEIVED' --enable_query_log connection ddl; drop table t1; ### # Test that sorted scan with sub scan is *not* pushed. ### connection ddl; create table t1 (pk int primary key, a int, b int) engine=ndb; create index ix1 on t1(b,a); connection spj; insert into t1 values (0,10,10); insert into t1 values (1,10,20); insert into t1 values (2,20,20); insert into t1 values (3,10,10); insert into t1 values (4,10,20); insert into t1 values (5,10,20); insert into t1 values (6,10,10); insert into t1 values (7,10,10); insert into t1 values (8,10,20); insert into t1 values (9,10,10); # Results would be sorted wrongly if pushed. explain extended select x1.pk,x1.a,x1.b from t1 as x1 join t1 as x2 on x1.a=x2.b join t1 as x3 on x2.a=x3.b order by x1.pk limit 70; select x1.pk,x1.a,x1.b from t1 as x1 join t1 as x2 on x1.a=x2.b join t1 as x3 on x2.a=x3.b order by x1.pk limit 70; # This query should not be pushed, since mysqld requires sorted # results for the root scan. explain extended select * from t1 as x1, t1 as x2 where x1.a=x2.b and x1.b = 3; select * from t1 as x1, t1 as x2 where x1.a=x2.b and x1.b = 3; connection ddl; drop table t1; ######## # Test correct cleanup of MRR accesses being executed multiple times. # This used to be bug#57481, and this is a SPJ specific testcase in addition to # the specific testcase commited together with patch for this bug. ####### connection ddl; create table t (pk int primary key, a int) engine=ndb; insert into t values (1,1), (2,1), (4,3), (6,3), (7,4), (8,4); connection spj; explain extended select distinct straight_join table1.pk FROM t as table1 join (t as table2 join (t as table3 join t as table4 on table3.pk = table4.a) on table2.pk = table3.pk ) on table1.a = table4.pk where table2.pk != 6; --sorted_result select distinct straight_join table1.pk FROM t as table1 join (t as table2 join (t as table3 join t as table4 on table3.pk = table4.a) on table2.pk = table3.pk ) on table1.a = table4.pk where table2.pk != 6; connection ddl; drop table t; ######## # SPJ variant of bug#57396 # Test correct format of an 'open bound' ######## connection ddl; create table t (b int, a int, primary key (a,b)) engine=ndb; connection spj; insert into t values(0,0); explain extended select * from t as t1 join t as t2 on t2.a=t1.a where t1.a < 8 or t1.a >= 8; select * from t as t1 join t as t2 on t2.a=t1.a where t1.a < 8 or t1.a >= 8; connection ddl; drop table t; ####### # Testcase for bug introduced by initial fix for # bug#57601 'Optimizer is overly eager to request ordered access.' # When we turned of 'sorted' for 'descending', we broke QUICK_SELECT_DESC # which required result to be read as an ordered index access ####### connection ddl; create table t (pk1 int, pk2 int, primary key(pk1,pk2)) engine = ndb; connection spj; insert into t values (1,3), (3,6), (6,9), (9,1); explain extended select * from t as t1 join t as t2 on t1.pk2 = t2.pk1 where t1.pk1 != 6 order by t1.pk1 DESC; select * from t as t1 join t as t2 on t1.pk2 = t2.pk1 where t1.pk1 != 6 order by t1.pk1 DESC; connection ddl; drop table t; ####### # Testcase using 'REF_OR_NULL' # 'ref_or_null' contains elements of left outer join wo/ being identical. # connection ddl; create table t (k int, uq int, unique key ix1 (uq)) engine = ndb; connection spj; insert into t values (1,3), (3,NULL), (6,9), (9,1); # Currently we do not handle 'ref_or_null' correctly. # It is therefore disabled as pushable explain extended select straight_join * from t as a join t as b on a.uq=b.uq or b.uq is null; --sorted_result select straight_join * from t as a join t as b on a.uq=b.uq or b.uq is null; connection ddl; drop table t; ######## # JT_SYSTEM testcase, 'a.k is null' is known 'false' -> # Join condition will always fail, and all 'left joins' can be NULL complemented wo/ # even requiring to access left table (b) which becomes 'system' -> No pushed joins ! ######## connection ddl; create table t (k int primary key, uq int) engine = ndb; connection spj; insert into t values (1,3), (3,NULL), (6,9), (9,1); explain extended select * from t as a left join t as b on a.k is null and a.uq=b.uq; --sorted_result select * from t as a left join t as b on a.k is null and a.uq=b.uq; connection ddl; drop table t; ####### # Test of varchar query parameteres. ####### connection ddl; create table tc( a varchar(10) not null, b varchar(10), c varchar(10), primary key (a), unique key uk1 (b, c) )engine=ndbcluster; connection spj; insert into tc values ('aa','bb', 'x'), ('bb','cc', 'x'), ('cc', 'dd', 'x'); explain extended select * from tc as x1 right outer join tc as x2 on x1.b=x2.a left outer join tc as x3 on x2.b = x3.b and x1.c=x3.c; --sorted_result select * from tc as x1 right outer join tc as x2 on x1.b=x2.a left outer join tc as x3 on x2.b = x3.b and x1.c=x3.c; #### # Test that 'select ... for update' is not pushed, since this requires locking. #### explain extended select * from tc as x1, tc as x2 where x1.b=x2.a for update; explain extended select * from tc as x1, tc as x2 where x1.b=x2.a; connection ddl; drop table tc; ### # prune with xfrm set incorrect keylen # connection ddl; create table t1 ( a varchar(16) not null, b int not null, c varchar(16) not null, d int not null, primary key (a,b) ) engine ndb partition by key (a); connection spj; insert into t1 values ('aaa', 1, 'aaa', 1); explain extended select * from t1 as q1, t1 as q2 where q1.a = 'aaa' and q1.c=q2.a; select * from t1 as q1, t1 as q2 where q1.a = 'aaa' and q1.c=q2.a; connection ddl; drop table t1; ####################################### # Some tests for nested left joins. connection ddl; CREATE TABLE t1 ( a int NOT NULL, b int NOT NULL, c int NOT NULL, d int, PRIMARY KEY (`a`,`b`), unique key(c) ) ENGINE=ndbcluster; connection spj; insert into t1 values (1,1,1,1), (1,2,2,1), (1,3,3,1), (1,4,4,1), (1,5,5,2), (1,6,6,2), (1,7,7,2), (1,8,8,2); explain extended select count(*) from t1 as x1 join (t1 as x2 left join (t1 as x3 cross join t1 as x4) on x2.d=x3.a) on x2.c is null or x1.a=x4.d; select count(*) from t1 as x1 join (t1 as x2 left join (t1 as x3 cross join t1 as x4) on x2.d=x3.a) on x2.c is null or x1.a=x4.d; explain extended select count(*) from t1 as x1 left join (t1 as x2 cross join t1 as x3) on x1.d=x2.a; select count(*) from t1 as x1 left join (t1 as x2 cross join t1 as x3) on x1.d=x2.a; explain extended select count(*) from t1 as x0 left join (t1 as x1 join (t1 as x2 left join (t1 as x3 join t1 as x4 on x3.d=x4.a) on x2.d=x3.a) on x2.c is null or x1.a=x4.d) on x0.d=x1.a; select count(*) from t1 as x0 left join (t1 as x1 join (t1 as x2 left join (t1 as x3 join t1 as x4 on x3.d=x4.a) on x2.d=x3.a) on x2.c is null or x1.a=x4.d) on x0.d=x1.a; connection ddl; drop table t1; ## Test scan sorted on string field. connection ddl; create table t1 (pk char(10) primary key, u int not null) engine=ndb; create table t2 (pk int primary key, u int not null) engine=ndb; connection spj; insert into t1 values ('wh',1); insert into t1 values ('ik',2); insert into t1 values ('cu',3); insert into t1 values ('pw',4); insert into t1 values ('cq',4); insert into t2 values (1,2), (2,3), (3,4), (4,5); explain select * from t1 join t2 on t1.u = t2.pk order by t1.pk; select * from t1 join t2 on t1.u = t2.pk order by t1.pk; connection ddl; drop table t1; drop table t2; ######################################## # Test query with very long records. connection ddl; create table t1 ( a char(10) primary key, b char(10) not null, c char(10) not null, l00 char(255) not null, l01 char(255) not null, l02 char(255) not null, l03 char(255) not null, l04 char(255) not null, l05 char(255) not null, l06 char(255) not null, l07 char(255) not null, l08 char(255) not null, l09 char(255) not null, l10 char(255) not null, l11 char(255) not null, l12 char(255) not null, l13 char(255) not null, l14 char(255) not null, l15 char(255) not null, l16 char(255) not null, l17 char(255) not null, l18 char(255) not null, l19 char(255) not null, l20 char(255) not null, l21 char(255) not null, l22 char(255) not null, l23 char(255) not null, l24 char(255) not null, l25 char(255) not null, l26 char(255) not null, l27 char(255) not null, l28 char(255) not null, l29 char(255) not null, l30 char(255) not null, l31 char(255) not null, index(c, b) ) engine=ndb partition by key(a) partitions 8; connection spj; insert into t1 values ('a','a','a','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'); insert into t1 values ('b','b','b','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'); insert into t1 values ('c','c','c','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'); explain select count(*) from t1 as x1 join t1 as x2 on x1.b = x2.c; select count(*) from t1 as x1 join t1 as x2 on x1.b = x2.c; connection ddl; drop table t1; ######################################## # Verify DBSPJ counters for entire test: # Note: These tables are 'temporary' withing 'connection spj' # Get new counter values. connection spj; create temporary table spj_counts_at_end select counter_name, sum(val) as val from ndbinfo.counters where block_name='DBSPJ' group by counter_name; connection spj; # Compute & report the difference. # Any change in SPJ counters will indicate a change in pushability which # should be verifyed. # - LOCAL/REMOTE counts can not be directly compared as they depends on # data distribution, and which TC used for the test. # - SCAN_BATCHES_RETURNED also seems to vary with a small delta - also assumed to be due to data distribution --sorted_result select spj_counts_at_end.counter_name, spj_counts_at_end.val - spj_counts_at_startup.val from spj_counts_at_end, spj_counts_at_startup where spj_counts_at_end.counter_name = spj_counts_at_startup.counter_name and spj_counts_at_end.counter_name <> 'LOCAL_READS_SENT' and spj_counts_at_end.counter_name <> 'REMOTE_READS_SENT' and spj_counts_at_end.counter_name <> 'LOCAL_RANGE_SCANS_SENT' and spj_counts_at_end.counter_name <> 'REMOTE_RANGE_SCANS_SENT' and spj_counts_at_end.counter_name <> 'SCAN_BATCHES_RETURNED'; # The sum of LOCAL+REMOTE should be constant select sum(spj_counts_at_end.val - spj_counts_at_startup.val) as 'LOCAL+REMOTE READS_SENT' from spj_counts_at_end, spj_counts_at_startup where spj_counts_at_end.counter_name = spj_counts_at_startup.counter_name and (spj_counts_at_end.counter_name = 'LOCAL_READS_SENT' or spj_counts_at_end.counter_name = 'REMOTE_READS_SENT'); connection spj; drop table spj_save_counts; drop table spj_counts_at_startup; drop table spj_counts_at_end; connection spj; # Similar for the SPJ specific 'STATUS' counters let $scan_count_at_end = query_get_value(show status like 'Ndb_scan_count', Value, 1); let $pruned_scan_count_at_end = query_get_value(show status like 'Ndb_pruned_scan_count', Value, 1); let $sorted_scan_count_at_end = query_get_value(show status like 'Ndb_sorted_scan_count', Value, 1); let $pushed_queries_defined_at_end = query_get_value(show status like 'Ndb_pushed_queries_defined', Value, 1); let $pushed_queries_dropped_at_end = query_get_value(show status like 'Ndb_pushed_queries_dropped', Value, 1); let $pushed_queries_executed_at_end = query_get_value(show status like 'Ndb_pushed_queries_executed', Value, 1); let $pushed_reads_at_end = query_get_value(show status like 'Ndb_pushed_reads', Value, 1); # Calculate the change. --disable_query_log --eval select $scan_count_at_end - $scan_count_at_startup as scan_count --eval select $pruned_scan_count_at_end - $pruned_scan_count_at_startup as pruned_scan_count --eval select $sorted_scan_count_at_end - $sorted_scan_count_at_startup as sorted_scan_count --eval select $pushed_queries_defined_at_end - $pushed_queries_defined_at_startup as pushed_queries_defined --eval select $pushed_queries_dropped_at_end - $pushed_queries_dropped_at_startup as pushed_queries_dropped --eval select $pushed_queries_executed_at_end - $pushed_queries_executed_at_startup as pushed_queries_executed #--eval select $pushed_reads_at_end - $pushed_reads_at_startup as pushed_reads --enable_query_log --source ndbinfo_drop.inc set ndb_join_pushdown = @save_ndb_join_pushdown;