From 4e7d73dd4e1584e9ad6046c86820feb1a8283123 Mon Sep 17 00:00:00 2001 From: Paul W Date: Sat, 9 Nov 2024 00:23:49 -0500 Subject: [PATCH] Bump sqlite version Signed-off-by: Paul W --- lib/libsqlite3_arm64.a | Bin 1589688 -> 1600216 bytes lib/libsqlite3_x64.a | Bin 0 -> 1521864 bytes lib/sqlite3.lib | Bin 3086590 -> 3120550 bytes bindings.odin => sqlite3.odin | 19 +- src/build.sh | 17 +- src/sqlite3.c | 8303 ++++++++++++++++++++++----------- 6 files changed, 5550 insertions(+), 2789 deletions(-) create mode 100644 lib/libsqlite3_x64.a rename bindings.odin => sqlite3.odin (98%) diff --git a/lib/libsqlite3_arm64.a b/lib/libsqlite3_arm64.a index d3213da6b3ca84fca6ca379fc57fd8678a85c7fa..6c03e4894339e68a2fcae26f68d22d17c29af6d7 100644 GIT binary patch delta 602871 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 z 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%0A1#;eK>4dMouKJQ zcze-cq^`|Dv^z}gfUGb}ux_wmzVs-n|u4Bb^Dc*BarVH!Zc`P_{!_RNTG!1fDc z>}-W;9UVJMSd1NX+U`%rbX}Wd{(BA|C&B4=^n#dP1L){iM}L2g)zROL6{e3m`nz(h zj{XjGda3!99IN?lX#H(3VE)@cYfexbD5KL$t)L;tY6Ukx64PrJ?f5i$UKqr$u;;q) zf3Y3k$ewEp)AjSq#Wx|g@vG$5Yb>}+M$uh)HIYxHVLC&1;UN~MQv5N-$aFL*1I;;B^Bd3x)CNj9RvWl_R&0Q}{$-BU z^)JwC!xGk9Xk)>_F*p{-a{Y&53)KedIaV83M9Wujmt%hVgK*mOcy^8HzMa@T0}dr z5T;pl_DrH3=tT$h?lZ#0XVjwNNfI2@6JcsVPfVxZUoQR}?>^drUHorG_fD8r(F!}V z7bE4;pR$E>-&edL9hwc(6ne*04bud!a|kDDEVzrubAq~y&%ZaGeh<*w=NWWM#?dWl zMz^#arqlly=_}|fooV#NWglKKov((YzEgBVj?ur4Sv!h_w2yBmVJ}R(SSQ{IQx!i& zg`;@Eo*BdzJAyW_{`A;mt602TLLb|w(QnO;V$mV=xuJxt$NYaB`J`B?g`ZK&SEUx#1 zamL$6Pe^+?##(Vk+9JU-nmQXcbF9vWg&eE-^Ep=Yr?J8rQ*B@>$Lbkx5OwD0qecO8RA(PS9JfZS?ZFivHMa0E8JQFY}rYej`5#~kHWN%&g&^WBfT1?!5k0dxD{<+>xt#k zKT&QoOdI%*#Oq(K6f0czMZrBRZmZEZm{t4?TQV7@{+xgDg!qVN z5#2Ji;)NWm9hpHtTbd5}hXzr9XzDtA}Y8 z&F{({_eQxxJf_@1nCfV`ks1r`nvR@s@VLmRXP3SuI;3`JF~@3$=I|{JO7!8gihu8( z3ey;R=mv6rKmHy0ePOC~I~uqS(;iy!HhSn5&;};a z1}5-`2FAnGfxb5^qvcBYN%C(ViOm0W#)4mmsiOsF@vkW`6Q;hLe)EWE;2Qsm{Hrh> zpcke6FskHw`Av=V++@_ z^XO=A&2b68m+~hMiSpZci?{>rpxVJoj@1sfpdBou^_|up9HYOACNyWu9WkF9@XzRZ zDNLsiiU!mMPI9a^aDX|glQgsk$5glv-lR`nJ`V`GVxTHs`zIA{?}wIq%mBfz-X8{&_ULK z-b9{PB3?#2IE#-ay%X2i;tIZk4QRy=GKP*Hz!wmx?;_+HA7p>NAa3z`3eEc`JA z2g1~ke?;6Drk?x9_59!)udsYSv;B%~d*VYR>(+OQgLqWAIZ_z^0uhiNsZFXJDOz7(bjd>}WSW!#~o$88*9 zK73Z|JF4Y`qew^xXajrrVJg}U(+D~X`tT7{*q%MPH!r6-=ITS}agLQZ9ioR~2c6#I z=y_laKScet(O5{GXu&diMm)M#d|I`Q-q&{{J+7+_b>&!Xs5!@KemTc#{>?p$L0DJw zuOqJ2U9iAOE}#}T&as-mjd!2}YW`M^)%=wltNF`0R`aLPzbT>SPZcqr|G8j+kz7D6 zFq~sGzZ?B_teW4IV>Q1e$7+6aj@A5&)<{1O(}D8&|ImI;*g=n_TETXX)e4%?V|aXz zm}WER#YUa)(>Ye>dnbBET)R7GM2_`pn3iyx!8nCA7kXIuFvq-t&i6KSdbNhBe7ADx zS4h8TDVOFMBg^PmnZx2*fjg|~xM7irQUE%N3@EUrCRHxT!j+HnqqSIT=pT7(9 z--P*GU=E${YJu4ts})S+@6pgWuCqmBVd_BtK5!*W$9IlHsUFIs9IJ+q%mpNARk8-T$ALdxi-$G_nt?q&aHY1^~7Ff=)n!l7|HGev%Pvv+d$HO`9L1&Y? zes_-5_2=)zY`TM={}l^-_>5bO+LD4c^;Vdc(Np*m z`s!sdMl6AdUFA_Ku?a<{5CAE@92DQ&9OS)8?Zus>iVS|tLtCi z7PCXmzry10f4X3S3$y{Xf%6=z4V<7i5NZX-Iab%-Mc;ZY;6s?EbNCA45%i)njK9mC z8w%4}nfdR#-qmvP&Nr=~?|PTRw1n>3#V}2yuh%=#t6^)7ubSc>@BlrLE#u4Rz+!d| zJ-<}(9;A2SCLQT)V*ay`t{UUm9^-4tI11A~Ua<9I)lD&>_$JoE29@3b&NFRSREsm zw~sA8$?l`i7hBnSPG3UqD{8kUS#XyQp?5a@=&|ZRFD6&Fi-s=4w1jqO28YS7q8Fh- zdOG#mr2k^vg`kADvt3L{x*B+GEB#4 z`7QLRc^&P@JbDK;iC(S;@cZb{&DWcX`i{_t*=BqP&;Pg1zt&Xr^Z;#m7w=Ab9o==) z=)0W>^b17Y=oYr2gKGJvshACO_*ObN8>Z8*M#p#X?WAvqX$wc)6G;2)ikzU%;|*kw z)b%4w$Mqa5aT-Loya(-A1$Qae9;TbGM8hZen>2hJ@?Wu$$C_Mwkt-T3P?+!dx)d=2&9TsM_| zjSke&ax2%hrqZucaG3;5lW0Z#=sCO>xjz`{2~!21>XwG-_Kk@8GE3Tk>stx_9r8P{~Uv4TcE|>Vr z9D<85&7<|rg=reCZyc?!7dQR?KdmhIsr1Ev=J|;>w1$3Gvl^yF{1|@^bRm3J1^uMs z;y)t&Jbcz7`tquZc62i2|AI9YpNK4>=amU8{{Pr-UEv!@zYNnc`pmeCc3=R#%=d?>58p}L`vvAd3#mdvacuGRZfTfK zFN#ro>lnT6Z{kC!us2&m*Sr3AI>LHaVLHa*%O>atm;>0x`rT;xPW%PRcli}OQ()7 z-F%)sLp{AU7KZ6z2l~&aF8?Kt-6=kfcprbAW40Hj9rT}5Zii_aJ=X2$FQ#w)xvBWY z^mUl7aDhX4p4~yF^{qj)}XMN+Q`yE#^` z3G3)}e<`P{rZpSBHsEm^S{c%A_+f=7k?8cpgkNR zUcwjRG`|kv(`PhKhV>_4!Xh; z{tWQ|xcx(*Un-gjiZBN z2>oQE1+BQ{6H!4Ke~J|v!gTc)O{Jf-!Z3CHdF%;wPju#3-4m_om?)zgbpB^W{k2;M zESRu`?xK2R+-ks|pd&MX+Eo0lhbqp{;AEJ3@s-3qVY=9FD*ZU|d6>rjq^bC~JfmS6 z!S`^{84lABZt(lRp}}IIlm_rY^t?YzCx09lk9~YK9a}(8Jagz}bT&+r=onD9d?Lr{ zmJj2bS-%tgYZzC56dOE?PxbxZj0;=^kN3D?V2gKg6t{4iE!qszIzEH+S$qZd;U*nA z`op-)_M!K5YDao=tahXmE8G*RXWR~~nc#w_+;;S)Q7zDxV>Q18Z9r|HImc=PCG?(A zUH|6e5v%K;q3;LQu?1H@&io&C^pfBiYz95oPoUTBVH|Qx(JvmHe5|ST-NXavq3FZ! zVh{C(>0&ny;dz*r&@UoQqwfn^(Dt@I8uhn-l=*K@T1fCzSwb(n=O2m7?pc^l(97;| zm^RS+gk}6VR`KO@?D`L)W0&|cI(8AJi=8;6r#MCWNtljmEO<;e&{O3aI_(y7JcHjv z`c#gG(Gyb#TCR+qN)JBVRC+0HqVY6(W*tP!wWG7E0bfk|*@q&(w#$OkuZ}*oR?$;& z2YSZ4`d~b*&Y|Td&~iO!N1D+y0%DojWCEaJm39pD)8e#k#4D=NG-k1w!6bc_4ZhC56rzI=bg$9Ty5 zzgs&jIDgeqy`5uqR4<}iJcV|27#)0r=y_luOufi79_k5GE4tqG`{JT@h`tBdKsz*} zH5SHLu;SiqbGGukO{M#@!uDoVw1lqMkCwlBZ=9;P@d1>ZMR#>ej<0?v%57q=`8n=G zJGTEG=D+9qRTli9pn?vz*$rMaU_aVW7rMnA_%c^W|&Uj75Q85V*Xojn1tt1K^cD-&)&&%KX#%ORPebp+#aT8^juyJQ+Ykk^$j8a z%*t~+Z_UDV^o}Th7^Z1-ns>Z|`R}7vg#=8k_%z~{FfF`2R-6y{^?N+oY}Ywqaf{Z2 zMMd}=>j~5DZ$6PvEO<(t`PJCfQ|KwR8m0=`Kzo?>R^ybq zj-FC0=$W$xJ$0ARQ}@-c#Cw1a^qQg0u1b!TxRzR2sBqCyFB;7`RxcV2=tW7*FXdRx zzkXXZpf+%oV|DtTqZcK0{j(gazyIaGR7H>1(5uq~diy%}QZ9$A6`s6Z}EakHfTpeg6J;j0G#|MDNe9-Wm;F;4@j_ zJWN~YeZe~Z0O|EGt)kbEQS=sT5S_;T=ryGazaP(jDNc0io;t<&{$C`deRTfLqwfJm z&{Jp!dOLphmN;=Npl3|AqWK)FyL<$#ryD)LTrEd@f=>6{?8-9p-v(w#u;38d^Io)q z)*RowIT}7iJGP0QN@vmY!!&v-o(fYpT3;DGv7Njr&XB9k(6sd&+(-&EiT3SU1*2T-x#OtUG(MjCYnB+oqa=0>nhsui5d%Q z^n5%_o#+XvBTNKe6y^Bqybq-j@1gf&spyr?ESj|61PdsY$sO-^XjN|8*CvV6RBv z={Mq3Mb8J_=ozkpp4k?Dp10i$q7nQU?*oU!XAPixq932ip6ClxHx}O;z(LZxa;$?j zE;=naqd80mKUcgut?PHP!hVjGIBj5sEmQN?bFAi9@qXm1`I9+T^M{ZPt82{ygE>Jh zaQPah3kB5tiyW)@2Y4^?)%^V&tNHVIU-H%bxg4wc6Ube69cx8_@tmL*7(l+wURNvV z&#{`{irm-N)%=zmtNB;+OhfY3{L37x`8#+|@^|K${}$NJ32K2wyblG`{DmB=`Bh|0 z)YbgS9IN?5*i62fKbT`Rzl>$_%e7pfAt$H>+UXdBvaVLpmSZ*l`c=g!uB-W1Iac$J z@D8l6<{#!*&7b>et_|eZT(H1wPEZTX;5Sl0&7aP(nm>i@qq5K&k22Xd_D_v0P?{l5zq z=qnOt!xkg~0$m4tvqt@@{+rwxf5o4fuHCv*$C|a1VW9 zv5Mb{gLrQ`(2K=yKGF5oCStv*iG2S*PJ$Uj=!*SlhkCGh06{x;^StQT8QQTUG=C3W ze*;}_EvGN#^l5wxuIZd38MB)4lUJcfd+Xn{HOEmbMU2jkJP8GJP5#?Xca z(DLWci4M=B=~Xnn48Ily!J4);pd54!_Td#R4xH z&=t=|n@Sz@_$*9E_#i6Y&rYMy^ON{M%1wl66uExi>PG)4efbCC(3H@@d-RMr6uamk z-NJ8R{@+^633FH+L#&YAg$~NG?~gsyi{D7RI}&?j4c#My=-^Zb=Rl6t!CApZ%FTXX zyppM+r{Hd^**|x#c#hRa zv3~R~EcT$k3A-AO_;{H4KSR%1D0;qz78uV32GD$U%ldMxZrRz>xyxnC*75c@iS7xt z{6vn`^1bK=cVt_hUW;SVkP|MS7V#N+%+}CXrE} zmQCb%IL8C%2Daz)GSUv8|9w|9w2k&~9&K<2ZE!kFRkXp$FpZ&C$I&o#q8(^K4^bKK zNq$3^Zk`(Fl@oN&?ql)(f0YFrT*6jXSPauZQGjWfZ9&i77lTcuFX9P$hjjjwI27uk zILomXhXNfNbsVOHi|8y{P_O^fEI7?3(P`F+Zb1h+%_?Eq|IV0ZTD-8x@m|Df8}H5@ zTtqw8j&}Iw$>9l_zmDdQV9kZIf!G3d3r=&aZovUsZZ_MQ-TRJ6pUPf7DdM&4VD|Fc zb9#0#d)CkVzZ<*aw4d8*_QYX0bdcjs^cZi1sSWMO`V+&R?CG~fypTOfae_I-7Pfdb zTSeC|qlf&akNJOB8o2H&Os8mpDfC35?vZMa)jcwZmOFn!RCI!Op`PO~?W6fKIlqc` zCVw(atHnYZMz?e*Oec?zS+S2rMcK=5jp=!ccVx@u-f=9lhl`>g7p^ za(n1lSU|5Cqv!)pZIA_@cv{h~$#gz08aVitdt$Y^cmVKvXIoOsCy(CR@j^kw1?&IE`O* zJ^Tu;KQbJ~|0QlgPe3=1;L|bUbF6)aiqBZUbb=?u$6?yWYYI-_|6sE*6QY^ww$u|AX|cheSi0_-Pv22-EI^n@X4DPi1@XOT?9qIAtF_C=T@jeu4G&AH@7; zA#Ic3P3H=Fap*>OeFt7puo9;BoZf=}MtXCY#vd4`?(J`i(Y=VimS3wxM^}(7A6gF6 zG5yVdqEwc)=Iw}xrs0ZpYhvEBmyGftqpxDCCAl<}U#r}vL} zeuU%1`{;jE*$Y!`iv{Q7G&wm*aVKR}P@ZvKc*3G@$2+Qkb^x(^UF<8eBy4 z=kf2zp9}d7XjAEL?I0E>GV}yBVC?%p7o7K9IN>! zSp5Ds=O5=-&ELtfy8d>K)%@Bj3mp5pT3{u|YJu4ttNAlIR`aLuui52e_*XcDepkF7 z|B~{3VQNRe6JAE&jNaU>sq_iw|8*>+bNmZdI1AG(x@GF`_hxde{(f&1nKgB_VTY{%B4g$#E|_Sk>}9IabS$-!(Q!|D60WJ_}(wy;GDs3Da(lcXGUnPG2qR%kfIiZ$>`MstuK6 zA@$!eek9Tt@@v@mkw{ONy3j8w9NkuY?tkk5{Y}U^`h|iie25pXayW*5T;GiIlsj#T zC#rSyTC;|0+G4oKOmjJ&&GAV?G_Zv>uz~xm zzaFMJ{1f8YFsrUxJQBGFm0g~PUrk7^vy5=Bn+em|*BXl(n$s{HevQAsY{3;0{J(wkXpg7R2FvINjf*#p zMaSmx59!!kn8wjtww`PUx*3IMIvb{O{5X4ZEa!LCSa=`_9q2pRmajAx zH;L*oYtFHH%&z~pv3STlL;rr?A-27r&JcS>ne61P_ zsf1Q^ecf342pLylIzgZBkHd6?e?b0Wm{!myry2BVxr$!rhtcc&!T-db+ru5!+YM6* zi}`=^-^D^Y!pCz6_K{QQ&|b(d9UDuZBHjwqI`YMVx^hMvs^?gV`DJ4?xPn!FXt*4v zDfFk@6X;mk{V&V$`QJ7RAEswpVVcAb(erWqpj(3PV+;GyKO)x`ro*eo(l+^%=%5|P z4^YoomPu)36o(OK?h|QI{142v$6EEtT^@`;q_(YALH%m z*f#zi`Eyv5&z^lL#?~?VYG)g_+|V%9vF1;t7g=z{QFKd&@tY|)6s7@OC+-hZ1>aAF z*Ix{e(ckwSh3OFANqi8d6?AMZ;rpm(F-+rM#%!Yi>K{oP(GP7#;Uh8x0k z^@T>yh_|NDj!xq5l0OlqG2A2`4f&yAW9hxbyaIab%Nm2!ew;Pl^%X;fDWoa9)|-_5a_zmsD%e>JDC{;{$6 z*X`3`>Ok+9Dq(8JXS04=n07zM{P%LZ`MJ2a&f-uW2vCbpF{|WAUQkj09d7q(iiUef(7#*bCDZdK0;Z zUPhPDw_{bbgCl5z4d@1x!gTVP#?r4)&vBS`(2lI*w~$`1#X?%a$C9udrgn7KwS}n# zebJyRlxxnh5~un}WAXn12ha}mhp7kcU>kahzx?~g(o^W@HoE6)gDiNHsGPZm26C*# zsRt|EWUBXw-8ok85j&AncwNo!$g!H=j@GZ%-cu+s_JpYu-6J>0?g6g<=PY>arqEqp4bwO_(Q|c| zkL6h1{xJ3Ce6@T}j@9y==$TK=?=bfM-vtXaqZO9JRI&j1>IyfXj#w>!iR_`e zntzdFHU9{$?=VdJIbSWmhkX9XH=ZLQZ6n8|t`^wJv0C9OTH#8VmU6yYelf>t`DwKL zRG22w_VlfkpZGM}ZvqP@q%ph$v0CA1j@1hL(F*&*)RXho^4&RB%XeULHO%>y9IN@| zPc#3muz>_jH-8f=s1;u4SY6=)eT-J~&vUHiAENagglRA5tL1ldtd?J`vGB`etb}O> ztzbG#Fg+0I1ST2 z4$^?yz+R5k2G-FA>S5acWW-xxs$)OvtLv}jScz+Cjs+{24O2soOF6#$>&8+q6{rX(#8a z<+pRJmfyfTP@mQ;u$~jt0!wIxi(#72`D*#O9INH0(P^gUPvuz6A4TgM3DZ!{$6B$% zU`|k1=tHNOT48UF)%*%tVSAWbbG}->CC6&{hMZo?@%blW{j*QR{7)w&xZ-h`HqndA zI{q6Ek@YYwBgee1mS4)T+E5$XvDPqc{Y4zw%`gq%FLC|vML%b3t+C*TLaoR#9%{+4 z5~rJk#^Q@am*`{m5&9wX4lYx{MowQsE1W>8~wCw3>_<@=u4@QFg2qu z8m9l4_Xs>GO@-<3j~Yv_p}qsHF=*yl@cDiay~!-2HzZekkv@q&a17(C$zT7&#?sH= zBF<6KLYS&ZeM6IB8pl@=kA-RY<8+Yqy3oh|7OeSCByK(yTX2lN>p2S36#7o56CD#R z_z@>^=tNG5!?!`)K*ioPP1qxCc}R<#~>=R*cGH5-Qw8s;Aha9IL0; z1DqjW&ELtLAr(D|?KiQXKmd!hq9G|k!C*-nh+BlIty?V|-&&|^Q3 zzR#O;#fZZZE|IC_61ETIiApbgK5>EL~l zzlJuv8m3u%HG^v=OqahK9T>+p>K#JsZ^H@dYYo%cW~5JV)*6d%w|A0oZwj`cUqC*6 zZxpEFkFe{G-V+rZhG`Amr5)MBjmF}iR2;lJ?8wf&E9x0Vr=>auMshq-i-dIb&M2T3 zxXiH3b0PyTje@pGFI^tUAaIc~$^&wHW&FQ|6$j(Bx)gl6ob zZ@D(muT0FN7oRbF9=mWfOr7YVs^AMaB<*2pM%V9ndt>Q`Nw0*dRaw6!OgDA*sPF%- zV?V;&EvOn2>Nr}g}0I3g06S|Td`pW*==;a)f_JtG0*=q zEHqJ36~}Q5pW~K>X#{<1H5{e^d=}+;&^Eai?&CKQZ(uL3;yrKye+b9$ z+Q0wN$AY`Mf~{nf@Sb@58;zy=;Q_iuTlj;-b!^00+$4Phxm~{1ojqP_EIpI_&Fn&U z97jp-%a*Wa!q%@xMf3Or#8rF-j%2&>`-!i9t+6zM=lFeifZvNd*$w=E#LGC06Zmu- z#;0K?eh;?d5SD(8`R~HTuQryx8;`Sl_*CKz{4RF=dYD#o`XUaJz7VEqd4{V@i{FMr zn6Q#PeH&wg_#nHDPas~y$Kzaftj59vNa#i1*_QGCc>2rn+06mon|Ld`meUt=Jd>S3 zXTwmAyU{(-h7P`l9G|U3e2C`Pc3AjE3ap`nZW`^t2)bfFTCkFB$my4Fjr4VV9OahL zH=0Xfn#acy&xL6Ot)~y&pe}r1asSUkHwg_ne{+;OLf6~QuA=1^jJaRGRm~YA_(=vLtP)+u!`>D(VX6& z(>u{U*o>Wc^Ts&Q9leqH@1R>H!HdZ<`oZH;m=^FM#PeaAz;?=r(V{5smfCA33*Z(#m^6AKj*v>|);`r@AN)*(6@Hgmk1|nk<@lub3$aD}Xn}fm6g~G3qCM?Jk97xn?!SCp-a<6Lj*f|Wybn&H zhh#YCcjLW?+tEFK`r5Fzkrz6%CA1@_3vspD&aUCzNuSSF(Tmn7-i`Ebyeqb03ts+w z#A|p**TcJD6+O}Q;%(0V<)3RTHIp!xt>T@ChtU;pUQ-mjb&6%;L-ew`jb64l&^@w} z(`V5=bvVzR6X{#%*xJC`GnUrFw2H55X8td+a0fCL!!(VqP(@dm4AUsSj=SU`ydCL- zVQNM0(QaM;Y`BbmDRm0Jj$_%uY$tw=^ftWl`oH_?#?n`D7{6i${x8n{Ol(O%{ttJ# zePP<3i`(@z^x1J1A4$i?u#0#o$KB}Hd)4QPt{kh+6-x~M+J8~;A`6%n@MYYy&4+0Y zr-*06G=ncEo(|JE{x|E7h3WiNMLk1jVLCgMa=hqU9iA-E}#~; zdP!8E=3nMm&0oy1n!k`^HGdWzyfb0y$oXpdim{*nx!?+0FU~zi3vA|C%^%3In%|#e zHNOvSus2K>)fmiY_$9{1X_ywVcp-t@f6()spjI@472as5CywbHt0#^s&XBL>Pv%(7 zA4eNd>mSRpTK_O|imqe)|F5B(pjL4Hqp>H{3eIw@R&a`L=}DL-bG}-BBFAd^ZnS(? zm{wjC^{>2$`R@wLIYC`vB*$w0aE{gdGFo9nn66$JuW0J%o0KK=JTQlzFGkS8szrS{ z9*ps>gH=J%(z<6X;8*t%)e7mfJwfspVGCa---~Wq8{1`T3#t%8*0x9 zYLDBn!U}2wtvOaJXhADb%QvHgNiAQ_v08rYdC>tie*|4$x&L4qv0#rI&}+c;4@b|> z(dYZ)9Pj6N1+75c;^iEx9a=)SSna?fR*2OOEaX`E`vbiHXTb{93g*x)QdgMGv0CBj zbE5$@{}^3g?a&^&K?~>x&7!YlrqI8#JB}@+k6_JvxPBJg(r)yamCy>+3U9_ERy%l& zZlT(tE36Q!9lFf1nty@Tr>=jFZXm||Kg$W~3d8th?hA&(bo89);2c_!+OgRjs})z# zj;I}(%&}VUINEVFf9yGTiG;CS;H}#)xJRWnKxF^aV*NQ*t7%1d@cy%72j4s^?;o^V z*E!Z=d(m#4qxGHTSgr2_?UoYPhK_TBTHp}fZnc4f9IFlNq8+ND2XYKO^26Dku}Ggp z>rv~O$gx__2v&F|uDf7Qhl>Qx)Dfpaw5MwRK#tXp_Mr`^4g7za?guRUHy!Z*ZJzrX z8KJcygnLa(=pnYHSzR{7gb*7VdRDu#o88v7yM1X!<8BBcgwWX5goc=y(9qDBW~Lz~ zWQ3T|m=Hn;4dM5Gf6nuF9M5sQKIe5^pY!_j`E&p6e)=<3JE)-p-TQ(V;3|3s&SyNK zToX?Qvf%FX<3qG%v}3j7MXb&Qw4-S>aSwhQ2^;D83! zc65vl8mJA9(2msvJ!k^8eOK129k!tZTN#gbYP%&gkJ_#mZMX4xToWc_qiVQ@HdGr< zq7579v2MfaqD4P$JowybueRUMSc%IXnqQsJE;fkOf$e;5GYWRH!8SSoHNhr&b*MXR zWUMBfMNhs4J|Ao7W8wbi#M6;I^fUF{u(YH3)d9CPv!E>sN(~*M+Tp`k#A=6k=#13* z+lSOU zx}r+^Ccog4H=rme1L%LKcK;uE(;TmHnGV$suQFCU+{YKOT`_V5{bRiHDw&sd$=ExK}Q{Y}Pd{S})3 z>NB|h?cg#C)DF(jrBf4}W~?SSMhCitzEqt?-Nxe z&I$FH_GYXe({A*fQR}-hR_i;_b4JbIk+J%kxU{n2Nuwrc$yiNr_WXD>J4N3qItj}# znpmrWXFL>f>BDN^Xx`q8)x6!$&&Pi@ss>%?Ow^_9MWo#k z{yN9_Ff4ueTxT4XZakyDD=fF4n12S*%#FKG;6pc`(cmXwD>`#^<}DekhwT32V`7YJy#KX)gw!U3)V#I}b}2_A!Br ze;+G$ggztMMOUov|BpYe`Y^xwi+HMp=m=8O>0p_0)N@F zIxH=HarWN-oA4Y>bQYFX^m<g zT7QtSTEB;`fZD-s#_9@ep(~*7znO8<4HK-QC*3mgxID5HmSOam4xz_%Ff3;u8F$J_ zbmdNaV>YUa?l^|y z=rJ72SUrYA*x(#ckKtg(>LKh$&k?o0FJra72R%pB{N32JzzsX-L{AbmK}W`Fg3Aw% zW4(!A&9mQS{1GNF{Xx&Jp8E}>&uoUmr{`S}pM_8R&;hFXd%C#(s}WJ)h&s@d>EO9B zQnh?PV|Ac=Xd-oByVxLB6YpfK)^DTzsQYhWbu~OUuK$tEEKqltM^Bb1e1@5h;D_N5 z{vyYCFf6q!zyH8z*M5QWyRd9EqWvZwdya%<5`UIFrysy)@VL`t!-7$?gAx3Bb{G!J z{rgAx9sV5Uw_%yf@>zT%1Jd=pV=&|Y!%hbP&%SXK&Co@(rr&09sQ!l@fjMb}Y2)$g@`oWB`dQZIc zQ{eTfcF>ox+CevZy{ZYiGFCfip!bdQcaO{VDBVZjH{3?wH*9}5Cd&S8VL5!4X8gUv z!MjwJt=9OkeHw?@aWw5uyYN-4Od~9v=-)eZgryz#T-va-;wMty5|%pt1ogGBj5gmn z9*stDmWtu996X0dKTf`dbQJwE{oOmo6OG%joTJ~JpF$tiM$iYd!*{H{V>@yXmRHjLvK+EJy$JxaRMs?BgTK_rkJ+{%*>4ST@n$O;LY0Wg}zt zcT-l;_ACF?tTxJ0Hc)q1%vjxF7JU{wjX%Q3r@}It<-@o``A}H;@D;?pVQE44ui+0< z{_u~L<)+ET4^eO(maTtyT>Cv{K8l`X>RCIIv3k-CpeLz%()DMoo^-wFNv+oRWUSVA zq4}F`*g+!;)DGIwvsz8ima&>(;qM<;HxPCI`HZz1Ao?pq4fN%`nx`{kC2p3}x5r4- zL?;=mi4L$q0yV*Y#_B+J(V43CI~l9>Tj)&H{F@nTb^Wig;Y`&8s~M{a=5d+?YJ$0p z)d9|+?+H!dB<<98;~A^%+R%2l_px&7-^7gEWP#dn6Q4`@Mp!ztUQOJQvD*IT?;@dE zf1R;b`LN0tmUeVSwE9j=TNbE0)Ud&lsw?vFw-Ku=a);F&GvblkjMe&Uv;%cOR~f7M z&(Rgf_)PpP3)BRg==HyWUjOT1X-DtrM}PCUdV6jUy#XztC)*Ud#I3l^0Mr4rWULP0 z^zLzW!`i>&`u8;-H~(q}b%)K2)g1=VCF~E&-CsYh?r^8*E&2exMepKEaXI5QbRcTp z){ND>+s(g<2HR+Zt&G(Mn^+yYu&kp$w6qqMVf3CpfUZOrx&kfeE&1**V}jG@AyW_O zBzlONZrE{OHc$`2`EBf=?r@f|T7QBjQ1{=@SdI5GRwuHH4KGtP-%iBMEjLWKjV4rg z*hEhfb%%|N)%FwkK|CXB`HRQ3zu;N#&Y$!3PvUj-gNSAH#pqJ_bOFDQ`hhI(uWZ(y z_GCpJUBd1^3(syI*WQO68u)&A@~5%1YiQ!t@aZtR-~FG23+PuGdBzu6;WzaGGwR`%R$j#>1y)e-JBna}_JC4)pqp z`7bl5>nJGWHejaeOvf@-XF7xpR!U7Un6WzWesm?(`o4_S`W`gDn!mf51>I3lI?<(3 z6Le&(Ca9sueD!T{*3Y3UG>M*Ut>~Tb{`X_Xr|1OLd?y*J`I-xCc=?Rt_mZF=JzMJ; z-@Y}<4=x|q-k-hbgtZQLeLQbF%tR9L(^iZgY4>DF_e#R&cg<8Lxv0A^4%e?=;<%S(>RRugzh`6kyheA!T zma&>(0X-DAzY_yKM`x+dsG z>u=Ex)DCVkR`Xw?6H@oT!0IueS{q1HvDAXwM9zO9~;l+8}`w!3=s~zlTtah-BPC%W}QpW0v&7u3N`_E>q?myjR zqk3G<22&ZU4JObI)DFfoRy!C$S4{0-IAeAH{ojlU^`j4F=f4q`^8$L6HAmTa4i!tk z9!s+rJ{`kr&h8$3SL%9>WpsD6;tbPGFI!a&<@lUyUbY4e}=A@`kOc-r&*vTI6)t+ zcF`qT%X+oL)r{5lW=3bs~xYR9pCpY{ppqCU)tf;7>_(^ox&c z|B)GWqSx#7FGPn|;nOo*r+z#gIga|_@ag5xN5>aoIYT>EJ3h@=eObT%^IZQw&e=Ok zfdlA5?*m6a_qg_-=x7!lP(M1;9(1PNVQHWsh+M(KETgGaKn{RwvdkrhOjt98h zWaDSpxIc=HXVH$P(2gdB)MveRsx9H{9X)4bkCI zSPswx`(fEdJ5&?wWUTH#i>~1D>tiCl_)1o`6a5^a4gK7pp7l4ctJ*c6w6o!k_lM!b zYhwj&(G|D}%N07H%dniI15yWcma#gZ4XoaPK=QL90zDx=M-q7&Vd=p3>hYfq6SZ4FVl~nDK_nVM6Ag!D z5S`ILSo+ZY)I7Zzt9jObCRSqnr(?gdunc3<9o=xpAv9KZ+#C?>u95zX^1}<6#*?2Rs^<8k%?Wr?~z-Myo#+m&G!ASxlnm#Bi1mWO+AwwOsyW zxPd+hoxdvX7t82C`_UU!U-+~Ke}cE)8t9>EM+eyUs%EuOS}1UY^{_nb#SGOM-e;`N z@CZ$Gh$cD+%PyK{CoG%jN~w7^GFI~}H`(|omSP&e8^_QaPd_%e_pA5*zKqp-|M^eE zOtD`8ng6D@>g2Hj6hG@Y?Jpi#8_NLU85UTr^+@jx>Q z%JKKdIWU{Hreoh1_eR{7o^3{a_C2`*Sgk-<4zXH+u~-Ti;`zM#e11J+_4)h~`g%akvzW1(XC8e$pzc4Hu~zT@PqN_)0yV)z#%h95Y|w#P zKa#OpKZvho<~4K$uD(5<@f_pla9MBSq?h-%asS|~KSJB>s^3spW5df~4t)%mKrhDu ztgc)1DO5Z9zw|9(Cz|i(o4Nj#@r^nwEcf5J@>Gm*sRScjfSASS~(37h>ES>1drJh_J8LQ{k+)Ct`M)ORqaQ(AU zCMYn`cvwc!L~5dujMYSU-x%$0!*YeTSKD7^thVpN2`17&pLpDULk#5l8{+YQ|JxnY9kDA-aHETY%7TECF7 zT0e(g*J=l|8LJ&kp_jF~|76DM{v-GTAOBm}a3*TQdd6zQ*{_awG+NOoo2OqDOL>GI z^TV+0p)0u?mMwH8)s@`LSY63k{B|Gz&t4K8oGpe2_+7joupgH7Ebl{?-Vd$*0grH> zTlF}4r#$@1IQHXdAAS${?_T`4_H)!<;dgTO&u83)O&heZ;mPr^5Hq?D%Pm%CaagX< z8L2b6%vhb#4*GO{1-$_+;Q>yg{fweFqB?rR+x-fze;aOmMKoMQ8$7(|aqWdRz;n(4 z_0a5OtR9+vbl^Scq38}vCpz$su(YBBR|npbam$NXI!8YK!dSX~^hst1n)q-&1~P{Z zL>V)>bEGD#tJ~k|)=fEJEzYopd?2V1mjdsu#mQJ(-wS$g~)edUtN}W9Oxb}s3 zHy4j~XJ`kTv3i}~{qJ~q zRu9c>#_Ez^qxTWD{wibT{O2!{*{}n(gY%5l4o=V;iJIUzW3_{A^h4=U^rP6d{}uVv ze5)C&`4+LkfRyu}J6jg03Fpues~yf}tkzGX16Dhj%2@4S938N_|5(QA{-fxC>sb9w z{O#=H>T7Z*=nUG>4%7}>Ggdoz_@6NYwS)VN)edga38?iq8LRbIXnw4||37k>1!@Op z=nT{Zrx~jW4$v74WA(j0^v`x4zBDFsflg!$9f+D|1npRzSofE5{hR3Ke>|@KHoFVm zLEWJf-9g>qd?wnDpzYLlLufm-T^pMB;J-hvetuvVtyk-JGTv!MLD@zVsx#ce2C>?~ zX2xp$2AWVwSk}=MQ`@g)thPV=Z;@ZEKghW0h7I=6gz5-)Ggdp;LOW0sY-X(PKaI|~ z6a8(?tuKiVwQ8U7X2fM3>94uvh8?a&!Is+LGTNbA##%l9KVZX-)CBt(s|j||j>ge1lh)Cb?(V-ve1*nm86Rc5hyE1Bc9zeh15pPu zXYBibZaCvvY;ergfy`vA4&>m!L;^Lze#Ywl+vxu4{#zNV`){DHzMiVutDf?lM*faD&cJt-sD#t-nO`tNAacxc)7;h=Ov8&QMKolChd#8T}21ZnPt{ zT?5UdCT>Nqg8MIunO>qRGm5rT+l@4{U?d94Fq&BHa0na3YDa?^tMvnDLUo1u(Fv&S z`!ZJB_o4%7{O8!O>4qce%mOu0E84M|s3l`HQ4JlaTL18$B3A3~(1EG>Z!=c&Um*i+ zZn`}C3NX$(Q{@p%P%J5na&aV0YfkP1f&an0@4UeJNg8tEi83x z_w#=@d;(Id3YbyEW%COo(Hfd)H7v_$qNT7bpwE=lJo6c=Ph=YS3==s0kMRs?1|8re z^7?}}9NeJcD4KXAEQ4rbHSs{kYT|aRW)zl|tXJFDGgjMQJdKV|(FvU(-#_BPfejNK zgk=})SWUE(v6^TceP`ogB95_ojPEm6kMT7&I7ie&e3h|Qhj@bP-;?Mf8=RxD+TavD ziPR2GGFCe{M9+4$gM*CK{ddt;6Pj6oExc05QY)+HmSW#2XK7=*d(| z_dok_^>Z3iY0GEvWRsKZdNe#jf9`M{eObPU)ybEhekQSh7_iEQwxKgpXVjXpI-`fr zh?7Yj=zYfOKyT4=Nv*%hSgpT8^Q-wUKZEPv0ye4+&d?=O6P#wOCg{cIdu-8T-0|sr zGm`z)gzXut13nvxuic;EH*vWhhh-Z-)XQ;%>)!+m6qsNhjnxFb_*}|+!qS2Mxy|XP z#rJ>v(X)BwQ{#KT-S`u(B>p(9QQi`k`{BrQgI`N|^Ex)lIXco4bfib< zt#S{&v+agYxAD~u6n__&(HW1VJ@_i(%jZY=0`3tH<5!b+0R3+a`okta67jh95-PfI z5!=x}9y$2rSkg5#9>8NxF7@2#&saS-y78rU{7KP%7mcrnsz)nwe6jEU zjk2*o#Yk8N@qaS&Ui=Emd&1JdQOZX?F;-+aeA+;N)n@k-;_Oz>rJan`b7=z`OhBE$ zx-s9s-*UqltfH5X+F&JPwSEb`TGS2}Ggdp8L$4ln|JjVy{im@|J{6W>YBcfvm#%@XNIQB9Uis)a6zZW^&R9JZ z^VlGtnr|*+HQx++sArnlU^)xb29xNqRy&x;SnXgGJ=SUmBN?mv_n?RN_TTcgT~68y z{NK#@JS->ZA0#!8*!W*m9EN2Y{nLvnd@+e9!*bCVpIXhMf2cSYmNE2>IE??3@}aQo z{Tsd)Ovl^U%|z6JZe^^*&9ceHf9DvjqJMTj|4|Xo;FpqcI^>549#{Xz^-x#_ke{aB zQWN)Qtgb*O`WKV;ANjcYzpxMRvl-|z+TQ}saQ%U=jcH9@wK>({;|piHoZmG*sue&gNF}~Snc2j8w^nG;5uWqgG+P*YW+pVYW*3S zU(J7-F~;wI98uuetR^_jSWU2x&R`yW3{cz6WvsTFLMPOL8yxGyC-Gpli|@dp>q7^k z4y5-9*S`h5QBWG_Ow|rLGgdojM`xx1jmd4(b`JD|z1&6IJ)WYi7Y+6qGac zx?Mv*Bwj#oJTvGYDox>Ev*Tn~I?)c*4m&bdJ8Z!Q16Dh%XRHpm`S4*eBelVO#%hCG zv;(z+n~c>CF404$?thW7y8kKu73C*k*}}gh-VFKvKO46cOowF@U4c4!=eqq+(r_QR z3Cjg~=Q_jxM)_%2meBqB@JlG~4NDigf=3^cR{`2?3a7pPC#wzKYC#(=bjL|Fgr0O= z89#h*#24sEwvn!8c~{0A_!ms5JuLSh6wiQm(MQLf@aYPEx6jAB*f8PMzkXc(9dJK- z3+_X2!M$NQ>Z(@a$tM0+X1EcSHT*Bct6^EjFD70J%RKtOgUy9y7JrC%2Agb@F*Y38 zX!!K*x$$=T9{wH!*-6*ZC2XO5Hsb;G1;)S!#!IeWZy!{RGF!R2!jD7&u{}f9# z@&T2lfqurj`u;J10j$1Y_yw93wNmBMavh^L{sSJ zfDQB`-P?EPvZmc3`Wf&p`qAzj{%6|t;cxKx|K#Lfa5mDg1N~OYWm_!K8M;KLVL3)u z=qM})=nAPTw4brMLK|rN^{}jDz1n`cih2Lf4R?5WxAO-`A z9!)$KmKk&)YU1gP)x5)4oxE6`ykY6ZU+4NC>2ZUGU09vHXre~OYNGjfiLd31p#!U- z-xWP-jYBYu9)i<%jzh4EetCToZ9j^>SRKUb5M$G0`0$(<;VnACo3LD=GrbJUIXXaf zfM*%20~|q*{SbQ0`_ekP0{8C}`R~GV^G;mkm*?h-1bPvxCkI*k5tUR0R->+KTJ&s4O+prv?ceHIZ@p!sb zj}F$;271!Aq6sgb<(EphW1{bN%_8q|JsHPw%Gci^R&*`o`@d{B<7ITlOBt&(?nAHJ zI(j)C@}SCP^W@>5>(yH}N9c`Z8LJ!9Kh>-I!EIPh(DFX~JO)rh-w|E^$B3H^Has@% z=&^4LOAC5v>S1|!s8<732YR2eI?#1A&kCAnIV_84o`tZ?p%Yg2YmUrjfmSm{cjygE zSJtZ?H!@b+-~L0r_PN}`Z^E*QK4DRxu&iXPK4DqF2G59;^PlJcS)e{+nMI%DDe=fm z#%lc(+JV}^WX5U-W9Ty?b^pV}S+cQ>Ye*E|K z>V~w2z8ydM_86Etu#t?_fem1TiKzqY$LjaL-Ed^R=*-myJsGR@UFgi!4jLJ&9kih{ zSNCttSlz#l{!Q8GeZ6`&eEXi?Kd9ae{=0g0c8~mRy*9?N91cqh{s-cESUUfv9#;eU zZMWmQSjq$Rq}vb64!V-tVc9@eQeDaQjMwjY|HY-8rohYM>aXK+nN6?%DhAep-r3sF zJ6jFC5q17$9D)}7L1wme8v~k02Q(L!8FWC?VVOh+G}&as5lv))I-q{^x11LKB088z z2hjHkThJ$`%YR<4?gta-4XAr4t^)L`X+^J^`#-2xFF+3Q-F*JP%Z8t9 zZlIrRu2?~N1HBy8L>*`%HPOXYB-%pTuc3Js(LA$R-htJA=zi@PE9XDgEgN>EUZ<_t zAXYnW$ylwgqY2ghYv^^awtskA#A^FPbR{RzV}JAe_1Y2k{XW;f6*q5I!V3`>XqJW~}bNgzm5IznJl2GYZNqnm|o3ld+m$ z3Oz(>{ba^!{W#iz+QC@H>Hvq)L!|CMlyTDy6SSjCw0RL{^#uCDVmvIJ=o5_={Ck{# zOTG5#+?waYa{XKUH*v&QVL3$GO`=agw$AI-7ng_88_@uAc{WG-W25w-*JpQFI??N0 zy*xWIRg?pt+w#v=x72zkO>T?4fG}3&TrIfpQ^uJubncG74+O#uH^fFGi>y- zwCd7KXRNNw1b%QUD-o83vq*INYteB7Kav5gyt!U|{5Ff#|1ySN-gmzm?%}7fLc3v^ z#gDVW*=Z!)#ec!sxr~-i|4Jm@`=xsAZyEU}`jN~uzK)mcQ{mGI{8{R6PU5oa#;;`m zF7*9_Mp#bXRIk02@_qCW>|%465$&*nWe{INgMR!XcI*pFH~JnM>tO-&$D<%RKtt(Og)1 z&h-&vv3mW^VS|%YJxOOXR!`DtoTpx` zpUPOPlNilEf#x62xao!+jG#9NHNkMkYJy($*Dh{;K9=|jKbaX{hUFALiTETe$2dfM z6qXfy2}{3(pGf&)*evsGcnD_DLogkdN&EyFPK0F)T|#vUM>AFr!O_pfvE9Q9I$F(m z8O^_hA8*HD8O4`yojn<5!?S%TECcw5BjbfUdsX~U)!Eo{7ozxS_){4ICARv7tASSE3Rcp@z0__4%eVd+N)+=C9d zJ1h-!z@1@fM+dA9xa|#G{}!-Ojrj8QB;sDZhkwJscJO(0v>lc$^oxZn=)jk-pZdkH zOr!4&PvXZo;IIs#?FaCqDen(U&+EDV|1AaG6ks`hUA_8Ldlen|N>~=rfvO{4$XJQX z0NOzx_K~kQEbZvk)E1UH{u}CRVYzP})@y%6gS)T{<1;2gzg|E3+IZnHjF$JJFEnO< zHeLtZye2xh4*BEsXt$Wopm~PTXIic3Q?Q4Fcp=j~W8?KC?8oO*aqu(o5^EcOns^Q0 zodiqh0A|sIL->)*WH2mU=sP8cKON5>*3dU7ThXUx_pgpe(Yvr5A>TP^K3QeMk&U9q zwi}0We?RV6>K$t@WA%o$g$?d_>Jo2etlqHJah`g$el26Qeg&)F|8c_(ma78Ziix-^ zpm#(y!Fgu*~d5Kes=@_0KVQ za^MC|qtEdsaEpPBhh+pmgpO{0yk6_Z6ZE;^aahLCJazP#cm7z^cZB6?H=YAdVD+3b zEUmk~{wLw+E9=#dN%iCV6R-Sez4l%>j=n!Ig3rT_jBEIh%<%L_;-s5L+fAT9y>`6A zV*&LCxXER!9^(Cs)pO|T6LHlJ2Ir-EInHLRUOm$|PrX_{m9bhsfz>l0H2-)N^ZvgZ zb})?9OC&VGP{wM40rZ2znu$NsM8?M04ch+lf;bC|?ESvb-#2aB*!`~ua4a+i~6EB5j9Iwf@{vEN@ z(`hH#&*56V_N(->rd$=;d@eIx%>pGZOZb~KQ0o^nR_mwHll0=-W5$E{Cfcj*2QpUM zH!@c1J2S>+)u5FE6JC8=jBo+p#)yY9?nalkhMY7{Hor9=E6`)wjULmkjMYQhjt$NU z^^mq@tRB*qZ{_;;q-n_pbu?BRJgi0sY6tfjs~udU=ZxCHRmST67w9=Nj&H?b^o7UH zw{TYusnQ2?0AKKv~qy&i-Y)PI$HdCo+og_S-`gw zkD~3`(Z_;|<#@2!LhpbZ_(cqCJ#3ayHXhiqf$z%*zQc4GJ@%JhTd(~Ao}~-e z!NBLkvi&u2sMJHXm9cuLRt0JMA@GN6B-w`@sHQ!;zYQBAR!1x|j zgS{+J8+_O5@A6;MZV)*vHO+d)YO8T{Ug|K$GFFE%gbqX9e=uWp|9*5BYJFeEO57|x zY}kR?L3hS#2c75u)dU?Gs~yzPb=!DJ{r=}YwT0lptHki*? zt)E2)s&+7wvD(2TI#6~0iHz0#9~NVOb^m)~ZWCK>nBW>43_wkAm9d)O0v(`Qf1a^g ze~J!J?cgM1HUA+xKz08EtbUr(4HJx_3Dg858LJ5fu)zS-1pOJS`}d*)RO@>(R_nXa z{A&KjA`eX#uwg-IM@Oh8XvcF>PJ7H+8n=*w8G??KNEbpYKNs~t43I;qk9J2O`IZ#QOt ztzMe8Wr3RDVIdNz3GOpi6I`J)R0nXGvAX{``hrZ||14v5|3h>Il=F}qK^CYDc5#&i zYW+^eYW+6yoOnyEU(Z;L*D_YyFJV6eRtLP8F~)yQGf#m_sy3L*Se?-fR@XDy!F0xI z2b1XKrtUwHvAX{-diALFLm3Y(T*TfcV(-@#V^YjY|rpkvoF}fvWEY}z;@>9wfA6PE9p4? z9UY8?r5D?I>e>^QZmixb!$0uW`+w@ScjBudPgdCY4mzAn+t3-F|L=I#fBnB=hk5k% z(k%WtHqdVix8lE~qn5B-&c@po+i3j?jild$aL8|moc zf5fZ)9rPorK{U}oSbEW)s%oGoZ5w(LUeEA>3@djPmJRe}%;|sUjUZl4>|*nXf@L;5 z#v|BA`J@i;_qsMwHEF0*tUJuJEdaTuBy^^sK^YaBUfVD4)k1YqkgzNw9 zbaXZyuiBTpb? zxa8gFtM-Y{j+1cUvm)WmXspbBI*fK)%XsfI<4|m)UvpSR>-+H!odCMzr=P(@DL+6j z>)TJ~-Nh!?;XWJJ6wHlqc`>uaPm2!EJ~iCLI}$A6U*SNOKYR)+#(tOR|D(K*&tm`i zj7QN9`!lZNJ5YZ!%z$WriA}HTGd8@gPs4JIUe`xqIY6&#^}62ASiP=S(Z3>CKoX72 zhh+l&q-YHPnR8(@EJNsb;|GVi{{3$J!Sf@*Bzh8d<1gUuC&yX3gq9DYZ%N;MQd|vl z=qF>XM!pAZfD(vy$pVUiBE(aUNL z{c_zD{ylLEdIQ@WjISllqaDwMWgP9eh7Ua4s<-Zke;@HflMM>W725Cw9pO595>29K z>&?eS{UJKz8u||LVu=|K^bPTu;oxs(<4foOk^iF!(7b|u8 zQPow!pQf|nlFWr=6n&Ix>*eD~PMX%R+5uDwq)Dps?i9S<1s&3nhUf3Cx)o9GhWchqaYMhACcS;Q?8 zFN9^}y&@hC%l3Q5Cq);nQGOnlUi9lrEloE3y3y4;M~9c;(-ZWQ-VyZYONa0|-ZI0o z|D0&Q7e1Xs&!v`h_nqSFPP1rvPkP-F<;VEPls7kWV-kH797cCId&h7CEnmvG2Ynu} z`RsUsq2BQ}GFIZUf*k%W_3~cMSiRvb;yhh!xnYBaDA-aP%;B<6&Cm{JGgdp8LSMnC z`%h-9?%#(#bGm;VpSho+m-7soSDoU>bQY+I$Faf4)x={NtBFUDk#DK>!x^jfgJ=ip zzy~r`^Y>!)-Vj!=|9i4PP0)dUzmMVYPLFu#^YfCqbTU2u2VQ?Uv#Ec0R4tjhWRn@IOE!uPW~|P5Bx7~PL+Bw< z>jyJd>-*6|qUP_*xbGjD(Lpx_9uqY|SH^0Bc68|<{{B(5wAbhhlymg^6a#1nY6txp zs}tx(C!kgSjJujqP&&~Ws0}(YRtM0AcA$39nz7nJ4V{3x|HIoOR`)+aFXMf5#TU@0 z`OS{p*ky13oAGsYMr~Mih*gIfw?4v!A+OuQ885TW&bQE}SJ+8#FRj z>#y$~Rc|DyiLWwN;=SjZYadd|2 zK*lmw2QrEc@~U}8GFI~pqx)n0Y5E`q9&2@nfsEB1`ti5uxEsCkEdO;RPzSJ-u{wY` zbO36;*^JeE)96Y~|25aY4W_a{Z7_k3Q0-tmW3_`3binHV!x^jl@BUTnukOE-vAX{T zHWnAc+2QY>X zKrXSrxc(0*Z~$rt2N|m!?4bit z>vuC&>$lMXs2yx&tPWrmy-H-m#3;`q3sEb~K767{Ths5)Jsvu!z+ij&7m@HQ@oezdE4RtXJDlq7UbH ze;WI#``u>Tbi;<%Xd*SyLN-u$n9o>kKZ~|k+u!_2bfC7s&RA`KiMChUk4AlS%MEuJ ziGnS4haq$ab%!2wCJTQY9jW`xXRPiwi`Br;{YKD_TD!AcE$^yg9{=5-pfs?-u~HLv zW~?UeKohI&+t5R$wr|Z?ZC^(Re19DSxIteP&tf$|S)eAk`=dwIAK87^^gr_rk!d1_qqd&PSZzIl z)j6N_;~A^Rl-u@p(A~n%o#%iK1Y%owY(PqZ# zK-STLs`YCbtMx1BK-K)qRm>UUh8--RBUKa3XRIbT{ewr<7u%2UEev=UpTRZsc~dvq zf!aY=#%lg{Y%oAIf19z75N_B(3pxX}K|N!&{^2S*P&>HKSnc2joq)Rkb;j!co9F=5 z{Wq{_fg2`R!3G0R6D((}CRjuVsMarJtk%z=`P2?(Ggk9Yp#xO+pS&Kc|FqREQ&<@lNhBH<>=tEabP0*XM z+Cew^-um!cqa(H5AevXr+k;+p&CScGP%AbvRy$lrN33?Rh7Dph@oL6u{R-NVy8kjd zV72{H#!B2QcfS`qr~|moSWR$=cBm$}$XM<03>~0af10sce~b=D&3}}!`VLX)&jPhU zU&iVHy0Ae9Y6p#s)ebt)0jTxu8LRcJ=m6CGEg7qi5as@NV~NxRcNwb*PVlREX}XWo zBvKRYWvmW#8(+&Yox(}lsqH2+R@+UW4_(99bfdw>&vVkWXGKfKcfa!}e&r1PBxwzg zd4F^@EHmhS4fOqzyNhrPov}KA(Tvpr3}S;7!}!n32eLq&aUZ&*>WcJctk!p<9jG02 zWvq74fu3~g{_Pp7``^4JUTfdHr5O#bvp{WdiZ106`a5s^S+6GS%UEsSjb2Vyzx}B8 zbF9b)`U98?=vV%y@Q9V03`=j;cQv!3krl1z4mEVi?|+N;KYU9%EJtYKeKg@-ST@o9 zme4oh7w`?#&xd6iJw%hp3T>&MkvAu@Kq)8#Xv6+2R~z z*M8$s^;!A~zJ>uThvoR!q0xuGuoFgA$Q z#6uaY^@HfSqV7L{o*P>Icu9X2s5`WvZ%1sNJ*vGU_Tf8Y7rq*Ae=ROUb$~Y+s~udU zm+LNi8LI7eGFICy;Y+#xpLDu`J8zD}>JHl(t2=C-EY zY79hef19yZuMjuc@UNebPs2s@Z++*{zXP2{?-PS~NW1f2iSiA6E%5-_zAww`Sp7Bi zFUPrXg`NwSVd=>7wqNG@x1u#Gc7G`nZKECcq953Fq8~4AoW!wLkM(-S>Y-ajkF`3} z1@xR6!0L-0`0m7Q=tkvWH2pbJXswNuFSWPsDE~#2Skg;0d zhYnQjpf_W6pk3%d)%_b8YxNDW8XJ!E;OF8p>p>H$3A-~^6Lw&O0jUYwGgb%GiVj$< zZ^>A#uc7(X>wo0ojZvU>aEp#uO>mR3n&1Q-@WWB=hvvD@Sj}^d4phx^m9d)V;)v_t zk+M-WI7ef(!6`aYwS$w4)ea8PfvO!GWUTJLfz`^sA@UrcdG<5je*@RQiMAH(ShH+ z?on+Y&+(^l6Mqty(XT6wp^qg4Ve?5Z8_xXv@KNnmJQkdV{26x)NFC5n#_E9ju)&Pf z0rh6A4yYTQv0C4iv0C4W)gLdrVFw*m0hd+8r4^mAnxG|PHNo|3W8j$K|2uRd zYWv%al^^fp2?HDMpblUtV>Lk^+M$}DH)D1GZmgC%>$@^m>pRi>YW|LlG2S6=rJ!1B zw1bw6)dW`uv2^`tA~jK8#_B-3(1EIX8X2p3I?#ct_3Z~-{}!}ogI2TywS$(7)eath zCI+e|xX)PaU=MvSXcWz>wj0SJGJx)%JIW z;Sf3ib^pPPmAF~@*|0;cW`OQ^xgUuR(0a9gKVx-(d)S}@wS(P^)dB9H`>XA@@tz53 z_56P;3)CID(U)GG_=toZVQEFbH`x;M;{=bY?@g-To4n6h{odpy`gh_>KN;UHXn)nC z+BE}J2ij&_z5f>los8JqjF=ns_&3trDX%9tg|rDs9r zmjaK~?T<#{3v@?y$McNU9Z%8rJ83&QkhZY2V6}2#S^ts9yMne`4$DH54I9pfWd`k7 z?RYw4wd4DpSlR|UfI9vF-o4^c?Z@x}jZe@+F^aZp;4AUqhhzVTAL8Me2d(A-8_&>i z2Y-|Xo$38{oQ&$y-({?xYzyc>)q&1utPZpX&3E;KkE;KN_6Y4~7CniTJk61rEKn2o z;{gpD_!?}>`0fXIr9`}fo>YtIQZ9sL4qeIFuuP%@R0lYbu{yxRmpdT7Av#rU@MSzS z@gSObAS``o;@+@yqlwkTT^Xy1ThK#ryA}B^(R>$SIYaZEDv$r=m<@8RF=I8)C_1n~^xWvd=8sTt^Zjv*&#^jr&<6Wx{UkboF?0Z< zVHrjTFcg*nbO7oA`ZHDsaQ}VL&s|t9zR%bHbaYCA9c`z5>B;xTxv+({>qiIHjSjSd zesSw!Guj=ac^1+7S+xCRmiMQ}FN^kjFXQ?*@eT#LhMr_2X$`A^eNXJLini-O+nsJi z`7T;Mg_a-x-*5`u|M|aIOEu$y-RFe&VXl5u2de8*dFAX=)rC&vtekCl6=+ZBQ zWfom}b?Ij^R+oNfJq9qIcB6Tlootx6BP?xb;?}U#(Zp(E|2KPMHSySYMdI#s_dDYl z?}ViVpJ75H-w_jCSd04kuvvQ9@ECTYOVfrf&HcB>3Y?(zedvh0(E)dbr4t=+M_Ag> z0jdLT%~&09=eIqoeIYCU@U0Gv>;H<4AEsazUxC-F@nyOV^oyDc=wJJ(cf$FM)f?6{ z`h`ukekxPNNj=jHuj zSlYkpQSJNq@uHEo*eGW&iR=Faz5Wl-JK+F2!^uV7Sl}5;YdZLqk7{R>_u?13f;f%W zFMd>8!%J*u0_uP+GFAt)g`3af8{(VQ25&gx3mD;ASUSOT+l`~`2Jkh${@?xbXrPX4?8~C#>u2Idbb{W9M)B)O z_%IjcbNH(yoDItuzM1&{W9j|_viyV~9E6?dQ2?u3@p ziVdNN2`55k8WZ9SAvA=>gb+?6gzSV6LI@$mw(iiqT3Xw#?6$Oo`}sWH@4p_$>-hXU zKF5#qM|E8jVX3441=x64u3j6bSe?ivR{wdi8xDMqo>TQAd3sGWP#Zj;j)c#gp!~O3LHmVMm(E-#3OZdn|r8Zd1tPa?L{@(NB=f;X%E?AvI=3xGL+qY3+8(rG1uq@zL zvVRDx7a^=(gu>E;Q`GMcODB5YtM`3JX7#>reCG4EW%{c(+4v?l25||WJ|lhxq%PrO zW_3k|(TSXW`tvq_xTMxQ&8*fNZ^VI(g)<{qr``Rh@i~FJXcuS5%?>tPf%b4_`%|A+ z{}}l&ek*swP*?`gm**OKdv>6==fbDNTddu=_$z{*PmUGpMpvjSEbaKaWdG+9EO(z& ztx&V&hD&rCJ6h@z4WUoC8hQ>7XP>tnF!L7ri`px=#SwJix8UO^@C5|kqWcff_B&|% z@tOFdq8ERZd_L_L7QFuVu;FiRs~1^!X7wUF`S`dC)bdUAJD$1RukN4DthO7)75Y`n zM>4DBV^fUl>%SYG!%=sT)pIz2H9Al`=+CTnP(vTtYI$#FwY(GUPwl@Wv)cdD$8i5Y za(lU92ajl0JGexz_A~Tco`&TJIfwPbuj zBf01k$lN#}5p0Y}sRe;X^-7tXY2Zp+*~9xI?8Kv(9b z8y-Oix&rD7?0;}HP#f%JR_nLW`fB}EY>?Hwl388BY4m}mmQO`)w%oA7`3J>->VT){ z0BVEPELSHmo8@ZxbY```DXekM)&3?ktL-PS`u^Vy8`RNrtTq_WtTq_L&t=IkKJaI5eihrtUG7i^KF0cUwIYx zzZI5qhgx9~T{`uM7BZ_x)Ig6&Z9kV;Z9jzrl&j^Fnbq>4fBn4rM^nd}AMm{G8@QPI zO4$AW@qp++9}w+fd3wKiK0Joy9(_Kj&xgCr>hqz7KDxWne!9Zafj(#2L;mx^;pj;1 z=rOa}(G7kbkLc^LT;UtYmton(uP3*{vV$As?Xaw(6IJ_P$*g4l@p3jCU@f4kYNwtxJm-2dKYY*ZB<(5zOtLkCa? zxXr8%aD|UNvef}DGpp@)(T{Ykuq@*R53JP}W5wrQ%=iDZ?BET@O#eU0m(g(M_#ej+ zs{$xt_TX9oT>S*>A^g-|KnXt7*T5UxD}k=y}^0;x78Bd9pA1-+e`_sJf!fR_;)j zbQ5dLT%GwwW_9Lk=qb|b$TF{H`7(OS)B%<2}>KiA`zaRmMo z$gjcC_lVq%UrIiH_s9)gCD-wnS&=cc{=+|v{aZLszU+-_;UX;k_)6dZpZ$XvaP8gV zWZCb*6R0vPT6ot z)e0w>)fG8HmsB0#Fta+qWM;K|BC}dPf;IYA`ybA%)%SmcY&Ze6!a!zq0)6NN)B$Rl z)d9Njk#nlH@64>W-+!0qZ7<<>N*8d2mAilE_#M;wJ9Gd02BMQ4cA$39ky-8F=AGh+ zc7fL4!E+ozJM2X7qV4XuCRVXJb@&_9+kMBlX7=A9UKMxoOMEW81NT20Wr-bj^z`=8 z@Ukl!?xP*m@R}7;C%Ex;k<|$vylq?y2QOzy>3BaZ-RR1y?K;twR9Eu4*%>>o(H&Qr z)up{eJ5UF@z#3WY@I13xeufU9wm(HzR;_=MS*_okV#7z|WLU<~tNZ$8aW`CrEEpenYYymL>EXjk(-EoBK!5Q`MP1zD@iq1KY?K63rJ^*k~|gbp@6)t4FYemvqoT zKR~GU<}$1GW|0nGtfK=CW$r;IcG(f%``6L0zUlK>AHn_{IHaJ9IT*lG& zbR*~+mf^4rpl?|E!%{=vfT(XkdNZqUKyKbDR^SMmmmHBB9?=Azlhs_$tRCSYI)OfP z0=2MoqZ8-~O9wgubpq{~)d?K8$Ezd8@Bbg=4t1bzbSc}=`+fU)%y<%=uvQb!JQ2B^ zJc|h)q7ys_%Pu;>R#>*t32r~*{&$93xkH`dI`Y-&i*x7?i>_XX+ejVwGP6423-qI# zdJ4}ntNApudP;ZDPfR;aHtcXacc>lCp`T#X4rVi}9ZaJiK-BU{^f{sSH<4NGZyc?! z)*s8X6{4%pzevbC9_J0<+*>b}Hj?pKT z+QCs~wSxn6$<*@w%xd`-dW7l#o0--A*U<^8?boX8-~YvqvVwM?cCegT?O-1LG^}>e z$gECa5{GH8wx7tXwjcTXXK_)Zf2wiux6k5Vh;YLWkMYO2=yuVWYBf;iM&vSwu7o=9 z5PG-lK0T|xR_npf;i7H-o3QrR)aM77YJa_%wR-(u`ajXZ9D2KrXC6R*@G#6j73RCu zetadK{^hf_*ZDxgPsaYt5B!T>z8M`s?uHka9-_Zl^md#M`4=RfRo|A^ANctTUz?Xv zc6dLkx8q1=^>%FWPk{O0*~ZuNVzm{PDgH^YX$HFEp91r1wmtO7m+zld-ybf8GycyIrhK3A*GhtkI#`;ZA0?d>b7=ZNG(H+-m*J z%$v>FQ5Ml7Y@kau7nW)C2MbeSnLt-cU8#Czb)|a$$FsK2V+Ef6dz^w6n&&eQA|G_- z2f~@=(Ov8~3}+TIFJvChJe0XBb7$t${}$~}!kKIS5j3xjX>saQd8--Rrn&+^Sb=KlA{H`u_LA@p{-<)3x)V!T2x z#>=prp)aGSVL3uCM)hJm%&cCFv*<^$I{JWmy3XeUHfXnW&He9EE#?mONT<*VOyDPR zzt_Vugf>*$4Q5u`-TcwBHs2$v<=2_j@?&%*2C=#e{-_y8UjIWHGShyvpf8*``-7Os zF}e~*VcADlVlON^=t`(7v7K36iN~ur^7Y@3Q>spIt(iO4Vnk#{ik?_FQTsniOkF@ z)!da?9k>&#s~;Vw18d&@ZrEXa>}aVK{1px~z>u;k2sO6hzdv!vM z%xa#iGOzz`IKV90f!g6T*2rpyQ<>HBNpt|U{RCD^8|C$SX0`t9@5aTqj$UJH%D?_M zGoCxf!kJ<8W%TMICZtZ_GPBy@IXVILh;}loc{{T@!7Z$DKx%)RSpDbaZrI@l+M(KD z9X%qo!CGduejj>`bfGW5=f4vZzx?fI)mJXt=#g%PGc~Nftop6+;+*^6C1;}=;0&FB zR!5Y1C-Zh@t&Rw7zlBa{6Fow8!W)^@@^!R-wf)*T_rFKD78UBNXx8co@nd-a)xvW7 zo6oAR)B5q%JTC@+<5}CMQa%utonMc0yosMe`OVq0wmHhL!{WbH;)*=|TII|@GdAY? zb4LgIgu4CJ7~lwfB+sL7wYt)qU&%)_`h>g;%P}@MLUjd?GOI`2!0JcmK<=)ap{-WmZ@220b-u`E_Qs{1WM}*>b}HE@DSZ9pDr_ z6>0}3nbi&!(MR_FFU3W;gqp@NQ{6r?yoq6>ao>jkMar*Ol3eordM?d$h?c->F zs9b+#kPT-%5Y8MNGZB_fJ@Wm`>XASEY+RK0VcA8$<30H4XVn)JTD8l(AGtgoJ*&R5 zc?`=rHqW?!kJ;cqAA4~NPjLnP9gn@A;_WmuZsDt$$WB=1(Q~T~)X1z(Z~_~YtL62~ zYWWEI0S4pq|8VY5EA*lRs2%iVR?ClnGA>5-+BwRsUORhOqrKXGH?!J)2kn37Cs}_h zZ08QO!X|pPs{?FgRtH$c>N$b7U&*YtU&bEVtL+yvtGR(*taD8^d?eO!h0kbehvS*m z4!hBhVr^*0YDZ5$5m}wsJ^Dz#M89%9#R=-G^-nUZ^_z!m*r8hCAhTLw0X=Q+)FIk>w|u)$$$ecscL?r`hoLc`kpPtDg?l4lgpR4NlO%a9YL&6ICa^lv$nl zBKmz{1O4^8xv)&2-=NmRGJ?Ow@Bh??-Js$8kL7KJPGAnb2-Shc(cgUX?VOc`^nR^TO|06S=%L=n-R*#^DUK45uy_wbWr~kmqHRWpgV`jDd7Ci-f_#vEv z-5+^Y{k_pDRv$!~Y)o;)gXj_WXI67xW_1O+GOOhsnbq8$S*`!DAE!i};C*Iwg3U`d zyp7Zf7n#)xhv;pjmLFtR%l9&?<-3{H@+tJiZ8Dr0!!^cJ%A57k+@Usj{NcE0)FXPx ztRB$~*62VT@H(^F{t~?i)$)tXYWW#@QL2CcUq8(q>HtURMX7dhm|5*$3GG0g;9_RA z{T$YqfZBdGv)XY5CaZ` z<^Biau2Ls_ml>}V!)NKjN=#akJgNZWe{D7 z4*V&6`2Kk0AAUdgzXKn#!;TNotaiMEKJ&-W*N9r?v+wi8gGXz+i@w}$;|DU4t+1?S z`3O32XXc09Xn)&e!-iKlM#Ian9A|}|@8#u^_Xl06f5zbLqfYqg&5_j!-)2_JZ!)Xp zE9iJb?&lh7y5U7Om^;*qtcEoPQakF+taj9mUd3v8S7x=m9UVaJ-#@D`tNlNGPjwMD zTW;9Fee7td9o(Qts+M18R?E-PC#O2VS!Q*BBXs2s(v>V%>n~TC&;M@NU@j}D6=pN5 z~IrnOi1l;9i6dSzLr@nUqL6V4zQeA9bf^S zu-bk;v)X?0ySe{;_uJ17-TSVbF;+9qyc@Y}p%YX)+{~xz|1*~R_4ltit?O+<6=xF-*o$<})E&8r@61^zZ0VXo5D>8~sQ0>3J$wq@6 z{kfxtzTB!6y3qz|?#!%C=zb^KtL1l@)$$v(KehZivs&KlV#5_sXWW@to$=Fm#FDEW zJZ4rqxJM_bmfvMo%Wu&B)&8$DE4f)N*l@|!4$d>H9h{;|zJo6D1lpn6VLh`t;SsDc zA+^8Z%xZsw=!CWU`~QL5p;oA&1E>S^W>yF2LMN;a(3x3n-+_MN@bvBRg~MZ5?vQJv zejAo+tp5Jb4Zm=>at8yeUpVZeFETsnO1hZ#p)2zEZBcJO-9=Yy9W7tU{k6*&92bN`Y;H7Y81jlLEjbA~-o2@9n4rlh!m*sx+WqRaI z@ePQ2YKAkbr)KAyIJKO6wS4=Vnz3U$c9a$L;!rCrXI48HM>|l<$1{qk((_ytgwtuK&`NpSuGz! zJ5b9{zYPn_2DnVk0_G%g-~b<;Pe( zpwd-z0<&npYP;#oYP$}s{)Y%RtkCWb8mJXczK+cEKz$G$XI39X`&gsC+I}yy+P;NO zKrP?Ntd?(K_4(fo2iQahR0mi?pLA*mtC`gfmT`dr)bgdwYIy@aAhmohvs&K!b=?0B z$VN4R9xIU533OnM4%80XGpijueQg|}TKEx$+mQxEViv)cdl*K+@RgxBn_gDW(v z9qge;pqB4uR?BzLuh-N8W-TYHc{;N?U>$4pr}j7A%pK#gql}{GOsz1ISsic)9Y7sm zFta*9A9?_4`&wqTeH-@BUTxoedP9EghIVj^PC)J8CbQbXA$r7W2M3we_APV(wR|VD zTE2nyuk_cfujdYRfJL+ewS$GsY6r7u2kHc;Gpp^#u|c_7K9*T6A3@&{Y5e=2xnnph zbmITZt6@i2+VGdjPwSQC0soGCAC@irY3}z8{4G5Bn#g-;3*BGGU+2|uAnmc-|NW~g zE8KiFAKH25Ux)m4`?I!RVxWt#oZ%_?G%UyXi{zuQ9HK9;Yv`-!YB)2B{q#E$mH{lR zOg}c+C^a@bf?o8UOAq>^lJ2l{;1sz%ERSCmZ&cJbE)SX2H!c_0-@#it^c0+DR!_k( zI?mBoasNBeAv>__p#$xPWgC4*qz<%|SsiE|C)wW!%M`wnBb^M(7<#0mVHrjbbO@cm z;8$_~JAnaqIDr~Ef!?rmp%YLi(3x4Cz|&fEc#ESPv3kTO=xf69SH^zz$oJ7xvlq@x zHrcr4>+;E{P@l-GHn{tW7~l+7Udp#t=m4jg)p~X8SLXuyfKhM1`ONC=H;pxJFSWy|%xZ@d=!gKqT5o>pT;)OwGZ)p{5BYaGxCc6xy5-O)l%!A@nfZDuZa%!V^l=*2OC zUR?FCjNp5)#KU13L@%y^u=Jr5tD)_?(QB(KEbZvEm2Q96A!sY)FWL*2U^BYCohF%5gX)%u*{?F)OL-`>I%(a(+Y05qZj?a(T)DxuN_}a zL;nr~%l((e(%pqKNB9@iTS2d#$1jPAUEuGqzk${3KRSWA%<6a-E8PDc$?8fpTtpkz z(FP-#yE1o%<(}Kti%hL|ms#z20PVLA|0ffB`r_z!8=a8aZtIJw;Et`>QRcE>HuL2d zMMo>?V0yP4`}ffauc95Ugk?JS59R*B+<*0jQGW-k`pw)ikvr;P893|MO#lbLlv~3okDNX#L*I&5qphxD+!xK`R`GWjFUP=l-SKfBX6vpp|Z- zD>09@AI$x|x&Q9-V*e5T9rbpR`uzTX7A%LwUsv?V)sCKC7g@<=8>@2|xxR`0+%@V0 zYXiL)>*#|<-9MgLea;MH^*=Usq;z z;_Z0mU9uPlpw;*P$80!|+HgNBs0~|Lu9k0SR?D~06;LO(nOU9K2EG&Lz5^Xc?WY~9 zfB(Y`J9>I;9HH9LHTnR$M4yBgVL8EnPd*OI9{MEQ4ND8X{WkEN=ZiYvdS-RJq1ST% zJ0mu#3WI1?EA*pFu1@IqHMvq~hew&!`Uhxzwf+KL^XjM8Z)8^MPrt_dp9a(Hu)!3X zm0TvV#)Q-kCNirX)Y1BC{c-dfQ0tFnR_hO=pP1D0p=RzF$_hQ$#TyB=LU(4hgN@JS zC!{Z7Nzw8K-f~e*;cxL?a55}|=qc#Maq6q}dorv2H6ItEL$$&}W;M@eRvS#?JMts{?FgRtH!@-#5(T+jFWKVVOb?Xbk%~5cNPt zK8yR`2h0#VoY7!dYUqS|!_t9Hs68xg=!EX(V?yeLZZoSB+C@*9I$$fax^kQI-2XMs z`6fH6BSP~=*%Q+56dumYKOvRsj=a??F~y0dT!g%i%lJ{ zEweh{!)L_G-JmO{*1OKE*1JR}rcUf4vsVB9|0x@OzCQ`e5&E(FFf1GBx8&>ic3jnK zVOd0fraOTy?QlAP*015)QolDW9a(<*>0DzRm{#}yN$yZ*JdG~3dPGy1)$$4Sh}0t* z&8+5Ow7uGXD6`uBrjaX#{{2t=I(MiQTId5u?QjbnP|YjY!-Ga`znocZzlhZX3$4G9 zS;?h=o-&Nz|C`GlY6sI;T})^PQ<>EchSAS*HS{9u#_FS1SlV%lc5PvK{IvLFrPU{` z%nzT&{qIMuJ$87}ZKo?}$7ARxB=ty#vU~vj=+z&VK5UR{VQE9#AAf4JSKIHSnVVS@+&oR0J^~~xDj9`r=R68Edtghf7y2NVvKxVbP5ADC{h6B`chdMwv zR_|uf4!Sa{9dx2c*pA-cZDG0pl(@g|!g7h;-WOpxM_1qoxxM-RpA82%j2$g?fIa+h zo@8tIa&Dv5u&iJwc{wbj=o7C4{aoK3&K%Fh5vm7xlvzE%J*?jUyWs?Os~x;pL@qn% z5~}6fnbiqyqD!a_u#s6EU=>|Kwf#zFwf!Q#zu*7Ov*8jp!ZL+EA}7OAN0)FsETiZW z4x&#;b%24)>HvM{Yd|kr|M1me3;j+=tNVW^cWBiReWG=u4Lj1iPmXiGhu#(Hz}slO zP4ueX2+KNpQLlw%6>X=sTlr+}e|NA^4ZNHc)QL3Eb32J1$q0TJc>q1v{o%~%Coy4; zNbUF}v)a!l`p!r#-^jf2N!}fX2572V8yoJ?~V|CV!tnCtN3bq#fbR!zado*XR+c^*8Z<`Ld0_O}iC*nRiK8 z7VzikXFi;nLl3w)%Z3-H^Z4u`~xn^^^XfX(v6ReCnv_= z|E=c^_0hSEH6Fd{#FjFv11+GBX0?1ivsylfKAP1>^K53d|4H=GJo&NB=wKpus2#MU z9jG1nM?hw^gZrtNpgMuO%xe1^bb@O6b!N5v67BD@$%X@5l6)%FdnF#)yxTxPZXG&;ei8&;Ug9cqOMbO3dLdS-QiQFMZ8`;p9Q`-hK-_G

}aVST%a>l%g-~b<)`Qb)d5a2s{!0>qZ3ri$1|(tqv!IBX+s}nfH zzvTfl_3vY#VYI);kBo^ugfo|!FEXE??TIsvu(G_zWM zj7~u9zj>59)Bzfq)e3W&)$&QKF@QS2L}qn>adZM|`B-MPd<30<(qFSaoIBJ3ZYH9F zI)UrVYWX?V7(gB1EVDYm2|59_{5Z2(euz#$tKa`W$Q|kc>*!UlcCeON?O*}DcpB){ zJdR#;Be{PN{rumL{H8>`FD%{oGqij9@Mw33C%*qbbHl3<{cdJAEZgW;Gh1O5xuPygK{ky9E%r*L+?*jd_e2zSSSTZ*JxO^OzL+o~m(2vUpnbl9r zYv{yQ!!n27=M(5kjG-&jh2EaGANH*6W7vO=PT&-M&w27;-2ZHp19tePb3ZKG=$p>1 zuxz4lp;pmPJnE@g$*i855%hC_T0WdvEw7<(Sk&^~599uKM{ibW$KPY1n|gSF4!n}i zqHjjk4kk0J1B{^c`_Zr6)p~uI)q36N3UxHusNTzc=(D!JW~nyt(j&!Rz(w>TS_sS9 zheX3=w0s_)I2DbsOyvGi{2TUD@z@1k!W)fsQ){>j|0 z?w`o49?2j&asT4PBY*thXKhz_ga3yKT!&>Jy=eEsnR(<|Xudedh8M$ZSSIjKXjl)+ zFnTQvg=G*O$UkX09?7icKJ<4- z)ZB@FUbq|Mn!#(dTq!SC_{hp$hUFNW4&a6z?Bc7i6_y>e1GRiRv)bV@T7M}li|EU> zT7MS*iUFrX{z2mCPc5Gu7!_tMeSIavyE4kdg zD(c^c&&e7_xNw3Kec}IA$O=9 zo}(SA6;3m&ttMyyxMXi=^XI65vY_Z`*s8-m_tadPg4?JK- z(fhs|y^YlRU76MT?db1(oc-&lzmNXJRIR_4S*zdwoz8-(u-uPE!wa;b+VDKHI?#4z zwR|hHT0Wcm$FO=$$nyT&-)HvozZ*7a%L;0TPahByP|HsSzb!VHra^7(m~6s1xeXtWId>|A`5!<=dIn@=f$jr+Qm%WZr1Tj(7| z&HT8m9xM6%|64X(@|&=nqf2=fmQ(Z;9HK|84seiJ9bgOnWfQf0GqYOWKz}Nx z9>AR0-~V&NBj`boP_59NSuJnJ8Y`p@(3V*p;Bh!sP%Xbl`&0Y7%dGZyjZK%#4I5mc zS?%xw{cRPs{5-Q-zKcGJ)$&$mwR{VG6tAPFR;{<18RPyRVaH$avN{}=e!M65h2`OW z<3&mB;6AfD&^7)!^{>LRkDlvY{2%OZg=GzWPpH*I-k1B|9jmdUjG^aHtuUHd9ccSs z^6r)+8b*&?tv87MEVa7S1Ng_(>&0REQ|t9)R{MKs{@<}Q4`_uuv?H~n+ss;>Gj!l< zwEksgwZjcF?bY_{nbr2oSfjn#zPXe;)D9NVbEQ^jpdG3m&Sh3RoIZ$eiGpj%UFB5EdL~4b4X0@a3 zf5v+@ZzKFz%GbiOieBYQ=;!&xur$z*^K)UD#%@+b{Ww3BS^fWi%NQFjnYu(H_@5cD zhFe^{>co08s}t+OeahAH&dh50-C%s~KTG%UjZC8F2+I`uS#dHfqv)f1BrL<|qq`IRldLxM3yO#LiLY>4@5BA?XS5bO9C!=O z>cFd6aT#49b%mDDH?3;B#ms8EY4oGm1pXH$SP#nxI*~qfB3(^3JhFE5$lAhk|4*N_ z-O%tZESKn!oTn$~gw(5i71zjWUdgOZcmZo(_2`7>GdJCE#&hUJs8*QGtd>uq1E>Q` zW>yCnN1p>~`?1Vw`%(0XIE+qQY1b?RZ1{CrANrNZ^^5UHRy(@Ntah}A-oI-3Zf3Q- zA6?=ebcs9B{x1gN)T-^ytIX$rH*C0t{=wif+Mtdu`5<0$pQ{af(2J})EL~Zy_H*=4 zVuEV@!^~>=HoDSU{r=BZ?ocbNp+~58u$oydUq+WuJrxsJJwKwnUeB!7A4BV_^+z)+ z-#_q-X2YfGL65u*eN|K^@br%(s~w)A&xd_}SInsvY!YRy%ljWqeV1iZ1y z`H!Bp{UO)TMOe#}j`#a05_P2}8kFY~F{JGsiSf(;hW*)%br@TKbd#{L7wupAT5SBW6&ei?nnbiT? z(Un!p+g`!_?+!Mq3K#!Z{LR)f+L2muDYM$qD0(sWpyyJp*PU6dcU+5dwfrcvTE0|! zSrpXR@zZbm#c%9>&t~gAqVF}dZ?)}eX0`1^X0^PYSuOW(#oYh&?vant{?z?PnbrC$ zA^#yR8y?)lKa2)ygZs>CgQLu9`C(?QI?VmcnXh|e_0{@UnbrEU_|yJEOq~rM|7ykY z%xc9B^r_v3zGr#*2bJXx{UCiCmJ9R_J`c+odSFNB2Whqc!^~Q}A>L=hpTcb6gzv^I zpyFm`bt2Q~L?+OQ)Wb4@zr*!99F{(GBDJveq7&&%+tKlE-;Eo>bL55t-k@2l0kIko zs{z9@g1%l2houjz0mIUZ)qv^4yGFi7AEN4bSMSOV;SM&c0eiFJZBH~f#p)r6HaNgZ(!nlJQ^sBbpK+DH+zq)_)U7AsGGssj#ZR$s`5&_DO=Lw|q0 z1N|ZB?K{QKoo>RJ3;Y#M)p=MB&>y<)ho!mAhQAKJ6_yS3*TL7rGLK#p>dYINwK_8V z1?o?R<)%A+k^VX?E%bLB*3ln`t%Wmnd|TcSzu3oykN2l{jHSQE_am?47vma!5d*J= zr5~-o^A0RIE2OT_c4l>j*0IKts}o<#tWJCdm;4WL+_1uOwS%W{R#-#_PzPAZtPU`T zzLikh&t_H!=s*vk9X)`yupGWUe=frQW&AULAl}c0@5H;^LB8*b71+cVIk!FO>f7<4 z;)v7%S2C*up1f^LSe@{3W_7~*Sfjn#eh;gE5X%iaXrWiBT45)%TE2y@h&sS#W_5ry zbVbzmtC`jI%jl6mzMLPHa-i2Q=l*|WHv$G)dA+P#st*?W;3e;Oks7K zW%*=gwY-k@ul7Iwa_)b3jK_{Lf*yf7z;I@@gF*b?Otc5R-5xsQs=g0ru9dstDlF&t zm(<%wFWMIVHF-PtZ#3C>V#g}}4K~nA+(KY7fgHuk0<#55lsC zmhXn8Kg;{Fyf@36Jz2qDpY=1u#oO@yk`>XPrGxX#N-igv)$-%aYWV@OQZ2Q7KeJli z%B(8rGOOi_$k#(HwR|D7T0WOqfA$6bLCo3Qp;nm0 zXLO);Fp*g;AIq$kk7icOhmcd%Qp*Q3tL1%}^=F$@sO1i|LU&m2%G{p0E%W?aKWlqW z&UGU!OC6CH!?J)2l+TA{6#0UzrC!t{nYH>4ar)VC$@OQLP+w*xmx-6g0QInpqXUeE z<@P0U?VP2D=}tP5_NQIx&|7i;clqk|R{Z)l7oWfP`_oL|slAf_IV-N}qp*zO5%q_0 zi@T*0e~NtfJaP-Yh&R&t^zK<+-03O$A!_d#_rDF=*x_?PeK0(|5LwCP4r@Gk)Fr&l ztUed6(Fc!OewA4*zd-v}`#;Zo-i#gP1by(R9UNy?JD5aY8%EIy4`r@pZp(bfrEB>q zR&Qi7@1W0>b@W5jQtofob7M3eO7H&ug|?sIRNRK;l;425po3NPNYo=)$*iu_0=iP_ zfy`%C4`dEqDJ3`Sv$;d9Foh1F4ltQn9bgI3m@?od0p#_C)~u3u$V%P-Il)d9{ks{@>1bt=&b9%okDZ=x%^q1^wa@f17e!g9hd z7@abJI>2#eb$|oxqFgQC&#ad3WLC?!Gppqr*hzc!3$glo?occAq3>qZBdBFokDwcW zf@|S`-+1z0;vYwU1E&LjoP5Hs-FUI>;TE5K)P8m|tNlzq^89rsY*aIyK(jiLVf-(V$`zzMp9ec5(Y+-|}R@ls}4zP}X z5w4c6Wmd~q(A#SncR6yk-cn|@-Xg!&<0E{b85?CDeWW(RGK@}4?O-Ug+QE&#mcsyQ z`E_Qs{0uv2ua=)?R?GKrhxSc3tgxFq)C%k9xl_y6GOOhc+@M@7pUbS4AM#5q?%zqb z!?Jp|e4`iJE`JZC-RL!-UISg3)&9@; z5v}DK{~&hmIIVVYk>HQAx_e<6MgP^sGk#=yz}0<-Z^2RYUtzrDN4J*mp?L_sd(;CM z%&ZM8?B1fR>N{_qce*!ZM0pJ0oG~ zMXw!o0zH}43GCm+1hx8wn7!PgR#-$mH&8(ImWA&SSS$>pRE#E<}kp=YCupayC<5_<7XD_t<5G#B6 zXWaj6lr47rAUih0GKt=w6Je?2o~I%#1Gviys7KhJSv|tz{~G0L`B7%I{1AVD{tlY4 zQFieAIp-VreH5&Rr5j)B)r{ZE{;teQE|>hI)N=hk$}ci2xol@v+izu7+c#%(hwf5g zIN+I-%R;%W+j&%WXW4D{P9ntTrGddtYrQ{TsByemRjLFv)aKyX0?1j zvs%7^&uOoguV+@v7c#5m^O^O{Tz{p`hVS>)3gem84o1;aGk~76{;+hR?bLRinbmgf zXuJDAiBoeImUHy;fxemRuYQ(0^vyKf&#dJ7US=hiN%Z1VFRqEq>cv$@FW&L6bmE)o zrz0$9{D{_TMw`17oaPQCmkqRo^{}jExqdJ8S2HWQEa6vkyUn8mHNrBHxt@8EAMx7n zLRjW+SbvX%jp|4mXjYG8G_!i7Bbn9mOMb*^eYN}|vs!+R4tN%psVrCPPyR9MUoB_zD{IWxnG_G+d=GUZO7+>Vz&bs}q_C9^R2>MB=4_`@tcfTL64L4Z* zhdAqOtZ|OibF`LOJx5DeV*qu4#mwpe^XLTC@^YDZm})$+&7 z=s+!h$gGyH<9D#s)A*g7(&PUacY(SBN13tugV@r@9cqQS%<3taMK99nuykkc$~^yj zF@V~>ky&j&ie99HxWmOb5SF&zYevJis91mc-N|AL1-m8+<0iZ>2#4eLFse+vNV---AET{CZ$A7oZ1zK5=WR=*Iln>*ABJLmxF0Na_>0XER*g*w1`X0`n)dbQ7^kK{&JrqLA} z!*Aihda&u$+{uPlb4OVG;htCX(|KiiK(A)?YQE2`Ud^XyKgVc4M`77V``HW24%&~} z&-OX@zdP8dI@&@zTE{n2VJ$2x_&wz1u*{-IHXW9J^hYgy=#N@zVLAIvJ~45md$`59 z-wn$Ey21m$$(803_va3EiF>fdIZ~InJF~jPo#;7K%R4fw<-?iP^5!5L4xkP&kXap| zhR#&&pf|JH!P&3Vo&nVI)68o50e&L~vV(8p6l{lO3%`l$uf7=@Wdp6ajBljkQdkyo zle`d?d9>a{I+XU{H&CxTEM4e3pw6(IoxM=~L{+PaR+*pwoyLx`fE#o$AC@_E>C^_Z znbjj3Lsv#EAI+?m_hWs{<}#HFI>pxv)&5 z15SnI;56#(q4jpdvV+#!4od^QYZ^^9I2ZM~+@a($fnI!Sc|EgQ-i|-T3Y`6N-hODk z)68nUJ@j>d6@5)u#IN&i3QKc>4PPFI(~Dnvq3vtA7ADiKbm$l3ozP%d2G9>G{b6}L zi3zI{dC06zLCuDJQ}*jGj}q{!nJMehuwU zE$=n^2eEEg;qm9A!-ufkq7BprH<{J?Ep$M&d?&M7zJ#_{%NH}N<=xn{12?SDg=V$F z{unbq>%pX2_w12(D(J!n=d__K67P&;@!j;xj+ zq4m}B!^~>=2HIXNU(c+Tw;gl;SFh9T@FIEo*~scea)&iKP&>HItafmX4xpA_Wmd~C z(Eio_&ogUv5jNTIMdSqS;5f6|!6Ckh+jA5BrN<3i=b~E=%OLvBX8?WY(;t?(pNWCh zfoC(T15aR$i8tMF;Ck**2OdL@Of4VHtdN2U%ilvy31A3ZR&eP3p^eJ}F6Ak7ya zj-rG6upHpm@BmsxKex}JuZk1stK!X1#YZ%C;Oorl!29@q)O+~JsHfJu&#czF#P{_5 z|3$UI#S+%nGcTiGrF7#O6MFm!-cYdg4`I2*SMsO9H(|L%PtgUwngP$lvWs4%>PoaS zYxVnon{0d)11zCSu2x*ktS;FII+6DD@G#E(0ebHD!!n5usP;3FS?y;OeNA}$aqj=G zq{DSKJeTTHtz}l1Y6)vj46BJ{UW{Dk(TS_&jm+wRvuOWn|I?W+F%gBf^$C* zmOlJ)axE+;2QRd(l8;0F>))7w+FvWP+TSXA0ISWcu#!8}3bW`Ds2xmaR?ElG0Y}3! zgm$RbAIz-QzkN&erJQ>4+3>B=7=D>c8kR2nUiKgTNUjXp!2x8#UH78EvN%M{a|FZ{WjV^#?Sw@ za)(-B741OnU?sC!?$6@=o3puNI(M{oxhS{>M(~SiI2@K9^hnf!x-+W--F$Cc zjQi-hRqO3#R_jgS7ui4lvakPFZ;q?;6dgcqc#>IdxPe~n3+Mo9z4^>)y*jedQp*i%lq-~xi-}DzRYU*`FHbeHxp3H&oZm!yV(3f z&T)$kEZewG1GT|cX0^dI+M!xLm02zC$G>wzS>BgfEx-RRo)a99+Wzjlxc}Y3Mpa=O z{mxgdu$5WuU;?KoSIg^})$;btYPmmovc6h={+)3*spV(i$))b?brw6yG7h@rSz#%& z+QA6+(4pGFaAvi<8(+cxuCR1uxmv$Hvs(YDxf2~ep%or8s})Yr?{L)e`)cf$sA)ec^UBbR9$XU1yzRAwcY33NcUyq;MtAIE9R)$&o?r9U-~nEm|k zh7E@BkgQf1%&eC8qaCW{eVNtr8hT39@?QKX-XZm1KP#cGM0aMb{vfuK4I8QrJ2I;s zKYaTO{v$mtwS)W2>Qdg}1m$Y^ZDzH6ABQMc%l9&4y#HUy9cqQe%xVWyI6wz#`DA9b zd<1KhtL4L))$$(nHA6kX?#$ia-i#w`XNSMhq;}v>l+0=e*Zd^Otd?J8R?9E2LAg4> zd1iG5x6xn0R?D|CZ#A>R20DN`zcKICG_@E>n&zh>n)%!Zff~F{{74N`@dN>d=;Dy%Q)JRT5&A1+R+Hw zky<{SSuO9x@8`kP5tfs0<$DBHP+!kD$C>r@Tz~w(($zbXmReyuvy#h7X0?1dvsylh zFJS<+d?K@2KA2f8AIPjtE8KlcbfAk=xXrBOa*7;TOYPt!v)Xa z8JpDr{kcP}(3e@AKzn9=E#?0B(g`WKTz_+Qv9;6*TxC`#u#;IW-_E@K&8)u_W^;!+ zf$7ZZ1V%Hf=>H#4i{ zOPTfaC|}I1Iy7mR?Fwj{QghN4J*{~1+u=L3gelTT>3NX z=TY95S;^)0jnQ6hf0J2lf0|ise}Y{9JegugS>JqhQR#)hDGmj80zsanYPk&=PYSk5(%B-%y>Nmti ztggVyH*oykb}O-?bfJ$@U8F*1W+j)|uaApJUq|_LW+j*Vjd(EWYbn3WtmM-8TE2K> z|6EvRn{0f(9ff5Ioq#T}e=@U@%LMx5Q_Jg_)$(!VWw)i4k7ZWNN6`aT%bO#)L#;53 z-luAXq0DOeAbQHw@`221d4KNj%UnZGMQ>Po(53GVo282lm$EY~9q7`xhvn%F@nzFv zSnjb}+OS+>i#6slsPbu@l#L zW1*bmdPim@m#43aAJyKX6TC(zcop*hP{#z%!*YsFP@UjOW_5yl$lt&5Q))Jl|9?6f zs13FzW_7~;RO2(L|Fl+F?$94r-QZ`i|9Xw}XQNE9!_R8! zo5;z`>YKE{mSYA^5Pc0 zHF*SWs5TtVthVdN8Uw2X_hnWG?nNi2miJ^<%e(yfivx6_19WCq2e|u+IM=uM=`7hz zSkADQYvu%BO}pc;9HPInaS)bW^j9`oVOd6hMPn)C_y5`OcQmHMa`ojgA$3BRnbirM zVvQqGkLV<`dPGO)5v%2gnbq=r^njKAn)SWhp$@Q)ekG%Ju$EcvU>QG^BX3XdR^y_& z#fB>smP`CJ@yyB&aT)zxUZ|0uN+dQ}}-wI1T z^LXYxp5vD9hNVAqU*-p%>mScV?!$7m$o>Cu?6_nHmP7OjsGj?S%<8${Mt^R%j6Z_2 z=xsWVZ-b-w`MAyt#0V=jf&Q}j82Tfge)MkX3ro*yS(1;X;sdV~p7T5OoZp6J2yNJh zQ%tlLmLBvG+=)JdJHqn7D~t!A9>9HO^#E?r-?q6x+n+Ysu!EDZ9HEco!?5h5&v5mT zyq8&hB(I~ln>yfHW_7?h^qLt-uNGp0YW?Op8!qV)ehd|N&<@oKE1A^}m(e3s^Fn5| z{v6uh1lr#a+Min9i~bV&1247gZ?@d9qkFVtHE(2A8?I+o%jeO7rqF>#(1FzY!XP;+_|Cf5YJ#y^XHI(#rii_|e=Y+m&zn%RlUXMRS~OC#eoPmRTKh z1gq1Q<-?iP@m2iQlCKO+ForxnOSW= zhBYRjwja%`)z6oQ*>Hwxg`v#q00Za%>Hz(j)d70Z399XTGOO)7(95D7y)4?oa>&bZ z^&c*|VaEsPKx)S=tT8dQS<|Nk`I4}7fIeE9L%-7JIbHA{94f?>lB zav20c9)gr<1;M33mO(JM7=#9420>^rt#D(d45Fe94Q?5vnzo@qT4|dy2vWUe5N-6A z*0hcKeLizeU$5nTzUO?ObIx;~Kl5Z}ZW2sp@fEb6L+>r>L?>cA@qAui9B70J?=Ai4 zhnNRE!Fd1QLvR1P!DI`){ci@74eZ|jv3vWE@p_1pHME}w`Xz{!V6ucCC9YRPA(_W* z2JXQpa&z0~2}UoXpN2NjrB?S~CC2IwRFL21J$^ozOyh@%OTnZMU5PeNM6QI|&xM_T z?#ooSh|(M=^+0XLSi1)bJ&<#;eKy8wdl_@|s`fe^V|8{@=}tL-hk_l2Kd;y3!uQ*^P_xzu8;&UHM-YI`xpYWpBMRduL*jMbs~ z(5b5JnHVc^HAz!&u4+P0jMWa>JQcf`>VTKf39A!2jIr9@M9(R;zl$+e`&&l0*Y3aQ zUy2oK2Mg#+KpDM^r_l+h0~TYf#v?ISw;x6aP}_%MthV=}{b~1K^rd5hxdvt&vD&_euCUs^8)NPMMxQkb-48|3rJF?)XJV{&R78)p+CCOz zwY?9oqdpT%(#ZX3RVTO+_QY6;lSYXcj?PtoAd2PF!uz#W+`rcib!$4xkRu7h`pRGzHE# z>h_B0PCL3Mzc7^?%6(Fv;CPsdo@{*)i_JT#qPa)PVG)#Fe| z_G7|cOxQ+VLsr#ew-sac*sY-*t_G8p*skU;$5_puKzBghf$T)fAt=b}PYT0euXZLC=1*-%5^#=M~<_7v5 zK>ervAP4p=nAMSFcf2T1qRUV)$McG{f&MW>>!ISv6|2qW3{~(9Y7r*9b3JNe0LHuQ!-n;{Aum5FZAUU35ve(IuUY@f7|R zd6U6p4DD|ef0O!=U{W2R;D#A=kJJhE##o)uE^lb~R^d)C*+kzeYzC7${(^Whn9Sob zaV?n4qVF8e1e0-m0I&aN2PqVpQ9hUqpbx42cm*3|gGn#?u$vAhr~K6I!>;LL0^Q_l{g<`btOt@{#1}ZbsJVr%`e7S z%|GFX+%X=WkMYs$=ut3f;7zM6{SH4wtg_*DFj>P#u|b1Nz#Gs?kUw#GS?V|FU_O`( zq8$(5BdN~?lT%K8cR-y`C&uc8w$MYZ-G9-)87tI;S+oPSgP9ns?bGPX@*ujzIrLEV z2a^nXsCt8m*P@3?JyfS$i`_%_Sg!x>v7*9v-rDFJXnXh^5_f~iCf<%cT|sBAPHZ{G z>csLmO5Q1#%s1(04j(~W#E0S-KAe>r4e}Q$x&GZ?h>C|{27Sk^#Wm&%r~~cCSRH5^ zU4a!ee+GR^@jUvL;yJt#`|y2uz_sW~?V&5R8%(yU6kMv!V6uVTAK}oYT92{1Qgi4E zs1uuwu{yCKbWaPIu&0B;B!hQj0w-Mj?wGoL^*C0j9jqC1tkgT#YK+x8*AnLFK<%I& zV|Dulbb@O8e2mrhIkbPJzv}pGtWXCykKP*94$3iBI~YMI7?;BUbyJi?Mc}|7R)Kq1wR= zI%9Q%N{rPG^Ju<0fq@vS+xMXZs@rE`tZtvi?utH&>)(W)SfM7Ia+`Aib%0Kc)d7yM zyQJv$?HH@uZ=owSg%9B>m<%R8_+VmhqnI3zasBsmlC-&xK8S`(LH@XBxLlUd_BsyJ zz8FmAag>2;LH@YsWvK_!UI`|7d=;0Q_h+~7aDVoOb`s=oZ(f$VJ?;Bd3SO6+ILC|| z_#Pa@`_o}QnDnC0g1rw9&w_p2wH`pnMebU+#VihCKNtUf*e)AP_PGh%hWZ9xYd)Se z5ATK5OI#y^Y;YJ%3TVOx>-GsIvV{Kb;`8XQ7%m5IIAZ-gMCu`G$5=f?EzEHasE24j z#_A#3Mb3fhss$5vLdB|fk0Cn17COLYjMV`)&~rfDem%zO_S5LgbScPRt_%IC{q1&R zp8qY_;U?yovD#rX#%hNf=vk}X0b{%#+gH&Es{=G*toFZzPFUT(ZtTD4x8ML3^sLQB z7dhjK#MAf|4naS92(rN&jyU7)$)VaqzXhUs4&`o)l{i^P`d?Ms*J7+y6Bc8Iny?UK zwY`k&!K&Im9b>h<7-O}4EXHd40P?E0s*pio>Y~Xa6ZOr!ZbR7IzTDL>Hz1^lS&<6BF5_W zMf9BNL4T$^;wItGk_YHxe|49Fd%782M-!LO#CbGvJk}4PKZ<41l~GrwFUIQ1q|xn< z?-#b;Mz>o<^BcixG9N2y!K8$q&1&LQjMa{}?;9tEYvj$ND^rWHx-x??R@?J2R@=9^ zO?Ll9?^d_KNravhi+DW)F9eek-i;NyR0wY1U1?trCQCR#Tn{FTc%9n^lX1KY+qdr> zUJDNK&a@vW=U=i)(nj74CsAN$$ZZuRvaoEp%dg=)HV5m<*sD^x*A0G`xa2a1(D! zynNV-;@pKsc<4Q=ztY;!1KW*jkjh`dV+~(;;o2J zIZ=>51QmW%I}Rpm=-I!FUf${vp>DXSv zUh1cUNio)s;Vq~i4JHGzK8H7_zCW1ka|zi0F8a~XPOzG+QE&pQ$enJy5lr&vpRn5J zTDci}zK(XVjNYKeFim|g-jspT!Q_xLxclxInm-iH;Z2-SFlljScmGA71($HYTfx7| z2ys$Gmso8di?O=IgXm?|iymV&FCAkwZs~sG3jlG|N z%4kPw-gJ!Bygb^E+CC6twSAsz(iI&>&xIAP&F*jXu;2#E=m6T?0KMT%$9grd6k|0n zk3S^ukZbV@4;4BQHGeI}YW^fT4uKcYJNG!YWsAI z)%GK92KKj(_E*DY;t9XxWJQ4r_jCaLdA=9@MH+|PJ#62?%W)>g)97RRP>g%=N>9RI za>Cul%lJ5$?4aAPMQi8|)v6Sn@m#D>XFP>R)K3Qa3qRath=+sxMW3)oC*01Q;5yo& z+TU7?)&6Q|-bAcd^Qz;qLQTw}dv?J6(G6D6j@1p8W31+%NAvS&{xP>n^VR&L7_0dQ z=nAhR?}${-u2Q&y#6~cwhlaEB*u#?6f=LDKSnc?HjMa{((2mE^w^~Ngen*1I5b_K; zUI_A+fqbWh=YI>n)iThn;3+l4Ne{Y#H-1b`xY7I8jGBKOV(X)62UHS}qlC^okaHZ7kF2z{g zZVx@#x3TJyl__|(51<{jd8M(V1H24p(GJxPXJV{&IDx#Edv>2!mXFZB7fhDW9a6We z$5`F2bcXBS0SZ(&fSNcMV>Pi4opFa(CNHa#VA940@ugsLi0;rDIoHc_XVLyg`zg3|z34#c zVA6vhyl~|e*IZYf<>j@z`eF;@GULi@_$L-B~0UAt-rlS}BFSI{}D{Vc~=?PnYv zM{O^LxVmb=gaUSt0x!px=x`eyXe*d(q65vL1F0R&##p=kpaT_R`(TXK_C9o+176-Q zafO~;r{F+q!DJO3Xc`?z9jFvzwWDFYkt=ct-M$b^vgicV?fPP@Zgt;tu`_r|=Ye@qh4y%lW_YBK{ZFv4iLEmrQsfm=w@^ z*Z_L-%w5hEN+Ic^!kb|xnDn4GL-l6p{lZwi8E$e}JJAaIG&YIuX+OH>Y4jPSNwyE% z7tsgqjbJi?K3o<3H%G6gP@tlF(x6K`7-MybH(4H6q>dg6HE%J-+C3ELgtF0ebeHAx zD@jFkLSyKJMysKaY_P62tfLKU!6c6!E7$#}c+9%{LD^9-X`}V~=m%zd!DKzwui!7J zUk)Zqv3?$psjt>TA(@K}=h08n%E6=u-SY|u`e)Ri4<==_ejwWB1aP7&_&io%7|kCF zCIvMAgcHQPaiqOEUJQj~3{A+!gjLQUPrhk%gC6`j9eQSAa)~p`-@Bq7io+PIhhiVE z=bygr1(WmWgv!BW8h_~ZpQqpetDI3Th@)%G&-v(2hHz;uk&_aY|I zcX8D1&&61~@6hKcc-Hpf)y#aAGt8w`H)zCI9k7H|@*13RpQL>ym@J_yGKF4#!{~~1 zI0JPL&EE|s6ThIF3pDI=Dw&QsNP4rNy?adgg z?Hg$SYX9riSg{@|k_LLL)DBi+tah-B9-;|!&pIsEPjD0ennSpX9-6sm8r`u|_R_0q z4ZTy&pr7nl2PyoRf%3tm4-_$=Osc$KZSKf2FG4<(+%OE?(q{3vX{j83SA zPG~H;|1Y6_6REGBU8CTDl~8dugWihuN+#ADVD7|lJep-ZjQkI%(e&D;Fvu+-W^ zdo#vLoUCEa-??GI4pzGrob@42R?q>|_T?C>1Ju!DsSdChV|9QUdMMTH=VGjGKZ94h zGzAK;#SH!vZt{QKlL+1LB07*d&{S+!+t0;zwY?uJOk8cx##kNLL0n<&enNlB8DfQ+ zaEND^$a!=kYDd%PMAU&s(UWoa2jL`}Li5%9b7;PH^U?gh@29$Nn4kMTr+@>szZW)C zH#|f)R5vWecC~#nwyW)9XveAO>_M1N1wTmrBr^8dv1lQ>`Q2(<>hFe*FJgD8(T?kA z$NS$2*S$J{y%;NTvWo7x+P;GJqxMrq``P?g*3p5~ zcnuv$=`dMEPdat`MvT?`I)0gn%;7dxOB6U9XZxd_R)`Of)jYe8tk&5wdXA_aPsdp8 zxEF6E@8nyl?w2DD@O{K<_zhgaeOyEq_3SLZ((Av60^6QF{$?u0DxICjkKrh~XX;Xo z#8}+I>@#zTQro!v$Us{BnV#eZkB{NG=o0ZnIHyPP1|P?lY=qt9rKX#aKOAw=l=KqfTTq#_B{aq9>c$z7b=!eGM1rziPn&R%3-az%qI@ zs2wcDSnXgAuV%sxmc@b8ypV;Muyj6*^u;Z?$?Q zd$NR1tP<I3w9_!e|^XNp2_&FTG?)6WnjxgHA$qZJAE5Rg>A7s01v{hw2thgAR!wbX} z{3IKm4<=Li3F>qBAZ)N)o+Ij>R${EKL@CB`x&F;)jyNB;zdn!grfwS5d- zA+>!p#%gQq*PjmfK z;MW_cQg>nCOI(9~v26j}6LnAKW32AU4CWX>9iS3pb$~KD0kwTP#%lW%+W*w2SbqnY zj1}qt|2elZh9n7K=R@-M{thS#=PcpUta*Wk;Yzn*I(6e9%lU8ujsU1w< z)$Sp>=UMa+Wza*k#qG`)p-uEfs2NOhXkHf0+vIj=yoSbg^eUUfs%P;ig;hEj2_`-0 zNpi}4)03?eOpef#tsP7b(34F)*;+AHPquxupB?-|+P8zrCVrH-`Ek~tLNZN-OQkMV zDaPtjjiXDgu2eC`>Pn5G+pF7;#8}!SB zYvRqxYoJTHgsbG$gGu9K;mxc9e#C)-$tk<<4ygThV%({QiewKxTh)Z!7^?#>;)58l z6djE1YJNV(YJLX23Qj(nN_p8G2a_Z8Tv|gXRJCv=39GR}iIW;SAtfH4i?I?X6X*ar zd;lJ?3=Y%|CYR8G8t6dEcH=8CR^lqZIXaw;r>vJJ;}*K%D!QS%VI#&$oGfBO{X#IA z!C~S`Fe&4QiKl}}54uBYe;%Li-`ufahsR{QN4xkT5_W>g8hWf7=pAuh=}7IU7Gt%a zG&+#l-VKof8$LHG+adYd>OqXj-vyq9Tj7&c9cdtI%Z?ld5~a}_hRbk;6W}EZlViNx0fWgQdgIZ{s6U9Y5+^ORpIzj?@tt6@ zg?~W28RVA%S5v7KD%PpMWDPxuR)fhjzSfCh_n4x4a!M~Q{Wf}TY@+AJin2m#-U7a# z`XZX2#T#*h!QO{`RSIr+K$g$_Exevjt@eY-0xnZu#`j=<^b)-ouSaL1Bhf6{Uk|>Q zi8v}IdyMLKi_z)?g(4NbSa1Vea)V&9#pti6eiL6ueKVMp(EJJPe%2G?0=}EP!63h@ zlaq`?ae}{3{c$ik#NVT7{2&yPO*FBIbrLTIlUl5w!*@|X8%%~`eF5L;fWah-?;!3A zCTUzG?g=KxEW_^-A9dwl=v<=UCmo0Qb{Y4@TnDoc`EWU;MzF@M(ai}`L0);ozFdt0%(UVBMOfqO*FV2&f4km{jr#BHF1e0BS zBk@i!so)zpMCY+aeL0vEF(DqqDurZ(f@ilnU?Ik8yw3r3LTWsZTsUVBIDnoTE%e;j z4<;U12RP+8+W!XLio6A!!|DHv-$ggCrDB)^>jabm#s~2=)OR?ruf}7X#eH=mXx<9C zojS2)d=>Re!K9AAL%bMFD(Lp=_T_i78&;G<1-~&eya?@Z26;zBPuh<-<9x)rg#I#@J)B{{-C(kV=csR1DY(HZc7O6g_hMi*&#_BD34|DXd_FvtN6>10D=m2WMR*cp5COUvR zz{MD=1FWI_k$soRrI3G;1=%GlVOMb#N>QeXP zb>wA(Ngq~-Gr{DDYxXYWEn=Pts}o*`vGV={KetnGrlY~6$nJSR7{%c<50z;9NQ~7z z8A9_0F-M-7myfZUmqYWim?lrn>ocxWVZp>+G_ePdZ_1NOs2_K|jn%vkcNg=Hu|>Vw z;Zcm$yh~`_0dA3}=Cxw1-OvB`D44i|Yb2_P+c8!<+(h#(Vx2rSZzINP-WrA)4311@hFq>VB+H6L-oS63~VSVt2VFi)bII3Hs*Zw}3y!3=q7UM0qA zUK!0RVTU)f)V!$}YxtX66igh)LlV`*VvN-eN71}t+#yfR8;Y@-H;Cp9;0AeWUM|LJ z-pQMh^Kbmv0u{&eVZ$~~a9>dB`7NR$R`U+f0rt@wl$y5}V>NFF&D%n6P-@<0jJ13H zU!-8-I(mmv6W3y_cGy7kmhqUYLCsr=v6{Dt=FMY^JTNGfK3@M7Dz->e6VJz3 zO`JwMoWeEo)V#?Ut9cV>UJ>i$sd-~DR`W*CyrFqt|4AH*i3K!P6Z0`Khb8LO4*O%Q z=JlZ+_F|DdH7^}wH7|wcb$D*`2GyxjF!3Z-sEJ2t;w8+IsOBBUSj}spd3%^5PtDtn zv6{Dy=51n|t47VMHe-dFxPd0F;U0-<;%bc5ycINW37h1pdG#2pc?)P>4IAXCd2=DI zu39j022DJV3nZ$EeYhu+qlm!znqOqDd73(KsJi$*BliVNF{P7s8`J-5( zU2PwUvD!Y2qqM8-LvP^vw}L`9VGxVNYC=B7Y6kPK ztL?pS;QF_sHzxF8mRL~#9n*=qX6=Su7ecYj4ZQqNr+P;H(w5#pgF;?5RaD#TWy}B7I)P#%JBtcEsh_Twf zj?1*G?Q1bs+Z))RU2R{9vD&_jHQJT9I=&Pu)PzM`AVKY5A;xO^JeFx!+iNja+h?&t zyV^bzW3|146SS+>|M>Y>p(ae@BnfHCLG}o32F!J7_04LAdkZ&cSKIevthVoAo%TKd`GX0556B8NVH=l;)%L9ztL>XOOS{_MjIr9jfi>FI z_VpO6?Q2+~eeM4yuo^4WgcU54pmwkvW3_z=i?pll^%$$|ey}`2yV^bm>Y_kw;W@&!#bL`fGzUWy!jZbd2?vq z3~rH!;rg${3N^7D6HB;8qT1n9jMcnzXouriCr`~Q##qf8Me~MnmOM3Y==B^6D~4j? zU`!mq67_0gF2-tyS+v6p7RgiddSk5S^`LpDyggbVPtEJZxKj-k$uXMP#w>|y;-wg? z9Uh>0`6AMmwCs3VCYYWQ^6k2{f;WljNy+V=-3q zM$o(=9K8wGzXcNu-3smpAx`pWVh;0ksOI&@SnaS6&FjSsd1_ud#%f*)&FjpC$9?U- z{-4AOHSq{dyo86`K-3NoW31-2(7ZkLd0)-jjj@`yjpl8lkN0X`6T|a=s7Q+VecxKe zKf_brn?J@H`f=JUo@2wAU^0zQA}$4!Nlb{(1(R{KpAp<+V0GZ(7-RVUUp^*gaF!)h z6MJKd1Q@@I{^r!aMh_Tw=GTL9&f*mf!3U$UaxJyT6 z+`>`(3w}M+NbrUsbjb(Nb0Qy1`mscu4JH}%oahZEJ?J6va~-y?o;{fjpYe3COE0GW0u)!xxJ_)J$>oHdIYv_ZD+CCR!_4-eW6kN(tbSX!I$sl@p<%3B- zx^x-za#B0&jj=l52_J#kuC^b?SZ!~k;~ikt0b3L>*}*B|?O?Kj4!DLM!_{EYz;9AN zk9IVR_A?Vqrt#^-r67NsCv0B~CSz#7*;ldt6TFI1=+3kcjn$bR@tK>6n>b9px<}0z zt9dKvNji-l3N^13V>NFOyN51#!=)M4e}R+Z(oDDt4$)Y>3idGP$7N`TyD?Tf+(s`m zwS6nbYI_syPrb@6##rrttxBQe$7N^-t1(tPsH01~fahqR4<@ttRN|RnQbG^WR4|!D zSMD6TeG$D%#)8Q(P7+s#LLnK%K4z+3Cixhvmsv0VHdjfT5APn2HC*P9s1u)yu{!Y* zUQgbbGJzp{EOCd=`kdGfa#d7UE!e?!s904yxQHe$;syh$c?&Vt?m+0oI(%s8u~+j> zVyxyJ;g{%d37>I)`*DrsJ$5|(rs&(XdVOy==P z#I;~@9z7)GU^0#F&;)vUYWMYjJXWYP9Yqs|@E;F0x4xru30#Cgv&<$2&taiA9eg?dZeQc*rWC_1V{d}|* z+tv2D7^~wIRt@ zs~ep11Zlh4-ifi=euOTmI-z!q)d}rm_fW?6J!Aj#8_>g!|reBvfu!-=z!_~CG@Ko<7fxPV6y(aP``v}e!IBZUXQUl zz#=+9wS6JRYWv*tSpOm&Q0OMiqOqEA9_>Kwpd4ehJ%=6I)%N}vtLKflCWq+dwvXni9q+|h-EIRt7xYTn*JG^2$ufE_ELTIt z_)@IUD@jI1s!Mxoya8qCIg)dCL?IS1+>4x;0*`Q3J)ebnCARjwcs9a zcPn_73vsfEb})};7-+A=)xj~>9`bi%ti;JC<~XKmf6W-HE4YE(b0W5{8+-j*FkuxP zKpmhFV|9Qf^jT3IpdMp&`?(ma?Xxjf+bigbjbfT{wEO=5NUTs3Q|NVn@Jzm=#Renj z#MFrm$5@?M9&_x7I`BY@)&Ba?Jy+YaF~;!vpP|A5)B$>9tPbGMXYRS$!Ra$XtPaq@ ztC?sWJr`!M;GSalyJP4R((Dc4P>y1O360)R4IPfe3bn&Dy5S{$9C|bz?csxP8wat7 zo)hh-g%xU`1FoRkRnU`m5Y0Q`SzTAqlW{qCL%mAD4d?Mu>{%_C6wvQ{4&rZ6pARO- zJhWSXgk#jVgUK?whx6#3sVh~BvASb@cyH=6!KB*e+1X>KZg45a>IMhs2CZPSj2!+ftPYQ>wfsY_>MLGYHAqsZX;o;qmHljy7#2+zmYa*3;2pjANlO4Pt@pdq| z^!Sjs{J;$1Eo+w15=Ch4x`vn9*0R7 z2qrmvAaQ>%IidFlkhhEO;VH@Yr@a$Q#!0rm58cBh8jYvWxHA;uEi^u<-Zzz^JboNZ z4$v95f=QEgqd0ysn6y}b&*J@HvV|^fG1ia8`a-PFaNy1F4JPfg;Slbl6RS>BFrgGo zPPn~!hdK`4&_wTeb^gy+!x{7$QN8>sF;*|XvN4yhdihS^GO-%-tJS)(5?7Nk3f>UZ z4o73Gb~uc7sCG~=CST1TjIo+OU`)Q6e|k@TWFueA@5ETU-~VY*utPOrKgMc@yT){= zcDREZm-E~Z2fBvt>3U$C)bjIq0W@4;oowS$2etK0XZw`6tuY>d_I_wNz* zSZ&{nF^1Rw87dq=9iS3pb$}A)n4sFhRE*UD&Y?S?wok-ZZ7-tztNo9~ctPXIJ4-;1hIF7Np{XRPJ4RpdwxWM*mf7KZ)n1I?rCB|w8Wn(r_H<-o_ zCzl$RVysSR4A*E^+ec%pwvV7!j}lkMhhv4B(2rg|Y6saEtL?q$<)cnG9bW{Iy{n1^+1dpl|?4TVhlsGvwrUSKu1N4}waVy4Zhg&gL+c#sZwqHa~aj&EXP>geimK&5wst@lDy#(}CJSI>u@TDP!`r zhxX&^!hmZ2QH<66OK85De}LWh|17vc%LE2gH)t5Mfx5v;jFmW9LQhJyy&hw=eF0qo zwg34TtNqXU7g8L6LbroiG*&y9L=Qy)YjmV`G#F#GqkgQ=uC`}mthW13^d#+S`{`Xm ze0mqw--Kf-?o7i`Fll3s_);+0!8;Le2a_$lBk^W1*}yvxuLt?F6RA``@oF$x#@iDw z1(Q17j(D*e3P}xbOT}C;nZ+#eOfV_qZHT9XNeQndo(d)tcn$G*Fezdm@mMe!LEleQ zS712CRST}b0G3%IH6a&cwLOC_q1xUXW3{~p-Ck`^#aL}`v%DV4i|9F~)K|whVuhMm zL6&}1J*m#eSUo3-=t-pxG!|oZ`vN)OnBs$M1aZb6fB+dv1u|`P^&1N&V-Z_q=QV@UqK({kf~k*Sz)e%Wrbkh4;RYihF-9 zdC@fwyy;~RzVOPIU-L_N@hh%*bTxg8)R`t@-wb^fyzP~#Grs!Wj<{ir%b3MF-X0h5 zD_FxX<1B7t1^)`m_?KA1zrab{!U_CyEaI1N^se0b{*1yf6`NSVFJd0QfI0j;X0eGG z{2Zq7vzWp^#m)e~F%5ln{0z47(|CxV!WM3zFK&N=JNQZ5@>{K+pwOgZ9XIfgaSi_n z8~AZt#x<LEVp3icE)P``uk#VvdfHgO3z@Q_1Y zU8C@BDjHa$gJt}E;yS*L*jKIJBd%c`XYpNF!FOT_-+`03h!Z%=4i)hw?jgR)9mH2+ z0cS9eFTYvp8E0}7UPeV0Uy2z#k7;}nrtpP$$Sw2**uv-G9zGX+QJTgrd^R@mS-64E zxbTiwU32|Y-_E>hgm1%H?7>RZmlWetbP^xJ0#8JJ33(v#Xml8#*~5O|GcH{9JJ;N% zdIg(j2<;|~Zk|Fn>)e^+#X5WAzdP+ac;__Bjd|i4=7=Zpdg5WcBXI`rMtsao=W606 ze!@!=?@IkL4&XwLOXxZZWh(BBlbFLI_G2C|r-L-!hB$@SqIa)ru#G>tIm?TE#4Wrv z?%}O)2d~C0e6JJ14Dklu5*v4_a)#cN6NZW#v4-!%3SPi6-h#vuUWJp`ixaWFh&Lx5 z#e@@X7(dC%74Q?7$92r&XKum{;4ZeghkhORsuaFPp^0C`2JYYj{xw$cD>#W?#tD2O zN3e)DbzpoWm&`EUgt&kn!aRBib9g27S@aNR&_kZa7xi)pr6>$i=-h!*ACK`q*v1dy zAzqCwEaM(ti#zzIxP=$7iJ!p@{4}m%6C2o%%lLH$uH)|!FW^sa!Jn6_QFu2Mvv>=v zU>?hO1(xuxIEe!|f!ARXFW@NN3y1MGSilcq9$$@FOk)P$jA?u$rm)7Bht70(%A2R+ z7+;TVd>tO*9JY{8q|WRipWB?-!8hO*z6qOnU);bUT*Lce12=FPSFw(t#RdFBtYOIx zXDNJ#r77d%h)Z}LC-F`=fxnMM{9PQyUL3}^VF6!>d3+Y;@MD<8A9&31dBkaKU4Zd;W^mG-^N3HGPdxExQC;-gCpoG{e!THZ3fuD16;$u#|C~4m+_0_)$vbo z0hh6c@5R~MbN#=ELWPP2EaPjigujE6cn6%oTVoM#g`;=|hw=kZgR!%Ng> zag#WMU%)he9y>g^za5WnSLK%jQD{@~ay-PBVGAFOdzix=?87b0U=y#x4ZIT9@K^3R zp1S9_hjsi0F5ur{4gUsbaThC93Nv(2##dkoABB@Rj1zcgEMf{raRP_&omjx9VIH50 zIeZsp@e`QAbxh+QV+t$S;i2p$SUsjNMWKyP$3uJ)wy=nM_#3!`W4MKn#3nuhH}K)O zh7ZLCCb*1u!8%@!3-~Xt0RFQpfIsy5uTc0WD$00>CHy{4;!W9b0)Iw4ijO58#>Zd* zKZ$w#IHqw8Q}|Kr@Uz!P@EAXgZTtf~#1(Ae`@R16DBMWJ4!#e!a0%D2j?1`+b$k^r z;7hTFFT`1V0aoz&SjK5A;C%wL$HYt#0`7^uHpT$fd#DNSzN$-VhyYJpfF3}?pVR=v5a@aNxUN# z@%A{1x5Ht)Ef(+^%;POFhd0A4-UQRwgB^a%y$svL4= zLHkLg{iN`hSnco@!+%mZ#{a-JzKdtIL;MCExA27eJ^X*Tga3|O_#PN^5x4OBxQ5@uIv(IG zeiuvl9W3Ivv4Abi;p zmv9aL4C}awv-m|U;TN!opT`0=F^iwW6n+-lx8&Io_ioAcf006yiqBvJKaC6cDXicI zPU4^7D1H+2_zBG5I(E+R>V}8-N4SF@#|>P=W&9Y{@DH(!AH@lte^aXzhN7Jd-7@B=uBKj9piz%~}~$2f{V!eRU&7Vr@B_yf%1_c4Rt!*rFxHz^$V z^6Es#ZCt@a^!je0C*K~v4|i}Gx9|cs@x8c#??GMxQ%l&ucjGetKGyM*T-FQdk76}k z$LcJFKc-N@Kf*G897|Yd!%2J>PT)JSh{HU6jp8ElF#awU@a>q#w_y$!FpF=+3|`9* zFll@XaSGq;_0Ro2HBSZi?bMr)2g=kN@etpD+-amkfUm+DzS8S|mck4b6?_Gj@#R>;m*FHqF5pwJhSeuin5A$IEBGWV;}fxjPe3+KO(6eEJsykrI2^^t z;xLY50Uv{T{4LDkZ(i9rhzz1OMW?cXGr!Y&!5LWPhSjPKe3GaiG z$ljfqzV3wTe=<2^8kcgHNUDrYiyJ*M$)n5t5^D}_#)pKkFOufsOp z1rPDg*g}@`%pTqeckqt5g?GRv_TvWL9@p@8*udN3GIAKs)bTdBfY)NRM&TL?v)G3f zyfv2bR#?KTaS}OxXD0BLSj00pidW$<_F@5VfqA?+=I~~iMUMNK4BiyecoVPx6oo6P z=-iZtMLfnUu#K1FAzp?p+kU$~4N ztm7|n0soWZf2Ky^Kd6|+6RhC>!!rImmhcxiiN`pB|As~UR~*Hk<1ij!0e^;h{3+(} zCz!=HX7IJM}|6#DBsT9wPt7JM{zPeWKL&aSOkP zO+3I2{4TEHcd&uq#${|_9lwPOSp6o28ijwvS=`48{sWfr@3Dk`hm*L66Zj1*;@{#Z z{tXV}E*9|Xn8&YS4!??7+`$a~HKzIH5vi|GNKx@+>|Du<5wC`Ie97g^5MPWnJdd;Z zBIN7vsTX1yUx1VNaGbzV%;Uo_iwUN21XK7B?DTMdz+=C>@gNFqDu(e8ABZh{0Pf-a zaSMOW+i6Wa!VUZxuHjFyfj_}I9^wN20BiVd=ld)uKC*V{{@sq;x03!$|6K`f1^1 zSly$LqOgNbWDA{06P?HgI*~PWA`SdC*3pS9pcAQ~6PZOPQb8wDLRVxGoyY{bB1OF0 zz^-)q`pN3UwKO1nGPHHkHpL9MC#~77SM^*(22~V6RF@6xfzzw6`4dQ zGJ#H{h)!e_U6BGhkv#sON+CzVCCOqx6UgB0F^#vw6grX4Wnm)6=tSD+MChzLkrv*T z{2g>6Tj)fZ=tMTqiL9X$S;nd}sZ(%C7SM^*kjb2x#cQyF*J2r+NC{n$NpvC;=tPR> zii~0(`2}<$d2}K7?0u~ z5f9^#dy4nNJl+>`IEY!iCuZ;-n8v#!q_*jIr}{u1lX*j63;XD>iMPcKybZ45wOGTq zk~fRyRnWXLnpZ;ehVd=r70|pq-WqdwHD-~AkTb^*;PIQhYMX+IhiGC8P258h*KnT1 z1-y#56ywntXYoz6cka*YzT2VkMvNEmjl^aAB_F|z;v0x_A?EpiD3z*F(ZZY2!3I`| z>oG3l>xql_eLBeD>xli%wQ=iyJpU6nk;ketb$l&x1$&5#G0w->?`FS-_QU&f2lVy7 zN#WI0EO#r|5c!$l%mn_50rL1e#OW9x-iIF`h_}!^TEE7d&9PsbNt`EJ6G5@rZjFZ{~z zBZTEael))D<|V=p5pLa+pNubD^&Y|x5M~KKc;P+&7gp}UQ{sg?yqDHLpmpc&{8W44 zqlWJ%%n{yr;p~NL_}%GT46|G{%T!OGAC49A3%pa~_f40XuU{+GLag^|qUNPy+_^rq z`}I)s+UWLMXkIhM8?k*Y+VH!JCeBjfr*V~-SdIy$=wz%fpm}~t((Q7wJsZu$`u5#I z-XWUTLMOHt-HG)Lzq@#A5|(2{Jti#RjcicE_u(Yoio6N5!y?+@C|*Fn)A%0D;Ilch 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

wlF)l$$8%7^4)>Nuz9+^ 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

** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -13550,6 +13631,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
    +**
  • There is no "iVersion" field, and +**
  • The xTokenize() method does not take a locale argument. +**
+** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -13658,6 +13763,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -13677,6 +13809,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -13696,7 +13829,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -13723,6 +13856,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -14532,132 +14684,132 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 @@ -14680,6 +14832,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #include #include #include +#include /* ** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. @@ -14700,7 +14853,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define float sqlite_int64 -# define LONGDOUBLE_TYPE sqlite_int64 +# define fabs(X) ((X)<0?-(X):(X)) +# define sqlite3IsOverflow(X) 0 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif @@ -14875,9 +15029,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define INT8_TYPE signed char # endif #endif -#ifndef LONGDOUBLE_TYPE -# define LONGDOUBLE_TYPE long double -#endif typedef sqlite_int64 i64; /* 8-byte signed integer */ typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ @@ -15377,6 +15528,7 @@ typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct Subquery Subquery; typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ @@ -16259,6 +16411,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( ); SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*); +#endif SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -16477,6 +16632,19 @@ typedef struct Vdbe Vdbe; */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; +typedef struct SubrtnSig SubrtnSig; + +/* +** A signature for a reusable subroutine that materializes the RHS of +** an IN operator. +*/ +struct SubrtnSig { + int selId; /* SELECT-id for the SELECT statement on the RHS */ + char *zAff; /* Affinity of the overall IN expression */ + int iTable; /* Ephemeral table generated by the subroutine */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ +}; /* ** A single instruction of the virtual machine has an opcode @@ -16505,6 +16673,7 @@ struct VdbeOp { u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -16572,6 +16741,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -16663,16 +16833,16 @@ typedef struct VdbeOpList VdbeOpList; #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 48 /* jump0 */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ -#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ +#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 62 /* jump */ @@ -16715,23 +16885,23 @@ typedef struct VdbeOpList VdbeOpList; #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ +#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_OpenDup 115 +#define OP_OpenDup 114 +#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ -#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ +#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_SorterOpen 119 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ @@ -16766,8 +16936,8 @@ typedef struct VdbeOpList VdbeOpList; #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 -#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_DropTrigger 154 +#define OP_DropTrigger 153 +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_IntegrityCk 155 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 157 @@ -16823,20 +16993,20 @@ typedef struct VdbeOpList VdbeOpList; /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ -/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ +/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ +/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ +/* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ +/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ @@ -17897,6 +18067,7 @@ struct sqlite3 { #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ +#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -18884,9 +19055,15 @@ struct AggInfo { ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ +#ifndef NDEBUG #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) +#else +#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) +#define AggInfoFuncReg(A,I) \ + ((A)->iFirstReg+(A)->nColumn+(I)) +#endif /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. @@ -19067,7 +19244,7 @@ struct Expr { #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ - /* 0x80000000 // Available */ +#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */ /* The EP_Propagate mask is a set of properties that automatically propagate ** upwards into parent nodes. @@ -19238,6 +19415,16 @@ struct IdList { #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ +/* +** Details of the implementation of a subquery. +*/ +struct Subquery { + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to initialize a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ +}; + /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. @@ -19250,29 +19437,40 @@ struct IdList { ** In the colUsed field, the high-order bit (bit 63) is set if the table ** contains more than 63 columns and the 64-th or later column is used. ** -** Union member validity: +** Aggressive use of "union" helps keep the size of the object small. This +** has been shown to boost performance, in addition to saving memory. +** Access to union elements is gated by the following rules which should +** always be checked, either by an if-statement or by an assert(). ** -** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc -** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy +** Field Only access if this is true +** --------------- ----------------------------------- +** u1.zIndexedBy fg.isIndexedBy +** u1.pFuncArg fg.isTabFunc ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy ** -** u2.pIBIndex fg.isIndexedBy && !fg.isCte -** u2.pCteUse fg.isCte && !fg.isIndexedBy +** u2.pIBIndex fg.isIndexedBy +** u2.pCteUse fg.isCte +** +** u3.pOn !fg.isUsing +** u3.pUsing fg.isUsing +** +** u4.zDatabase !fg.fixedSchema && !fg.isSubquery +** u4.pSchema fg.fixedSchema +** u4.pSubq fg.isSubquery +** +** See also the sqlite3SrcListDelete() routine for assert() statements that +** check invariants on the fields of this object, especially the flags +** inside the fg struct. */ struct SrcItem { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ + Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ struct { u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isSubquery :1; /* True if this term is a subquery */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned isMaterialized:1; /* This is a materialized view */ @@ -19286,12 +19484,10 @@ struct SrcItem { unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ unsigned rowidUsed :1; /* The ROWID of this table is referenced */ + unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ + unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ - union { - Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ - IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ - } u3; Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ union { char *zIndexedBy; /* Identifier from "INDEXED BY " clause */ @@ -19302,6 +19498,15 @@ struct SrcItem { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ } u2; + union { + Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ + IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ + } u3; + union { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + Subquery *pSubq; /* Description of a subquery */ + } u4; }; /* @@ -19433,7 +19638,7 @@ struct NameContext { #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x002000 /* True if a function or subquery seen */ +/* 0x002000 // available for reuse */ #define NC_AllowWin 0x004000 /* Window functions are allowed here */ #define NC_HasWin 0x008000 /* One or more window functions seen */ #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ @@ -19561,8 +19766,10 @@ struct Select { #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ #define SF_Correlated 0x20000000 /* True if references the outer context */ -/* True if S exists and has SF_NestedFrom */ -#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) +/* True if SrcItem X is a subquery that has SF_NestedFrom */ +#define IsNestedFrom(X) \ + ((X)->fg.isSubquery && \ + ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) /* ** The results of a SELECT can be distributed in several ways, as defined @@ -19592,7 +19799,11 @@ struct Select { ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". +** results. if pDest->iSDParm2 is positive, then it is +** a register holding a Bloom filter for the IN operator +** that should be populated in addition to the +** pDest->iSDParm table. This SRT is used to +** implement "IN (SELECT ...)". ** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after @@ -19800,6 +20011,7 @@ struct Parse { u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif @@ -20095,7 +20307,7 @@ struct Returning { }; /* -** An objected used to accumulate the text of a string where we +** An object used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ struct sqlite3_str { @@ -20109,7 +20321,7 @@ struct sqlite3_str { }; #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ -#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ +#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) @@ -20187,7 +20399,6 @@ struct Sqlite3Config { u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ - u8 bUseLongDouble; /* Make use of long double */ #ifdef SQLITE_DEBUG u8 bJsonSelfcheck; /* Double-check JSON parsing */ #endif @@ -20562,15 +20773,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define SQLITE_ENABLE_FTS3 1 #endif -/* -** The ctype.h header is needed for non-ASCII systems. It is also -** needed by FTS3 when FTS3 is included in the amalgamation. -*/ -#if !defined(SQLITE_ASCII) || \ - (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) -# include -#endif - /* ** The following macros mimic the standard library functions toupper(), ** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The @@ -20949,6 +21151,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); @@ -20998,6 +21203,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); @@ -21060,7 +21266,7 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,i #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); @@ -21188,7 +21394,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); @@ -22174,6 +22380,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC "ENABLE_OFFSET_SQL_FUNC", #endif +#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES + "ENABLE_ORDERED_SET_AGGREGATES", +#endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif @@ -22921,7 +23130,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ - sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ #ifdef SQLITE_DEBUG 0, /* bJsonSelfcheck */ #endif @@ -23644,6 +23852,7 @@ struct PreUpdate { Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ + sqlite3_value **apDflt; /* Array of default values, if required */ }; /* @@ -24490,8 +24699,8 @@ static void computeJD(DateTime *p){ Y--; M += 12; } - A = Y/100; - B = 2 - A + (A/4); + A = (Y+4800)/100; + B = 38 - A + (A/4); X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); @@ -24675,7 +24884,7 @@ static int validJulianDay(sqlite3_int64 iJD){ ** Compute the Year, Month, and Day from the julian day number. */ static void computeYMD(DateTime *p){ - int Z, A, B, C, D, E, X1; + int Z, alpha, A, B, C, D, E, X1; if( p->validYMD ) return; if( !p->validJD ){ p->Y = 2000; @@ -24686,8 +24895,8 @@ static void computeYMD(DateTime *p){ return; }else{ Z = (int)((p->iJD + 43200000)/86400000); - A = (int)((Z - 1867216.25)/36524.25); - A = Z + 1 + A - (A/4); + alpha = (int)((Z + 32044.75)/36524.25) - 52; + A = Z + 1 + alpha - ((alpha+100)/4) + 25; B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; @@ -24886,8 +25095,8 @@ static const struct { /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, /* 3 */ { 3, "day", 5373485.0, 86400.0 }, - /* 4 */ { 5, "month", 176546.0, 30.0*86400.0 }, - /* 5 */ { 4, "year", 14713.0, 365.0*86400.0 }, + /* 4 */ { 5, "month", 176546.0, 2592000.0 }, + /* 5 */ { 4, "year", 14713.0, 31536000.0 }, }; /* @@ -29089,16 +29298,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. +** +** Because these routines raise false-positive alerts in TSAN, disable +** them (make them always return 1) when compiling with TSAN. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } -#endif +#endif /* NDEBUG */ #endif /* !defined(SQLITE_MUTEX_OMIT) */ @@ -31986,16 +32208,19 @@ SQLITE_API void sqlite3_str_vappendf( if( pItem->zAlias && !flag_altform2 ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( pItem->zName ){ - if( pItem->zDatabase ){ - sqlite3_str_appendall(pAccum, pItem->zDatabase); + if( pItem->fg.fixedSchema==0 + && pItem->fg.isSubquery==0 + && pItem->u4.zDatabase!=0 + ){ + sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); sqlite3_str_append(pAccum, ".", 1); } sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); - }else{ - Select *pSel = pItem->pSelect; - assert( pSel!=0 ); /* Because of tag-20240424-1 */ + }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ + Select *pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); if( pSel->selFlags & SF_NestedFrom ){ sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); }else if( pSel->selFlags & SF_MultiValue ){ @@ -32777,9 +33002,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); - if( pItem->pTab ){ + if( pItem->pSTab ){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", - pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, + pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, pItem->colUsed, pItem->fg.rowidUsed ? "+rowid" : ""); } @@ -32810,25 +33035,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); + if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); + if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); + if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); n = 0; - if( pItem->pSelect ) n++; + if( pItem->fg.isSubquery ) n++; if( pItem->fg.isTabFunc ) n++; if( pItem->fg.isUsing ) n++; if( pItem->fg.isUsing ){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } - if( pItem->pSelect ){ - sqlite3TreeViewPush(&pView, i+1nSrc); - if( pItem->pTab ){ - Table *pTab = pItem->pTab; + if( pItem->fg.isSubquery ){ + assert( n==1 ); + if( pItem->pSTab ){ + Table *pTab = pItem->pSTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "SUBQUERY"); sqlite3TreeViewPop(&pView); + sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); @@ -32870,7 +33100,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m n = 1000; }else{ n = 0; - if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; @@ -32896,7 +33126,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewPop(&pView); } #endif - if( p->pSrc && p->pSrc->nSrc ){ + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); @@ -33404,7 +33634,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "RAISE %s", zType); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif @@ -33484,9 +33715,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; + u8 sortFlags = pList->a[i].fg.sortFlags; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); @@ -33507,13 +33739,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( } } if( j ){ - fprintf(stdout, "iOrderByCol=%d", j); + fprintf(stdout, "iOrderByCol=%d ", j); + } + if( sortFlags & KEYINFO_ORDER_DESC ){ + fprintf(stdout, "DESC "); + }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ + fprintf(stdout, "NULLS-LAST"); } fprintf(stdout, "\n"); fflush(stdout); } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPop(&pView); } } @@ -34476,7 +34713,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { c = *(zIn++); \ if( c>=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zIn=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; n++; } return (int)(z-(unsigned char const *)zIn) @@ -35448,6 +35687,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + double rr[2]; + u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -35559,68 +35800,41 @@ do_atof_calc: e++; } - if( e==0 ){ - *pResult = s; - }else if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; - if( e>0 ){ - while( e>=100 ){ e-=100; r *= 1.0e+100L; } - while( e>=10 ){ e-=10; r *= 1.0e+10L; } - while( e>=1 ){ e-=1; r *= 1.0e+01L; } - }else{ - while( e<=-100 ){ e+=100; r *= 1.0e-100L; } - while( e<=-10 ){ e+=10; r *= 1.0e-10L; } - while( e<=-1 ){ e+=1; r *= 1.0e-01L; } - } - assert( r>=0.0 ); - if( r>+1.7976931348623157081452742373e+308L ){ -#ifdef INFINITY - *pResult = +INFINITY; -#else - *pResult = 1.0e308*10.0; + rr[0] = (double)s; + s2 = (u64)rr[0]; +#if defined(_MSC_VER) && _MSC_VER<1700 + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } #endif - }else{ - *pResult = (double)r; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + if( e>0 ){ + while( e>=100 ){ + e -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( e>=10 ){ + e -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( e>=1 ){ + e -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); } }else{ - double rr[2]; - u64 s2; - rr[0] = (double)s; - s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } -#endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - if( e>0 ){ - while( e>=100 ){ - e -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( e>=10 ){ - e -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( e>=1 ){ - e -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - }else{ - while( e<=-100 ){ - e += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( e<=-10 ){ - e += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( e<=-1 ){ - e += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } + while( e<=-100 ){ + e += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( e<=-10 ){ + e += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( e<=-1 ){ + e += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - *pResult = rr[0]+rr[1]; - if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; } + *pResult = rr[0]+rr[1]; + if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; if( sign<0 ) *pResult = -*pResult; assert( !sqlite3IsNaN(*pResult) ); @@ -35924,10 +36138,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ ** Decode a floating-point value into an approximate decimal ** representation. ** -** Round the decimal representation to n significant digits if -** n is positive. Or round to -n signficant digits after the -** decimal point if n is negative. No rounding is performed if -** n is zero. +** If iRound<=0 then round to -iRound significant digits to the +** the left of the decimal point, or to a maximum of mxRound total +** significant digits. +** +** If iRound>0 round to min(iRound,mxRound) significant digits total. +** +** mxRound must be positive. ** ** The significant digits of the decimal representation are ** stored in p->z[] which is a often (but not always) a pointer @@ -35938,8 +36155,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou int i; u64 v; int e, exp = 0; + double rr[2]; + p->isSpecial = 0; p->z = p->zBuf; + assert( mxRound>0 ); /* Convert negative numbers to positive. Deal with Infinity, 0.0, and ** NaN. */ @@ -35966,62 +36186,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou /* Multiply r by powers of ten until it lands somewhere in between ** 1.0e+19 and 1.0e+17. + ** + ** Use Dekker-style double-double computation to increase the + ** precision. + ** + ** The error terms on constants like 1.0e+100 computed using the + ** decimal extension, for example as follows: + ** + ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); */ - if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE rr = r; - if( rr>=1.0e+19 ){ - while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } - while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } - while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } - }else{ - while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } - while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } - while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } + rr[0] = r; + rr[1] = 0.0; + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ + exp += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( rr[0]>9.223372036854774784e+28 ){ + exp += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( rr[0]>9.223372036854774784e+18 ){ + exp += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - v = (u64)rr; }else{ - /* If high-precision floating point is not available using "long double", - ** then use Dekker-style double-double computation to increase the - ** precision. - ** - ** The error terms on constants like 1.0e+100 computed using the - ** decimal extension, for example as follows: - ** - ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - double rr[2]; - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>9.223372036854774784e+18 ){ - while( rr[0]>9.223372036854774784e+118 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>9.223372036854774784e+28 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>9.223372036854774784e+18 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - }else{ - while( rr[0]<9.223372036854774784e-83 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<9.223372036854774784e+07 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<9.22337203685477478e+17 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } + while( rr[0]<9.223372036854774784e-83 ){ + exp -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( rr[0]<9.223372036854774784e+07 ){ + exp -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( rr[0]<9.22337203685477478e+17 ){ + exp -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); } - v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; } - + v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; /* Extract significant digits. */ i = sizeof(p->zBuf)-1; @@ -36792,104 +36995,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam return 0; } -/* -** High-resolution hardware timer used for debugging and testing only. -*/ -#if defined(VDBE_PROFILE) \ - || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) -/************** Include hwtime.h in the middle of util.c *********************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on Pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in util.c ***********************/ -#endif - /************** End of util.c ************************************************/ /************** Begin file hash.c ********************************************/ /* @@ -37227,16 +37332,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 57 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 59 */ "ElseEq" OpHelp(""), /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 62 */ "IncrVacuum" OpHelp(""), @@ -37279,23 +37384,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 115 */ "OpenDup" OpHelp(""), + /* 114 */ "OpenDup" OpHelp(""), + /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 117 */ "String8" OpHelp("r[P2]='P4'"), - /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 118 */ "String8" OpHelp("r[P2]='P4'"), /* 119 */ "SorterOpen" OpHelp(""), /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), @@ -37330,8 +37435,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), - /* 153 */ "Real" OpHelp("r[P2]=P4"), - /* 154 */ "DropTrigger" OpHelp(""), + /* 153 */ "DropTrigger" OpHelp(""), + /* 154 */ "Real" OpHelp("r[P2]=P4"), /* 155 */ "IntegrityCk" OpHelp(""), /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 157 */ "Param" OpHelp(""), @@ -38680,7 +38785,7 @@ static pid_t randomnessPid = 0; #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#ifndef SQLITE_DISABLE_DIRSYNC +#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 @@ -40637,26 +40742,22 @@ static int nolockClose(sqlite3_file *id) { /* ** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -** -** In dotfile locking, either a lock exists or it does not. So in this -** variation of CheckReservedLock(), *pResOut is set to true if any lock -** is held on the file and false if the file is unlocked. +** file by this or any other process. If the caller holds a SHARED +** or greater lock when it is called, then it is assumed that no other +** client may hold RESERVED. Or, if the caller holds no lock, then it +** is assumed another client holds RESERVED if the lock-file exists. */ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { - int rc = SQLITE_OK; - int reserved = 0; unixFile *pFile = (unixFile*)id; - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - assert( pFile ); - reserved = osAccess((const char*)pFile->lockingContext, 0)==0; - OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); - *pResOut = reserved; - return rc; + if( pFile->eFileLock>=SHARED_LOCK ){ + *pResOut = 0; + }else{ + *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); + return SQLITE_OK; } /* @@ -40826,54 +40927,33 @@ static int robust_flock(int fd, int op){ ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; +#ifdef SQLITE_DEBUG unixFile *pFile = (unixFile*)id; +#else + UNUSED_PARAMETER(id); +#endif SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } + /* The flock VFS only ever takes exclusive locks (see function flockLock). + ** Therefore, if this connection is holding any lock at all, no other + ** connection may be holding a RESERVED lock. So set *pResOut to 0 + ** in this case. + ** + ** Or, this connection may be holding no lock. In that case, set *pResOut to + ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the + ** db in order to roll the hot journal back. If there is another connection + ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to + ** the user. With other VFS, we try to avoid this, in order to allow a reader + ** to proceed while a writer is preparing its transaction. But that won't + ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is + ** not a problem in this case. */ + *pResOut = 0; - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - /* attempt to get the lock */ - int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); - if( !lrc ){ - /* got the lock, unlock it */ - lrc = robust_flock(pFile->h, LOCK_UN); - if ( lrc ) { - int tErrno = errno; - /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } else { - int tErrno = errno; - reserved = 1; - /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); - -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - *pResOut = reserved; - return rc; + return SQLITE_OK; } /* @@ -42345,7 +42425,7 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) static int unixFcntlExternalReader(unixFile*, int*); #endif @@ -42472,7 +42552,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) return unixFcntlExternalReader((unixFile*)id, (int*)pArg); #else *(int*)pArg = 0; @@ -42561,7 +42641,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42569,7 +42649,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42645,7 +42725,7 @@ static int unixGetpagesize(void){ #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) /* ** Object used to represent an shared memory buffer. @@ -54730,6 +54810,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); + assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; @@ -55476,7 +55557,8 @@ static int pcache1InitBulk(PCache1 *pCache){ do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; - pX->page.pExtra = &pX[1]; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; @@ -55613,7 +55695,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; - p->page.pExtra = &p[1]; + p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); + assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ @@ -61172,6 +61255,7 @@ static int pagerAcquireMapPage( return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; + assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; @@ -64955,7 +65039,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). ** ** Immediately following the wal-header are zero or more frames. Each -** frame consists of a 24-byte frame-header followed by a bytes +** frame consists of a 24-byte frame-header followed by bytes ** of page data. The frame-header is six big-endian 32-bit unsigned ** integer values, as follows: ** @@ -65452,6 +65536,7 @@ struct Wal { #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; @@ -67344,7 +67429,7 @@ static int walHandleException(Wal *pWal){ /* ** Assert that the Wal.lockMask mask, which indicates the locks held -** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** by the connection, is consistent with the Wal.readLock, Wal.writeLock ** and Wal.ckptLock variables. To be used as: ** ** assert( walAssertLockmask(pWal) ); @@ -68008,7 +68093,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ SEH_INJECT_FAULT; if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif ){ /* The WAL has been completely backfilled (or it is empty). @@ -69408,7 +69493,20 @@ SQLITE_PRIVATE void sqlite3WalSnapshotOpen( Wal *pWal, sqlite3_snapshot *pSnapshot ){ - pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ + /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In + ** this case set the bGetSnapshot flag so that if the call to + ** sqlite3_snapshot_get() is about to read transaction on this wal + ** file, it does not take read-lock 0 if the wal file has been completely + ** checkpointed. Taking read-lock 0 would work, but then it would be + ** possible for a subsequent writer to destroy the snapshot even while + ** this connection is holding its read-transaction open. This is contrary + ** to user expectations, so we avoid it by not taking read-lock 0. */ + pWal->bGetSnapshot = 1; + }else{ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + pWal->bGetSnapshot = 0; + } } /* @@ -75289,6 +75387,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ return ROUND8(sizeof(BtCursor)); } +#ifdef SQLITE_DEBUG +/* +** Return true if and only if the Btree object will be automatically +** closed with the BtCursor closes. This is used within assert() statements +** only. +*/ +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor( + Btree *pBtree, /* the btree object */ + BtCursor *pCur /* Corresponding cursor */ +){ + BtShared *pBt = pBtree->pBt; + if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0; + if( pBt->pCursor!=pCur ) return 0; + if( pCur->pNext!=0 ) return 0; + if( pCur->pBtree!=pBtree ) return 0; + return 1; +} +#endif + /* ** Initialize memory that will be converted into a BtCursor object. ** @@ -76532,7 +76649,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ - pCur->curFlags &= ~BTCF_ValidOvfl; + pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); if( !pCur->pPage->isInit ){ return SQLITE_CORRUPT_BKPT; } @@ -78110,7 +78227,8 @@ static int rebuildPage( if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; ALWAYS(kixNx[k]<=i; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; @@ -78193,7 +78311,8 @@ static int pageInsertArray( u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; ALWAYS(kixNx[k]<=i ; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -78478,6 +78597,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ b.szCell = &szCell; b.apEnd[0] = pPage->aDataEnd; b.ixNx[0] = 2; + b.ixNx[NB*2-1] = 0x7fffffff; rc = rebuildPage(&b, 0, 1, pNew); if( NEVER(rc) ){ releasePage(pNew); @@ -78713,7 +78833,9 @@ static int balance_nonroot( CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); - memset(&b, 0, sizeof(b)); + assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); + memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); + b.ixNx[NB*2-1] = 0x7fffffff; pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -79304,7 +79426,8 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; ALWAYS(kj ); + for(k=0; b.ixNx[k]<=j; k++){} pSrcEnd = b.apEnd[k]; if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; @@ -84316,7 +84439,8 @@ static int valueFromFunction( goto value_from_function_out; } for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff, + &apVal[i]); if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } @@ -86250,6 +86374,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = (SubrtnSig*)p4; + sqlite3DbFree(db, pSig->zAff); + sqlite3DbFree(db, pSig); + break; + } } } @@ -86829,6 +86959,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ zP4 = pOp->p4.pTab->zName; break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); + break; + } default: { zP4 = pOp->p4.z; } @@ -89338,7 +89473,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem ** We must use separate SQLITE_NOINLINE functions here, since otherwise ** optimizer code movement causes gcov to become very confused. */ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) static int SQLITE_NOINLINE doubleLt(double a, double b){ return ar ); - testcase( x==r ); - return (xr); }else{ i64 y; if( r<-9223372036854775808.0 ) return +1; @@ -90369,6 +90497,13 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( } sqlite3DbNNFreeNN(db, preupdate.aNew); } + if( preupdate.apDflt ){ + int i; + for(i=0; inCol; i++){ + sqlite3ValueFree(preupdate.apDflt[i]); + } + sqlite3DbFree(db, preupdate.apDflt); + } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91997,6 +92132,17 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ ** ** The error code stored in database p->db is overwritten with the return ** value in any case. +** +** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, +** that means all of the the following will be true: +** +** p!=0 +** p->pVar!=0 +** i>0 +** i<=p->nVar +** +** An assert() is normally added after vdbeUnbind() to help static analyzers +** realize this. */ static int vdbeUnbind(Vdbe *p, unsigned int i){ Mem *pVar; @@ -92054,6 +92200,7 @@ static int bindText( rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); @@ -92103,6 +92250,7 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } @@ -92116,6 +92264,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } @@ -92126,6 +92275,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -92141,6 +92291,7 @@ SQLITE_API int sqlite3_bind_pointer( Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ @@ -92222,6 +92373,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else @@ -92581,7 +92733,30 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey1); }else if( iIdx>=p->pUnpacked->nField ){ - *ppValue = (sqlite3_value *)columnNullValue(); + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ if( pMem->flags & (MEM_Int|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); @@ -93134,6 +93309,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ +/* +** High-resolution hardware timer used for debugging and testing only. +*/ +#if defined(VDBE_PROFILE) \ + || defined(SQLITE_PERFORMANCE_TRACE) \ + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/************** Include hwtime.h in the middle of vdbe.c *********************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +/* +** The following routine only works on Pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in vdbe.c ***********************/ +#endif + /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are @@ -94327,7 +94600,7 @@ case OP_HaltIfNull: { /* in3 */ /* no break */ deliberate_fall_through } -/* Opcode: Halt P1 P2 * P4 P5 +/* Opcode: Halt P1 P2 P3 P4 P5 ** ** Exit immediately. All open cursors, etc are closed ** automatically. @@ -94340,18 +94613,22 @@ case OP_HaltIfNull: { /* in3 */ ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** -** If P4 is not null then it is an error message string. +** If P3 is not zero and P4 is NULL, then P3 is a register that holds the +** text of an error message. ** -** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** If P3 is zero and P4 is not null then the error message string is held +** in P4. +** +** P5 is a value between 1 and 4, inclusive, then the P4 error message +** string is modified as follows: ** -** 0: (no change) ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** -** If P5 is not zero and P4 is NULL, then everything after the ":" is -** omitted. +** If P3 is zero and P5 is not zero and P4 is NULL, then everything after +** the ":" is omitted. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program @@ -94364,6 +94641,9 @@ case OP_Halt: { #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_STATIC + || pOp->p4type==P4_DYNAMIC ); /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates ** something is wrong with the code generator. Raise an assertion in order @@ -94394,7 +94674,12 @@ case OP_Halt: { p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ - if( pOp->p5 ){ + if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ + const char *zErr; + assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); + zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); + sqlite3VdbeError(p, "%s", zErr); + }else if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; testcase( pOp->p5==1 ); @@ -95197,7 +95482,7 @@ case OP_RealAffinity: { /* in1 */ } #endif -#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE) +#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) /* Opcode: Cast P1 P2 * * * ** Synopsis: affinity(r[P1]) ** @@ -97437,23 +97722,23 @@ case OP_OpenWrite: if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } }else{ wrFlag = 0; - } - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); - assert( pOp->opcode==OP_OpenWrite ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateBtree opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ - assert( p2>=2 ); + assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; @@ -97631,7 +97916,10 @@ case OP_OpenEphemeral: { /* ncycle */ } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); if( rc ){ + assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + }else{ + assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } } } @@ -98409,6 +98697,7 @@ case OP_Found: { /* jump, in3, ncycle */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG + (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ for(ii=0; iip4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + - (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); + + /* Allocate space for (a) the context object and (n-1) extra pointers + ** to append to the sqlite3_context.argv[1] array, and (b) a memory + ** cell in which to store the accumulation. Be careful that the memory + ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. + ** + ** Note: We could avoid this by using a regular memory cell from aMem[] for + ** the accumulator, instead of allocating one here. */ + nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); + pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; - pCtx->pOut = (Mem*)&(pCtx->argv[n]); + pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); + assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; @@ -102116,14 +102416,29 @@ case OP_ReleaseReg: { /* Opcode: Noop * * * * * ** -** Do nothing. This instruction is often useful as a jump -** destination. +** Do nothing. Continue downward to the next opcode. */ -/* -** The magic Explain opcode are only inserted when explain==2 (which -** is to say when the EXPLAIN QUERY PLAN syntax is used.) -** This opcode records information from the optimizer. It is the -** the same as a no-op. This opcodesnever appears in a real VM program. +/* Opcode: Explain P1 P2 P3 P4 * +** +** This is the same as OP_Noop during normal query execution. The +** purpose of this opcode is to hold information about the query +** plan for the purpose of EXPLAIN QUERY PLAN output. +** +** The P4 value is human-readable text that describes the query plan +** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". +** +** The P1 value is the ID of the current element and P2 is the parent +** element for the case of nested query plan elements. If P2 is zero +** then this element is a top-level element. +** +** For loop elements, P3 is the estimated code of each invocation of this +** element. +** +** As with all opcodes, the meanings of the parameters for OP_Explain +** are subject to change from one release to the next. Applications +** should not attempt to interpret or use any of the information +** contained in the OP_Explain opcode. The information provided by this +** opcode is intended for testing and debugging use only. */ default: { /* This is really OP_Noop, OP_Explain */ assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); @@ -102450,6 +102765,11 @@ SQLITE_API int sqlite3_blob_open( pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } + if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", + zTable); + } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; @@ -103357,13 +103677,14 @@ static int vdbePmaReadBlob( while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ - u8 *aNext; /* Pointer to buffer to copy data from */ + u8 *aNext = 0; /* Pointer to buffer to copy data from */ nCopy = nRem; if( nRem>p->nBuffer ) nCopy = p->nBuffer; rc = vdbePmaReadBlob(p, nCopy, &aNext); if( rc!=SQLITE_OK ) return rc; assert( aNext!=p->aAlloc ); + assert( aNext!=0 ); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); nRem -= nCopy; } @@ -106633,7 +106954,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ pSrc = p->pSrc; if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + if( pItem->fg.isSubquery + && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) + ){ return WRC_Abort; } if( pItem->fg.isTabFunc @@ -106939,7 +107262,7 @@ static void extendFJMatch( if( pNew ){ pNew->iTable = pMatch->iCursor; pNew->iColumn = iColumn; - pNew->y.pTab = pMatch->pTab; + pNew->y.pTab = pMatch->pSTab; assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); @@ -107070,10 +107393,10 @@ static int lookupName( if( pSrcList ){ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ u8 hCol; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: @@ -107082,8 +107405,12 @@ static int lookupName( ** This pItem -------------^ */ int hit = 0; - assert( pItem->pSelect!=0 ); - pEList = pItem->pSelect->pEList; + Select *pSel; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); + pEList = pSel->pEList; assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ @@ -107206,9 +107533,9 @@ static int lookupName( */ if( cntTab==0 || (cntTab==1 - && ALWAYS(pMatch!=0) - && ALWAYS(pMatch->pTab!=0) - && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 + && pMatch!=0 + && ALWAYS(pMatch->pSTab!=0) + && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 && (pTab->tabFlags & TF_Ephemeral)==0) ){ cntTab = 1; @@ -107229,7 +107556,7 @@ static int lookupName( if( pMatch ){ pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pMatch->pTab; + pExpr->y.pTab = pMatch->pSTab; if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } @@ -107271,7 +107598,7 @@ static int lookupName( if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ - pTab = pUpsert->pUpsertSrc->a[0].pTab; + pTab = pUpsert->pUpsertSrc->a[0].pSTab; pExpr->iTable = EXCLUDED_TABLE_NUMBER; } } @@ -107354,11 +107681,11 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) + && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) ){ cnt = cntTab; #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 - if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){ + if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ eNewExprOp = TK_NULL; } #endif @@ -107595,7 +107922,7 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab; assert( ExprUseYTab(p) ); - pTab = p->y.pTab = pItem->pTab; + pTab = p->y.pTab = pItem->pSTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; @@ -107714,7 +108041,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pItem = pSrcList->a; pExpr->op = TK_COLUMN; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pItem->pTab; + pExpr->y.pTab = pItem->pSTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn--; pExpr->affExpr = SQLITE_AFF_INTEGER; @@ -107839,8 +108166,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Resolve function names */ case TK_FUNCTION: { - ExprList *pList = pExpr->x.pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ + ExprList *pList; /* The argument list */ + int n; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ @@ -107853,6 +108180,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); + pList = pExpr->x.pList; + n = pList ? pList->nExpr : 0; zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -107901,6 +108230,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } } #endif + + /* If the function may call sqlite3_value_subtype(), then set the + ** EP_SubtArg flag on all of its argument expressions. This prevents + ** where.c from replacing the expression with a value read from an + ** index on the same expression, which will not have the correct + ** subtype. Also set the flag if the function expression itself is + ** an EP_SubtArg expression. In this case subtypes are required as + ** the function may return a value with a subtype back to its + ** caller using sqlite3_result_value(). */ + if( (pDef->funcFlags & SQLITE_SUBTYPE) + || ExprHasProperty(pExpr, EP_SubtArg) + ){ + int ii; + for(ii=0; iia[ii].pExpr, EP_SubtArg); + } + } + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ /* For the purposes of the EP_ConstFunc flag, date and time ** functions and other functions that change slowly are considered @@ -108020,9 +108367,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC - if( pWin ){ + if( pWin && pParse->nErr==0 ){ Select *pSel = pNC->pWinSelect; - assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); + assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); if( pParse->db->mallocFailed ) break; @@ -108229,7 +108576,7 @@ static int resolveOrderByTermToExprList( int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ - assert( sqlite3ExprIsInteger(pE, &i)==0 ); + assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression @@ -108328,7 +108675,7 @@ static int resolveCompoundOrderBy( if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; - if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; @@ -108513,7 +108860,7 @@ static int resolveOrderGroupBy( continue; } } - if( sqlite3ExprIsInteger(pE2, &iCol) ){ + if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ @@ -108604,7 +108951,11 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** moves the pOrderBy down to the sub-query. It will be moved back ** after the names have been resolved. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + assert( p->pSrc->a[0].u4.pSubq!=0 ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); assert( p->pSrc->nSrc==1 && p->pOrderBy ); assert( pSub->pPrior && pSub->pOrderBy==0 ); pSub->pOrderBy = p->pOrderBy; @@ -108616,13 +108967,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; - assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/ - if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ + assert( pItem->zName!=0 + || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ + if( pItem->fg.isSubquery + && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 + ){ int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; if( pItem->zName ) pParse->zAuthContext = pItem->zName; - sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr ) return WRC_Abort; assert( db->mallocFailed==0 ); @@ -108724,7 +109078,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** These integers will be replaced by copies of the corresponding result ** set expressions by the call to resolveOrderGroupBy() below. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); p->pOrderBy = pSub->pOrderBy; pSub->pOrderBy = 0; } @@ -108991,7 +109348,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( if( pTab ){ sSrc.nSrc = 1; sSrc.a[0].zName = pTab->zName; - sSrc.a[0].pTab = pTab; + sSrc.a[0].pSTab = pTab; sSrc.a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP @@ -109096,7 +109453,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ op = pExpr->op; continue; } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op!=TK_REGISTER ) break; + op = pExpr->op2; + if( NEVER( op==TK_REGISTER ) ) break; } return pExpr->affExpr; } @@ -110886,15 +111245,30 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; - pNewItem->pSchema = pOldItem->pSchema; - pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->fg = pOldItem->fg; + if( pOldItem->fg.isSubquery ){ + Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); + if( pNewSubq==0 ){ + assert( db->mallocFailed ); + pNewItem->fg.isSubquery = 0; + }else{ + memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); + pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); + if( pNewSubq->pSelect==0 ){ + sqlite3DbFree(db, pNewSubq); + pNewSubq = 0; + pNewItem->fg.isSubquery = 0; + } + } + pNewItem->u4.pSubq = pNewSubq; + }else if( pOldItem->fg.fixedSchema ){ + pNewItem->u4.pSchema = pOldItem->u4.pSchema; + }else{ + pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); + } pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->fg = pOldItem->fg; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->addrFillSub = pOldItem->addrFillSub; - pNewItem->regReturn = pOldItem->regReturn; - pNewItem->regResult = pOldItem->regResult; if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); }else if( pNewItem->fg.isTabFunc ){ @@ -110907,11 +111281,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla if( pNewItem->fg.isCte ){ pNewItem->u2.pCteUse->nUse++; } - pTab = pNewItem->pTab = pOldItem->pTab; + pTab = pNewItem->pSTab = pOldItem->pSTab; if( pTab ){ pTab->nTabRef++; } - pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); if( pOldItem->fg.isUsing ){ assert( pNewItem->fg.isUsing ); pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); @@ -110985,7 +111358,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla pp = &pNew->pPrior; pNext = pNew; } - return pRet; } #else @@ -111800,8 +112172,12 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +** +** If the pParse pointer is provided, then allow the expression p to be +** a parameter (TK_VARIABLE) that is bound to an integer. +** But if pParse is NULL, then p must be a pure integer literal. */ -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ @@ -111816,18 +112192,38 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ } switch( p->op ){ case TK_UPLUS: { - rc = sqlite3ExprIsInteger(p->pLeft, pValue); + rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); break; } case TK_UMINUS: { int v = 0; - if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ assert( ((unsigned int)v)!=0x80000000 ); *pValue = -v; rc = 1; } break; } + case TK_VARIABLE: { + sqlite3_value *pVal; + if( pParse==0 ) break; + if( NEVER(pParse->pVdbe==0) ) break; + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; + sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); + pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, + SQLITE_AFF_BLOB); + if( pVal ){ + if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ + sqlite3_int64 vv = sqlite3_value_int64(pVal); + if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ + *pValue = (int)vv; + rc = 1; + } + } + sqlite3ValueFree(pVal); + } + break; + } default: break; } return rc; @@ -111981,8 +112377,8 @@ static Select *isCandidateForInOpt(const Expr *pX){ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ - if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ - pTab = pSrc->a[0].pTab; + if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ + pTab = pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ @@ -112165,7 +112561,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; /* Code an OP_Transaction and OP_TableLock for . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -112405,6 +112801,49 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ } } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Scan all previously generated bytecode looking for an OP_BeginSubrtn +** that is compatible with pExpr. If found, add the y.sub values +** to pExpr and return true. If not found, return false. +*/ +static int findCompatibleInRhsSubrtn( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* IN operator with RHS that we want to reuse */ + SubrtnSig *pNewSig /* Signature for the IN operator */ +){ + VdbeOp *pOp, *pEnd; + SubrtnSig *pSig; + Vdbe *v; + + if( pNewSig==0 ) return 0; + if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; + assert( pExpr->op==TK_IN ); + assert( !ExprUseYSub(pExpr) ); + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); + v = pParse->pVdbe; + assert( v!=0 ); + pOp = sqlite3VdbeGetOp(v, 1); + pEnd = sqlite3VdbeGetLastOp(v); + for(; pOpp4type!=P4_SUBRTNSIG ) continue; + assert( pOp->opcode==OP_BeginSubrtn ); + pSig = pOp->p4.pSubrtnSig; + assert( pSig!=0 ); + if( pNewSig->selId!=pSig->selId ) continue; + if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; + pExpr->y.sub.iAddr = pSig->iAddr; + pExpr->y.sub.regReturn = pSig->regReturn; + pExpr->iTable = pSig->iTable; + ExprSetProperty(pExpr, EP_Subrtn); + return 1; + } + return 0; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that will construct an ephemeral table containing all terms @@ -112454,11 +112893,28 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ - /* Reuse of the RHS is allowed */ - /* If this routine has already been coded, but the previous code - ** might not have been invoked yet, so invoke it now as a subroutine. + /* Reuse of the RHS is allowed + ** + ** Compute a signature for the RHS of the IN operator to facility + ** finding and reusing prior instances of the same IN operator. */ - if( ExprHasProperty(pExpr, EP_Subrtn) ){ + SubrtnSig *pSig = 0; + assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); + if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ + pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); + if( pSig ){ + pSig->selId = pExpr->x.pSelect->selId; + pSig->zAff = exprINAffinity(pParse, pExpr); + } + } + + /* Check to see if there is a prior materialization of the RHS of + ** this IN operator. If there is, then make use of that prior + ** materialization rather than recomputing it. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) + || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) + ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", @@ -112470,6 +112926,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); + if( pSig ){ + sqlite3DbFree(pParse->db, pSig->zAff); + sqlite3DbFree(pParse->db, pSig); + } return; } @@ -112480,7 +112940,13 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; - + if( pSig ){ + pSig->iAddr = pExpr->y.sub.iAddr; + pSig->regReturn = pExpr->y.sub.regReturn; + pSig->iTable = iTab; + pParse->mSubrtnSig = 1 << (pSig->selId&7); + sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); + } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -112521,15 +112987,30 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( SelectDest dest; int i; int rc; + int addrBloom = 0; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; + if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); + dest.iSDParm2 = regBloom; + } testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); + if( addrBloom ){ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + if( dest.iSDParm2==0 ){ + sqlite3VdbeChangeToNoop(v, addrBloom); + }else{ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + } + } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; @@ -112827,9 +113308,7 @@ static void sqlite3ExprCodeIN( if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)sqlite3DbMallocZero( - pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 - ); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than @@ -112972,6 +113451,15 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); + if( pOp->opcode==OP_Once && pOp->p3>0 ){ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } + } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; @@ -113254,13 +113742,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ -static void exprToRegister(Expr *pExpr, int iReg){ +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); if( NEVER(p==0) ) return; - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iReg; - ExprClearProperty(p, EP_Skip); + if( p->op==TK_REGISTER ){ + assert( p->iTable==iReg ); + }else{ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); + } } /* @@ -113430,6 +113922,59 @@ static int exprCodeInlineFunction( return target; } +/* +** Expression Node callback for sqlite3ExprCanReturnSubtype(). +** +** Only a function call is able to return a subtype. So if the node +** is not a function call, return WRC_Prune immediately. +** +** A function call is able to return a subtype if it has the +** SQLITE_RESULT_SUBTYPE property. +** +** Assume that every function is able to pass-through a subtype from +** one of its argument (using sqlite3_result_value()). Most functions +** are not this way, but we don't have a mechanism to distinguish those +** that are from those that are not, so assume they all work this way. +** That means that if one of its arguments is another function and that +** other function is able to return a subtype, then this function is +** able to return a subtype. +*/ +static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } + assert( ExprUseXList(pExpr) ); + db = pWalker->pParse->db; + n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Return TRUE if expression pExpr is able to return a subtype. +** +** A TRUE return does not guarantee that a subtype will be returned. +** It only indicates that a subtype return is possible. False positives +** are acceptable as they only disable an optimization. False negatives, +** on the other hand, can lead to incorrect answers. +*/ +static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = exprNodeCanReturnSubtype; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + + /* ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. ** If it is, then resolve the expression by reading from the index and @@ -113462,6 +114007,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( continue; } + + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index if they are themselves an + ** argument to another scalar function or aggregate. + ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + if( ExprHasProperty(pExpr, EP_SubtArg) + && sqlite3ExprCanReturnSubtype(pParse, pExpr) + ){ + continue; + } + v = pParse->pVdbe; assert( v!=0 ); if( p->bMaybeNullRow ){ @@ -114263,7 +114819,7 @@ expr_code_doover: break; } testcase( pX->op==TK_COLUMN ); - exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); testcase( regFree1==0 ); memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; @@ -114317,15 +114873,14 @@ expr_code_doover: } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ - sqlite3VdbeAddOp4( - v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); VdbeCoverage(v); }else{ - sqlite3HaltConstraint(pParse, + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp3(v, OP_Halt, pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, - pExpr->affExpr, pExpr->u.zToken, 0, 0); + pExpr->affExpr, r1); } - break; } #endif @@ -114614,7 +115169,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ @@ -117508,8 +118063,9 @@ static int renameResolveTrigger(Parse *pParse){ int i; for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ SrcItem *p = &pStep->pFrom->a[i]; - if( p->pSelect ){ - sqlite3SelectPrep(pParse, p->pSelect, 0); + if( p->fg.isSubquery ){ + assert( p->u4.pSubq!=0 ); + sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); } } } @@ -117577,8 +118133,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ } if( pStep->pFrom ){ int i; - for(i=0; ipFrom->nSrc; i++){ - sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + SrcList *pFrom = pStep->pFrom; + for(i=0; inSrc; i++){ + if( pFrom->a[i].fg.isSubquery ){ + assert( pFrom->a[i].u4.pSubq!=0 ); + sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); + } } } } @@ -117825,7 +118385,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ } for(i=0; inSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->pTab==p->pTab ){ + if( pItem->pSTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } } @@ -120253,12 +120813,13 @@ static int loadStatTbl( while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - int nSample; /* Number of samples */ - int nByte; /* Bytes of space required */ - int i; /* Bytes of space required */ - tRowcnt *pSpace; + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + i64 nByte; /* Bytes of space required */ + i64 i; /* Bytes of space required */ + tRowcnt *pSpace; /* Available allocated memory space */ + u8 *pPtr; /* Available memory as a u8 for easier manipulation */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; @@ -120278,7 +120839,7 @@ static int loadStatTbl( } pIdx->nSampleCol = nIdxCol; pIdx->mxSample = nSample; - nByte = sizeof(IndexSample) * nSample; + nByte = ROUND8(sizeof(IndexSample) * nSample); nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ @@ -120287,7 +120848,10 @@ static int loadStatTbl( sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } - pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + pPtr = (u8*)pIdx->aSample; + pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); + pSpace = (tRowcnt*)pPtr; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; ia; inSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase ){ - if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ + if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); + pFix->zType, pFix->pName, pItem->u4.zDatabase); return WRC_Abort; } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; + sqlite3DbFree(db, pItem->u4.zDatabase); pItem->fg.notCte = 1; + pItem->fg.hadSchema = 1; } - pItem->pSchema = pFix->pSchema; + pItem->u4.pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; + pItem->fg.fixedSchema = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( pList->a[i].fg.isUsing==0 @@ -121261,7 +121826,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( assert( pTabList ); for(iSrc=0; iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ - pTab = pTabList->a[iSrc].pTab; + pTab = pTabList->a[iSrc].pSTab; break; } } @@ -121864,12 +122429,12 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( SrcItem *p ){ const char *zDb; - assert( p->pSchema==0 || p->zDatabase==0 ); - if( p->pSchema ){ - int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + if( p->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); zDb = pParse->db->aDb[iDb].zDbSName; }else{ - zDb = p->zDatabase; + assert( !p->fg.isSubquery ); + zDb = p->u4.zDatabase; } return sqlite3LocateTable(pParse, flags, p->zName, zDb); } @@ -124854,6 +125419,8 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); @@ -124862,7 +125429,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, if( pTab==0 ){ if( noErr ){ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } goto exit_drop_table; @@ -125953,15 +126520,17 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists } assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } - pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); }else{ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } pParse->checkSchema = 1; @@ -126258,12 +126827,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } + assert( pItem->fg.fixedSchema==0 ); + assert( pItem->fg.isSubquery==0 ); if( pDatabase ){ pItem->zName = sqlite3NameFromToken(db, pDatabase); - pItem->zDatabase = sqlite3NameFromToken(db, pTable); + pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); }else{ pItem->zName = sqlite3NameFromToken(db, pTable); - pItem->zDatabase = 0; + pItem->u4.zDatabase = 0; } return pList; } @@ -126279,13 +126850,40 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; - if( pItem->pSelect ){ - sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + if( pItem->fg.isSubquery ){ + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); + sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); } } } } +/* +** Delete a Subquery object and its substructure. +*/ +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ + assert( pSubq!=0 && pSubq->pSelect!=0 ); + sqlite3SelectDelete(db, pSubq->pSelect); + sqlite3DbFree(db, pSubq); +} + +/* +** Remove a Subquery from a SrcItem. Return the associated Select object. +** The returned Select becomes the responsibility of the caller. +*/ +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ + Select *pSel; + assert( pItem!=0 ); + assert( pItem->fg.isSubquery ); + pSel = pItem->u4.pSubq->pSelect; + sqlite3DbFree(db, pItem->u4.pSubq); + pItem->u4.pSubq = 0; + pItem->fg.isSubquery = 0; + return pSel; +} + /* ** Delete an entire SrcList including all its substructure. */ @@ -126295,13 +126893,24 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); + + /* Check invariants on SrcItem */ + assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); + assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); + assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); + assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && + pItem->u4.pSubq->pSelect!=0) ); + if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->fg.isSubquery ){ + sqlite3SubqueryDelete(db, pItem->u4.pSubq); + }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); + } if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); - sqlite3DeleteTable(db, pItem->pTab); - if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + sqlite3DeleteTable(db, pItem->pSTab); if( pItem->fg.isUsing ){ sqlite3IdListDelete(db, pItem->u3.pUsing); }else if( pItem->u3.pOn ){ @@ -126311,6 +126920,54 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3DbNNFreeNN(db, pList); } +/* +** Attach a Subquery object to pItem->uv.pSubq. Set the +** pSelect value but leave all the other values initialized +** to zero. +** +** A copy of the Select object is made if dupSelect is true, and the +** SrcItem takes responsibility for deleting the copy. If dupSelect is +** false, ownership of the Select passes to the SrcItem. Either way, +** the SrcItem will take responsibility for deleting the Select. +** +** When dupSelect is zero, that means the Select might get deleted right +** away if there is an OOM error. Beware. +** +** Return non-zero on success. Return zero on an OOM error. +*/ +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* Item to which the subquery is to be attached */ + Select *pSelect, /* The subquery SELECT. Must be non-NULL */ + int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ +){ + Subquery *p; + assert( pSelect!=0 ); + assert( pItem->fg.isSubquery==0 ); + if( pItem->fg.fixedSchema ){ + pItem->u4.pSchema = 0; + pItem->fg.fixedSchema = 0; + }else if( pItem->u4.zDatabase!=0 ){ + sqlite3DbFree(pParse->db, pItem->u4.zDatabase); + pItem->u4.zDatabase = 0; + } + if( dupSelect ){ + pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); + if( pSelect==0 ) return 0; + } + p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); + if( p==0 ){ + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + } + pItem->fg.isSubquery = 1; + p->pSelect = pSelect; + assert( offsetof(Subquery, pSelect)==0 ); + memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); + return 1; +} + + /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of @@ -126360,10 +127017,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } + assert( pSubquery==0 || pDatabase==0 ); if( pSubquery ){ - pItem->pSelect = pSubquery; - if( pSubquery->selFlags & SF_NestedFrom ){ - pItem->fg.isNestedFrom = 1; + if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } } } assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); @@ -127641,8 +128300,8 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** ** The following fields are initialized appropriate in pSrc: ** -** pSrc->a[0].pTab Pointer to the Table object -** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** pSrc->a[0].spTab Pointer to the Table object +** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ @@ -127650,8 +128309,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); - if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); - pItem->pTab = pTab; + if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); + pItem->pSTab = pTab; pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; @@ -127692,6 +128351,7 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char * ** is for a top-level SQL statement. */ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + assert( IsVirtual(pTab) ); if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ return 1; } @@ -127773,7 +128433,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView( if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); + pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].fg.isUsing==0 ); assert( pFrom->a[0].u3.pOn==0 ); } @@ -127835,7 +128496,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( ** ); */ - pTab = pSrc->a[0].pTab; + pTab = pSrc->a[0].pSTab; if( HasRowid(pTab) ){ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); pEList = sqlite3ExprListAppend( @@ -127868,9 +128529,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab = 0; pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); - pSrc->a[0].pTab = pTab; + pSrc->a[0].pSTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ assert( pSrc->a[0].fg.isCte==0 ); pSrc->a[0].u2.pIBIndex = 0; @@ -130697,7 +131358,11 @@ static void minMaxFinalize(sqlite3_context *context){ ** group_concat(EXPR, ?SEPARATOR?) ** string_agg(EXPR, SEPARATOR) ** -** The SEPARATOR goes before the EXPR string. This is tragic. The +** Content is accumulated in GroupConcatCtx.str with the SEPARATOR +** coming before the EXPR value, except for the first entry which +** omits the SEPARATOR. +** +** It is tragic that the SEPARATOR goes before the EXPR string. The ** groupConcatInverse() implementation would have been easier if the ** SEPARATOR were appended after EXPR. And the order is undocumented, ** so we could change it, in theory. But the old behavior has been @@ -130801,7 +131466,7 @@ static void groupConcatInverse( /* pGCC is always non-NULL since groupConcatStep() will have always ** run first to initialize it */ if( ALWAYS(pGCC) ){ - int nVS; + int nVS; /* Number of characters to remove */ /* Must call sqlite3_value_text() to convert the argument into text prior ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ (void)sqlite3_value_text(argv[0]); @@ -131179,7 +131844,13 @@ static void signFunc( ** Implementation of fpdecode(x,y,z) function. ** ** x is a real number that is to be decoded. y is the precision. -** z is the maximum real precision. +** z is the maximum real precision. Return a string that shows the +** results of the sqlite3FpDecode() function. +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3FpDecode() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. */ static void fpdecodeFunc( sqlite3_context *context, @@ -131195,6 +131866,7 @@ static void fpdecodeFunc( x = sqlite3_value_double(argv[0]); y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); + if( z<=0 ) z = 1; sqlite3FpDecode(&s, x, y, z); if( s.isSpecial==2 ){ sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); @@ -131205,6 +131877,82 @@ static void fpdecodeFunc( } #endif /* SQLITE_DEBUG */ +#ifdef SQLITE_DEBUG +/* +** Implementation of parseuri(uri,flags) function. +** +** Required Arguments: +** "uri" The URI to parse. +** "flags" Bitmask of flags, as if to sqlite3_open_v2(). +** +** Additional arguments beyond the first two make calls to +** sqlite3_uri_key() for integers and sqlite3_uri_parameter for +** anything else. +** +** The result is a string showing the results of calling sqlite3ParseUri(). +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3ParseUri() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. +*/ +static void parseuriFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + sqlite3_str *pResult; + const char *zVfs; + const char *zUri; + unsigned int flgs; + int rc; + sqlite3_vfs *pVfs = 0; + char *zFile = 0; + char *zErr = 0; + + if( argc<2 ) return; + pVfs = sqlite3_vfs_find(0); + assert( pVfs ); + zVfs = pVfs->zName; + zUri = (const char*)sqlite3_value_text(argv[0]); + if( zUri==0 ) return; + flgs = (unsigned int)sqlite3_value_int(argv[1]); + rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); + pResult = sqlite3_str_new(0); + if( pResult ){ + int i; + sqlite3_str_appendf(pResult, "rc=%d", rc); + sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); + sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0); + sqlite3_str_appendf(pResult, ", err=%Q", zErr); + sqlite3_str_appendf(pResult, ", file=%Q", zFile); + if( zFile ){ + const char *z = zFile; + z += sqlite3Strlen30(z)+1; + while( z[0] ){ + sqlite3_str_appendf(pResult, ", %Q", z); + z += sqlite3Strlen30(z)+1; + } + for(i=2; ia; - pItem->pTab = pFKey->pFrom; + pItem->pSTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; - pItem->pTab->nTabRef++; + pItem->pSTab->nTabRef++; pItem->iCursor = pParse->nTab++; if( regNew!=0 ){ @@ -132736,7 +133486,8 @@ static Trigger *fkActionTrigger( SrcList *pSrc; Expr *pRaise; - pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), + pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); if( pRaise ){ pRaise->affExpr = OE_Abort; } @@ -132744,7 +133495,8 @@ static Trigger *fkActionTrigger( if( pSrc ){ assert( pSrc->nSrc==1 ); pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); + pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), @@ -133478,8 +134230,11 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ SrcItem *pItem = &pVal->pSrc->a[0]; - sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn); - sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1); + assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); + if( pItem->fg.isSubquery ){ + sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); + sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); + } } } @@ -133607,6 +134362,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList if( pRet ){ SelectDest dest; + Subquery *pSubq; pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; @@ -133616,28 +134372,32 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList assert( pLeft->pNext==0 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; - p->pSelect = pLeft; p->fg.viaCoroutine = 1; - p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; - p->regReturn = ++pParse->nMem; p->iCursor = -1; + assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); p->u1.nRow = 2; - sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub); - sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn); + if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ + pSubq = p->u4.pSubq; + pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, + pSubq->regReturn, 0, pSubq->addrFillSub); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); - /* Allocate registers for the output of the co-routine. Do so so - ** that there are two unused registers immediately before those - ** used by the co-routine. This allows the code in sqlite3Insert() - ** to use these registers directly, instead of copying the output - ** of the co-routine to a separate array for processing. */ - dest.iSdst = pParse->nMem + 3; - dest.nSdst = pLeft->pEList->nExpr; - pParse->nMem += 2 + dest.nSdst; + /* Allocate registers for the output of the co-routine. Do so so + ** that there are two unused registers immediately before those + ** used by the co-routine. This allows the code in sqlite3Insert() + ** to use these registers directly, instead of copying the output + ** of the co-routine to a separate array for processing. */ + dest.iSdst = pParse->nMem + 3; + dest.nSdst = pLeft->pEList->nExpr; + pParse->nMem += 2 + dest.nSdst; - pLeft->selFlags |= SF_MultiValue; - sqlite3Select(pParse, pLeft, &dest); - p->regResult = dest.iSdst; - assert( pParse->nErr || dest.iSdst>0 ); + pLeft->selFlags |= SF_MultiValue; + sqlite3Select(pParse, pLeft, &dest); + pSubq->regResult = dest.iSdst; + assert( pParse->nErr || dest.iSdst>0 ); + } pLeft = pRet; } }else{ @@ -133647,12 +134407,18 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList } if( pParse->nErr==0 ){ + Subquery *pSubq; assert( p!=0 ); - if( p->pSelect->pEList->nExpr!=pRow->nExpr ){ - sqlite3SelectWrongNumTermsError(pParse, p->pSelect); + assert( p->fg.isSubquery ); + pSubq = p->u4.pSubq; + assert( pSubq!=0 ); + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); }else{ - sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0); - sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn); + sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); + sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); } } sqlite3ExprListDelete(pParse->db, pRow); @@ -134003,9 +134769,14 @@ SQLITE_PRIVATE void sqlite3Insert( && pSelect->pPrior==0 ){ SrcItem *pItem = &pSelect->pSrc->a[0]; - dest.iSDParm = pItem->regReturn; - regFromSelect = pItem->regResult; - nColumn = pItem->pSelect->pEList->nExpr; + Subquery *pSubq; + assert( pItem->fg.isSubquery ); + pSubq = pItem->u4.pSubq; + dest.iSDParm = pSubq->regReturn; + regFromSelect = pSubq->regResult; + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + nColumn = pSubq->pSelect->pEList->nExpr; ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); if( bIdListInOrder && nColumn==pTab->nCol ){ regData = regFromSelect; @@ -135925,7 +136696,7 @@ static int xferOptimization( if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ } - if( pSelect->pSrc->a[0].pSelect ){ + if( pSelect->pSrc->a[0].fg.isSubquery ){ return 0; /* FROM clause cannot contain a subquery */ } if( pSelect->pWhere ){ @@ -140485,6 +141256,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Make sure sufficient number of registers have been allocated */ sqlite3TouchRegister(pParse, 8+cnt); + sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ @@ -142810,12 +143582,24 @@ static int sqlite3Prepare16( if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } + + /* Make sure nBytes is non-negative and correct. It should be the + ** number of bytes until the end of the input buffer or until the first + ** U+0000 character. If the input nBytes is odd, convert it into + ** an even number. If the input nBytes is negative, then the input + ** must be terminated by at least one U+0000 character */ if( nBytes>=0 ){ int sz; const char *z = (const char*)zSql; for(sz=0; szmutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ @@ -142829,7 +143613,7 @@ static int sqlite3Prepare16( ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); - *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); } sqlite3DbFree(db, zSql8); rc = sqlite3ApiExit(db, rc); @@ -143223,11 +144007,13 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; - assert( pItem->pSelect!=0 ); - pResults = pItem->pSelect->pEList; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + pResults = pItem->u4.pSubq->pSelect->pEList; assert( pResults!=0 ); assert( iCol>=0 && iColnExpr ); pResults->a[iCol].fg.bUsed = 1; @@ -143261,9 +144047,9 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=iStart; i<=iEnd; i++){ - iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); if( iCol>=0 - && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) ){ if( piTab ){ sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); @@ -143392,10 +144178,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; inSrc-1; i++, pRight++, pLeft++){ - Table *pRightTab = pRight->pTab; + Table *pRightTab = pRight->pSTab; u32 joinType; - if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; + if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; /* If this is a NATURAL join, synthesize an appropriate USING clause @@ -144268,12 +145054,18 @@ static void selectInnerLoop( ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + if( pDest->iSDParm2 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + regResult, nResultCol); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); } break; @@ -144815,8 +145607,12 @@ static const char *columnTypeImpl( SrcList *pTabList = pNC->pSrcList; for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); if( jnSrc ){ - pTab = pTabList->a[j].pTab; - pS = pTabList->a[j].pSelect; + pTab = pTabList->a[j].pSTab; + if( pTabList->a[j].fg.isSubquery ){ + pS = pTabList->a[j].u4.pSubq->pSelect; + }else{ + pS = 0; + } }else{ pNC = pNC->pNext; } @@ -145383,7 +146179,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -145863,7 +146659,7 @@ static int multiSelect( p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit - && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -146207,6 +147003,11 @@ static int generateOutputSubroutine( r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); + if( pDest->iSDParm2>0 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + pIn->iSdst, pIn->nSdst); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); break; } @@ -146863,7 +147664,9 @@ static void substSelect( pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(pSubst, pItem->pSelect, 1); + if( pItem->fg.isSubquery ){ + substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); + } if( pItem->fg.isTabFunc ){ substExprList(pSubst, pItem->u1.pFuncArg); } @@ -146894,7 +147697,7 @@ static void recomputeColumnsUsed( SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; - if( NEVER(pSrcItem->pTab==0) ) return; + if( NEVER(pSrcItem->pSTab==0) ) return; memset(&w, 0, sizeof(w)); w.xExprCallback = recomputeColumnsUsedExpr; w.xSelectCallback = sqlite3SelectWalkNoop; @@ -146934,8 +147737,10 @@ static void srclistRenumberCursors( aCsrMap[pItem->iCursor+1] = pParse->nTab++; } pItem->iCursor = aCsrMap[pItem->iCursor+1]; - for(p=pItem->pSelect; p; p=p->pPrior){ - srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + if( pItem->fg.isSubquery ){ + for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } } } } @@ -147246,7 +148051,8 @@ static int flattenSubquery( assert( pSrc && iFrom>=0 && iFromnSrc ); pSubitem = &pSrc->a[iFrom]; iParent = pSubitem->iCursor; - pSub = pSubitem->pSelect; + assert( pSubitem->fg.isSubquery ); + pSub = pSubitem->u4.pSubq->pSelect; assert( pSub!=0 ); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -147299,7 +148105,7 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ + || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ @@ -147385,14 +148191,18 @@ static int flattenSubquery( pParse->zAuthContext = zSavedAuthContext; /* Delete the transient structures associated with the subquery */ - pSub1 = pSubitem->pSelect; - sqlite3DbFree(db, pSubitem->zDatabase); + + if( ALWAYS(pSubitem->fg.isSubquery) ){ + pSub1 = sqlite3SubqueryDetach(db, pSubitem); + }else{ + pSub1 = 0; + } + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->fg.fixedSchema==0 ); sqlite3DbFree(db, pSubitem->zName); sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; pSubitem->zName = 0; pSubitem->zAlias = 0; - pSubitem->pSelect = 0; assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions @@ -147433,8 +148243,8 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; - Table *pItemTab = pSubitem->pTab; - pSubitem->pTab = 0; + Table *pItemTab = pSubitem->pSTab; + pSubitem->pSTab = 0; p->pOrderBy = 0; p->pPrior = 0; p->pLimit = 0; @@ -147442,7 +148252,7 @@ static int flattenSubquery( p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->op = TK_ALL; - pSubitem->pTab = pItemTab; + pSubitem->pSTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ @@ -147457,11 +148267,14 @@ static int flattenSubquery( TREETRACE(0x4,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - assert( pSubitem->pSelect==0 ); + assert( pSubitem->fg.isSubquery==0 ); } sqlite3DbFree(db, aCsrMap); if( db->mallocFailed ){ - pSubitem->pSelect = pSub1; + assert( pSubitem->fg.fixedSchema==0 ); + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->u4.zDatabase==0 ); + sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); return 1; } @@ -147472,8 +148285,8 @@ static int flattenSubquery( ** ** pSubitem->pTab is always non-NULL by test restrictions and tests above. */ - if( ALWAYS(pSubitem->pTab!=0) ){ - Table *pTabToDel = pSubitem->pTab; + if( ALWAYS(pSubitem->pSTab!=0) ){ + Table *pTabToDel = pSubitem->pSTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); @@ -147481,7 +148294,7 @@ static int flattenSubquery( }else{ pTabToDel->nTabRef--; } - pSubitem->pTab = 0; + pSubitem->pSTab = 0; } /* The following loop runs once for each term in a compound-subquery @@ -147537,8 +148350,11 @@ static int flattenSubquery( */ for(i=0; ia[i+iFrom]; - if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); assert( pItem->fg.isTabFunc==0 ); + assert( pItem->fg.isSubquery + || pItem->fg.fixedSchema + || pItem->u4.zDatabase==0 ); + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; iNewParent = pSubSrc->a[i].iCursor; @@ -147957,7 +148773,8 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** ** NAME AMBIGUITY ** -** This optimization is called the "WHERE-clause push-down optimization". +** This optimization is called the "WHERE-clause push-down optimization" +** or sometimes the "predicate push-down optimization". ** ** Do not confuse this optimization with another unrelated optimization ** with a similar name: The "MySQL push-down optimization" causes WHERE @@ -148221,10 +149038,10 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ if( pItem->fg.isCorrelated || pItem->fg.isCte ){ return 0; } - assert( pItem->pTab!=0 ); - pTab = pItem->pTab; - assert( pItem->pSelect!=0 ); - pSub = pItem->pSelect; + assert( pItem->pSTab!=0 ); + pTab = pItem->pSTab; + assert( pItem->fg.isSubquery ); + pSub = pItem->u4.pSubq->pSelect; assert( pSub->pEList->nExpr==pTab->nCol ); for(pX=pSub; pX; pX=pX->pPrior){ if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ @@ -148353,13 +149170,13 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 - || p->pSrc->a[0].pSelect + || p->pSrc->a[0].fg.isSubquery || pAggInfo->nFunc!=1 || p->pHaving ){ return 0; } - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); if( !IsOrdinaryTable(pTab) ) return 0; @@ -148384,7 +149201,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; assert( pTab!=0 ); @@ -148461,7 +149278,11 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); - if( pNewSrc==0 ) return WRC_Abort; + assert( pNewSrc!=0 || pParse->nErr ); + if( pParse->nErr ){ + sqlite3SrcListDelete(db, pNewSrc); + return WRC_Abort; + } *pNew = *p; p->pSrc = pNewSrc; p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); @@ -148516,7 +149337,7 @@ static struct Cte *searchWith( ){ const char *zName = pItem->zName; With *p; - assert( pItem->zDatabase==0 ); + assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); assert( zName!=0 ); for(p=pWith; p; p=p->pOuter){ int i; @@ -148586,7 +149407,7 @@ static int resolveFromTermToCte( Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( pParse->pWith==0 ){ /* There are no WITH clauses in the stack. No match is possible */ return 0; @@ -148596,7 +149417,8 @@ static int resolveFromTermToCte( ** go no further. */ return 0; } - if( pFrom->zDatabase!=0 ){ + assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); + if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ /* The FROM term contains a schema qualifier (ex: main.t1) and so ** it cannot possibly be a CTE reference. */ return 0; @@ -148632,7 +149454,7 @@ static int resolveFromTermToCte( } if( cannotBeFunction(pParse, pFrom) ) return 2; - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; pCteUse = pCte->pUse; @@ -148646,26 +149468,29 @@ static int resolveFromTermToCte( } pCteUse->eM10d = pCte->eM10d; } - pFrom->pTab = pTab; + pFrom->pSTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; - pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); if( db->mallocFailed ) return 2; - pFrom->pSelect->selFlags |= SF_CopyCte; - assert( pFrom->pSelect ); + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + pSel = pFrom->u4.pSubq->pSelect; + assert( pSel!=0 ); + pSel->selFlags |= SF_CopyCte; if( pFrom->fg.isIndexedBy ){ sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); return 2; } + assert( !pFrom->fg.isIndexedBy ); pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; /* Check if this is a recursive CTE. */ - pRecTerm = pSel = pFrom->pSelect; + pRecTerm = pSel; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; @@ -148673,11 +149498,13 @@ static int resolveFromTermToCte( assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->zDatabase==0 - && pItem->zName!=0 + if( pItem->zName!=0 + && !pItem->fg.hadSchema + && ALWAYS( !pItem->fg.isSubquery ) + && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ - pItem->pTab = pTab; + pItem->pSTab = pTab; pTab->nTabRef++; pItem->fg.isRecursive = 1; if( pRecTerm->selFlags & SF_Recursive ){ @@ -148779,11 +149606,14 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ - Select *pSel = pFrom->pSelect; + Select *pSel; Table *pTab; + assert( pFrom->fg.isSubquery ); + assert( pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; assert( pSel ); - pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ @@ -148903,33 +149733,35 @@ static int selectExpander(Walker *pWalker, Select *p){ */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab; - assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); - if( pFrom->pTab ) continue; + assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); + if( pFrom->pSTab ) continue; assert( pFrom->fg.isRecursive==0 ); if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY - Select *pSel = pFrom->pSelect; + Select *pSel; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif #ifndef SQLITE_OMIT_CTE }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ if( rc>1 ) return WRC_Abort; - pTab = pFrom->pTab; + pTab = pFrom->pSTab; assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + assert( pFrom->pSTab==0 ); + pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; if( pTab->nTabRef>=0xffff ){ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); - pFrom->pTab = 0; + pFrom->pSTab = 0; return WRC_Abort; } pTab->nTabRef++; @@ -148941,7 +149773,7 @@ static int selectExpander(Walker *pWalker, Select *p){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; - assert( pFrom->pSelect==0 ); + assert( pFrom->fg.isSubquery==0 ); if( IsView(pTab) ){ if( (db->flags & SQLITE_EnableView)==0 && pTab->pSchema!=db->aDb[1].pSchema @@ -148949,7 +149781,7 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } - pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( ALWAYS(IsVirtual(pTab)) @@ -148965,7 +149797,9 @@ static int selectExpander(Walker *pWalker, Select *p){ nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ - sqlite3WalkSelect(pWalker, pFrom->pSelect); + if( pFrom->fg.isSubquery ){ + sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); + } pWalker->eCode = eCodeOrig; pTab->nCol = nCol; } @@ -149052,7 +149886,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ int nAdd; /* Number of cols including rowid */ - Table *pTab = pFrom->pTab; /* Table for this data source */ + Table *pTab = pFrom->pSTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ @@ -149063,10 +149897,11 @@ static int selectExpander(Walker *pWalker, Select *p){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); if( pFrom->fg.isNestedFrom ){ - assert( pFrom->pSelect!=0 ); - pNestedFrom = pFrom->pSelect->pEList; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + assert( pFrom->u4.pSubq->pSelect!=0 ); + pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); @@ -149305,14 +150140,12 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; assert( pTab!=0 ); - if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ + if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ /* A sub-query in the FROM clause of a SELECT */ - Select *pSel = pFrom->pSelect; - if( pSel ){ - sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); - } + Select *pSel = pFrom->u4.pSubq->pSelect; + sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); } } } @@ -149626,6 +150459,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); + if( pParse->nErr ) return; pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs @@ -149835,6 +150669,7 @@ static void updateAccumulator( if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } + if( pParse->nErr ) return; } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; @@ -149844,6 +150679,7 @@ static void updateAccumulator( } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + if( pParse->nErr ) return; } pAggInfo->directMode = 0; @@ -149959,25 +150795,28 @@ static SrcItem *isSelfJoinView( int iFirst, int iEnd /* Range of FROM-clause entries to search. */ ){ SrcItem *pItem; - assert( pThis->pSelect!=0 ); - if( pThis->pSelect->selFlags & SF_PushDown ) return 0; + Select *pSel; + assert( pThis->fg.isSubquery ); + pSel = pThis->u4.pSubq->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_PushDown ) return 0; while( iFirsta[iFirst++]; - if( pItem->pSelect==0 ) continue; + if( !pItem->fg.isSubquery ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; - assert( pItem->pTab!=0 ); - assert( pThis->pTab!=0 ); - if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; + assert( pItem->pSTab!=0 ); + assert( pThis->pSTab!=0 ); + if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; - pS1 = pItem->pSelect; - if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ + pS1 = pItem->u4.pSubq->pSelect; + if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ /* The query flattener left two different CTE tables with identical ** names in the same FROM clause. */ continue; } - if( pItem->pSelect->selFlags & SF_PushDown ){ + if( pS1->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -150021,6 +150860,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ Expr *pExpr; Expr *pCount; sqlite3 *db; + SrcItem *pFrom; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; @@ -150035,8 +150875,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ - pSub = p->pSrc->a[0].pSelect; - if( pSub==0 ) return 0; /* The FROM is a subquery */ + pFrom = p->pSrc->a; + if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ @@ -150045,7 +150886,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ @@ -150053,8 +150894,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ db = pParse->db; pCount = pExpr; pExpr = 0; - pSub = p->pSrc->a[0].pSelect; - p->pSrc->a[0].pSelect = 0; + pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ @@ -150099,12 +150939,12 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ for(i=0; inSrc; i++){ SrcItem *p1 = &pSrc->a[i]; if( p1==p0 ) continue; - if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ return 1; } - if( p1->pSelect - && (p1->pSelect->selFlags & SF_NestedFrom)!=0 - && sameSrcAlias(p0, p1->pSelect->pSrc) + if( p1->fg.isSubquery + && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 + && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) ){ return 1; } @@ -150169,13 +151009,13 @@ static int fromClauseTermCanBeCoroutine( if( i==0 ) break; i--; pItem--; - if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ + if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ } return 1; } /* -** Generate code for the SELECT statement given in the p argument. +** Generate byte-code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. @@ -150186,6 +151026,40 @@ static int fromClauseTermCanBeCoroutine( ** ** This routine does NOT free the Select structure passed in. The ** calling function needs to do that. +** +** This is a long function. The following is an outline of the processing +** steps, with tags referencing various milestones: +** +** * Resolve names and similar preparation tag-select-0100 +** * Scan of the FROM clause tag-select-0200 +** + OUTER JOIN strength reduction tag-select-0220 +** + Sub-query ORDER BY removal tag-select-0230 +** + Query flattening tag-select-0240 +** * Separate subroutine for compound-SELECT tag-select-0300 +** * WHERE-clause constant propagation tag-select-0330 +** * Count()-of-VIEW optimization tag-select-0350 +** * Scan of the FROM clause again tag-select-0400 +** + Authorize unreferenced tables tag-select-0410 +** + Predicate push-down optimization tag-select-0420 +** + Omit unused subquery columns optimization tag-select-0440 +** + Generate code to implement subqueries tag-select-0480 +** - Co-routines tag-select-0482 +** - Reuse previously computed CTE tag-select-0484 +** - REuse previously computed VIEW tag-select-0486 +** - Materialize a VIEW or CTE tag-select-0488 +** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 +** * Set up for ORDER BY tag-select-0600 +** * Create output table tag-select-0630 +** * Prepare registers for LIMIT tag-select-0650 +** * Setup for DISTINCT tag-select-0680 +** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 +** * Generate code for aggregate and/or GROUP BY tag-select-0800 +** + GROUP BY queries tag-select-0810 +** + non-GROUP BY queries tag-select-0820 +** - Special case of count() w/o GROUP BY tag-select-0821 +** - General case of non-GROUP BY aggregates tag-select-0822 +** * Sort results, as needed tag-select-0900 +** * Internal self-checks tag-select-1000 */ SQLITE_PRIVATE int sqlite3Select( Parse *pParse, /* The parser context */ @@ -150229,6 +151103,7 @@ SQLITE_PRIVATE int sqlite3Select( } #endif + /* tag-select-0100 */ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); @@ -150280,7 +151155,7 @@ SQLITE_PRIVATE int sqlite3Select( if( sameSrcAlias(p0, p->pSrc) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", - p0->zAlias ? p0->zAlias : p0->pTab->zName + p0->zAlias ? p0->zAlias : p0->pSTab->zName ); goto select_end; } @@ -150315,12 +151190,13 @@ SQLITE_PRIVATE int sqlite3Select( /* Try to do various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query + ** tag-select-0200 */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ SrcItem *pItem = &pTabList->a[i]; - Select *pSub = pItem->pSelect; - Table *pTab = pItem->pTab; + Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; + Table *pTab = pItem->pSTab; /* The expander should have already created transient Table objects ** even for FROM clause elements such as subqueries that do not correspond @@ -150337,6 +151213,7 @@ SQLITE_PRIVATE int sqlite3Select( ** way that the i-th table cannot be the NULL row of a join, then ** perform the appropriate simplification. This is called ** "OUTER JOIN strength reduction" in the SQLite documentation. + ** tag-select-0220 */ if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, @@ -150407,7 +151284,8 @@ SQLITE_PRIVATE int sqlite3Select( if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); - /* If a FROM-clause subquery has an ORDER BY clause that is not + /* tag-select-0230: + ** If a FROM-clause subquery has an ORDER BY clause that is not ** really doing anything, then delete it now so that it does not ** interfere with query flattening. See the discussion at ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a @@ -150426,13 +151304,16 @@ SQLITE_PRIVATE int sqlite3Select( ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 + ** (6) The subquery is not a recursive CTE. ORDER BY has a different + ** meaning for recursive CTEs and this optimization does not + ** apply. ** ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ && pSub->pLimit==0 /* Condition (1) */ - && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ @@ -150470,6 +151351,7 @@ SQLITE_PRIVATE int sqlite3Select( continue; } + /* tag-select-0240 */ if( flattenSubquery(pParse, p, i, isAgg) ){ if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ @@ -150485,7 +151367,7 @@ SQLITE_PRIVATE int sqlite3Select( #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() - ** procedure. + ** procedure. tag-select-0300 */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); @@ -150501,9 +151383,9 @@ SQLITE_PRIVATE int sqlite3Select( #endif /* Do the WHERE-clause constant propagation optimization if this is - ** a join. No need to speed time on this operation for non-join queries + ** a join. No need to spend time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in - ** sqlite3WhereBegin(). + ** sqlite3WhereBegin(). tag-select-0330 */ if( p->pWhere!=0 && p->pWhere->op==TK_AND @@ -150520,6 +151402,7 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); } + /* tag-select-0350 */ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ @@ -150527,20 +151410,26 @@ SQLITE_PRIVATE int sqlite3Select( pTabList = p->pSrc; } - /* For each term in the FROM clause, do two things: - ** (1) Authorized unreferenced tables - ** (2) Generate code for all sub-queries + /* Loop over all terms in the FROM clause and do two things for each term: + ** + ** (1) Authorize unreferenced tables + ** (2) Generate code for all sub-queries + ** + ** tag-select-0400 */ for(i=0; inSrc; i++){ SrcItem *pItem = &pTabList->a[i]; SrcItem *pPrior; SelectDest dest; + Subquery *pSubq; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) const char *zSavedAuthContext; #endif - /* Issue SQLITE_READ authorizations with a fake column name for any + /* Authorized unreferenced tables. tag-select-0410 + ** + ** Issue SQLITE_READ authorizations with a fake column name for any ** tables that are referenced but from which no values are extracted. ** Examples of where these kinds of null SQLITE_READ authorizations ** would occur: @@ -150557,17 +151446,28 @@ SQLITE_PRIVATE int sqlite3Select( ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ - sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + const char *zDb; + if( pItem->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); + zDb = db->aDb[iDb].zDbSName; + }else if( pItem->fg.isSubquery ){ + zDb = 0; + }else{ + zDb = pItem->u4.zDatabase; + } + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Generate code for all sub-queries in the FROM clause */ - pSub = pItem->pSelect; - if( pSub==0 || pItem->addrFillSub!=0 ) continue; + if( pItem->fg.isSubquery==0 ) continue; + pSubq = pItem->u4.pSubq; + assert( pSubq!=0 ); + pSub = pSubq->pSelect; /* The code for a subquery should only be generated once. */ - assert( pItem->addrFillSub==0 ); + if( pSubq->addrFillSub!=0 ) continue; /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select @@ -150580,6 +151480,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. + ** This is the "predicate push-down optimization". tag-select-0420 */ if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 @@ -150593,13 +151494,14 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewSelect(0, p, 0); } #endif - assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); + assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL ** expressions, to avoid unneeded searching and computation. + ** tag-select-0440 */ if( OptimizationEnabled(db, SQLITE_NullUnusedCols) && disableUnusedSubqueryResultColumns(pItem) @@ -150617,32 +151519,33 @@ SQLITE_PRIVATE int sqlite3Select( zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; - /* Generate code to implement the subquery + /* Generate byte-code to implement the subquery tag-select-0480 */ if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ /* Implement a co-routine that will return a single row of the result - ** set on each invocation. + ** set on each invocation. tag-select-0482 */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; - pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); VdbeComment((v, "%!S", pItem)); - pItem->addrFillSub = addrTop; - sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + pSubq->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; - pItem->regResult = dest.iSdst; - sqlite3VdbeEndCoroutine(v, pItem->regReturn); + pSubq->regResult = dest.iSdst; + sqlite3VdbeEndCoroutine(v, pSubq->regReturn); + VdbeComment((v, "end %!S", pItem)); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, - ** the make the pItem->iCursor be a copy of the ephemeral table that - ** holds the result of the materialization. */ + ** then make the pItem->iCursor be a copy of the ephemeral table that + ** holds the result of the materialization. tag-select-0484 */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); if( pItem->iCursor!=pCteUse->iCur ){ @@ -150652,25 +151555,30 @@ SQLITE_PRIVATE int sqlite3Select( pSub->nSelectRow = pCteUse->nRowEst; }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ /* This view has already been materialized by a prior entry in - ** this same FROM clause. Reuse it. */ - if( pPrior->addrFillSub ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + ** this same FROM clause. Reuse it. tag-select-0486 */ + Subquery *pPriorSubq; + assert( pPrior->fg.isSubquery ); + pPriorSubq = pPrior->u4.pSubq; + assert( pPriorSubq!=0 ); + if( pPriorSubq->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, + pPriorSubq->addrFillSub); } sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; + pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; }else{ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of - ** the same view can reuse the materialization. */ + ** the same view can reuse the materialization. tag-select-0488 */ int topAddr; int onceAddr = 0; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int addrExplain; #endif - pItem->regReturn = ++pParse->nMem; + pSubq->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp0(v, OP_Goto); - pItem->addrFillSub = topAddr+1; + pSubq->addrFillSub = topAddr+1; pItem->fg.isMaterialized = 1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of @@ -150685,17 +151593,17 @@ SQLITE_PRIVATE int sqlite3Select( ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); - sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); + sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); VdbeComment((v, "end %!S", pItem)); sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); sqlite3VdbeJumpHere(v, topAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; - pCteUse->addrM9e = pItem->addrFillSub; - pCteUse->regRtn = pItem->regReturn; + pCteUse->addrM9e = pSubq->addrFillSub; + pCteUse->regRtn = pSubq->regReturn; pCteUse->iCur = pItem->iCursor; pCteUse->nRowEst = pSub->nSelectRow; } @@ -150721,7 +151629,9 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + /* tag-select-0500 + ** + ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: ** @@ -150738,12 +151648,18 @@ SQLITE_PRIVATE int sqlite3Select( */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 + && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + if( pGroupBy ){ + for(i=0; inExpr; i++){ + pGroupBy->a[i].u.x.iOrderByCol = i+1; + } + } p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the @@ -150765,7 +151681,7 @@ SQLITE_PRIVATE int sqlite3Select( ** If that is the case, then the OP_OpenEphemeral instruction will be ** changed to an OP_Noop once we figure out that the sorting index is ** not needed. The sSort.addrSortIndex variable is used to facilitate - ** that change. + ** that change. tag-select-0600 */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; @@ -150782,6 +151698,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If the output is destined for a temporary table, open that table. + ** tag-select-0630 */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); @@ -150799,7 +151716,7 @@ SQLITE_PRIVATE int sqlite3Select( } } - /* Set the limiter. + /* Set the limiter. tag-select-0650 */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ @@ -150811,7 +151728,7 @@ SQLITE_PRIVATE int sqlite3Select( sSort.sortFlags |= SORTFLAG_UseSorter; } - /* Open an ephemeral index to use for the distinct set. + /* Open an ephemeral index to use for the distinct set. tag-select-0680 */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; @@ -150826,7 +151743,7 @@ SQLITE_PRIVATE int sqlite3Select( } if( !isAgg && pGroupBy==0 ){ - /* No aggregate functions and no GROUP BY clause */ + /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) | (p->selFlags & SF_FixedLimit); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -150899,8 +151816,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3WhereEnd(pWInfo); } }else{ - /* This case when there exist aggregate functions or a GROUP BY clause - ** or both */ + /* This case is for when there exist aggregate functions or a GROUP BY + ** clause or both. tag-select-0800 */ NameContext sNC; /* Name context for processing aggregate information */ int iAMem; /* First Mem address for storing current GROUP BY */ int iBMem; /* First Mem address for previous GROUP BY */ @@ -151019,7 +151936,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Processing for aggregates with GROUP BY is very different and - ** much more complex than aggregates without a GROUP BY. + ** much more complex than aggregates without a GROUP BY. tag-select-0810 */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ @@ -151206,12 +152123,25 @@ SQLITE_PRIVATE int sqlite3Select( sortOut, sortPTab); } for(j=0; jnExpr; j++){ + int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; + if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } + + if( iOrderByCol ){ + Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; + Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); + if( ALWAYS(pBase!=0) + && pBase->op!=TK_AGG_COLUMN + && pBase->op!=TK_REGISTER + ){ + sqlite3ExprToRegister(pX, iAMem+j); + } + } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); @@ -151227,9 +152157,9 @@ SQLITE_PRIVATE int sqlite3Select( ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ - sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); @@ -151303,9 +152233,12 @@ SQLITE_PRIVATE int sqlite3Select( } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { + /* Aggregate functions without GROUP BY. tag-select-0820 */ Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ - /* If isSimpleCount() returns a pointer to a Table structure, then + /* tag-select-0821 + ** + ** If isSimpleCount() returns a pointer to a Table structure, then ** the SQL statement is of the form: ** ** SELECT count(*) FROM @@ -151364,6 +152297,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ + /* The general case of an aggregate query without GROUP BY + ** tag-select-0822 */ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; u16 distFlag = 0; @@ -151452,7 +152387,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If there is an ORDER BY clause, then we need to sort the results - ** and send them to the callback one by one. + ** and send them to the callback one by one. tag-select-0900 */ if( sSort.pOrderBy ){ assert( p->pEList==pEList ); @@ -151475,6 +152410,7 @@ select_end: assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG + /* Internal self-checks. tag-select-1000 */ if( pAggInfo && !db->mallocFailed ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x20 ){ @@ -151864,8 +152800,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( ** name on pTableName if we are reparsing out of the schema table */ if( db->init.busy && iDb!=1 ){ - sqlite3DbFree(db, pTableName->a[0].zDatabase); - pTableName->a[0].zDatabase = 0; + assert( pTableName->a[0].fg.fixedSchema==0 ); + assert( pTableName->a[0].fg.isSubquery==0 ); + sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); + pTableName->a[0].u4.zDatabase = 0; } /* If the trigger name was unqualified, and the table is a temp table, @@ -152343,7 +153281,8 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) } assert( pName->nSrc==1 ); - zDb = pName->a[0].zDatabase; + assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); + zDb = pName->a[0].u4.zDatabase; zName = pName->a[0].zName; assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ @@ -152580,7 +153519,9 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( Schema *pSchema = pStep->pTrig->pSchema; pSrc->a[0].zName = zName; if( pSchema!=db->aDb[1].pSchema ){ - pSrc->a[0].pSchema = pSchema; + assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); + pSrc->a[0].u4.pSchema = pSchema; + pSrc->a[0].fg.fixedSchema = 1; } if( pStep->pFrom ){ SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); @@ -152693,7 +153634,7 @@ static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ pSrc = pSelect->pSrc; assert( pSrc!=0 ); for(i=0; inSrc; i++){ - if( pSrc->a[i].pTab==pWalker->u.pTab ){ + if( pSrc->a[i].pSTab==pWalker->u.pTab ){ testcase( pSelect->selFlags & SF_Correlated ); pSelect->selFlags |= SF_Correlated; pWalker->eCode = 1; @@ -152764,7 +153705,7 @@ static void codeReturningTrigger( sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = &sFrom; sFrom.nSrc = 1; - sFrom.a[0].pTab = pTab; + sFrom.a[0].pSTab = pTab; sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); @@ -153475,7 +154416,7 @@ static void updateFromSelect( Expr *pLimit2 = 0; ExprList *pOrderBy2 = 0; sqlite3 *db = pParse->db; - Table *pTab = pTabList->a[0].pTab; + Table *pTab = pTabList->a[0].pSTab; SrcList *pSrc; Expr *pWhere2; int eDest; @@ -153499,8 +154440,8 @@ static void updateFromSelect( if( pSrc ){ assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; - pSrc->a[0].pTab->nTabRef--; - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab->nTabRef--; + pSrc->a[0].pSTab = 0; } if( pPk ){ for(i=0; inKeyCol; i++){ @@ -154748,7 +155689,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); - assert( pTabList->a[0].pTab!=0 ); + assert( pTabList->a[0].pSTab!=0 ); assert( pUpsert!=0 ); assert( pUpsert->pUpsertTarget!=0 ); @@ -154767,7 +155708,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; pTarget = pUpsert->pUpsertTarget; iCursor = pTabList->a[0].iCursor; if( HasRowid(pTab) @@ -155138,6 +156079,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -155178,27 +156122,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; - rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); @@ -155275,11 +156221,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_schema " + "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain + zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; @@ -155291,11 +156237,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** from the schema table. */ rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_schema" + "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", - zDbMain + zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; @@ -156259,6 +157205,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; + assert( IsOrdinaryTable(pNew) ); sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); @@ -156933,11 +157880,13 @@ struct WhereLoop { u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ + ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ u32 bOmitOffset : 1; /* True to let virtual table handle offset */ + u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ @@ -156950,6 +157899,8 @@ struct WhereLoop { /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not + ** initialized unless pWInfo->nOutStarDelta>0 */ WhereTerm **aLTerm; /* WhereTerms used */ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ @@ -157272,6 +158223,7 @@ struct WhereInfo { unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ + LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ @@ -157423,7 +158375,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ - /* 0x02000000 -- available for reuse */ +#define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. + ** NB: False-negatives are possible */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -157568,7 +158521,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); - if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ + if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ if( isSearch ){ zFmt = "PRIMARY KEY"; } @@ -157611,7 +158564,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", + sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); + sqlite3_str_appendf(&str, + pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif @@ -157629,7 +158584,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + pParse->addrExplain, pLoop->rRun, + zMsg, P4_DYNAMIC); } return ret; } @@ -157664,7 +158620,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); pLoop = pLevel->pWLoop; if( pLoop->wsFlags & WHERE_IPK ){ - const Table *pTab = pItem->pTab; + const Table *pTab = pItem->pSTab; if( pTab->iPKey>=0 ){ sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); }else{ @@ -157727,7 +158683,9 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } }else{ - int addr = pSrclist->a[pLvl->iFrom].addrFillSub; + int addr; + assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); + addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); @@ -157871,6 +158829,39 @@ static void updateRangeAffinityStr( } } +/* +** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because +** columns might have been rearranged in the result set. This routine +** fixes them up. +** +** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values +** contain the *old* locations of each expression. This is a temporary +** use of u.x.iOrderByCol, not its intended use. The caller must reset +** u.x.iOrderByCol back to zero for all entries in pEList before the +** caller returns. +** +** This routine changes pOrderBy->a[].u.x.iOrderByCol values from +** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based +** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. +*/ +static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ + int i, j; + if( pOrderBy==0 ) return; + for(i=0; inExpr; i++){ + int t = pOrderBy->a[i].u.x.iOrderByCol; + if( t==0 ) continue; + for(j=0; jnExpr; j++){ + if( pEList->a[j].u.x.iOrderByCol==t ){ + pOrderBy->a[i].u.x.iOrderByCol = j+1; + break; + } + } + if( j>=pEList->nExpr ){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } +} + /* ** pX is an expression of the form: (vector) IN (SELECT ...) @@ -157934,6 +158925,7 @@ static Expr *removeUnindexableInClauseTerms( if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; + if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; if( pOrigLhs ){ assert( pOrigLhs->a[iField].pExpr!=0 ); pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); @@ -157956,18 +158948,16 @@ static Expr *removeUnindexableInClauseTerms( sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } + + /* If either the ORDER BY clause or the GROUP BY clause contains + ** references to result-set columns, those references might now be + ** obsolete. So fix them up. + */ + assert( pRhs!=0 || db->mallocFailed ); + if( pRhs ){ + adjustOrderByCol(pSelect->pOrderBy, pRhs); + adjustOrderByCol(pSelect->pGroupBy, pRhs); + for(i=0; inExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; } #if 0 @@ -157982,6 +158972,147 @@ static Expr *removeUnindexableInClauseTerms( } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for a single X IN (....) term of the WHERE clause. +** +** This is a special-case of codeEqualityTerm() that works for IN operators +** only. It is broken out into a subroutine because this case is +** uncommon and by splitting it off into a subroutine, the common case +** runs faster. +** +** The current value for the constraint is left in register iTarget. +** This routine sets up a loop that will iterate over all values of X. +*/ +static SQLITE_NOINLINE void codeINTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + int eType = IN_INDEX_NOOP; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + Vdbe *v = pParse->pVdbe; + int i; + int nEq = 0; + int *aiMap = 0; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + + for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return; + } + } + for(i=iEq;inLTerm; i++){ + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + iTab = 0; + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + }else{ + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + } + sqlite3ExprDelete(db, pX); + }else{ + int n = sqlite3ExprVectorSize(pX->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + } + pX = pExpr; + } + + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; + pLevel->u.in.aInLoop = + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq;inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iTarget + i - iEq; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 ){ + pIn->iBase = iTarget - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } + }else{ + pIn->eEndLoopOp = OP_Noop; + } + pIn++; + } + } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } + }else{ + pLevel->u.in.nIn = 0; + } + sqlite3DbFree(pParse->db, aiMap); +} +#endif + + /* ** Generate code for a single equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the term to be @@ -158006,7 +159137,6 @@ static int codeEqualityTerm( int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; - Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); @@ -158015,125 +159145,12 @@ static int codeEqualityTerm( iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; - sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ - int eType = IN_INDEX_NOOP; - int iTab; - struct InLoop *pIn; - WhereLoop *pLoop = pLevel->pWLoop; - int i; - int nEq = 0; - int *aiMap = 0; - - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 - && pLoop->u.btree.pIndex!=0 - && pLoop->u.btree.pIndex->aSortOrder[iEq] - ){ - testcase( iEq==0 ); - testcase( bRev ); - bRev = !bRev; - } assert( pX->op==TK_IN ); iReg = iTarget; - - for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ - disableTerm(pLevel, pTerm); - return iTarget; - } - } - for(i=iEq;inLTerm; i++){ - assert( pLoop->aLTerm[i]!=0 ); - if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } - - iTab = 0; - if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else{ - Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); - pExpr->iTable = iTab; - } - sqlite3ExprDelete(db, pX); - }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); - } - pX = pExpr; - } - - if( eType==IN_INDEX_INDEX_DESC ){ - testcase( bRev ); - bRev = !bRev; - } - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); - VdbeCoverageIf(v, bRev); - VdbeCoverageIf(v, !bRev); - - assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); - pLoop->wsFlags |= WHERE_IN_ABLE; - if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); - } - if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ - pLoop->wsFlags |= WHERE_IN_EARLYOUT; - } - - i = pLevel->u.in.nIn; - pLevel->u.in.nIn += nEq; - pLevel->u.in.aInLoop = - sqlite3WhereRealloc(pTerm->pWC->pWInfo, - pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); - pIn = pLevel->u.in.aInLoop; - if( pIn ){ - int iMap = 0; /* Index in aiMap[] */ - pIn += i; - for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iOut = iReg + i - iEq; - if( eType==IN_INDEX_ROWID ){ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); - }else{ - int iCol = aiMap ? aiMap[iMap++] : 0; - pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); - } - sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); - if( i==iEq ){ - pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; - if( iEq>0 ){ - pIn->iBase = iReg - i; - pIn->nPrefix = i; - }else{ - pIn->nPrefix = 0; - } - }else{ - pIn->eEndLoopOp = OP_Noop; - } - pIn++; - } - } - testcase( iEq>0 - && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 - && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); - if( iEq>0 - && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 - ){ - sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); - } - }else{ - pLevel->u.in.nIn = 0; - } - sqlite3DbFree(pParse->db, aiMap); + codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); #endif } @@ -158805,7 +159822,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; - VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); + VdbeModuleComment((v, "Begin WHERE-loop%d: %s", + iLevel, pTabItem->pSTab->zName)); #if WHERETRACE_ENABLED /* 0x4001 */ if( sqlite3WhereTrace & 0x1 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", @@ -158860,11 +159878,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + int regYield; + Subquery *pSubq; + assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); + pSubq = pTabItem->u4.pSubq; + regYield = pSubq->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); pLevel->op = OP_Goto; }else @@ -159593,7 +160615,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); @@ -160052,7 +161074,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** least once. This is accomplished by storing the PK for the row in ** both the iMatch index and the regBloom Bloom filter. */ - pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; + pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; if( HasRowid(pTab) ){ r = sqlite3GetTempRange(pParse, 2); sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); @@ -160159,7 +161181,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( Bitmask mAll = 0; int k; - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, pRJ->regReturn); for(k=0; kpTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; if( pRight->fg.viaCoroutine ){ + Subquery *pSubq; + assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); + pSubq = pRight->u4.pSubq; + assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); sqlite3VdbeAddOp3( - v, OP_Null, 0, pRight->regResult, - pRight->regResult + pRight->pSelect->pEList->nExpr-1 + v, OP_Null, 0, pSubq->regResult, + pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 ); } sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); @@ -160209,7 +161235,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); nPk = 1; @@ -160342,7 +161368,12 @@ static int allowedOp(int op){ assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; + assert( TK_INTK_GE ) return 0; + if( op>=TK_EQ ) return 1; + return op==TK_IN || op==TK_ISNULL || op==TK_IS; } /* @@ -160375,15 +161406,16 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ static u16 operatorMask(int op){ u16 c; assert( allowedOp(op) ); - if( op==TK_IN ){ + if( op>=TK_EQ ){ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + }else if( op==TK_IN ){ c = WO_IN; }else if( op==TK_ISNULL ){ c = WO_ISNULL; - }else if( op==TK_IS ){ - c = WO_IS; }else{ - assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); - c = (u16)(WO_EQ<<(op-TK_EQ)); + assert( op==TK_IS ); + c = WO_IS; } assert( op!=TK_ISNULL || c==WO_ISNULL ); assert( op!=TK_IN || c==WO_IN ); @@ -160454,12 +161486,26 @@ static int isLikeOrGlob( z = (u8*)pRight->u.zToken; } if( z ){ - - /* Count the number of prefix characters prior to the first wildcard */ + /* Count the number of prefix bytes prior to the first wildcard. + ** or U+fffd character. If the underlying database has a UTF16LE + ** encoding, then only consider ASCII characters. Note that the + ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in + ** this code, but the database engine itself might be processing + ** content using a different encoding. */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; - if( c==wc[3] && z[cnt]!=0 ) cnt++; + if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ + cnt++; + }else if( c>=0x80 ){ + const u8 *z2 = z+cnt-1; + if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){ + cnt--; + break; + }else{ + cnt = (int)(z2-z); + } + } } /* The optimization is possible only if (1) the pattern does not begin @@ -160470,11 +161516,11 @@ static int isLikeOrGlob( ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ - *pisComplete = c==wc[0] && z[cnt+1]==0; + *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; /* Get the pattern prefix. Remove all escapes from the prefix. */ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); @@ -160670,6 +161716,13 @@ static int isAuxiliaryVtabOperator( } } } + }else if( pExpr->op>=TK_EQ ){ + /* Comparison operators are a common case. Save a few comparisons for + ** that common case by terminating early. */ + assert( TK_NE < TK_EQ ); + assert( TK_ISNOT < TK_EQ ); + assert( TK_NOTNULL < TK_EQ ); + return 0; }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; @@ -161186,7 +162239,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ if( ALWAYS(pSrc!=0) ){ int i; for(i=0; inSrc; i++){ - mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); + if( pSrc->a[i].fg.isSubquery ){ + mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); + } if( pSrc->a[i].fg.isUsing==0 ){ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); } @@ -161224,7 +162279,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( int iCur; do{ iCur = pFrom->a[j].iCursor; - for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; @@ -161268,7 +162323,7 @@ static int exprMightBeIndexed( for(i=0; inSrc; i++){ Index *pIdx; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr ){ return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); } @@ -161811,7 +162866,7 @@ static void whereAddLimitExpr( Expr *pNew; int iVal = 0; - if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); if( pVal==0 ) return; ExprSetProperty(pVal, EP_IntValue); @@ -161856,7 +162911,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ if( p->pGroupBy==0 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ - && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; @@ -162077,7 +163132,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Expr *pColRef; Expr *pTerm; if( pItem->fg.isTabFunc==0 ) return; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; @@ -162761,7 +163816,7 @@ static int isDistinctRedundant( ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the @@ -162836,6 +163891,12 @@ static void translateColumnToCopy( VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", + iTabCur, iStart, iEnd); + } +#endif for(; iStartp1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ @@ -162957,6 +164018,40 @@ static int constraintCompatibleWithOuterJoin( return 1; } +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return true if column iCol of table pTab seem like it might be a +** good column to use as part of a query-time index. +** +** Current algorithm (subject to improvement!): +** +** 1. If iCol is already the left-most column of some other index, +** then return false. +** +** 2. If iCol is part of an existing index that has an aiRowLogEst of +** more than 20, then return false. +** +** 3. If no disqualifying conditions above are found, return true. +*/ +static SQLITE_NOINLINE int columnIsGoodIndexCandidate( + const Table *pTab, + int iCol +){ + const Index *pIdx; + for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + if( pIdx->aiColumn[j]==iCol ){ + if( j==0 ) return 0; + if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; + break; + } + } + } + return 1; +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + #ifndef SQLITE_OMIT_AUTOMATIC_INDEX @@ -162971,6 +164066,8 @@ static int termCanDriveIndex( const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; + int leftCol; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); @@ -162981,11 +164078,12 @@ static int termCanDriveIndex( } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - if( pTerm->u.x.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; + leftCol = pTerm->u.x.leftColumn; + if( leftCol<0 ) return 0; + aff = pSrc->pSTab->aCol[leftCol].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); - return 1; + return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); } #endif @@ -163093,7 +164191,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( nKeyCol = 0; pTabList = pWC->pWInfo->pTabList; pSrc = &pTabList->a[pLevel->iFrom]; - pTable = pSrc->pTab; + pTable = pSrc->pSTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; @@ -163235,12 +164333,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex( /* Fill the automatic index with content */ assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); if( pSrc->fg.viaCoroutine ){ - int regYield = pSrc->regReturn; + int regYield; + Subquery *pSubq; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + assert( pSubq!=0 ); + regYield = pSubq->regReturn; addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pSrc->pTab->zName)); + VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -163262,11 +164365,12 @@ static SQLITE_NOINLINE void constructAutomaticIndex( sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pSrc->fg.viaCoroutine ){ + assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, - pSrc->regResult, pLevel->iIdxCur); + pSrc->u4.pSubq->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); pSrc->fg.viaCoroutine = 0; }else{ @@ -163357,7 +164461,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( iSrc = pLevel->iFrom; pItem = &pTabList->a[iSrc]; assert( pItem!=0 ); - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); sz = sqlite3LogEstToInt(pTab->nRowLogEst); if( sz<10000 ){ @@ -163388,7 +164492,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jjpTable==pItem->pTab ); + assert( pIdx->pTable==pItem->pSTab ); sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); } sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); @@ -163426,6 +164530,20 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return term iTerm of the WhereClause passed as the first argument. Terms +** are numbered from 0 upwards, starting with the terms in pWC->a[], then +** those in pWC->pOuter->a[] (if any), and so on. +*/ +static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ + WhereClause *p; + for(p=pWC; p; p=p->pOuter){ + if( iTermnTerm ) return &p->a[iTerm]; + iTerm -= p->nTerm; + } + return 0; +} + /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure @@ -163452,9 +164570,10 @@ static sqlite3_index_info *allocateIndexInfo( const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; + WhereClause *p; assert( pSrc!=0 ); - pTab = pSrc->pTab; + pTab = pSrc->pSTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); @@ -163462,28 +164581,30 @@ static sqlite3_index_info *allocateIndexInfo( ** Mark each term with the TERM_OK flag. Set nTerm to the number of ** terms found. */ - for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - pTerm->wtFlags &= ~TERM_OK; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; + for(p=pWC, nTerm=0; p; p=p->pOuter){ + for(i=0, pTerm=p->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->prereqRight & mUnusable ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - assert( pTerm->u.x.leftColumn>=XN_ROWID ); - assert( pTerm->u.x.leftColumnnCol ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - continue; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + nTerm++; + pTerm->wtFlags |= TERM_OK; } - nTerm++; - pTerm->wtFlags |= TERM_OK; } /* If the ORDER BY clause contains only columns in the current @@ -163558,53 +164679,69 @@ static sqlite3_index_info *allocateIndexInfo( pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + if( HasRowid(pTab)==0 ){ + /* Ensure that all bits associated with PK columns are set. This is to + ** ensure they are available for cases like RIGHT joins or OR loops. */ + Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); + assert( pPk!=0 ); + for(i=0; inKeyCol; i++){ + int iCol = pPk->aiColumn[i]; + assert( iCol>=0 ); + if( iCol>=BMS-1 ) iCol = BMS-1; + pIdxInfo->colUsed |= MASKBIT(iCol); + } + } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; - for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - u16 op; - if( (pTerm->wtFlags & TERM_OK)==0 ) continue; - pIdxCons[j].iColumn = pTerm->u.x.leftColumn; - pIdxCons[j].iTermOffset = i; - op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ){ - if( (pTerm->wtFlags & TERM_SLICE)==0 ){ - pHidden->mIn |= SMASKBIT32(j); + for(p=pWC, i=j=0; p; p=p->pOuter){ + int nLast = i+p->nTerm;; + for(pTerm=p->a; iwtFlags & TERM_OK)==0 ) continue; + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; + pIdxCons[j].iTermOffset = i; + op = pTerm->eOperator & WO_ALL; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; } - op = WO_EQ; - } - if( op==WO_AUX ){ - pIdxCons[j].op = pTerm->eMatchOp; - }else if( op & (WO_ISNULL|WO_IS) ){ - if( op==WO_ISNULL ){ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } }else{ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; - } - }else{ - pIdxCons[j].op = (u8)op; - /* The direct assignment in the previous line is possible only because - ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The - ** following asserts verify this fact. */ - assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); - assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); - assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); - assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); - assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); - assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); - if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) - ){ - testcase( j!=i ); - if( j<16 ) mNoOmit |= (1 << j); - if( op==WO_LT ) pIdxCons[j].op = WO_LE; - if( op==WO_GT ) pIdxCons[j].op = WO_GE; + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } } + + j++; } - - j++; } assert( j==nTerm ); pIdxInfo->nConstraint = j; @@ -163624,6 +164761,17 @@ static sqlite3_index_info *allocateIndexInfo( return pIdxInfo; } +/* +** Free and zero the sqlite3_index_info.idxStr value if needed. +*/ +static void freeIdxStr(sqlite3_index_info *pIdxInfo){ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } +} + /* ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() ** and possibly modified by xBestIndex methods. @@ -163639,6 +164787,7 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ pHidden->aRhs[i] = 0; } + freeIdxStr(pIdxInfo); sqlite3DbFree(db, pIdxInfo); } @@ -163659,9 +164808,11 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ ** that this is required. */ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ - sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; + sqlite3_vtab *pVtab; + assert( IsVirtual(pTab) ); + pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; whereTraceIndexInfoInputs(p, pTab); pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); @@ -164432,7 +165583,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; + Table *pTab = pItem->pSTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); @@ -164604,7 +165755,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ ** and Y has additional constraints that might speed the search that X lacks ** but the cost of running X is not more than the cost of running Y. ** -** In other words, return true if the cost relationwship between X and Y +** In other words, return true if the cost relationship between X and Y ** is inverted and needs to be adjusted. ** ** Case 1: @@ -164990,7 +166141,7 @@ static void whereLoopOutputAdjust( Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); - if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; @@ -165287,7 +166438,7 @@ static int whereLoopAddBtreeIndex( || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull - || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) ){ pNew->wsFlags |= WHERE_ONEROW; }else{ @@ -165420,7 +166571,7 @@ static int whereLoopAddBtreeIndex( ** 2. Stepping forward in the index pNew->nOut times to find all ** additional matching entries. */ - assert( pSrc->pTab->szTabRow>0 ); + assert( pSrc->pSTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior ** pages are small. Thus szIdxRow gives a good estimate of seek cost. @@ -165428,7 +166579,7 @@ static int whereLoopAddBtreeIndex( ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; }else{ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; } rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); @@ -165893,9 +167044,9 @@ static int whereLoopAddBtree( pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; - pTab = pSrc->pTab; + pTab = pSrc->pSTab; pWC = pBuilder->pWC; - assert( !IsVirtual(pSrc->pTab) ); + assert( !IsVirtual(pSrc->pSTab) ); if( pSrc->fg.isIndexedBy ){ assert( pSrc->fg.isCte==0 ); @@ -165920,7 +167071,7 @@ static int whereLoopAddBtree( sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; - pFirst = pSrc->pTab->pIndex; + pFirst = pSrc->pSTab->pIndex; if( pSrc->fg.notIndexed==0 ){ /* The real indices of the table are only considered if the ** NOT INDEXED qualifier is omitted from the FROM clause */ @@ -166010,6 +167161,7 @@ static int whereLoopAddBtree( pNew->prereq = mPrereq; pNew->nOut = rSize; pNew->u.btree.pIndex = pProbe; + pNew->u.btree.pOrderBy = 0; b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ @@ -166039,6 +167191,10 @@ static int whereLoopAddBtree( #endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); + if( pSrc->fg.isSubquery ){ + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; + pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + } rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; @@ -166241,7 +167397,7 @@ static int whereLoopAddVirtualOne( ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ia[pIdxCons->iTermOffset]; + WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset); pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 @@ -166260,11 +167416,10 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ - rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); + rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); if( rc ){ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means @@ -166272,6 +167427,7 @@ static int whereLoopAddVirtualOne( ** Make no entries in the loop table. */ WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + freeIdxStr(pIdxInfo); return SQLITE_OK; } return rc; @@ -166289,18 +167445,17 @@ static int whereLoopAddVirtualOne( int j = pIdxCons->iTermOffset; if( iTerm>=nConstraint || j<0 - || j>=pWC->nTerm + || (pTerm = termFromWhereClause(pWC, j))==0 || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } testcase( iTerm==nConstraint-1 ); testcase( j==0 ); testcase( j==pWC->nTerm-1 ); - pTerm = &pWC->a[j]; pNew->prereq |= pTerm->prereqRight; assert( iTermnLSlot ); pNew->aLTerm[iTerm] = pTerm; @@ -166345,11 +167500,7 @@ static int whereLoopAddVirtualOne( ** the plan cannot be used. In these cases set variable *pbRetryLimit ** to true to tell the caller to retry with LIMIT and OFFSET ** disabled. */ - if( pIdxInfo->needToFreeIdxStr ){ - sqlite3_free(pIdxInfo->idxStr); - pIdxInfo->idxStr = 0; - pIdxInfo->needToFreeIdxStr = 0; - } + freeIdxStr(pIdxInfo); *pbRetryLimit = 1; return SQLITE_OK; } @@ -166361,8 +167512,8 @@ static int whereLoopAddVirtualOne( if( pNew->aLTerm[i]==0 ){ /* The non-zero argvIdx values must be contiguous. Raise an ** error if they are not */ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } } @@ -166373,6 +167524,7 @@ static int whereLoopAddVirtualOne( pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? pIdxInfo->nOrderBy : 0); + pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); @@ -166417,7 +167569,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int if( iCons>=0 && iConsnConstraint ){ CollSeq *pC = 0; int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; - Expr *pX = pHidden->pWC->a[iTerm].pExpr; + Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; if( pX->pLeft ){ pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } @@ -166463,7 +167615,9 @@ SQLITE_API int sqlite3_vtab_rhs_value( rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ - WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + WhereTerm *pTerm = termFromWhereClause( + pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset + ); rc = sqlite3ValueFromExpr( pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), SQLITE_AFF_BLOB, &pH->aRhs[iCons] @@ -166561,7 +167715,7 @@ static int whereLoopAddVirtual( pWC = pBuilder->pWC; pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; - assert( IsVirtual(pSrc->pTab) ); + assert( IsVirtual(pSrc->pSTab) ); p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; @@ -166575,7 +167729,7 @@ static int whereLoopAddVirtual( } /* First call xBestIndex() with all constraints usable. */ - WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); WHERETRACE(0x800, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry @@ -166619,9 +167773,8 @@ static int whereLoopAddVirtual( Bitmask mNext = ALLBITS; assert( mNext>0 ); for(i=0; ia[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq - ); + int iTerm = p->aConstraint[i].iTermOffset; + Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; if( mThis>mPrev && mThisneedToFreeIdxStr ) sqlite3_free(p->idxStr); freeIndexInfo(pParse->db, p); - WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -166731,7 +167883,7 @@ static int whereLoopAddOr( } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); }else #endif @@ -166845,7 +167997,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ @@ -166877,6 +168029,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ return rc; } +/* Implementation of the order-by-subquery optimization: +** +** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really +** a subquery or CTE that has an ORDER BY clause. See if any of the terms +** in the subquery ORDER BY clause will satisfy pOrderBy from the outer +** query. Mark off all satisfied terms (by setting bits in *pOBSat) and +** return TRUE if they do. If not, return false. +** +** Example: +** +** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); +** CREATE TABLE t2(x,y); +** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) +** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; +** +** The CTE named "t3" comes out in the natural order of "p", so the first +** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" +** and sorting only needs to occur on the second term "b". +** +** Limitations: +** +** (1) The optimization is not applied if the outer ORDER BY contains +** a COLLATE clause. The optimization might be applied if the +** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as +** long as the subquery ORDER BY does the same. But if the +** outer ORDER BY uses COLLATE, even a redundant COLLATE, the +** optimization is bypassed. +** +** (2) The subquery ORDER BY terms must exactly match subquery result +** columns, including any COLLATE annotations. This routine relies +** on iOrderByCol to do matching between order by terms and result +** columns, and iOrderByCol will not be set if the result column +** and ORDER BY collations differ. +** +** (3) The subquery and outer ORDER BY can be in opposite directions as +** long as the subquery is materialized. If the subquery is +** implemented as a co-routine, the sort orders must be in the same +** direction because there is no way to run a co-routine backwards. +*/ +static SQLITE_NOINLINE int wherePathMatchSubqueryOB( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereLoop *pLoop, /* The nested loop term that is a subquery */ + int iLoop, /* Which level of the nested loop. 0==outermost */ + int iCur, /* Cursor used by the this loop */ + ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ + Bitmask *pRevMask, /* When loops need to go in reverse order */ + Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ +){ + int iOB; /* Index into pOrderBy->a[] */ + int jSub; /* Index into pSubOB->a[] */ + u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ + u8 revIdx = 0; /* Sort direction for jSub */ + Expr *pOBExpr; /* Current term of outer ORDER BY */ + ExprList *pSubOB; /* Complete ORDER BY on the subquery */ + + pSubOB = pLoop->u.btree.pOrderBy; + assert( pSubOB!=0 ); + for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} + for(jSub=0; jSubnExpr && iOBnExpr; jSub++, iOB++){ + if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; + pOBExpr = pOrderBy->a[iOB].pExpr; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; + if( pOBExpr->iTable!=iCur ) break; + if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; + if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ + u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ + u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ + if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ + break; + } + revIdx = sfSub & KEYINFO_ORDER_DESC; + if( jSub>0 ){ + if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ + break; + } + }else{ + rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); + if( rev ){ + if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ + /* Cannot run a co-routine in reverse order */ + break; + } + *pRevMask |= MASKBIT(iLoop); + } + } + } + *pOBSat |= MASKBIT(iOB); + } + return jSub>0; +} + /* ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY @@ -167022,9 +168265,18 @@ static i8 wherePathSatisfiesOrderBy( if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( pLoop->wsFlags & WHERE_IPK ){ + if( pLoop->u.btree.pOrderBy + && OptimizationEnabled(db, SQLITE_OrderBySubq) + && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, + pOrderBy,pRevMask, &obSat) + ){ + nColumn = 0; + isOrderDistinct = 0; + }else{ + nColumn = 1; + } pIndex = 0; nKeyCol = 0; - nColumn = 1; }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ @@ -167034,7 +168286,7 @@ static i8 wherePathSatisfiesOrderBy( assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); /* All relevant terms of the index must also be non-NULL in order - ** for isOrderDistinct to be true. So the isOrderDistint value + ** for isOrderDistinct to be true. So the isOrderDistinct value ** computed here might be a false positive. Corrections will be ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) @@ -167119,7 +168371,7 @@ static i8 wherePathSatisfiesOrderBy( } /* Find the ORDER BY term that corresponds to the j-th column - ** of the index and mark that ORDER BY term off + ** of the index and mark that ORDER BY term having been satisfied. */ isMatch = 0; for(i=0; bOnce && inOutStarDelta and the cost adjustment +** for each WhereLoop is stored in its rStarDelta field. +*/ +static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){ + int nLoop = pWInfo->nLevel; /* Number of terms in the join */ + if( nRowEst==0 && nLoop>=5 ){ + /* Check to see if we are dealing with a star schema and if so, reduce + ** the cost of fact tables relative to dimension tables, as a heuristic + ** to help keep the fact tables in outer loops. + */ + int iLoop; /* Counter over join terms */ + Bitmask m; /* Bitmask for current loop */ + assert( pWInfo->nOutStarDelta==0 ); + for(iLoop=0, m=1; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){ + nDep++; + mSeen |= pWLoop->maskSelf; + } + } + if( nDep<=3 ) continue; + rDelta = 15*(nDep-3); +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + SrcItem *pItem = pWInfo->pTabList->a + iLoop; + sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n", + pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName, + nDep, rDelta); + } +#endif + if( pWInfo->nOutStarDelta==0 ){ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + pWLoop->rStarDelta = 0; + } + } + pWInfo->nOutStarDelta += rDelta; + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( pWLoop->maskSelf==m ){ + pWLoop->rRun -= rDelta; + pWLoop->nOut -= rDelta; + pWLoop->rStarDelta = rDelta; + } + } + } + } + return pWInfo->nOutStarDelta>0 ? 18 : 12; +} + /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop @@ -167361,13 +168690,25 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pParse = pWInfo->pParse; nLoop = pWInfo->nLevel; - /* TUNING: For simple queries, only the best path is tracked. - ** For 2-way joins, the 5 best paths are followed. - ** For joins of 3 or more tables, track the 10 best paths */ - mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); - assert( nLoop<=pWInfo->pTabList->nSrc ); WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", nRowEst, pParse->nQueryLoop)); + /* TUNING: mxChoice is the maximum number of possible paths to preserve + ** at each step. Based on the number of loops in the FROM clause: + ** + ** nLoop mxChoice + ** ----- -------- + ** 1 1 // the most common case + ** 2 5 + ** 3+ 12 or 18 // see computeMxChoice() + */ + if( nLoop<=1 ){ + mxChoice = 1; + }else if( nLoop==2 ){ + mxChoice = 5; + }else{ + mxChoice = computeMxChoice(pWInfo, nRowEst); + } + assert( nLoop<=pWInfo->pTabList->nSrc ); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -167450,7 +168791,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ - rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = pWLoop->rRun + pFrom->nRow; + if( pWLoop->rSetup ){ + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted); + } rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; @@ -167495,6 +168839,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range ** of legal values for isOrdered, -1..64. */ + testcase( nTo==0 ); for(jj=0, pTo=aTo; jjmaskLoop==maskNew && ((pTo->isOrdered^isOrdered)&0x80)==0 @@ -167611,16 +168956,28 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ #ifdef WHERETRACE_ENABLED /* >=2 */ if( sqlite3WhereTrace & 0x02 ){ + LogEst rMin, rFloor = 0; + int nDone = 0; sqlite3DebugPrintf("---- after round %d ----\n", iLoop); - for(ii=0, pTo=aTo; iirCost, pTo->nRow, - pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); - if( pTo->isOrdered>0 ){ - sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); - }else{ - sqlite3DebugPrintf("\n"); + while( nDonerCost>rFloor && pTo->rCostrCost; } + for(ii=0, pTo=aTo; iirCost==rMin ){ + sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + nDone++; + } + } + rFloor = rMin; } } #endif @@ -167715,7 +169072,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } } - pWInfo->nRowOut = pFrom->nRow; + pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta; /* Free temporary memory and return success */ sqlite3StackFreeNN(pParse->db, pSpace); @@ -167826,7 +169183,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; - pTab = pItem->pTab; + pTab = pItem->pSTab; if( IsVirtual(pTab) ) return 0; if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ testcase( pItem->fg.isIndexedBy ); @@ -168016,6 +169373,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; + Bitmask m1; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; @@ -168042,7 +169400,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } } if( pTerm drop loop %c not used\n", pLoop->cId)); + WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId)); + m1 = MASKBIT(i)-1; + testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); + pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ @@ -168089,7 +169450,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; - Table *pTab = pItem->pTab; + Table *pTab = pItem->pSTab; if( (pTab->tabFlags & TF_HasStat1)==0 ) break; pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 @@ -168109,61 +169470,10 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } nSearch += pLoop->nOut; + if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta; } } -/* -** Expression Node callback for sqlite3ExprCanReturnSubtype(). -** -** Only a function call is able to return a subtype. So if the node -** is not a function call, return WRC_Prune immediately. -** -** A function call is able to return a subtype if it has the -** SQLITE_RESULT_SUBTYPE property. -** -** Assume that every function is able to pass-through a subtype from -** one of its argument (using sqlite3_result_value()). Most functions -** are not this way, but we don't have a mechanism to distinguish those -** that are from those that are not, so assume they all work this way. -** That means that if one of its arguments is another function and that -** other function is able to return a subtype, then this function is -** able to return a subtype. -*/ -static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ - int n; - FuncDef *pDef; - sqlite3 *db; - if( pExpr->op!=TK_FUNCTION ){ - return WRC_Prune; - } - assert( ExprUseXList(pExpr) ); - db = pWalker->pParse->db; - n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; - pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ - pWalker->eCode = 1; - return WRC_Prune; - } - return WRC_Continue; -} - -/* -** Return TRUE if expression pExpr is able to return a subtype. -** -** A TRUE return does not guarantee that a subtype will be returned. -** It only indicates that a subtype return is possible. False positives -** are acceptable as they only disable an optimization. False negatives, -** on the other hand, can lead to incorrect answers. -*/ -static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ - Walker w; - memset(&w, 0, sizeof(w)); - w.pParse = pParse; - w.xExprCallback = exprNodeCanReturnSubtype; - sqlite3WalkExpr(&w, pExpr); - return w.eCode; -} - /* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor @@ -168197,12 +169507,6 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( continue; } if( sqlite3ExprIsConstant(0,pExpr) ) continue; - if( pExpr->op==TK_FUNCTION && sqlite3ExprCanReturnSubtype(pParse,pExpr) ){ - /* Functions that might set a subtype should not be replaced by the - ** value taken from an expression index since the index omits the - ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ - continue; - } p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; p->pIENext = pParse->pIdxEpr; @@ -168245,8 +169549,8 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ SrcItem *pItem = &pWInfo->pTabList->a[ii]; if( !pItem->fg.isCte || pItem->u2.pCteUse->eM10d!=M10d_Yes - || NEVER(pItem->pSelect==0) - || pItem->pSelect->pOrderBy==0 + || NEVER(pItem->fg.isSubquery==0) + || pItem->u4.pSubq->pSelect->pOrderBy==0 ){ pWInfo->revMask |= MASKBIT(ii); } @@ -168625,7 +169929,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); - wherePathSolver(pWInfo, pWInfo->nRowOut+1); + wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } @@ -168736,15 +170040,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; - assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); + assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); if( bOnerow || ( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) - && !IsVirtual(pTabList->a[0].pTab) + && !IsVirtual(pTabList->a[0].pSTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ bFordelete = OPFLAG_FORDELETE; } @@ -168762,7 +170066,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; - pTab = pTabItem->pTab; + pTab = pTabItem->pSTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ @@ -168833,7 +170137,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( iIndexCur = pLevel->iTabCur; op = 0; }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ - Index *pJ = pTabItem->pTab->pIndex; + Index *pJ = pTabItem->pSTab->pIndex; iIndexCur = iAuxArg; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); while( ALWAYS(pJ) && pJ!=pIx ){ @@ -168900,7 +170204,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); - assert( pTab==pTabItem->pTab ); + assert( pTab==pTabItem->pSTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); @@ -168939,13 +170243,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( wsFlags = pLevel->pWLoop->wsFlags; pSrc = &pTabList->a[pLevel->iFrom]; if( pSrc->fg.isMaterialized ){ - if( pSrc->fg.isCorrelated ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); + Subquery *pSubq; + int iOnce = 0; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + if( pSrc->fg.isCorrelated==0 ){ + iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); }else{ - int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); - sqlite3VdbeJumpHere(v, iOnce); + iOnce = 0; } + sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); + VdbeComment((v, "materialize %!S", pSrc)); + if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); } assert( pTabList == pWInfo->pTabList ); if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ @@ -169158,9 +170467,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pLevel->iTabCur==pSrc->iCursor ); if( pSrc->fg.viaCoroutine ){ int m, n; - n = pSrc->regResult; - assert( pSrc->pTab!=0 ); - m = pSrc->pTab->nCol; + assert( pSrc->fg.isSubquery ); + n = pSrc->u4.pSubq->regResult; + assert( pSrc->pSTab!=0 ); + m = pSrc->pSTab->nCol; sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); @@ -169184,7 +170494,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, - pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); + pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); } assert( pWInfo->nLevel<=pTabList->nSrc ); @@ -169193,7 +170503,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeOp *pOp, *pLastOp; Index *pIdx = 0; SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; @@ -169212,9 +170522,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ if( pTabItem->fg.viaCoroutine ){ testcase( pParse->db->mallocFailed ); - assert( pTabItem->regResult>=0 ); + assert( pTabItem->fg.isSubquery ); + assert( pTabItem->u4.pSubq->regResult>=0 ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, - pTabItem->regResult, 0); + pTabItem->u4.pSubq->regResult, 0); continue; } @@ -170256,7 +171567,7 @@ static ExprList *exprListAppendList( int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); - if( sqlite3ExprIsInteger(pSub, &iDummy) ){ + if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; @@ -170424,9 +171735,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ - if( p->pSrc ){ + if( p->pSrc==0 ){ + sqlite3SelectDelete(db, pSub); + }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ Table *pTab2; - p->pSrc->a[0].pSelect = pSub; p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; @@ -170440,7 +171752,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ }else{ memcpy(pTab, pTab2, sizeof(Table)); pTab->tabFlags |= TF_Ephemeral; - p->pSrc->a[0].pTab = pTab; + p->pSrc->a[0].pSTab = pTab; pTab = pTab2; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3WindowExtraAggFuncDepth; @@ -170448,8 +171760,6 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } - }else{ - sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; @@ -170736,10 +172046,15 @@ SQLITE_PRIVATE int sqlite3WindowCompare( ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ - int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; - Window *pMWin = pSelect->pWin; Window *pWin; - Vdbe *v = sqlite3GetVdbe(pParse); + int nEphExpr; + Window *pMWin; + Vdbe *v; + + assert( pSelect->pSrc->a[0].fg.isSubquery ); + nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; + pMWin = pSelect->pWin; + v = sqlite3GetVdbe(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); @@ -172136,7 +173451,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ - int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ + int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ int iInput; /* To iterate through sub cols */ int addrNe; /* Address of OP_Ne */ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ @@ -172733,132 +174048,132 @@ static void updateDeleteLimitError( #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 @@ -172939,7 +174254,7 @@ static void updateDeleteLimitError( #define YYCODETYPE unsigned short int #define YYNOCODE 322 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 101 +#define YYWILDCARD 102 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; @@ -173076,446 +174391,452 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2142) +#define YY_ACTTAB_COUNT (2207) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 576, 128, 125, 232, 1622, 549, 576, 1290, 1281, 576, - /* 10 */ 328, 576, 1300, 212, 576, 128, 125, 232, 578, 412, - /* 20 */ 578, 391, 1542, 51, 51, 523, 405, 1293, 529, 51, - /* 30 */ 51, 983, 51, 51, 81, 81, 1107, 61, 61, 984, - /* 40 */ 1107, 1292, 380, 135, 136, 90, 1228, 1228, 1063, 1066, - /* 50 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 1577, 412, - /* 60 */ 287, 287, 7, 287, 287, 422, 1050, 1050, 1064, 1067, - /* 70 */ 289, 556, 492, 573, 524, 561, 573, 497, 561, 482, - /* 80 */ 530, 262, 229, 135, 136, 90, 1228, 1228, 1063, 1066, - /* 90 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 128, 125, - /* 100 */ 232, 1506, 132, 132, 132, 132, 131, 131, 130, 130, - /* 110 */ 130, 129, 126, 450, 1204, 1255, 1, 1, 582, 2, - /* 120 */ 1259, 1571, 420, 1582, 379, 320, 1174, 153, 1174, 1584, - /* 130 */ 412, 378, 1582, 543, 1341, 330, 111, 570, 570, 570, - /* 140 */ 293, 1054, 132, 132, 132, 132, 131, 131, 130, 130, - /* 150 */ 130, 129, 126, 450, 135, 136, 90, 1228, 1228, 1063, - /* 160 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 287, - /* 170 */ 287, 1204, 1205, 1204, 255, 287, 287, 510, 507, 506, - /* 180 */ 137, 455, 573, 212, 561, 447, 446, 505, 573, 1616, - /* 190 */ 561, 134, 134, 134, 134, 127, 400, 243, 132, 132, - /* 200 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, - /* 210 */ 282, 471, 345, 132, 132, 132, 132, 131, 131, 130, - /* 220 */ 130, 130, 129, 126, 450, 574, 155, 936, 936, 454, - /* 230 */ 227, 521, 1236, 412, 1236, 134, 134, 134, 134, 132, - /* 240 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, - /* 250 */ 450, 130, 130, 130, 129, 126, 450, 135, 136, 90, - /* 260 */ 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, - /* 270 */ 134, 134, 128, 125, 232, 450, 576, 412, 397, 1249, - /* 280 */ 180, 92, 93, 132, 132, 132, 132, 131, 131, 130, - /* 290 */ 130, 130, 129, 126, 450, 381, 387, 1204, 383, 81, - /* 300 */ 81, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, - /* 310 */ 133, 133, 134, 134, 134, 134, 132, 132, 132, 132, - /* 320 */ 131, 131, 130, 130, 130, 129, 126, 450, 131, 131, - /* 330 */ 130, 130, 130, 129, 126, 450, 556, 1204, 302, 319, - /* 340 */ 567, 121, 568, 480, 4, 555, 1149, 1657, 1628, 1657, - /* 350 */ 45, 128, 125, 232, 1204, 1205, 1204, 1250, 571, 1169, - /* 360 */ 132, 132, 132, 132, 131, 131, 130, 130, 130, 129, - /* 370 */ 126, 450, 1169, 287, 287, 1169, 1019, 576, 422, 1019, - /* 380 */ 412, 451, 1602, 582, 2, 1259, 573, 44, 561, 95, - /* 390 */ 320, 110, 153, 565, 1204, 1205, 1204, 522, 522, 1341, - /* 400 */ 81, 81, 7, 44, 135, 136, 90, 1228, 1228, 1063, - /* 410 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 295, - /* 420 */ 1149, 1658, 1040, 1658, 1204, 1147, 319, 567, 119, 119, - /* 430 */ 343, 466, 331, 343, 287, 287, 120, 556, 451, 577, - /* 440 */ 451, 1169, 1169, 1028, 319, 567, 438, 573, 210, 561, - /* 450 */ 1339, 1451, 546, 531, 1169, 1169, 1598, 1169, 1169, 416, - /* 460 */ 319, 567, 243, 132, 132, 132, 132, 131, 131, 130, - /* 470 */ 130, 130, 129, 126, 450, 1028, 1028, 1030, 1031, 35, - /* 480 */ 44, 1204, 1205, 1204, 472, 287, 287, 1328, 412, 1307, - /* 490 */ 372, 1595, 359, 225, 454, 1204, 195, 1328, 573, 1147, - /* 500 */ 561, 1333, 1333, 274, 576, 1188, 576, 340, 46, 196, - /* 510 */ 537, 217, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, - /* 520 */ 1053, 133, 133, 134, 134, 134, 134, 19, 19, 19, - /* 530 */ 19, 412, 581, 1204, 1259, 511, 1204, 319, 567, 320, - /* 540 */ 944, 153, 425, 491, 430, 943, 1204, 488, 1341, 1450, - /* 550 */ 532, 1277, 1204, 1205, 1204, 135, 136, 90, 1228, 1228, - /* 560 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 570 */ 575, 132, 132, 132, 132, 131, 131, 130, 130, 130, - /* 580 */ 129, 126, 450, 287, 287, 528, 287, 287, 372, 1595, - /* 590 */ 1204, 1205, 1204, 1204, 1205, 1204, 573, 486, 561, 573, - /* 600 */ 889, 561, 412, 1204, 1205, 1204, 886, 40, 22, 22, - /* 610 */ 220, 243, 525, 1449, 132, 132, 132, 132, 131, 131, - /* 620 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 630 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 640 */ 134, 412, 180, 454, 1204, 879, 255, 287, 287, 510, - /* 650 */ 507, 506, 372, 1595, 1568, 1331, 1331, 576, 889, 505, - /* 660 */ 573, 44, 561, 559, 1207, 135, 136, 90, 1228, 1228, - /* 670 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 680 */ 81, 81, 422, 576, 377, 132, 132, 132, 132, 131, - /* 690 */ 131, 130, 130, 130, 129, 126, 450, 297, 287, 287, - /* 700 */ 460, 1204, 1205, 1204, 1204, 534, 19, 19, 448, 448, - /* 710 */ 448, 573, 412, 561, 230, 436, 1187, 535, 319, 567, - /* 720 */ 363, 432, 1207, 1435, 132, 132, 132, 132, 131, 131, - /* 730 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 740 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 750 */ 134, 412, 211, 949, 1169, 1041, 1110, 1110, 494, 547, - /* 760 */ 547, 1204, 1205, 1204, 7, 539, 1570, 1169, 376, 576, - /* 770 */ 1169, 5, 1204, 486, 3, 135, 136, 90, 1228, 1228, - /* 780 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 790 */ 576, 513, 19, 19, 427, 132, 132, 132, 132, 131, - /* 800 */ 131, 130, 130, 130, 129, 126, 450, 305, 1204, 433, - /* 810 */ 225, 1204, 385, 19, 19, 273, 290, 371, 516, 366, - /* 820 */ 515, 260, 412, 538, 1568, 549, 1024, 362, 437, 1204, - /* 830 */ 1205, 1204, 902, 1552, 132, 132, 132, 132, 131, 131, - /* 840 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 850 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 860 */ 134, 412, 1435, 514, 1281, 1204, 1205, 1204, 1204, 1205, - /* 870 */ 1204, 903, 48, 342, 1568, 1568, 1279, 1627, 1568, 911, - /* 880 */ 576, 129, 126, 450, 110, 135, 136, 90, 1228, 1228, - /* 890 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 900 */ 265, 576, 459, 19, 19, 132, 132, 132, 132, 131, - /* 910 */ 131, 130, 130, 130, 129, 126, 450, 1345, 204, 576, - /* 920 */ 459, 458, 50, 47, 19, 19, 49, 434, 1105, 573, - /* 930 */ 497, 561, 412, 428, 108, 1224, 1569, 1554, 376, 205, - /* 940 */ 550, 550, 81, 81, 132, 132, 132, 132, 131, 131, - /* 950 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 960 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 970 */ 134, 480, 576, 1204, 576, 1541, 412, 1435, 969, 315, - /* 980 */ 1659, 398, 284, 497, 969, 893, 1569, 1569, 376, 376, - /* 990 */ 1569, 461, 376, 1224, 459, 80, 80, 81, 81, 497, - /* 1000 */ 374, 114, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, - /* 1010 */ 133, 134, 134, 134, 134, 132, 132, 132, 132, 131, - /* 1020 */ 131, 130, 130, 130, 129, 126, 450, 1204, 1505, 576, - /* 1030 */ 1204, 1205, 1204, 1366, 316, 486, 281, 281, 497, 431, - /* 1040 */ 557, 288, 288, 402, 1340, 471, 345, 298, 429, 573, - /* 1050 */ 576, 561, 81, 81, 573, 374, 561, 971, 386, 132, - /* 1060 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, - /* 1070 */ 450, 231, 117, 81, 81, 287, 287, 231, 287, 287, - /* 1080 */ 576, 1511, 576, 1336, 1204, 1205, 1204, 139, 573, 556, - /* 1090 */ 561, 573, 412, 561, 441, 456, 969, 213, 558, 1511, - /* 1100 */ 1513, 1550, 969, 143, 143, 145, 145, 1368, 314, 478, - /* 1110 */ 444, 970, 412, 850, 851, 852, 135, 136, 90, 1228, - /* 1120 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1130 */ 134, 357, 412, 397, 1148, 304, 135, 136, 90, 1228, - /* 1140 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1150 */ 134, 1575, 323, 6, 862, 7, 135, 124, 90, 1228, - /* 1160 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1170 */ 134, 409, 408, 1511, 212, 132, 132, 132, 132, 131, - /* 1180 */ 131, 130, 130, 130, 129, 126, 450, 411, 118, 1204, - /* 1190 */ 116, 10, 352, 265, 355, 132, 132, 132, 132, 131, - /* 1200 */ 131, 130, 130, 130, 129, 126, 450, 576, 324, 306, - /* 1210 */ 576, 306, 1250, 469, 158, 132, 132, 132, 132, 131, - /* 1220 */ 131, 130, 130, 130, 129, 126, 450, 207, 1224, 1126, - /* 1230 */ 65, 65, 470, 66, 66, 412, 447, 446, 882, 531, - /* 1240 */ 335, 258, 257, 256, 1127, 1233, 1204, 1205, 1204, 327, - /* 1250 */ 1235, 874, 159, 576, 16, 480, 1085, 1040, 1234, 1128, - /* 1260 */ 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, - /* 1270 */ 134, 134, 134, 134, 1029, 576, 81, 81, 1028, 1040, - /* 1280 */ 922, 576, 463, 1236, 576, 1236, 1224, 502, 107, 1435, - /* 1290 */ 923, 6, 576, 410, 1498, 882, 1029, 480, 21, 21, - /* 1300 */ 1028, 332, 1380, 334, 53, 53, 497, 81, 81, 874, - /* 1310 */ 1028, 1028, 1030, 445, 259, 19, 19, 533, 132, 132, - /* 1320 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, - /* 1330 */ 551, 301, 1028, 1028, 1030, 107, 532, 545, 121, 568, - /* 1340 */ 1188, 4, 1126, 1576, 449, 576, 462, 7, 1282, 418, - /* 1350 */ 462, 350, 1435, 576, 518, 571, 544, 1127, 121, 568, - /* 1360 */ 442, 4, 1188, 464, 533, 1180, 1223, 9, 67, 67, - /* 1370 */ 487, 576, 1128, 303, 410, 571, 54, 54, 451, 576, - /* 1380 */ 123, 944, 576, 417, 576, 333, 943, 1379, 576, 236, - /* 1390 */ 565, 576, 1574, 564, 68, 68, 7, 576, 451, 362, - /* 1400 */ 419, 182, 69, 69, 541, 70, 70, 71, 71, 540, - /* 1410 */ 565, 72, 72, 484, 55, 55, 473, 1180, 296, 1040, - /* 1420 */ 56, 56, 296, 493, 541, 119, 119, 410, 1573, 542, - /* 1430 */ 569, 418, 7, 120, 1244, 451, 577, 451, 465, 1040, - /* 1440 */ 1028, 576, 1557, 552, 476, 119, 119, 527, 259, 121, - /* 1450 */ 568, 240, 4, 120, 576, 451, 577, 451, 576, 477, - /* 1460 */ 1028, 576, 156, 576, 57, 57, 571, 576, 286, 229, - /* 1470 */ 410, 336, 1028, 1028, 1030, 1031, 35, 59, 59, 219, - /* 1480 */ 983, 60, 60, 220, 73, 73, 74, 74, 984, 451, - /* 1490 */ 75, 75, 1028, 1028, 1030, 1031, 35, 96, 216, 291, - /* 1500 */ 552, 565, 1188, 318, 395, 395, 394, 276, 392, 576, - /* 1510 */ 485, 859, 474, 1311, 410, 541, 576, 417, 1530, 1144, - /* 1520 */ 540, 399, 1188, 292, 237, 1153, 326, 38, 23, 576, - /* 1530 */ 1040, 576, 20, 20, 325, 299, 119, 119, 164, 76, - /* 1540 */ 76, 1529, 121, 568, 120, 4, 451, 577, 451, 203, - /* 1550 */ 576, 1028, 141, 141, 142, 142, 576, 322, 39, 571, - /* 1560 */ 341, 1021, 110, 264, 239, 901, 900, 423, 242, 908, - /* 1570 */ 909, 370, 173, 77, 77, 43, 479, 1310, 264, 62, - /* 1580 */ 62, 369, 451, 1028, 1028, 1030, 1031, 35, 1601, 1192, - /* 1590 */ 453, 1092, 238, 291, 565, 163, 1309, 110, 395, 395, - /* 1600 */ 394, 276, 392, 986, 987, 859, 481, 346, 264, 110, - /* 1610 */ 1032, 489, 576, 1188, 503, 1088, 261, 261, 237, 576, - /* 1620 */ 326, 121, 568, 1040, 4, 347, 1376, 413, 325, 119, - /* 1630 */ 119, 948, 319, 567, 351, 78, 78, 120, 571, 451, - /* 1640 */ 577, 451, 79, 79, 1028, 354, 356, 576, 360, 1092, - /* 1650 */ 110, 576, 974, 942, 264, 123, 457, 358, 239, 576, - /* 1660 */ 519, 451, 939, 1104, 123, 1104, 173, 576, 1032, 43, - /* 1670 */ 63, 63, 1324, 565, 168, 168, 1028, 1028, 1030, 1031, - /* 1680 */ 35, 576, 169, 169, 1308, 872, 238, 157, 1589, 576, - /* 1690 */ 86, 86, 365, 89, 568, 375, 4, 1103, 941, 1103, - /* 1700 */ 123, 576, 1040, 1389, 64, 64, 1188, 1434, 119, 119, - /* 1710 */ 571, 576, 82, 82, 563, 576, 120, 165, 451, 577, - /* 1720 */ 451, 413, 1362, 1028, 144, 144, 319, 567, 576, 1374, - /* 1730 */ 562, 498, 279, 451, 83, 83, 1439, 576, 166, 166, - /* 1740 */ 576, 1289, 554, 576, 1280, 565, 576, 12, 576, 1268, - /* 1750 */ 457, 146, 146, 1267, 576, 1028, 1028, 1030, 1031, 35, - /* 1760 */ 140, 140, 1269, 167, 167, 1609, 160, 160, 1359, 150, - /* 1770 */ 150, 149, 149, 311, 1040, 576, 312, 147, 147, 313, - /* 1780 */ 119, 119, 222, 235, 576, 1188, 396, 576, 120, 576, - /* 1790 */ 451, 577, 451, 1192, 453, 1028, 508, 291, 148, 148, - /* 1800 */ 1421, 1612, 395, 395, 394, 276, 392, 85, 85, 859, - /* 1810 */ 87, 87, 84, 84, 553, 576, 294, 576, 1426, 338, - /* 1820 */ 339, 1425, 237, 300, 326, 1416, 1409, 1028, 1028, 1030, - /* 1830 */ 1031, 35, 325, 344, 403, 483, 226, 1307, 52, 52, - /* 1840 */ 58, 58, 368, 1371, 1502, 566, 1501, 121, 568, 221, - /* 1850 */ 4, 208, 268, 209, 390, 1244, 1549, 1188, 1372, 1370, - /* 1860 */ 1369, 1547, 239, 184, 571, 233, 421, 1241, 95, 218, - /* 1870 */ 173, 1507, 193, 43, 91, 94, 178, 186, 467, 188, - /* 1880 */ 468, 1422, 13, 189, 190, 191, 501, 451, 245, 108, - /* 1890 */ 238, 401, 1428, 1427, 1430, 475, 404, 1496, 197, 565, - /* 1900 */ 14, 490, 249, 101, 1518, 496, 349, 280, 251, 201, - /* 1910 */ 353, 499, 252, 406, 1270, 253, 517, 1327, 1326, 435, - /* 1920 */ 1325, 1318, 103, 893, 1296, 413, 227, 407, 1040, 1626, - /* 1930 */ 319, 567, 1625, 1297, 119, 119, 439, 367, 1317, 1295, - /* 1940 */ 1624, 526, 120, 440, 451, 577, 451, 1594, 309, 1028, - /* 1950 */ 310, 373, 266, 267, 457, 1580, 1579, 443, 138, 1394, - /* 1960 */ 552, 1393, 11, 1483, 384, 115, 317, 1350, 109, 536, - /* 1970 */ 42, 579, 382, 214, 1349, 388, 1198, 389, 275, 277, - /* 1980 */ 278, 1028, 1028, 1030, 1031, 35, 580, 1265, 414, 1260, - /* 1990 */ 170, 415, 183, 1534, 1535, 1533, 171, 154, 307, 1532, - /* 2000 */ 846, 223, 224, 88, 452, 215, 172, 321, 234, 1102, - /* 2010 */ 152, 1188, 1100, 329, 185, 174, 1223, 925, 187, 241, - /* 2020 */ 337, 244, 1116, 192, 175, 176, 424, 426, 97, 194, - /* 2030 */ 98, 99, 100, 177, 1119, 1115, 246, 247, 161, 24, - /* 2040 */ 248, 348, 1238, 264, 1108, 250, 495, 199, 198, 15, - /* 2050 */ 861, 500, 369, 254, 504, 509, 512, 200, 102, 25, - /* 2060 */ 179, 361, 26, 364, 104, 891, 308, 162, 105, 904, - /* 2070 */ 520, 106, 1185, 1069, 1155, 17, 228, 27, 1154, 283, - /* 2080 */ 285, 263, 978, 202, 972, 123, 28, 1175, 29, 30, - /* 2090 */ 1179, 1171, 31, 1173, 1160, 41, 32, 206, 548, 33, - /* 2100 */ 110, 1178, 1083, 8, 112, 1070, 113, 1068, 1072, 34, - /* 2110 */ 1073, 560, 1125, 269, 1124, 270, 36, 18, 1194, 1033, - /* 2120 */ 873, 151, 122, 37, 393, 271, 272, 572, 181, 1193, - /* 2130 */ 1256, 1256, 1256, 935, 1256, 1256, 1256, 1256, 1256, 1256, - /* 2140 */ 1256, 1617, + /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, + /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, + /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, + /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, + /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, + /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, + /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, + /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, + /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, + /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, + /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, + /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067, + /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, + /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341, + /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228, + /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, + /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523, + /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562, + /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547, + /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132, + /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133, + /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205, + /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127, + /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137, + /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135, + /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472, + /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134, + /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363, + /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134, + /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, + /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413, + /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128, + /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413, + /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063, + /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51, + /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063, + /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320, + /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204, + /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264, + /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333, + /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132, + /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511, + /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506, + /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582, + /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138, + /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553, + /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344, + /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882, + /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066, + /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, + /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403, + /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205, + /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331, + /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132, + /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423, + /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562, + /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234, + /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462, + /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50, + /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122, + /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212, + /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053, + /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, + /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, + /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339, + /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353, + /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028, + /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971, + /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562, + /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411, + /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228, + /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121, + /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452, + /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138, + /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, + /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, + /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205, + /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573, + /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134, + /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392, + /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205, + /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658, + /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066, + /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311, + /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066, + /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131, + /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516, + /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435, + /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205, + /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19, + /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936, + /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19, + /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315, + /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115, + /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529, + /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169, + /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576, + /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134, + /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, + /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134, + /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336, + /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19, + /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207, + /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411, + /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334, + /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969, + /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267, + /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409, + /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554, + /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111, + /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7, + /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569, + /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984, + /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228, + /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228, + /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108, + /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123, + /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133, + /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576, + /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133, + /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223, + /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576, + /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70, + /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576, + /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56, + /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59, + /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452, + /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20, + /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320, + /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576, + /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293, + /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111, + /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889, + /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62, + /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908, + /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568, + /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64, + /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170, + /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576, + /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452, + /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84, + /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111, + /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576, + /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111, + /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188, + /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162, + /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348, + /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149, + /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872, + /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941, + /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359, + /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121, + /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452, + /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269, + /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416, + /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228, + /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031, + /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501, + /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612, + /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547, + /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235, + /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193, + /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402, + /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102, + /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254, + /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326, + /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441, + /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121, + /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452, + /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90, + /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216, + /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389, + /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031, + /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172, + /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217, + /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154, + /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116, + /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100, + /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24, + /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452, + /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396, + /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, + /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, + /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, + /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, + /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, + /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171, + /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173, + /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33, + /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114, + /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194, + /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572, + /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, + /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, + /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 194, 276, 277, 278, 216, 194, 194, 217, 194, 194, - /* 10 */ 194, 194, 224, 194, 194, 276, 277, 278, 204, 19, - /* 20 */ 206, 202, 297, 217, 218, 205, 207, 217, 205, 217, - /* 30 */ 218, 31, 217, 218, 217, 218, 29, 217, 218, 39, - /* 40 */ 33, 217, 220, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 312, 19, - /* 60 */ 240, 241, 316, 240, 241, 194, 46, 47, 48, 49, - /* 70 */ 22, 254, 65, 253, 254, 255, 253, 194, 255, 194, - /* 80 */ 263, 258, 259, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 276, 277, - /* 100 */ 278, 285, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 113, 59, 186, 187, 188, 189, 190, - /* 120 */ 191, 310, 239, 317, 318, 196, 86, 198, 88, 317, - /* 130 */ 19, 319, 317, 318, 205, 264, 25, 211, 212, 213, - /* 140 */ 205, 121, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, - /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 240, - /* 170 */ 241, 116, 117, 118, 119, 240, 241, 122, 123, 124, - /* 180 */ 69, 298, 253, 194, 255, 106, 107, 132, 253, 141, - /* 190 */ 255, 54, 55, 56, 57, 58, 207, 268, 102, 103, - /* 200 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 210 */ 214, 128, 129, 102, 103, 104, 105, 106, 107, 108, - /* 220 */ 109, 110, 111, 112, 113, 134, 25, 136, 137, 300, - /* 230 */ 165, 166, 153, 19, 155, 54, 55, 56, 57, 102, - /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 250 */ 113, 108, 109, 110, 111, 112, 113, 43, 44, 45, - /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 270 */ 56, 57, 276, 277, 278, 113, 194, 19, 22, 23, - /* 280 */ 194, 67, 24, 102, 103, 104, 105, 106, 107, 108, - /* 290 */ 109, 110, 111, 112, 113, 220, 250, 59, 252, 217, - /* 300 */ 218, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, - /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 106, 107, - /* 330 */ 108, 109, 110, 111, 112, 113, 254, 59, 205, 138, - /* 340 */ 139, 19, 20, 194, 22, 263, 22, 23, 231, 25, - /* 350 */ 72, 276, 277, 278, 116, 117, 118, 101, 36, 76, - /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 112, 113, 89, 240, 241, 92, 73, 194, 194, 73, - /* 380 */ 19, 59, 188, 189, 190, 191, 253, 81, 255, 151, - /* 390 */ 196, 25, 198, 71, 116, 117, 118, 311, 312, 205, - /* 400 */ 217, 218, 316, 81, 43, 44, 45, 46, 47, 48, - /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 270, - /* 420 */ 22, 23, 100, 25, 59, 101, 138, 139, 106, 107, - /* 430 */ 127, 128, 129, 127, 240, 241, 114, 254, 116, 117, - /* 440 */ 118, 76, 76, 121, 138, 139, 263, 253, 264, 255, - /* 450 */ 205, 275, 87, 19, 89, 89, 194, 92, 92, 199, - /* 460 */ 138, 139, 268, 102, 103, 104, 105, 106, 107, 108, - /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, - /* 480 */ 81, 116, 117, 118, 129, 240, 241, 224, 19, 226, - /* 490 */ 314, 315, 23, 25, 300, 59, 22, 234, 253, 101, - /* 500 */ 255, 236, 237, 26, 194, 183, 194, 152, 72, 22, - /* 510 */ 145, 150, 43, 44, 45, 46, 47, 48, 49, 50, - /* 520 */ 51, 52, 53, 54, 55, 56, 57, 217, 218, 217, - /* 530 */ 218, 19, 189, 59, 191, 23, 59, 138, 139, 196, - /* 540 */ 135, 198, 232, 283, 232, 140, 59, 287, 205, 275, - /* 550 */ 116, 205, 116, 117, 118, 43, 44, 45, 46, 47, - /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 570 */ 194, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 580 */ 111, 112, 113, 240, 241, 194, 240, 241, 314, 315, - /* 590 */ 116, 117, 118, 116, 117, 118, 253, 194, 255, 253, - /* 600 */ 59, 255, 19, 116, 117, 118, 23, 22, 217, 218, - /* 610 */ 142, 268, 205, 275, 102, 103, 104, 105, 106, 107, - /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 640 */ 57, 19, 194, 300, 59, 23, 119, 240, 241, 122, - /* 650 */ 123, 124, 314, 315, 194, 236, 237, 194, 117, 132, - /* 660 */ 253, 81, 255, 205, 59, 43, 44, 45, 46, 47, - /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 680 */ 217, 218, 194, 194, 194, 102, 103, 104, 105, 106, - /* 690 */ 107, 108, 109, 110, 111, 112, 113, 294, 240, 241, - /* 700 */ 120, 116, 117, 118, 59, 194, 217, 218, 211, 212, - /* 710 */ 213, 253, 19, 255, 194, 19, 23, 254, 138, 139, - /* 720 */ 24, 232, 117, 194, 102, 103, 104, 105, 106, 107, - /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 750 */ 57, 19, 264, 108, 76, 23, 127, 128, 129, 311, - /* 760 */ 312, 116, 117, 118, 316, 87, 306, 89, 308, 194, - /* 770 */ 92, 22, 59, 194, 22, 43, 44, 45, 46, 47, - /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 790 */ 194, 95, 217, 218, 265, 102, 103, 104, 105, 106, - /* 800 */ 107, 108, 109, 110, 111, 112, 113, 232, 59, 113, - /* 810 */ 25, 59, 194, 217, 218, 119, 120, 121, 122, 123, - /* 820 */ 124, 125, 19, 145, 194, 194, 23, 131, 232, 116, - /* 830 */ 117, 118, 35, 194, 102, 103, 104, 105, 106, 107, - /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 860 */ 57, 19, 194, 66, 194, 116, 117, 118, 116, 117, - /* 870 */ 118, 74, 242, 294, 194, 194, 206, 23, 194, 25, - /* 880 */ 194, 111, 112, 113, 25, 43, 44, 45, 46, 47, - /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 900 */ 24, 194, 194, 217, 218, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 241, 232, 194, - /* 920 */ 212, 213, 242, 242, 217, 218, 242, 130, 11, 253, - /* 930 */ 194, 255, 19, 265, 149, 59, 306, 194, 308, 232, - /* 940 */ 309, 310, 217, 218, 102, 103, 104, 105, 106, 107, - /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 970 */ 57, 194, 194, 59, 194, 239, 19, 194, 25, 254, - /* 980 */ 303, 304, 23, 194, 25, 126, 306, 306, 308, 308, - /* 990 */ 306, 271, 308, 117, 286, 217, 218, 217, 218, 194, - /* 1000 */ 194, 159, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, - /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 59, 239, 194, - /* 1030 */ 116, 117, 118, 260, 254, 194, 240, 241, 194, 233, - /* 1040 */ 205, 240, 241, 205, 239, 128, 129, 270, 265, 253, - /* 1050 */ 194, 255, 217, 218, 253, 194, 255, 143, 280, 102, - /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1070 */ 113, 118, 159, 217, 218, 240, 241, 118, 240, 241, - /* 1080 */ 194, 194, 194, 239, 116, 117, 118, 22, 253, 254, - /* 1090 */ 255, 253, 19, 255, 233, 194, 143, 24, 263, 212, - /* 1100 */ 213, 194, 143, 217, 218, 217, 218, 261, 262, 271, - /* 1110 */ 254, 143, 19, 7, 8, 9, 43, 44, 45, 46, - /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 16, 19, 22, 23, 294, 43, 44, 45, 46, - /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 312, 194, 214, 21, 316, 43, 44, 45, 46, - /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 106, 107, 286, 194, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 207, 158, 59, - /* 1190 */ 160, 22, 77, 24, 79, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 194, 194, 229, - /* 1210 */ 194, 231, 101, 80, 22, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 288, 59, 12, - /* 1230 */ 217, 218, 293, 217, 218, 19, 106, 107, 59, 19, - /* 1240 */ 16, 127, 128, 129, 27, 115, 116, 117, 118, 194, - /* 1250 */ 120, 59, 22, 194, 24, 194, 123, 100, 128, 42, - /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 117, 194, 217, 218, 121, 100, - /* 1280 */ 63, 194, 245, 153, 194, 155, 117, 19, 115, 194, - /* 1290 */ 73, 214, 194, 256, 161, 116, 117, 194, 217, 218, - /* 1300 */ 121, 77, 194, 79, 217, 218, 194, 217, 218, 117, - /* 1310 */ 153, 154, 155, 254, 46, 217, 218, 144, 102, 103, - /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 232, 270, 153, 154, 155, 115, 116, 66, 19, 20, - /* 1340 */ 183, 22, 12, 312, 254, 194, 262, 316, 209, 210, - /* 1350 */ 266, 239, 194, 194, 108, 36, 85, 27, 19, 20, - /* 1360 */ 265, 22, 183, 245, 144, 94, 25, 48, 217, 218, - /* 1370 */ 293, 194, 42, 270, 256, 36, 217, 218, 59, 194, - /* 1380 */ 25, 135, 194, 115, 194, 161, 140, 194, 194, 15, - /* 1390 */ 71, 194, 312, 63, 217, 218, 316, 194, 59, 131, - /* 1400 */ 301, 302, 217, 218, 85, 217, 218, 217, 218, 90, - /* 1410 */ 71, 217, 218, 19, 217, 218, 245, 146, 262, 100, - /* 1420 */ 217, 218, 266, 265, 85, 106, 107, 256, 312, 90, - /* 1430 */ 209, 210, 316, 114, 60, 116, 117, 118, 194, 100, - /* 1440 */ 121, 194, 194, 145, 115, 106, 107, 19, 46, 19, - /* 1450 */ 20, 24, 22, 114, 194, 116, 117, 118, 194, 245, - /* 1460 */ 121, 194, 164, 194, 217, 218, 36, 194, 258, 259, - /* 1470 */ 256, 194, 153, 154, 155, 156, 157, 217, 218, 150, - /* 1480 */ 31, 217, 218, 142, 217, 218, 217, 218, 39, 59, - /* 1490 */ 217, 218, 153, 154, 155, 156, 157, 149, 150, 5, - /* 1500 */ 145, 71, 183, 245, 10, 11, 12, 13, 14, 194, - /* 1510 */ 116, 17, 129, 227, 256, 85, 194, 115, 194, 23, - /* 1520 */ 90, 25, 183, 99, 30, 97, 32, 22, 22, 194, - /* 1530 */ 100, 194, 217, 218, 40, 152, 106, 107, 23, 217, - /* 1540 */ 218, 194, 19, 20, 114, 22, 116, 117, 118, 257, - /* 1550 */ 194, 121, 217, 218, 217, 218, 194, 133, 53, 36, - /* 1560 */ 23, 23, 25, 25, 70, 120, 121, 61, 141, 7, - /* 1570 */ 8, 121, 78, 217, 218, 81, 23, 227, 25, 217, - /* 1580 */ 218, 131, 59, 153, 154, 155, 156, 157, 0, 1, - /* 1590 */ 2, 59, 98, 5, 71, 23, 227, 25, 10, 11, - /* 1600 */ 12, 13, 14, 83, 84, 17, 23, 23, 25, 25, - /* 1610 */ 59, 194, 194, 183, 23, 23, 25, 25, 30, 194, - /* 1620 */ 32, 19, 20, 100, 22, 194, 194, 133, 40, 106, - /* 1630 */ 107, 108, 138, 139, 194, 217, 218, 114, 36, 116, - /* 1640 */ 117, 118, 217, 218, 121, 194, 194, 194, 23, 117, - /* 1650 */ 25, 194, 23, 23, 25, 25, 162, 194, 70, 194, - /* 1660 */ 145, 59, 23, 153, 25, 155, 78, 194, 117, 81, - /* 1670 */ 217, 218, 194, 71, 217, 218, 153, 154, 155, 156, - /* 1680 */ 157, 194, 217, 218, 194, 23, 98, 25, 321, 194, - /* 1690 */ 217, 218, 194, 19, 20, 194, 22, 153, 23, 155, - /* 1700 */ 25, 194, 100, 194, 217, 218, 183, 194, 106, 107, - /* 1710 */ 36, 194, 217, 218, 237, 194, 114, 243, 116, 117, - /* 1720 */ 118, 133, 194, 121, 217, 218, 138, 139, 194, 194, - /* 1730 */ 194, 290, 289, 59, 217, 218, 194, 194, 217, 218, - /* 1740 */ 194, 194, 140, 194, 194, 71, 194, 244, 194, 194, - /* 1750 */ 162, 217, 218, 194, 194, 153, 154, 155, 156, 157, - /* 1760 */ 217, 218, 194, 217, 218, 194, 217, 218, 257, 217, - /* 1770 */ 218, 217, 218, 257, 100, 194, 257, 217, 218, 257, - /* 1780 */ 106, 107, 215, 299, 194, 183, 192, 194, 114, 194, - /* 1790 */ 116, 117, 118, 1, 2, 121, 221, 5, 217, 218, - /* 1800 */ 273, 197, 10, 11, 12, 13, 14, 217, 218, 17, - /* 1810 */ 217, 218, 217, 218, 140, 194, 246, 194, 273, 295, - /* 1820 */ 247, 273, 30, 247, 32, 269, 269, 153, 154, 155, - /* 1830 */ 156, 157, 40, 246, 273, 295, 230, 226, 217, 218, - /* 1840 */ 217, 218, 220, 261, 220, 282, 220, 19, 20, 244, - /* 1850 */ 22, 250, 141, 250, 246, 60, 201, 183, 261, 261, - /* 1860 */ 261, 201, 70, 299, 36, 299, 201, 38, 151, 150, - /* 1870 */ 78, 285, 22, 81, 296, 296, 43, 235, 18, 238, - /* 1880 */ 201, 274, 272, 238, 238, 238, 18, 59, 200, 149, - /* 1890 */ 98, 247, 274, 274, 235, 247, 247, 247, 235, 71, - /* 1900 */ 272, 201, 200, 158, 292, 62, 291, 201, 200, 22, - /* 1910 */ 201, 222, 200, 222, 201, 200, 115, 219, 219, 64, - /* 1920 */ 219, 228, 22, 126, 221, 133, 165, 222, 100, 225, - /* 1930 */ 138, 139, 225, 219, 106, 107, 24, 219, 228, 219, - /* 1940 */ 219, 307, 114, 113, 116, 117, 118, 315, 284, 121, - /* 1950 */ 284, 222, 201, 91, 162, 320, 320, 82, 148, 267, - /* 1960 */ 145, 267, 22, 279, 201, 158, 281, 251, 147, 146, - /* 1970 */ 25, 203, 250, 249, 251, 248, 13, 247, 195, 195, - /* 1980 */ 6, 153, 154, 155, 156, 157, 193, 193, 305, 193, - /* 1990 */ 208, 305, 302, 214, 214, 214, 208, 223, 223, 214, - /* 2000 */ 4, 215, 215, 214, 3, 22, 208, 163, 15, 23, - /* 2010 */ 16, 183, 23, 139, 151, 130, 25, 20, 142, 24, - /* 2020 */ 16, 144, 1, 142, 130, 130, 61, 37, 53, 151, - /* 2030 */ 53, 53, 53, 130, 116, 1, 34, 141, 5, 22, - /* 2040 */ 115, 161, 75, 25, 68, 141, 41, 115, 68, 24, - /* 2050 */ 20, 19, 131, 125, 67, 67, 96, 22, 22, 22, - /* 2060 */ 37, 23, 22, 24, 22, 59, 67, 23, 149, 28, - /* 2070 */ 22, 25, 23, 23, 23, 22, 141, 34, 97, 23, - /* 2080 */ 23, 34, 116, 22, 143, 25, 34, 75, 34, 34, - /* 2090 */ 75, 88, 34, 86, 23, 22, 34, 25, 24, 34, - /* 2100 */ 25, 93, 23, 44, 142, 23, 142, 23, 23, 22, - /* 2110 */ 11, 25, 23, 25, 23, 22, 22, 22, 1, 23, - /* 2120 */ 23, 23, 22, 22, 15, 141, 141, 25, 25, 1, - /* 2130 */ 322, 322, 322, 135, 322, 322, 322, 322, 322, 322, - /* 2140 */ 322, 141, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2150 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2160 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2180 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2190 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2200 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240, + /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19, + /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217, + /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39, + /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, + /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276, + /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217, + /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270, + /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50, + /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89, + /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205, + /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47, + /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311, + /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255, + /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88, + /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110, + /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107, + /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118, + /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277, + /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43, + /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53, + /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129, + /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106, + /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132, + /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103, + /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19, + /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113, + /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19, + /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49, + /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217, + /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49, + /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139, + /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117, + /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258, + /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109, + /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237, + /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109, + /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123, + /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133, + /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317, + /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44, + /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, + /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146, + /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128, + /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60, + /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50, + /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, + /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205, + /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118, + /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237, + /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110, + /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194, + /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255, + /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278, + /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271, + /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242, + /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115, + /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264, + /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52, + /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, + /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, + /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205, + /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78, + /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122, + /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144, + /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255, + /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256, + /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48, + /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107, + /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117, + /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44, + /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54, + /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, + /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, + /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118, + /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253, + /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104, + /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202, + /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118, + /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25, + /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50, + /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227, + /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50, + /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112, + /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125, + /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194, + /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118, + /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218, + /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137, + /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218, + /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262, + /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160, + /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194, + /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77, + /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194, + /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106, + /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194, + /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106, + /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239, + /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218, + /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232, + /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256, + /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162, + /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, + /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25, + /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52, + /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24, + /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52, + /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108, + /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194, + /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25, + /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316, + /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209, + /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39, + /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48, + /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48, + /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116, + /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19, + /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108, + /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194, + /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108, + /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25, + /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194, + /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217, + /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194, + /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218, + /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217, + /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119, + /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217, + /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139, + /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194, + /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100, + /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25, + /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60, + /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217, + /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7, + /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20, + /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218, + /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218, + /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194, + /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60, + /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217, + /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25, + /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194, + /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25, + /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183, + /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217, + /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194, + /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218, + /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23, + /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23, + /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194, + /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107, + /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117, + /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194, + /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269, + /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230, + /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157, + /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220, + /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197, + /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201, + /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299, + /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238, + /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247, + /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159, + /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200, + /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219, + /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114, + /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107, + /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117, + /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19, + /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249, + /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248, + /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157, + /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208, + /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22, + /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16, + /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1, + /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54, + /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22, + /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119, + /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10, + /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, + /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, + /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, + /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, + /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, + /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89, + /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87, + /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34, + /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143, + /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1, + /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25, + /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322, + /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140, + /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322, + /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322, + /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322, + /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322, /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, @@ -173527,118 +174848,125 @@ static const YYCODETYPE yy_lookahead[] = { /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, + /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2390 */ 186, 186, 186, }; #define YY_SHIFT_COUNT (582) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2128) +#define YY_SHIFT_MAX (2152) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1792, 1588, 1494, 322, 322, 399, 306, 1319, 1339, 1430, - /* 10 */ 1828, 1828, 1828, 580, 399, 399, 399, 399, 399, 0, - /* 20 */ 0, 214, 1093, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 30 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1130, 1130, - /* 40 */ 365, 365, 55, 278, 436, 713, 713, 201, 201, 201, - /* 50 */ 201, 40, 111, 258, 361, 469, 512, 583, 622, 693, - /* 60 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, - /* 70 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 80 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1523, 1602, - /* 90 */ 1674, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 100 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 110 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 120 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 130 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 140 */ 137, 181, 181, 181, 181, 181, 181, 181, 96, 222, - /* 150 */ 143, 477, 713, 1133, 1268, 713, 713, 79, 79, 713, - /* 160 */ 770, 83, 65, 65, 65, 288, 162, 162, 2142, 2142, - /* 170 */ 696, 696, 696, 238, 474, 474, 474, 474, 1217, 1217, - /* 180 */ 678, 477, 324, 398, 713, 713, 713, 713, 713, 713, - /* 190 */ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, - /* 200 */ 713, 713, 713, 1220, 366, 366, 713, 917, 283, 283, - /* 210 */ 434, 434, 605, 605, 1298, 2142, 2142, 2142, 2142, 2142, - /* 220 */ 2142, 2142, 1179, 1157, 1157, 487, 527, 585, 645, 749, - /* 230 */ 914, 968, 752, 713, 713, 713, 713, 713, 713, 713, - /* 240 */ 713, 713, 713, 303, 713, 713, 713, 713, 713, 713, - /* 250 */ 713, 713, 713, 713, 713, 713, 797, 797, 797, 713, - /* 260 */ 713, 713, 959, 713, 713, 713, 1169, 1271, 713, 713, - /* 270 */ 1330, 713, 713, 713, 713, 713, 713, 713, 713, 629, - /* 280 */ 7, 91, 876, 876, 876, 876, 953, 91, 91, 1246, - /* 290 */ 1065, 1106, 1374, 1329, 1348, 468, 1348, 1394, 785, 1329, - /* 300 */ 1329, 785, 1329, 468, 1394, 859, 854, 1402, 1449, 1449, - /* 310 */ 1449, 1173, 1173, 1173, 1173, 1355, 1355, 1030, 1341, 405, - /* 320 */ 1230, 1795, 1795, 1711, 1711, 1829, 1829, 1711, 1717, 1719, - /* 330 */ 1850, 1833, 1860, 1860, 1860, 1860, 1711, 1868, 1740, 1719, - /* 340 */ 1719, 1740, 1850, 1833, 1740, 1833, 1740, 1711, 1868, 1745, - /* 350 */ 1843, 1711, 1868, 1887, 1711, 1868, 1711, 1868, 1887, 1801, - /* 360 */ 1801, 1801, 1855, 1900, 1900, 1887, 1801, 1797, 1801, 1855, - /* 370 */ 1801, 1801, 1761, 1912, 1830, 1830, 1887, 1711, 1862, 1862, - /* 380 */ 1875, 1875, 1810, 1815, 1940, 1711, 1807, 1810, 1821, 1823, - /* 390 */ 1740, 1945, 1963, 1963, 1974, 1974, 1974, 2142, 2142, 2142, - /* 400 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, - /* 410 */ 2142, 2142, 20, 1224, 256, 1111, 1115, 1114, 1192, 1496, - /* 420 */ 1424, 1505, 1427, 355, 1383, 1537, 1506, 1538, 1553, 1583, - /* 430 */ 1584, 1591, 1625, 541, 1445, 1562, 1450, 1572, 1515, 1428, - /* 440 */ 1532, 1592, 1629, 1520, 1630, 1639, 1510, 1544, 1662, 1675, - /* 450 */ 1551, 48, 1996, 2001, 1983, 1844, 1993, 1994, 1986, 1989, - /* 460 */ 1874, 1863, 1885, 1991, 1991, 1995, 1876, 1997, 1877, 2004, - /* 470 */ 2021, 1881, 1894, 1991, 1895, 1965, 1990, 1991, 1878, 1975, - /* 480 */ 1977, 1978, 1979, 1903, 1918, 2002, 1896, 2034, 2033, 2017, - /* 490 */ 1925, 1880, 1976, 2018, 1980, 1967, 2005, 1904, 1932, 2025, - /* 500 */ 2030, 2032, 1921, 1928, 2035, 1987, 2036, 2037, 2038, 2040, - /* 510 */ 1988, 2006, 2039, 1960, 2041, 2042, 1999, 2023, 2044, 2043, - /* 520 */ 1919, 2048, 2049, 2050, 2046, 2051, 2053, 1981, 1935, 2056, - /* 530 */ 2057, 1966, 2047, 2061, 1941, 2060, 2052, 2054, 2055, 2058, - /* 540 */ 2003, 2012, 2007, 2059, 2015, 2008, 2062, 2071, 2073, 2074, - /* 550 */ 2072, 2075, 2065, 1962, 1964, 2079, 2060, 2082, 2084, 2085, - /* 560 */ 2087, 2086, 2089, 2088, 2091, 2093, 2099, 2094, 2095, 2096, - /* 570 */ 2097, 2100, 2101, 2102, 1998, 1984, 1985, 2000, 2103, 2098, - /* 580 */ 2109, 2117, 2128, + /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642, + /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0, + /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, + /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406, + /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260, + /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741, + /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, + /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, + /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, + /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, + /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, + /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880, + /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113, + /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765, + /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598, + /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, + /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147, + /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207, + /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461, + /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598, + /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598, + /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105, + /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249, + /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598, + /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902, + /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162, + /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300, + /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414, + /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683, + /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707, + /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836, + /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854, + /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769, + /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823, + /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789, + /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207, + /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, + /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415, + /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567, + /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275, + /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696, + /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965, + /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855, + /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856, + /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015, + /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921, + /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, + /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, + /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959, + /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076, + /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094, + /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104, + /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117, + /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128, + /* 580 */ 2137, 2138, 2152, }; -#define YY_REDUCE_COUNT (411) -#define YY_REDUCE_MIN (-275) -#define YY_REDUCE_MAX (1798) +#define YY_REDUCE_COUNT (412) +#define YY_REDUCE_MIN (-276) +#define YY_REDUCE_MAX (1775) static const short yy_reduce_ofst[] = { - /* 0 */ -71, 194, 343, 835, -180, -177, 838, -194, -188, -185, - /* 10 */ -183, 82, 183, -65, 133, 245, 346, 407, 458, -178, - /* 20 */ 75, -275, -4, 310, 312, 489, 575, 596, 463, 686, - /* 30 */ 707, 725, 780, 1098, 856, 778, 1059, 1090, 708, 887, - /* 40 */ 86, 448, 980, 630, 680, 681, 684, 796, 801, 796, - /* 50 */ 801, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 60 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 70 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 80 */ -261, -261, -261, -261, -261, -261, -261, -261, 391, 886, - /* 90 */ 888, 1013, 1016, 1081, 1087, 1151, 1159, 1177, 1185, 1188, - /* 100 */ 1190, 1194, 1197, 1203, 1247, 1260, 1264, 1267, 1269, 1273, - /* 110 */ 1315, 1322, 1335, 1337, 1356, 1362, 1418, 1425, 1453, 1457, - /* 120 */ 1465, 1473, 1487, 1495, 1507, 1517, 1521, 1534, 1543, 1546, - /* 130 */ 1549, 1552, 1554, 1560, 1581, 1590, 1593, 1595, 1621, 1623, - /* 140 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 150 */ -261, -186, -117, 260, 263, 460, 631, -74, 497, -181, - /* 160 */ -261, 939, 176, 274, 338, 676, -261, -261, -261, -261, - /* 170 */ -212, -212, -212, -184, 149, 777, 1061, 1103, 265, 419, - /* 180 */ -254, 670, 677, 677, -11, -129, 184, 488, 736, 789, - /* 190 */ 805, 844, 403, 529, 579, 668, 783, 841, 1158, 1112, - /* 200 */ 806, 861, 1095, 846, 839, 1031, -189, 1077, 1080, 1116, - /* 210 */ 1084, 1156, 1139, 1221, 46, 1099, 1037, 1118, 1171, 1214, - /* 220 */ 1210, 1258, -210, -190, -176, -115, 117, 262, 376, 490, - /* 230 */ 511, 520, 618, 639, 743, 901, 907, 958, 1014, 1055, - /* 240 */ 1108, 1193, 1244, 720, 1248, 1277, 1324, 1347, 1417, 1431, - /* 250 */ 1432, 1440, 1451, 1452, 1463, 1478, 1286, 1350, 1369, 1490, - /* 260 */ 1498, 1501, 773, 1509, 1513, 1528, 1292, 1367, 1535, 1536, - /* 270 */ 1477, 1542, 376, 1547, 1550, 1555, 1559, 1568, 1571, 1441, - /* 280 */ 1443, 1474, 1511, 1516, 1519, 1522, 773, 1474, 1474, 1503, - /* 290 */ 1567, 1594, 1484, 1527, 1556, 1570, 1557, 1524, 1573, 1545, - /* 300 */ 1548, 1576, 1561, 1587, 1540, 1575, 1606, 1611, 1622, 1624, - /* 310 */ 1626, 1582, 1597, 1598, 1599, 1601, 1603, 1563, 1608, 1605, - /* 320 */ 1604, 1564, 1566, 1655, 1660, 1578, 1579, 1665, 1586, 1607, - /* 330 */ 1610, 1642, 1641, 1645, 1646, 1647, 1679, 1688, 1644, 1618, - /* 340 */ 1619, 1648, 1628, 1659, 1649, 1663, 1650, 1700, 1702, 1612, - /* 350 */ 1615, 1706, 1708, 1689, 1709, 1712, 1713, 1715, 1691, 1698, - /* 360 */ 1699, 1701, 1693, 1704, 1707, 1705, 1714, 1703, 1718, 1710, - /* 370 */ 1720, 1721, 1632, 1634, 1664, 1666, 1729, 1751, 1635, 1636, - /* 380 */ 1692, 1694, 1716, 1722, 1684, 1763, 1685, 1723, 1724, 1727, - /* 390 */ 1730, 1768, 1783, 1784, 1793, 1794, 1796, 1683, 1686, 1690, - /* 400 */ 1782, 1779, 1780, 1781, 1785, 1788, 1774, 1775, 1786, 1787, - /* 410 */ 1789, 1798, + /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162, + /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207, + /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945, + /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224, + /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237, + /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895, + /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242, + /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286, + /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366, + /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427, + /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519, + /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45, + /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370, + /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45, + /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678, + /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419, + /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813, + /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443, + /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933, + /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277, + /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209, + /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474, + /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764, + /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260, + /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576, + /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520, + /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537, + /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585, + /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577, + /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560, + /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612, + /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668, + /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660, + /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692, + /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596, + /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690, + /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661, + /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765, + /* 410 */ 1771, 1767, 1775, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, @@ -173647,57 +174975,57 @@ static const YYACTIONTYPE yy_default[] = { /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, - /* 60 */ 1492, 1493, 1254, 1254, 1254, 1543, 1545, 1508, 1420, 1419, - /* 70 */ 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, 1486, - /* 80 */ 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, 1254, + /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, + /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, + /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 140 */ 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, 1456, 1458, - /* 150 */ 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, 1254, 1254, - /* 160 */ 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, 1473, 1472, - /* 170 */ 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, 1254, 1254, - /* 180 */ 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, + /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, + /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, + /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, + /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 200 */ 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, 1578, 1578, - /* 210 */ 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, 1358, 1358, - /* 220 */ 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, 1546, 1254, - /* 240 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, + /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, + /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, + /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, + /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, 1254, 1254, - /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, 1254, - /* 280 */ 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, 1357, - /* 290 */ 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, 1423, - /* 300 */ 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, 1397, - /* 310 */ 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, 1357, - /* 320 */ 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, 1638, - /* 330 */ 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, 1638, - /* 340 */ 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, 1525, - /* 350 */ 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, 1330, - /* 360 */ 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, 1319, - /* 370 */ 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, 1588, - /* 380 */ 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, 1401, - /* 390 */ 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, 1558, - /* 400 */ 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, 1288, - /* 410 */ 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, 1254, - /* 420 */ 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1564, - /* 440 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 450 */ 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, 1254, - /* 460 */ 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, 1254, - /* 470 */ 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, 1254, - /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, 1254, - /* 490 */ 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, 1254, + /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, + /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, + /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, + /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, + /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, + /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, + /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, + /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, + /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, + /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, + /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, + /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, + /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, + /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, + /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, + /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, + /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, + /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, + /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, + /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, + /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, + /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 510 */ 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 530 */ 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, 1254, + /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 550 */ 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, 1254, - /* 560 */ 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, + /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, /* 580 */ 1266, 1254, 1254, }; @@ -173721,52 +175049,53 @@ static const YYACTIONTYPE yy_default[] = { static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ - 59, /* EXPLAIN => ID */ - 59, /* QUERY => ID */ - 59, /* PLAN => ID */ - 59, /* BEGIN => ID */ + 60, /* EXPLAIN => ID */ + 60, /* QUERY => ID */ + 60, /* PLAN => ID */ + 60, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 59, /* DEFERRED => ID */ - 59, /* IMMEDIATE => ID */ - 59, /* EXCLUSIVE => ID */ + 60, /* DEFERRED => ID */ + 60, /* IMMEDIATE => ID */ + 60, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 59, /* END => ID */ - 59, /* ROLLBACK => ID */ - 59, /* SAVEPOINT => ID */ - 59, /* RELEASE => ID */ + 60, /* END => ID */ + 60, /* ROLLBACK => ID */ + 60, /* SAVEPOINT => ID */ + 60, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ - 59, /* IF => ID */ + 60, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ - 59, /* TEMP => ID */ + 60, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ - 59, /* WITHOUT => ID */ - 59, /* ABORT => ID */ - 59, /* ACTION => ID */ - 59, /* AFTER => ID */ - 59, /* ANALYZE => ID */ - 59, /* ASC => ID */ - 59, /* ATTACH => ID */ - 59, /* BEFORE => ID */ - 59, /* BY => ID */ - 59, /* CASCADE => ID */ - 59, /* CAST => ID */ - 59, /* CONFLICT => ID */ - 59, /* DATABASE => ID */ - 59, /* DESC => ID */ - 59, /* DETACH => ID */ - 59, /* EACH => ID */ - 59, /* FAIL => ID */ + 60, /* WITHOUT => ID */ + 60, /* ABORT => ID */ + 60, /* ACTION => ID */ + 60, /* AFTER => ID */ + 60, /* ANALYZE => ID */ + 60, /* ASC => ID */ + 60, /* ATTACH => ID */ + 60, /* BEFORE => ID */ + 60, /* BY => ID */ + 60, /* CASCADE => ID */ + 60, /* CAST => ID */ + 60, /* CONFLICT => ID */ + 60, /* DATABASE => ID */ + 60, /* DESC => ID */ + 60, /* DETACH => ID */ + 60, /* EACH => ID */ + 60, /* FAIL => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ - 59, /* MATCH => ID */ - 59, /* LIKE_KW => ID */ + 0, /* ISNOT => nothing */ + 60, /* MATCH => ID */ + 60, /* LIKE_KW => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ 0, /* ISNULL => nothing */ @@ -173779,47 +175108,47 @@ static const YYCODETYPE yyFallback[] = { 0, /* GE => nothing */ 0, /* ESCAPE => nothing */ 0, /* ID => nothing */ - 59, /* COLUMNKW => ID */ - 59, /* DO => ID */ - 59, /* FOR => ID */ - 59, /* IGNORE => ID */ - 59, /* INITIALLY => ID */ - 59, /* INSTEAD => ID */ - 59, /* NO => ID */ - 59, /* KEY => ID */ - 59, /* OF => ID */ - 59, /* OFFSET => ID */ - 59, /* PRAGMA => ID */ - 59, /* RAISE => ID */ - 59, /* RECURSIVE => ID */ - 59, /* REPLACE => ID */ - 59, /* RESTRICT => ID */ - 59, /* ROW => ID */ - 59, /* ROWS => ID */ - 59, /* TRIGGER => ID */ - 59, /* VACUUM => ID */ - 59, /* VIEW => ID */ - 59, /* VIRTUAL => ID */ - 59, /* WITH => ID */ - 59, /* NULLS => ID */ - 59, /* FIRST => ID */ - 59, /* LAST => ID */ - 59, /* CURRENT => ID */ - 59, /* FOLLOWING => ID */ - 59, /* PARTITION => ID */ - 59, /* PRECEDING => ID */ - 59, /* RANGE => ID */ - 59, /* UNBOUNDED => ID */ - 59, /* EXCLUDE => ID */ - 59, /* GROUPS => ID */ - 59, /* OTHERS => ID */ - 59, /* TIES => ID */ - 59, /* GENERATED => ID */ - 59, /* ALWAYS => ID */ - 59, /* MATERIALIZED => ID */ - 59, /* REINDEX => ID */ - 59, /* RENAME => ID */ - 59, /* CTIME_KW => ID */ + 60, /* COLUMNKW => ID */ + 60, /* DO => ID */ + 60, /* FOR => ID */ + 60, /* IGNORE => ID */ + 60, /* INITIALLY => ID */ + 60, /* INSTEAD => ID */ + 60, /* NO => ID */ + 60, /* KEY => ID */ + 60, /* OF => ID */ + 60, /* OFFSET => ID */ + 60, /* PRAGMA => ID */ + 60, /* RAISE => ID */ + 60, /* RECURSIVE => ID */ + 60, /* REPLACE => ID */ + 60, /* RESTRICT => ID */ + 60, /* ROW => ID */ + 60, /* ROWS => ID */ + 60, /* TRIGGER => ID */ + 60, /* VACUUM => ID */ + 60, /* VIEW => ID */ + 60, /* VIRTUAL => ID */ + 60, /* WITH => ID */ + 60, /* NULLS => ID */ + 60, /* FIRST => ID */ + 60, /* LAST => ID */ + 60, /* CURRENT => ID */ + 60, /* FOLLOWING => ID */ + 60, /* PARTITION => ID */ + 60, /* PRECEDING => ID */ + 60, /* RANGE => ID */ + 60, /* UNBOUNDED => ID */ + 60, /* EXCLUDE => ID */ + 60, /* GROUPS => ID */ + 60, /* OTHERS => ID */ + 60, /* TIES => ID */ + 60, /* GENERATED => ID */ + 60, /* ALWAYS => ID */ + 60, /* MATERIALIZED => ID */ + 60, /* REINDEX => ID */ + 60, /* RENAME => ID */ + 60, /* CTIME_KW => ID */ 0, /* ANY => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ @@ -173890,7 +175219,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* AGG_FUNCTION => nothing */ 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ - 0, /* ISNOT => nothing */ 0, /* FUNCTION => nothing */ 0, /* UPLUS => nothing */ 0, /* UMINUS => nothing */ @@ -174034,132 +175362,132 @@ static const char *const yyTokenName[] = { /* 43 */ "OR", /* 44 */ "AND", /* 45 */ "IS", - /* 46 */ "MATCH", - /* 47 */ "LIKE_KW", - /* 48 */ "BETWEEN", - /* 49 */ "IN", - /* 50 */ "ISNULL", - /* 51 */ "NOTNULL", - /* 52 */ "NE", - /* 53 */ "EQ", - /* 54 */ "GT", - /* 55 */ "LE", - /* 56 */ "LT", - /* 57 */ "GE", - /* 58 */ "ESCAPE", - /* 59 */ "ID", - /* 60 */ "COLUMNKW", - /* 61 */ "DO", - /* 62 */ "FOR", - /* 63 */ "IGNORE", - /* 64 */ "INITIALLY", - /* 65 */ "INSTEAD", - /* 66 */ "NO", - /* 67 */ "KEY", - /* 68 */ "OF", - /* 69 */ "OFFSET", - /* 70 */ "PRAGMA", - /* 71 */ "RAISE", - /* 72 */ "RECURSIVE", - /* 73 */ "REPLACE", - /* 74 */ "RESTRICT", - /* 75 */ "ROW", - /* 76 */ "ROWS", - /* 77 */ "TRIGGER", - /* 78 */ "VACUUM", - /* 79 */ "VIEW", - /* 80 */ "VIRTUAL", - /* 81 */ "WITH", - /* 82 */ "NULLS", - /* 83 */ "FIRST", - /* 84 */ "LAST", - /* 85 */ "CURRENT", - /* 86 */ "FOLLOWING", - /* 87 */ "PARTITION", - /* 88 */ "PRECEDING", - /* 89 */ "RANGE", - /* 90 */ "UNBOUNDED", - /* 91 */ "EXCLUDE", - /* 92 */ "GROUPS", - /* 93 */ "OTHERS", - /* 94 */ "TIES", - /* 95 */ "GENERATED", - /* 96 */ "ALWAYS", - /* 97 */ "MATERIALIZED", - /* 98 */ "REINDEX", - /* 99 */ "RENAME", - /* 100 */ "CTIME_KW", - /* 101 */ "ANY", - /* 102 */ "BITAND", - /* 103 */ "BITOR", - /* 104 */ "LSHIFT", - /* 105 */ "RSHIFT", - /* 106 */ "PLUS", - /* 107 */ "MINUS", - /* 108 */ "STAR", - /* 109 */ "SLASH", - /* 110 */ "REM", - /* 111 */ "CONCAT", - /* 112 */ "PTR", - /* 113 */ "COLLATE", - /* 114 */ "BITNOT", - /* 115 */ "ON", - /* 116 */ "INDEXED", - /* 117 */ "STRING", - /* 118 */ "JOIN_KW", - /* 119 */ "CONSTRAINT", - /* 120 */ "DEFAULT", - /* 121 */ "NULL", - /* 122 */ "PRIMARY", - /* 123 */ "UNIQUE", - /* 124 */ "CHECK", - /* 125 */ "REFERENCES", - /* 126 */ "AUTOINCR", - /* 127 */ "INSERT", - /* 128 */ "DELETE", - /* 129 */ "UPDATE", - /* 130 */ "SET", - /* 131 */ "DEFERRABLE", - /* 132 */ "FOREIGN", - /* 133 */ "DROP", - /* 134 */ "UNION", - /* 135 */ "ALL", - /* 136 */ "EXCEPT", - /* 137 */ "INTERSECT", - /* 138 */ "SELECT", - /* 139 */ "VALUES", - /* 140 */ "DISTINCT", - /* 141 */ "DOT", - /* 142 */ "FROM", - /* 143 */ "JOIN", - /* 144 */ "USING", - /* 145 */ "ORDER", - /* 146 */ "GROUP", - /* 147 */ "HAVING", - /* 148 */ "LIMIT", - /* 149 */ "WHERE", - /* 150 */ "RETURNING", - /* 151 */ "INTO", - /* 152 */ "NOTHING", - /* 153 */ "FLOAT", - /* 154 */ "BLOB", - /* 155 */ "INTEGER", - /* 156 */ "VARIABLE", - /* 157 */ "CASE", - /* 158 */ "WHEN", - /* 159 */ "THEN", - /* 160 */ "ELSE", - /* 161 */ "INDEX", - /* 162 */ "ALTER", - /* 163 */ "ADD", - /* 164 */ "WINDOW", - /* 165 */ "OVER", - /* 166 */ "FILTER", - /* 167 */ "COLUMN", - /* 168 */ "AGG_FUNCTION", - /* 169 */ "AGG_COLUMN", - /* 170 */ "TRUEFALSE", - /* 171 */ "ISNOT", + /* 46 */ "ISNOT", + /* 47 */ "MATCH", + /* 48 */ "LIKE_KW", + /* 49 */ "BETWEEN", + /* 50 */ "IN", + /* 51 */ "ISNULL", + /* 52 */ "NOTNULL", + /* 53 */ "NE", + /* 54 */ "EQ", + /* 55 */ "GT", + /* 56 */ "LE", + /* 57 */ "LT", + /* 58 */ "GE", + /* 59 */ "ESCAPE", + /* 60 */ "ID", + /* 61 */ "COLUMNKW", + /* 62 */ "DO", + /* 63 */ "FOR", + /* 64 */ "IGNORE", + /* 65 */ "INITIALLY", + /* 66 */ "INSTEAD", + /* 67 */ "NO", + /* 68 */ "KEY", + /* 69 */ "OF", + /* 70 */ "OFFSET", + /* 71 */ "PRAGMA", + /* 72 */ "RAISE", + /* 73 */ "RECURSIVE", + /* 74 */ "REPLACE", + /* 75 */ "RESTRICT", + /* 76 */ "ROW", + /* 77 */ "ROWS", + /* 78 */ "TRIGGER", + /* 79 */ "VACUUM", + /* 80 */ "VIEW", + /* 81 */ "VIRTUAL", + /* 82 */ "WITH", + /* 83 */ "NULLS", + /* 84 */ "FIRST", + /* 85 */ "LAST", + /* 86 */ "CURRENT", + /* 87 */ "FOLLOWING", + /* 88 */ "PARTITION", + /* 89 */ "PRECEDING", + /* 90 */ "RANGE", + /* 91 */ "UNBOUNDED", + /* 92 */ "EXCLUDE", + /* 93 */ "GROUPS", + /* 94 */ "OTHERS", + /* 95 */ "TIES", + /* 96 */ "GENERATED", + /* 97 */ "ALWAYS", + /* 98 */ "MATERIALIZED", + /* 99 */ "REINDEX", + /* 100 */ "RENAME", + /* 101 */ "CTIME_KW", + /* 102 */ "ANY", + /* 103 */ "BITAND", + /* 104 */ "BITOR", + /* 105 */ "LSHIFT", + /* 106 */ "RSHIFT", + /* 107 */ "PLUS", + /* 108 */ "MINUS", + /* 109 */ "STAR", + /* 110 */ "SLASH", + /* 111 */ "REM", + /* 112 */ "CONCAT", + /* 113 */ "PTR", + /* 114 */ "COLLATE", + /* 115 */ "BITNOT", + /* 116 */ "ON", + /* 117 */ "INDEXED", + /* 118 */ "STRING", + /* 119 */ "JOIN_KW", + /* 120 */ "CONSTRAINT", + /* 121 */ "DEFAULT", + /* 122 */ "NULL", + /* 123 */ "PRIMARY", + /* 124 */ "UNIQUE", + /* 125 */ "CHECK", + /* 126 */ "REFERENCES", + /* 127 */ "AUTOINCR", + /* 128 */ "INSERT", + /* 129 */ "DELETE", + /* 130 */ "UPDATE", + /* 131 */ "SET", + /* 132 */ "DEFERRABLE", + /* 133 */ "FOREIGN", + /* 134 */ "DROP", + /* 135 */ "UNION", + /* 136 */ "ALL", + /* 137 */ "EXCEPT", + /* 138 */ "INTERSECT", + /* 139 */ "SELECT", + /* 140 */ "VALUES", + /* 141 */ "DISTINCT", + /* 142 */ "DOT", + /* 143 */ "FROM", + /* 144 */ "JOIN", + /* 145 */ "USING", + /* 146 */ "ORDER", + /* 147 */ "GROUP", + /* 148 */ "HAVING", + /* 149 */ "LIMIT", + /* 150 */ "WHERE", + /* 151 */ "RETURNING", + /* 152 */ "INTO", + /* 153 */ "NOTHING", + /* 154 */ "FLOAT", + /* 155 */ "BLOB", + /* 156 */ "INTEGER", + /* 157 */ "VARIABLE", + /* 158 */ "CASE", + /* 159 */ "WHEN", + /* 160 */ "THEN", + /* 161 */ "ELSE", + /* 162 */ "INDEX", + /* 163 */ "ALTER", + /* 164 */ "ADD", + /* 165 */ "WINDOW", + /* 166 */ "OVER", + /* 167 */ "FILTER", + /* 168 */ "COLUMN", + /* 169 */ "AGG_FUNCTION", + /* 170 */ "AGG_COLUMN", + /* 171 */ "TRUEFALSE", /* 172 */ "FUNCTION", /* 173 */ "UPLUS", /* 174 */ "UMINUS", @@ -174597,7 +175925,7 @@ static const char *const yyRuleName[] = { /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", /* 278 */ "trigger_cmd ::= scanpt select scanpt", /* 279 */ "expr ::= RAISE LP IGNORE RP", - /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", /* 281 */ "raisetype ::= ROLLBACK", /* 282 */ "raisetype ::= ABORT", /* 283 */ "raisetype ::= FAIL", @@ -175522,7 +176850,7 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ 293, /* (278) trigger_cmd ::= scanpt select scanpt */ 218, /* (279) expr ::= RAISE LP IGNORE RP */ - 218, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ 237, /* (281) raisetype ::= ROLLBACK */ 237, /* (282) raisetype ::= ABORT */ 237, /* (283) raisetype ::= FAIL */ @@ -175936,7 +177264,7 @@ static const signed char yyRuleInfoNRhs[] = { -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -3, /* (278) trigger_cmd ::= scanpt select scanpt */ -4, /* (279) expr ::= RAISE LP IGNORE RP */ - -6, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ -1, /* (281) raisetype ::= ROLLBACK */ -1, /* (282) raisetype ::= ABORT */ -1, /* (283) raisetype ::= FAIL */ @@ -176574,11 +177902,21 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-5].minor.yy203 ){ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; SrcItem *pOld = yymsp[-3].minor.yy203->a; + assert( pOld->fg.fixedSchema==0 ); pNew->zName = pOld->zName; - pNew->zDatabase = pOld->zDatabase; - pNew->pSelect = pOld->pSelect; - if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ - pNew->fg.isNestedFrom = 1; + assert( pOld->fg.fixedSchema==0 ); + if( pOld->fg.isSubquery ){ + pNew->fg.isSubquery = 1; + pNew->u4.pSubq = pOld->u4.pSubq; + pOld->u4.pSubq = 0; + pOld->fg.isSubquery = 0; + assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); + if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } + }else{ + pNew->u4.zDatabase = pOld->u4.zDatabase; + pOld->u4.zDatabase = 0; } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; @@ -176586,8 +177924,7 @@ static YYACTIONTYPE yy_reduce( pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; } - pOld->zName = pOld->zDatabase = 0; - pOld->pSelect = 0; + pOld->zName = 0; } sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); }else{ @@ -177321,9 +178658,9 @@ static YYACTIONTYPE yy_reduce( } } break; - case 280: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ { - yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); if( yymsp[-5].minor.yy454 ) { yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; } @@ -179914,32 +181251,6 @@ SQLITE_API char *sqlite3_temp_directory = 0; */ SQLITE_API char *sqlite3_data_directory = 0; -/* -** Determine whether or not high-precision (long double) floating point -** math works correctly on CPU currently running. -*/ -static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ - if( sizeof(LONGDOUBLE_TYPE)<=8 ){ - /* If the size of "long double" is not more than 8, then - ** high-precision math is not possible. */ - return 0; - }else{ - /* Just because sizeof(long double)>8 does not mean that the underlying - ** hardware actually supports high-precision floating point. For example, - ** clearing the 0x100 bit in the floating-point control word on Intel - ** processors will make long double work like double, even though long - ** double takes up more space. The only way to determine if long double - ** actually works is to run an experiment. */ - LONGDOUBLE_TYPE a, b, c; - rc++; - a = 1.0+rc*0.1; - b = 1.0e+18+rc*25.0; - c = a+b; - return b!=c; - } -} - - /* ** Initialize SQLite. ** @@ -180134,13 +181445,6 @@ SQLITE_API int sqlite3_initialize(void){ rc = SQLITE_EXTRA_INIT(0); } #endif - - /* Experimentally determine if high-precision floating point is - ** available. */ -#ifndef SQLITE_OMIT_WSD - sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); -#endif - return rc; } @@ -181681,7 +182985,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS| + SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But @@ -183236,6 +184541,7 @@ static int openDatabase( if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ + if( zFilename==0 ) zFilename = ":memory:"; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); } if( rc!=SQLITE_OK ){ @@ -184148,6 +185454,18 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) + ** + ** Write the current optimization settings into *N. A zero bit means that + ** the optimization is on, and a 1 bit means that the optimization is off. + */ + case SQLITE_TESTCTRL_GETOPT: { + sqlite3 *db = va_arg(ap, sqlite3*); + int *pN = va_arg(ap, int*); + *pN = db->dbOptFlags; + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** ** If parameter onoff is 1, subsequent calls to localtime() fail. @@ -184379,24 +185697,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } -#if !defined(SQLITE_OMIT_WSD) - /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); - ** - ** X<0 Make no changes to the bUseLongDouble. Just report value. - ** X==0 Disable bUseLongDouble - ** X==1 Enable bUseLongDouble - ** X>=2 Set bUseLongDouble to its default value for this platform - */ - case SQLITE_TESTCTRL_USELONGDOUBLE: { - int b = va_arg(ap, int); - if( b>=2 ) b = hasHighPrecisionDouble(b); - if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; - rc = sqlite3Config.bUseLongDouble!=0; - break; - } -#endif - - #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -184704,7 +186004,11 @@ SQLITE_API int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + i64 dummy = 0; + sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy); rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -195475,11 +196779,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* #include */ /* @@ -202706,6 +204006,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ return 1; } + assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; inPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; @@ -207699,7 +209000,9 @@ static u32 jsonLookupStep( zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; - for(i=1; zPath[i] && zPath[i]!='"'; i++){} + for(i=1; zPath[i] && zPath[i]!='"'; i++){ + if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; + } nKey = i-1; if( zPath[i] ){ i++; @@ -208709,10 +210012,16 @@ static void jsonExtractFunc( ** NUMBER ==> $[NUMBER] // PG compatible ** LABEL ==> $.LABEL // PG compatible ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + ** + ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from + ** the right of the array. Hence for negative NUMBER: + ** + ** NUMBER ==> $[#NUMBER] // PG compatible */ jsonStringInit(&jx, ctx); if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ jsonAppendRawNZ(&jx, "[", 1); + if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); jsonAppendRaw(&jx, zPath, nPath); jsonAppendRawNZ(&jx, "]", 2); }else if( jsonAllAlphanum(zPath, nPath) ){ @@ -218454,6 +219763,27 @@ struct RbuFrame { u32 iWalFrame; }; +#ifndef UNUSED_PARAMETER +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) +#endif + /* ** RBU handle. ** @@ -218505,7 +219835,7 @@ struct sqlite3rbu { int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ - int nProgress; /* Rows processed for all objects */ + sqlite3_int64 nProgress; /* Rows processed for all objects */ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ @@ -218622,7 +219952,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ v = (v<<6) + c; } z--; - *pLen -= z - zStart; + *pLen -= (int)(z - zStart); *pz = (char*)z; return v; } @@ -218807,6 +220137,7 @@ static void rbuFossilDeltaFunc( char *aOut; assert( argc==2 ); + UNUSED_PARAMETER(argc); nOrig = sqlite3_value_bytes(argv[0]); aOrig = (const char*)sqlite3_value_blob(argv[0]); @@ -220386,13 +221717,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ else if( c==')' ){ nParen--; if( nParen==0 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; i++; break; } }else if( c==',' && nParen==1 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; }else if( c=='"' || c=='\'' || c=='`' ){ @@ -221082,6 +222413,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){ for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } +#else + UNUSED_PARAMETER2(zBase,z); #endif } @@ -221666,7 +222999,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ "(%d, %Q), " "(%d, %Q), " "(%d, %d), " - "(%d, %d), " + "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " @@ -222024,6 +223357,7 @@ static void rbuIndexCntFunc( sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); + UNUSED_PARAMETER(nVal); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " @@ -222299,7 +223633,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( ){ if( zTarget==0 ){ return rbuMisuseError(); } if( zState ){ - int n = strlen(zState); + size_t n = strlen(zState); if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ return rbuMisuseError(); } @@ -222516,6 +223850,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ */ static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ int rc = SQLITE_OK; + UNUSED_PARAMETER(pArg); #if defined(_WIN32_WCE) { LPWSTR zWideOld; @@ -223420,6 +224755,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(a); + UNUSED_PARAMETER(b); return 0; } @@ -223818,6 +225156,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->orderByConsumed = 1; pIdxInfo->idxNum |= 0x08; } + pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX; return SQLITE_OK; } @@ -224475,7 +225814,13 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; } ** ** The data field of sqlite_dbpage table can be updated. The new ** value must be a BLOB which is the correct page size, otherwise the -** update fails. Rows may not be deleted or inserted. +** update fails. INSERT operations also work, and operate as if they +** where REPLACE. The size of the database can be extended by INSERT-ing +** new pages on the end. +** +** Rows may not be deleted. However, doing an INSERT to page number N +** with NULL page data causes the N-th page and all subsequent pages to be +** deleted and the database to be truncated. */ /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ @@ -224498,6 +225843,8 @@ struct DbpageCursor { struct DbpageTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database */ + int iDbTrunc; /* Database to truncate */ + Pgno pgnoTrunc; /* Size to truncate to */ }; /* Columns */ @@ -224506,7 +225853,6 @@ struct DbpageTable { #define DBPAGE_COLUMN_SCHEMA 2 - /* ** Connect to or create a dbpagevfs virtual table. */ @@ -224768,11 +226114,11 @@ static int dbpageUpdate( DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; - const char *zSchema; int iDb; Btree *pBt; Pager *pPager; int szPage; + int isInsert; (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ @@ -224783,21 +226129,29 @@ static int dbpageUpdate( zErr = "cannot delete"; goto update_fail; } - pgno = sqlite3_value_int(argv[0]); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (Pgno)sqlite3_value_int(argv[1])!=pgno - ){ - zErr = "cannot insert"; - goto update_fail; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + pgno = (Pgno)sqlite3_value_int(argv[2]); + isInsert = 1; + }else{ + pgno = sqlite3_value_int(argv[0]); + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ + zErr = "cannot insert"; + goto update_fail; + } + isInsert = 0; } - zSchema = (const char*)sqlite3_value_text(argv[4]); - iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; - if( NEVER(iDb<0) ){ - zErr = "no such schema"; - goto update_fail; + if( sqlite3_value_type(argv[4])==SQLITE_NULL ){ + iDb = 0; + }else{ + const char *zSchema = (const char*)sqlite3_value_text(argv[4]); + iDb = sqlite3FindDbName(pTab->db, zSchema); + if( iDb<0 ){ + zErr = "no such schema"; + goto update_fail; + } } pBt = pTab->db->aDb[iDb].pBt; - if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ + if( pgno<1 || NEVER(pBt==0) ){ zErr = "bad page number"; goto update_fail; } @@ -224805,18 +226159,25 @@ static int dbpageUpdate( if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ - zErr = "bad page value"; - goto update_fail; + if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ + /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and + ** all subsequent pages to be deleted. */ + pTab->iDbTrunc = iDb; + pgno--; + pTab->pgnoTrunc = pgno; + }else{ + zErr = "bad page value"; + goto update_fail; + } } pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ const void *pData = sqlite3_value_blob(argv[3]); - assert( pData!=0 || pTab->db->mallocFailed ); - if( pData - && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK - ){ - memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); + if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){ + unsigned char *aPage = sqlite3PagerGetData(pDbPage); + memcpy(aPage, pData, szPage); + pTab->pgnoTrunc = 0; } } sqlite3PagerUnref(pDbPage); @@ -224840,9 +226201,31 @@ static int dbpageBegin(sqlite3_vtab *pVtab){ Btree *pBt = db->aDb[i].pBt; if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); } + pTab->pgnoTrunc = 0; return SQLITE_OK; } +/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT +*/ +static int dbpageSync(sqlite3_vtab *pVtab){ + DbpageTable *pTab = (DbpageTable *)pVtab; + if( pTab->pgnoTrunc>0 ){ + Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + } + pTab->pgnoTrunc = 0; + return SQLITE_OK; +} + +/* Cancel any pending truncate. +*/ +static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ + DbpageTable *pTab = (DbpageTable *)pVtab; + pTab->pgnoTrunc = 0; + (void)notUsed1; + return SQLITE_OK; +} /* ** Invoke this routine to register the "dbpage" virtual table module @@ -224864,14 +226247,14 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ dbpageRowid, /* xRowid - read data */ dbpageUpdate, /* xUpdate */ dbpageBegin, /* xBegin */ - 0, /* xSync */ + dbpageSync, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0, /* xRollbackTo */ + dbpageRollbackTo, /* xRollbackTo */ 0, /* xShadowName */ 0 /* xIntegrity */ }; @@ -224959,6 +226342,10 @@ struct SessionBuffer { ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. ** sqlite3changeset_start_strm()). +** +** bNoDiscard: +** If true, then the only time data is discarded is as a result of explicit +** sessionDiscardData() calls. Not within every sessionInputBuffer() call. */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ @@ -226642,16 +228029,19 @@ static void sessionPreupdateOneChange( for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); - assert( trc==SQLITE_OK ); + /* This may fail if the column has a non-NULL default and was added + ** using ALTER TABLE ADD COLUMN after this record was created. */ + rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); } - /* This may fail if SQLite value p contains a utf-16 string that must - ** be converted to utf-8 and an OOM error occurs while doing so. */ - rc = sessionSerializeValue(0, p, &nByte); + if( rc==SQLITE_OK ){ + /* This may fail if SQLite value p contains a utf-16 string that must + ** be converted to utf-8 and an OOM error occurs while doing so. */ + rc = sessionSerializeValue(0, p, &nByte); + } if( rc!=SQLITE_OK ) goto error_out; } if( pTab->bRowid ){ @@ -230009,15 +231399,21 @@ static int sessionChangesetApply( int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; + u64 savedFlag = db->flags & SQLITE_FkNoAction; assert( xConflict!=0 ); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); - sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } @@ -230179,6 +231575,12 @@ static int sessionChangesetApply( sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_free((char*)sApply.rebase.aBuf); + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -230207,12 +231609,6 @@ SQLITE_API int sqlite3changeset_apply_v2( sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); - u64 savedFlag = db->flags & SQLITE_FkNoAction; - - if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ - db->flags |= ((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } if( rc==SQLITE_OK ){ rc = sessionChangesetApply( @@ -230220,11 +231616,6 @@ SQLITE_API int sqlite3changeset_apply_v2( ); } - if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ - assert( db->flags & SQLITE_FkNoAction ); - db->flags &= ~((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } return rc; } @@ -230545,6 +231936,9 @@ static int sessionChangesetExtendRecord( sessionAppendBlob(pOut, aRec, nRec, &rc); if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){ + rc = sqlite3_errcode(pGrp->db); + } } for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ int eType = sqlite3_column_type(pTab->pDfltStmt, ii); @@ -230561,6 +231955,7 @@ static int sessionChangesetExtendRecord( } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + pOut->nBuf += 8; } break; } @@ -230700,6 +232095,8 @@ static int sessionOneChangeToHash( u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; + assert( nRec>0 ); + /* Ensure that only changesets, or only patchsets, but not a mixture ** of both, are being combined. It is an error to try to combine a ** changeset and a patchset. */ @@ -230777,6 +232174,7 @@ static int sessionChangesetToHash( int nRec; int rc = SQLITE_OK; + pIter->in.bNoDiscard = 1; while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ rc = sessionOneChangeToHash(pGrp, pIter, bRebase); if( rc!=SQLITE_OK ) break; @@ -231658,6 +233056,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -231724,9 +233126,32 @@ struct Fts5PhraseIter { ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -231768,6 +233193,15 @@ struct Fts5ExtensionApi { const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -231788,7 +233222,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -231812,7 +233246,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -231836,6 +233270,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -231859,6 +233300,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
    +**
  • There is no "iVersion" field, and +**
  • The xTokenize() method does not take a locale argument. +**
+** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -231967,6 +233432,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -231986,6 +233478,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -232005,7 +233498,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -232032,6 +233525,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -232105,6 +233617,22 @@ typedef sqlite3_uint64 u64; # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +#endif + #endif /* Truncate very long tokens to this many bytes. Hard limit is @@ -232188,6 +233716,18 @@ struct Fts5Colset { */ typedef struct Fts5Config Fts5Config; +typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; + +struct Fts5TokenizerConfig { + Fts5Tokenizer *pTok; + fts5_tokenizer_v2 *pApi2; + fts5_tokenizer *pApi1; + const char **azArg; + int nArg; + int ePattern; /* FTS_PATTERN_XXX constant */ + const char *pLocale; /* Current locale to use */ + int nLocale; /* Size of pLocale in bytes */ +}; /* ** An instance of the following structure encodes all information that can @@ -232227,9 +233767,12 @@ typedef struct Fts5Config Fts5Config; ** ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); ** +** bLocale: +** Set to true if locale=1 was specified when the table was created. */ struct Fts5Config { sqlite3 *db; /* Database handle */ + Fts5Global *pGlobal; /* Global fts5 object for handle db */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ @@ -232239,16 +233782,17 @@ struct Fts5Config { int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ + int bContentlessUnindexed; /* "contentless_unindexed=" option (dflt=0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int bTokendata; /* "tokendata=" option value (dflt==0) */ + int bLocale; /* "locale=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; - Fts5Tokenizer *pTok; - fts5_tokenizer *pTokApi; + Fts5TokenizerConfig t; int bLock; /* True when table is preparing statement */ - int ePattern; /* FTS_PATTERN_XXX constant */ + /* Values loaded from the %_config table */ int iVersion; /* fts5 file format 'version' */ @@ -232277,9 +233821,10 @@ struct Fts5Config { #define FTS5_CURRENT_VERSION 4 #define FTS5_CURRENT_VERSION_SECUREDELETE 5 -#define FTS5_CONTENT_NORMAL 0 -#define FTS5_CONTENT_NONE 1 -#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_NORMAL 0 +#define FTS5_CONTENT_NONE 1 +#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_UNINDEXED 3 #define FTS5_DETAIL_FULL 0 #define FTS5_DETAIL_NONE 1 @@ -232314,6 +233859,8 @@ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, i static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...); + /* ** End of interface to code in fts5_config.c. **************************************************************************/ @@ -232358,7 +233905,7 @@ static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); static void sqlite3Fts5Put32(u8*, int); static int sqlite3Fts5Get32(const u8*); -#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) +#define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF) #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; @@ -232643,18 +234190,20 @@ struct Fts5Table { Fts5Index *pIndex; /* Full-text index */ }; -static int sqlite3Fts5GetTokenizer( - Fts5Global*, - const char **azArg, - int nArg, - Fts5Config*, - char **pzErr -); +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); static int sqlite3Fts5FlushToDisk(Fts5Table*); +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig); +static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc); + +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal); +static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal, + const char **ppText, int *pnText, const char **ppLoc, int *pnLoc +); + /* ** End of interface to code in fts5.c. **************************************************************************/ @@ -232734,8 +234283,8 @@ static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); static int sqlite3Fts5DropAll(Fts5Config*); static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); -static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); +static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int); +static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, int, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); @@ -232760,6 +234309,9 @@ static int sqlite3Fts5StorageOptimize(Fts5Storage *p); static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); static int sqlite3Fts5StorageReset(Fts5Storage *p); +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*); +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel); + /* ** End of interface to code in fts5_storage.c. **************************************************************************/ @@ -232912,6 +234464,7 @@ static int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -234689,6 +236242,7 @@ static int fts5HighlightCb( return rc; } + /* ** Implementation of highlight() function. */ @@ -234719,12 +236273,19 @@ static void fts5HighlightFunction( sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); rc = SQLITE_OK; }else if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iCol */ + int nLoc = 0; /* Size of pLoc in bytes */ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -234921,6 +236482,8 @@ static void fts5SnippetFunction( memset(&sFinder, 0, sizeof(Fts5SFinder)); for(i=0; ixColumnText(pFts, i, &sFinder.zDoc, &nDoc); if( rc!=SQLITE_OK ) break; - rc = pApi->xTokenize(pFts, - sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb + rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc); + if( rc!=SQLITE_OK ) break; + rc = pApi->xTokenize_v2(pFts, + sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb ); if( rc!=SQLITE_OK ) break; rc = pApi->xColumnSize(pFts, i, &nDocsize); @@ -234987,6 +236552,9 @@ static void fts5SnippetFunction( rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); } if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iBestCol */ + int nLoc = 0; /* Bytes in pLoc */ + if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } @@ -235005,7 +236573,12 @@ static void fts5SnippetFunction( } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -235189,6 +236762,53 @@ static void fts5Bm25Function( } } +/* +** Implementation of fts5_get_locale() function. +*/ +static void fts5GetLocaleFunction( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + sqlite3_context *pCtx, /* Context for returning result/error */ + int nVal, /* Number of values in apVal[] array */ + sqlite3_value **apVal /* Array of trailing arguments */ +){ + int iCol = 0; + int eType = 0; + int rc = SQLITE_OK; + const char *zLocale = 0; + int nLocale = 0; + + /* xColumnLocale() must be available */ + assert( pApi->iVersion>=4 ); + + if( nVal!=1 ){ + const char *z = "wrong number of arguments to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + eType = sqlite3_value_numeric_type(apVal[0]); + if( eType!=SQLITE_INTEGER ){ + const char *z = "non-integer argument passed to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + iCol = sqlite3_value_int(apVal[0]); + if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ + sqlite3_result_error_code(pCtx, SQLITE_RANGE); + return; + } + + rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + return; + } + + sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT); +} + static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ @@ -235196,9 +236816,10 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ fts5_extension_function xFunc;/* Callback function */ void (*xDestroy)(void*); /* Destructor function */ } aBuiltin [] = { - { "snippet", 0, fts5SnippetFunction, 0 }, - { "highlight", 0, fts5HighlightFunction, 0 }, - { "bm25", 0, fts5Bm25Function, 0 }, + { "snippet", 0, fts5SnippetFunction, 0 }, + { "highlight", 0, fts5HighlightFunction, 0 }, + { "bm25", 0, fts5Bm25Function, 0 }, + { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 }, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ @@ -235863,7 +237484,6 @@ static int fts5ConfigSetEnum( ** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( - Fts5Global *pGlobal, Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ @@ -235871,6 +237491,7 @@ static int fts5ConfigParseSpecial( ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); + if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; @@ -235927,12 +237548,11 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; - char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); - char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); - char *pSpace = pDel; + char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); - if( azArg && pSpace ){ - if( pConfig->pTok ){ + if( azArg ){ + char *pSpace = (char*)&azArg[nArg]; + if( pConfig->t.azArg ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ @@ -235955,16 +237575,14 @@ static int fts5ConfigParseSpecial( *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ - rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, pConfig, - pzErr - ); + pConfig->t.azArg = (const char**)azArg; + pConfig->t.nArg = nArg; + azArg = 0; } } } - sqlite3_free(azArg); - sqlite3_free(pDel); + return rc; } @@ -235993,6 +237611,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("contentless_unindexed", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bContentlessUnindexed = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); @@ -236013,6 +237641,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed locale=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bLocale = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, @@ -236041,16 +237679,6 @@ static int fts5ConfigParseSpecial( return SQLITE_ERROR; } -/* -** Allocate an instance of the default tokenizer ("simple") at -** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error -** code if an error occurs. -*/ -static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ - assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); -} - /* ** Gobble up the first bareword or quoted word from the input buffer zIn. ** Return a pointer to the character immediately following the last in @@ -236110,7 +237738,8 @@ static int fts5ConfigParseColumn( Fts5Config *p, char *zCol, char *zArg, - char **pzErr + char **pzErr, + int *pbUnindexed ){ int rc = SQLITE_OK; if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) @@ -236121,6 +237750,7 @@ static int fts5ConfigParseColumn( }else if( zArg ){ if( 0==sqlite3_stricmp(zArg, "unindexed") ){ p->abUnindexed[p->nCol] = 1; + *pbUnindexed = 1; }else{ *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); rc = SQLITE_ERROR; @@ -236141,11 +237771,26 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); if( p->eContent!=FTS5_CONTENT_NONE ){ + assert( p->eContent==FTS5_CONTENT_EXTERNAL + || p->eContent==FTS5_CONTENT_NORMAL + || p->eContent==FTS5_CONTENT_UNINDEXED + ); for(i=0; inCol; i++){ if( p->eContent==FTS5_CONTENT_EXTERNAL ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); - }else{ + }else if( p->eContent==FTS5_CONTENT_NORMAL || p->abUnindexed[i] ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); + } + } + } + if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){ + for(i=0; inCol; i++){ + if( p->abUnindexed[i]==0 ){ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); } } } @@ -236179,10 +237824,12 @@ static int sqlite3Fts5ConfigParse( Fts5Config *pRet; /* New object to return */ int i; sqlite3_int64 nByte; + int bUnindexed = 0; /* True if there are one or more UNINDEXED */ *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); + pRet->pGlobal = pGlobal; pRet->db = db; pRet->iCookie = -1; @@ -236231,13 +237878,13 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; }else{ if( bOption ){ - rc = fts5ConfigParseSpecial(pGlobal, pRet, + rc = fts5ConfigParseSpecial(pRet, ALWAYS(zOne)?zOne:"", zTwo?zTwo:"", pzErr ); }else{ - rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); + rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr, &bUnindexed); zOne = 0; } } @@ -236269,11 +237916,17 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; } - /* If a tokenizer= option was successfully parsed, the tokenizer has - ** already been allocated. Otherwise, allocate an instance of the default - ** tokenizer (unicode61) now. */ - if( rc==SQLITE_OK && pRet->pTok==0 ){ - rc = fts5ConfigDefaultTokenizer(pGlobal, pRet); + /* We only allow contentless_unindexed=1 if the table is actually a + ** contentless one. + */ + if( rc==SQLITE_OK + && pRet->bContentlessUnindexed + && pRet->eContent!=FTS5_CONTENT_NONE + ){ + *pzErr = sqlite3_mprintf( + "contentless_unindexed=1 requires a contentless table" + ); + rc = SQLITE_ERROR; } /* If no zContent option was specified, fill in the default values. */ @@ -236284,6 +237937,9 @@ static int sqlite3Fts5ConfigParse( ); if( pRet->eContent==FTS5_CONTENT_NORMAL ){ zTail = "content"; + }else if( bUnindexed && pRet->bContentlessUnindexed ){ + pRet->eContent = FTS5_CONTENT_UNINDEXED; + zTail = "content"; }else if( pRet->bColumnsize ){ zTail = "docsize"; } @@ -236317,9 +237973,14 @@ static int sqlite3Fts5ConfigParse( static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; - if( pConfig->pTok ){ - pConfig->pTokApi->xDelete(pConfig->pTok); + if( pConfig->t.pTok ){ + if( pConfig->t.pApi1 ){ + pConfig->t.pApi1->xDelete(pConfig->t.pTok); + }else{ + pConfig->t.pApi2->xDelete(pConfig->t.pTok); + } } + sqlite3_free((char*)pConfig->t.azArg); sqlite3_free(pConfig->zDb); sqlite3_free(pConfig->zName); for(i=0; inCol; i++){ @@ -236394,10 +238055,24 @@ static int sqlite3Fts5Tokenize( void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ - if( pText==0 ) return SQLITE_OK; - return pConfig->pTokApi->xTokenize( - pConfig->pTok, pCtx, flags, pText, nText, xToken - ); + int rc = SQLITE_OK; + if( pText ){ + if( pConfig->t.pTok==0 ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } + if( rc==SQLITE_OK ){ + if( pConfig->t.pApi1 ){ + rc = pConfig->t.pApi1->xTokenize( + pConfig->t.pTok, pCtx, flags, pText, nText, xToken + ); + }else{ + rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags, + pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken + ); + } + } + } + return rc; } /* @@ -236651,13 +238326,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ rc = SQLITE_ERROR; - if( pConfig->pzErrmsg ){ - assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " - "(found %d, expected %d or %d) - run 'rebuild'", - iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE - ); - } + sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format " + "(found %d, expected %d or %d) - run 'rebuild'", + iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE + ); }else{ pConfig->iVersion = iVersion; } @@ -236668,6 +238340,29 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ return rc; } +/* +** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer +** containing the error message created using printf() style formatting +** string zFmt and its trailing arguments. +*/ +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ + va_list ap; /* ... printf arguments */ + char *zMsg = 0; + + va_start(ap, zFmt); + zMsg = sqlite3_vmprintf(zFmt, ap); + if( pConfig->pzErrmsg ){ + assert( *pConfig->pzErrmsg==0 ); + *pConfig->pzErrmsg = zMsg; + }else{ + sqlite3_free(zMsg); + } + + va_end(ap); +} + + + /* ** 2014 May 31 ** @@ -236724,7 +238419,7 @@ struct Fts5Expr { /* ** eType: -** Expression node type. Always one of: +** Expression node type. Usually one of: ** ** FTS5_AND (nChild, apChild valid) ** FTS5_OR (nChild, apChild valid) @@ -236732,6 +238427,10 @@ struct Fts5Expr { ** FTS5_STRING (pNear valid) ** FTS5_TERM (pNear valid) ** +** An expression node with eType==0 may also exist. It always matches zero +** rows. This is created when a phrase containing no tokens is parsed. +** e.g. "". +** ** iHeight: ** Distance from this node to furthest leaf. This is always 0 for nodes ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one @@ -236952,11 +238651,12 @@ static int sqlite3Fts5ExprNew( }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); + assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ - if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ + if( sParse.rc==SQLITE_OK && iColnCol ){ int n = sizeof(Fts5Colset); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ @@ -236973,15 +238673,7 @@ static int sqlite3Fts5ExprNew( sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ - if( !sParse.pExpr ){ - const int nByte = sizeof(Fts5ExprNode); - pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); - if( pNew->pRoot ){ - pNew->pRoot->bEof = 1; - } - }else{ - pNew->pRoot = sParse.pExpr; - } + pNew->pRoot = sParse.pExpr; pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; @@ -237799,7 +239491,7 @@ static int fts5ExprNodeTest_STRING( } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; - if( pIter->iRowid==iLast || pIter->bEof ) continue; + if( pIter->iRowid==iLast ) continue; bMatch = 0; if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ return rc; @@ -238321,9 +240013,6 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ - if( pPhrase==0 ){ - return pNear; - } if( pNear==0 ){ sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); @@ -238545,6 +240234,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } + assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } @@ -238564,7 +240254,7 @@ static int sqlite3Fts5ExprClonePhrase( Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ - if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){ rc = SQLITE_RANGE; }else{ pOrig = pExpr->apExprPhrase[iPhrase]; @@ -238932,6 +240622,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ } } +/* +** Add pSub as a child of p. +*/ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ @@ -239076,19 +240769,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; + pNear = 0; + assert( pLeft==0 && pRight==0 ); } } }else{ + assert( pNear==0 ); fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); + pLeft = pRight = 0; if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ sqlite3Fts5ParseError(pParse, "fts5 expression tree is too large (maximum depth %d)", SQLITE_FTS5_MAX_EXPR_DEPTH ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } @@ -239140,6 +240837,8 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( ); if( pRight->eType==FTS5_EOF ){ + assert( pParse->apPhrase!=0 ); + assert( pParse->nPhrase>0 ); assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; @@ -239772,6 +241471,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ pNode->iRowid = iRowid; pNode->bEof = 0; switch( pNode->eType ){ + case 0: case FTS5_TERM: case FTS5_STRING: return (pNode->pNear->apPhrase[0]->poslist.n>0); @@ -241355,11 +243055,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); - sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + int szData = (sizeof(Fts5Data) + 7) & ~7; + sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; - aOut = pRet->p = (u8*)&pRet[1]; + aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; } @@ -241382,6 +243083,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); + assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); return pRet; } @@ -242707,7 +244409,7 @@ static void fts5SegIterNext_None( if( iOffiEndofDoclist ){ /* Next entry is on the current page */ - i64 iDelta; + u64 iDelta; iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); pIter->iLeafOffset = iOff; pIter->iRowid += iDelta; @@ -245411,6 +247113,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ nBest = nPercent; } } + + /* If pLvl is already the input level to an ongoing merge, look no + ** further for a merge candidate. The caller should be allowed to + ** continue merging from pLvl first. */ + if( pLvl->nMerge ) break; } } return iRet; @@ -249335,7 +251042,7 @@ static int fts5structConnectMethod( /* ** We must have a single struct=? constraint that will be passed through -** into the xFilter method. If there is no valid stmt=? constraint, +** into the xFilter method. If there is no valid struct=? constraint, ** then return an SQLITE_CONSTRAINT error. */ static int fts5structBestIndexMethod( @@ -249677,8 +251384,17 @@ struct Fts5Global { Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ Fts5Cursor *pCsr; /* First in list of all open cursors */ + u32 aLocaleHdr[4]; }; +/* +** Size of header on fts5_locale() values. And macro to access a buffer +** containing a copy of the header from an Fts5Config pointer. +*/ +#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) +#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) + + /* ** Each auxiliary function registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part @@ -249697,11 +251413,28 @@ struct Fts5Auxiliary { ** Each tokenizer module registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pTok list. +** +** bV2Native: +** True if the tokenizer was registered using xCreateTokenizer_v2(), false +** for xCreateTokenizer(). If this variable is true, then x2 is populated +** with the routines as supplied by the caller and x1 contains synthesized +** wrapper routines. In this case the user-data pointer passed to +** x1.xCreate should be a pointer to the Fts5TokenizerModule structure, +** not a copy of pUserData. +** +** Of course, if bV2Native is false, then x1 contains the real routines and +** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule +** object should be passed to x2.xCreate. +** +** The synthesized wrapper routines are necessary for xFindTokenizer(_v2) +** calls. */ struct Fts5TokenizerModule { char *zName; /* Name of tokenizer */ void *pUserData; /* User pointer passed to xCreate() */ - fts5_tokenizer x; /* Tokenizer functions */ + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ void (*xDestroy)(void*); /* Destructor function */ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ }; @@ -249789,7 +251522,7 @@ struct Fts5Cursor { Fts5Auxiliary *pAux; /* Currently executing extension function */ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ - /* Cache used by auxiliary functions xInst() and xInstCount() */ + /* Cache used by auxiliary API functions xInst() and xInstCount() */ Fts5PoslistReader *aInstIter; /* One for each phrase */ int nInstAlloc; /* Size of aInst[] array (entries / 3) */ int nInstCount; /* Number of phrase instances */ @@ -249900,10 +251633,16 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ #endif /* -** Return true if pTab is a contentless table. +** Return true if pTab is a contentless table. If parameter bIncludeUnindexed +** is true, this includes contentless tables that store UNINDEXED columns +** only. */ -static int fts5IsContentless(Fts5FullTable *pTab){ - return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE; +static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){ + int eContent = pTab->p.pConfig->eContent; + return ( + eContent==FTS5_CONTENT_NONE + || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED) + ); } /* @@ -249971,8 +251710,12 @@ static int fts5InitVtab( assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ + pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; + if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } } /* Open the index sub-system */ @@ -249994,11 +251737,7 @@ static int fts5InitVtab( /* Load the initial configuration */ if( rc==SQLITE_OK ){ - assert( pConfig->pzErrmsg==0 ); - pConfig->pzErrmsg = pzErr; - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - sqlite3Fts5IndexRollback(pTab->p.pIndex); - pConfig->pzErrmsg = 0; + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1); } if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -250008,6 +251747,7 @@ static int fts5InitVtab( rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } + if( pConfig ) pConfig->pzErrmsg = 0; if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -250075,10 +251815,10 @@ static int fts5UsePatternMatch( ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); - if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ return 1; } - if( pConfig->ePattern==FTS5_PATTERN_LIKE + if( pConfig->t.ePattern==FTS5_PATTERN_LIKE && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) ){ return 1; @@ -250125,10 +251865,10 @@ static int fts5UsePatternMatch( ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** -** Costs are assigned as follows: +** If an unusable MATCH operator is present in the WHERE clause, then +** SQLITE_CONSTRAINT is returned. ** -** a) If an unusable MATCH operator is present in the WHERE clause, the -** cost is unconditionally set to 1e50 (a really big number). +** Costs are assigned as follows: ** ** a) If a MATCH operator is present, the cost depends on the other ** constraints also present. As follows: @@ -250161,7 +251901,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; - int bSeenMatch = 0; + int nSeenMatch = 0; int bSeenRank = 0; @@ -250192,18 +251932,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an - ** unusable plan. Set a prohibitively high cost. */ - pInfo->estimatedCost = 1e50; - assert( iIdxStr < pInfo->nConstraint*6 + 1 ); - idxStr[iIdxStr] = 0; - return SQLITE_OK; + ** unusable plan. Return SQLITE_CONSTRAINT. */ + return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; - }else if( iCol>=0 ){ - bSeenMatch = 1; + }else{ + nSeenMatch++; idxStr[iIdxStr++] = 'M'; sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); @@ -250220,6 +251957,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ idxStr += strlen(&idxStr[iIdxStr]); pInfo->aConstraintUsage[i].argvIndex = ++iCons; assert( idxStr[iIdxStr]=='\0' ); + nSeenMatch++; }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; @@ -250256,7 +251994,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; - if( iSort==(pConfig->nCol+1) && bSeenMatch ){ + if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){ idxFlags |= FTS5_BI_ORDER_RANK; }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; @@ -250271,14 +252009,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ - pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; - if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); + pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0; + if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo); }else if( bSeenLt && bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; + pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0; }else if( bSeenLt || bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; + pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0; }else{ - pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; + pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0; + } + for(i=1; iestimatedCost *= 0.4; } pInfo->idxNum = idxFlags; @@ -250554,6 +252295,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ } }else{ rc = SQLITE_OK; + CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE); } break; } @@ -250583,7 +252325,7 @@ static int fts5PrepareStatement( rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ - *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); + sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db)); } sqlite3_free(zSql); } @@ -250807,6 +252549,145 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ return iDefault; } +/* +** Set the error message on the virtual table passed as the first argument. +*/ +static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ + va_list ap; /* ... printf arguments */ + va_start(ap, zFormat); + sqlite3_free(p->p.base.zErrMsg); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale +** specified by pLocale/nLocale. The buffer indicated by pLocale must remain +** valid until after the final call to sqlite3Fts5Tokenize() that will use +** the locale. +*/ +static void sqlite3Fts5SetLocale( + Fts5Config *pConfig, + const char *zLocale, + int nLocale +){ + Fts5TokenizerConfig *pT = &pConfig->t; + pT->pLocale = zLocale; + pT->nLocale = nLocale; +} + +/* +** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale(). +*/ +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){ + sqlite3Fts5SetLocale(pConfig, 0, 0); +} + +/* +** Return true if the value passed as the only argument is an +** fts5_locale() value. +*/ +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){ + int ret = 0; + if( sqlite3_value_type(pVal)==SQLITE_BLOB ){ + /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case. + ** If the blob was created using zeroblob(), then sqlite3_value_blob() + ** may call malloc(). If this malloc() fails, then the values returned + ** by both value_blob() and value_bytes() will be 0. If value_bytes() were + ** called first, then the NULL pointer returned by value_blob() might + ** be dereferenced. */ + const u8 *pBlob = sqlite3_value_blob(pVal); + int nBlob = sqlite3_value_bytes(pVal); + if( nBlob>FTS5_LOCALE_HDR_SIZE + && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE) + ){ + ret = 1; + } + } + return ret; +} + +/* +** Value pVal is guaranteed to be an fts5_locale() value, according to +** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale +** from the value and returns them separately. +** +** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set +** to point to buffers containing the text and locale, as utf-8, +** respectively. In this case output parameters (*pnText) and (*pnLoc) are +** set to the sizes in bytes of these two buffers. +** +** Or, if an error occurs, then an SQLite error code is returned. The final +** value of the four output parameters is undefined in this case. +*/ +static int sqlite3Fts5DecodeLocaleValue( + sqlite3_value *pVal, + const char **ppText, + int *pnText, + const char **ppLoc, + int *pnLoc +){ + const char *p = sqlite3_value_blob(pVal); + int n = sqlite3_value_bytes(pVal); + int nLoc = 0; + + assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); + assert( n>FTS5_LOCALE_HDR_SIZE ); + + for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){ + if( nLoc==(n-1) ){ + return SQLITE_MISMATCH; + } + } + *ppLoc = &p[FTS5_LOCALE_HDR_SIZE]; + *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE; + + *ppText = &p[nLoc+1]; + *pnText = n - nLoc - 1; + return SQLITE_OK; +} + +/* +** Argument pVal is the text of a full-text search expression. It may or +** may not have been wrapped by fts5_locale(). This function extracts +** the text of the expression, and sets output variable (*pzText) to +** point to a nul-terminated buffer containing the expression. +** +** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called +** to set the tokenizer to use the specified locale. +** +** If output variable (*pbFreeAndReset) is set to true, then the caller +** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer +** locale, and (b) call sqlite3_free() to free (*pzText). +*/ +static int fts5ExtractExprText( + Fts5Config *pConfig, /* Fts5 configuration */ + sqlite3_value *pVal, /* Value to extract expression text from */ + char **pzText, /* OUT: nul-terminated buffer of text */ + int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */ +){ + int rc = SQLITE_OK; + + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText); + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + } + *pbFreeAndReset = 1; + }else{ + *pzText = (char*)sqlite3_value_text(pVal); + *pbFreeAndReset = 0; + } + + return rc; +} + + /* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional @@ -250841,13 +252722,7 @@ static int fts5FilterMethod( int iIdxStr = 0; Fts5Expr *pExpr = 0; - if( pConfig->bLock ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "recursively defined fts5 content table" - ); - return SQLITE_ERROR; - } - + assert( pConfig->bLock==0 ); if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); @@ -250871,8 +252746,14 @@ static int fts5FilterMethod( pRank = apVal[i]; break; case 'M': { - const char *zText = (const char*)sqlite3_value_text(apVal[i]); + char *zText = 0; + int bFreeAndReset = 0; + int bInternal = 0; + + rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); + if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + iCol = 0; do{ iCol = iCol*10 + (idxStr[iIdxStr]-'0'); @@ -250884,7 +252765,7 @@ static int fts5FilterMethod( ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); - goto filter_out; + bInternal = 1; }else{ char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); @@ -250892,9 +252773,15 @@ static int fts5FilterMethod( rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } - if( rc!=SQLITE_OK ) goto filter_out; } + if( bFreeAndReset ){ + sqlite3_free(zText); + sqlite3Fts5ClearLocale(pConfig); + } + + if( bInternal || rc!=SQLITE_OK ) goto filter_out; + break; } case 'L': @@ -250982,9 +252869,7 @@ static int fts5FilterMethod( } } }else if( pConfig->zContent==0 ){ - *pConfig->pzErrmsg = sqlite3_mprintf( - "%s: table does not support scanning", pConfig->zName - ); + fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup @@ -251027,9 +252912,13 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ assert( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE + || pCsr->ePlan==FTS5_PLAN_SCAN + || pCsr->ePlan==FTS5_PLAN_ROWID ); if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; + }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){ + return sqlite3_column_int64(pCsr->pStmt, 0); }else{ return sqlite3Fts5ExprRowid(pCsr->pExpr); } @@ -251046,25 +252935,16 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ int ePlan = pCsr->ePlan; assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); - switch( ePlan ){ - case FTS5_PLAN_SPECIAL: - *pRowid = 0; - break; - - case FTS5_PLAN_SOURCE: - case FTS5_PLAN_MATCH: - case FTS5_PLAN_SORTED_MATCH: - *pRowid = fts5CursorRowid(pCsr); - break; - - default: - *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); - break; + if( ePlan==FTS5_PLAN_SPECIAL ){ + *pRowid = 0; + }else{ + *pRowid = fts5CursorRowid(pCsr); } return SQLITE_OK; } + /* ** If the cursor requires seeking (bSeekRequired flag is set), seek it. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. @@ -251101,8 +252981,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; + fts5SetVtabError((Fts5FullTable*)pTab, + "fts5: missing row %lld from content table %s", + fts5CursorRowid(pCsr), + pTab->pConfig->zContent + ); }else if( pTab->pConfig->pzErrmsg ){ - *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + fts5SetVtabError((Fts5FullTable*)pTab, "%s", sqlite3_errmsg(pTab->pConfig->db) ); } @@ -251111,14 +252996,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ return rc; } -static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ - va_list ap; /* ... printf arguments */ - va_start(ap, zFormat); - assert( p->p.base.zErrMsg==0 ); - p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); - va_end(ap); -} - /* ** This function is called to handle an FTS INSERT command. In other words, ** an INSERT statement of the form: @@ -251156,7 +253033,7 @@ static int fts5SpecialInsert( } bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ - if( pConfig->eContent==FTS5_CONTENT_NONE ){ + if( fts5IsContentless(pTab, 1) ){ fts5SetVtabError(pTab, "'rebuild' may not be used with a contentless fts5 table" ); @@ -251212,7 +253089,7 @@ static int fts5SpecialDelete( int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0); } return rc; } @@ -251225,7 +253102,7 @@ static void fts5StorageInsert( ){ int rc = *pRc; if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); @@ -251233,6 +253110,67 @@ static void fts5StorageInsert( *pRc = rc; } +/* +** +** This function is called when the user attempts an UPDATE on a contentless +** table. Parameter bRowidModified is true if the UPDATE statement modifies +** the rowid value. Parameter apVal[] contains the new values for each user +** defined column of the fts5 table. pConfig is the configuration object of the +** table being updated (guaranteed to be contentless). The contentless_delete=1 +** and contentless_unindexed=1 options may or may not be set. +** +** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite +** error code if it cannot. In this case an error message is also loaded into +** pConfig. Output parameter (*pbContent) is set to true if the caller should +** update the %_content table only - not the FTS index or any other shadow +** table. This occurs when an UPDATE modifies only UNINDEXED columns of the +** table. +** +** An UPDATE may proceed if: +** +** * The only columns modified are UNINDEXED columns, or +** +** * The contentless_delete=1 option was specified and all of the indexed +** columns (not a subset) have been modified. +*/ +static int fts5ContentlessUpdate( + Fts5Config *pConfig, + sqlite3_value **apVal, + int bRowidModified, + int *pbContent +){ + int ii; + int bSeenIndex = 0; /* Have seen modified indexed column */ + int bSeenIndexNC = 0; /* Have seen unmodified indexed column */ + int rc = SQLITE_OK; + + for(ii=0; iinCol; ii++){ + if( pConfig->abUnindexed[ii]==0 ){ + if( sqlite3_value_nochange(apVal[ii]) ){ + bSeenIndexNC++; + }else{ + bSeenIndex++; + } + } + } + + if( bSeenIndex==0 && bRowidModified==0 ){ + *pbContent = 1; + }else{ + if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){ + rc = SQLITE_ERROR; + sqlite3Fts5ConfigErrmsg(pConfig, + (pConfig->bContentlessDelete ? + "%s a subset of columns on fts5 contentless-delete table: %s" : + "%s contentless fts5 table: %s") + , "cannot UPDATE", pConfig->zName + ); + } + } + + return rc; +} + /* ** This function is the implementation of the xUpdate callback used by ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be @@ -251319,41 +253257,46 @@ static int fts5UpdateMethod( assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); - /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. Except - they are both supported if the CREATE - ** VIRTUAL TABLE statement contained "contentless_delete=1". */ - if( eType0==SQLITE_INTEGER - && pConfig->eContent==FTS5_CONTENT_NONE - && pConfig->bContentlessDelete==0 - ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "cannot %s contentless fts5 table: %s", - (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName - ); - rc = SQLITE_ERROR; - } - /* DELETE */ - else if( nArg==1 ){ - i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); - bUpdateOrDelete = 1; + if( nArg==1 ){ + /* It is only possible to DELETE from a contentless table if the + ** contentless_delete=1 flag is set. */ + if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){ + fts5SetVtabError(pTab, + "cannot DELETE from contentless fts5 table: %s", pConfig->zName + ); + rc = SQLITE_ERROR; + }else{ + i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); + bUpdateOrDelete = 1; + } } /* INSERT or UPDATE */ else{ int eType1 = sqlite3_value_numeric_type(apVal[1]); - if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ - rc = SQLITE_MISMATCH; + /* It is an error to write an fts5_locale() value to a table without + ** the locale=1 option. */ + if( pConfig->bLocale==0 ){ + int ii; + for(ii=0; iinCol; ii++){ + sqlite3_value *pVal = apVal[ii+2]; + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + fts5SetVtabError(pTab, "fts5_locale() requires locale=1"); + rc = SQLITE_MISMATCH; + goto update_out; + } + } } - else if( eType0!=SQLITE_INTEGER ){ + if( eType0!=SQLITE_INTEGER ){ /* An INSERT statement. If the conflict-mode is REPLACE, first remove ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); @@ -251361,30 +253304,57 @@ static int fts5UpdateMethod( /* UPDATE */ else{ + Fts5Storage *pStorage = pTab->pStorage; i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ - if( eType1==SQLITE_INTEGER && iOld!=iNew ){ + int bContent = 0; /* Content only update */ + + /* If this is a contentless table (including contentless_unindexed=1 + ** tables), check if the UPDATE may proceed. */ + if( fts5IsContentless(pTab, 1) ){ + rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent); + if( rc!=SQLITE_OK ) goto update_out; + } + + if( eType1!=SQLITE_INTEGER ){ + rc = SQLITE_MISMATCH; + }else if( iOld!=iNew ){ + assert( bContent==0 ); if( eConflict==SQLITE_REPLACE ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid); } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid); } } + }else if( bContent ){ + /* This occurs when an UPDATE on a contentless table affects *only* + ** UNINDEXED columns. This is a no-op for contentless_unindexed=0 + ** tables, or a write to the %_content table only for =1 tables. */ + assert( fts5IsContentless(pTab, 1) ); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid); + } }else{ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } bUpdateOrDelete = 1; + sqlite3Fts5StorageReleaseDeleteRow(pStorage); } + } } @@ -251401,6 +253371,7 @@ static int fts5UpdateMethod( } } + update_out: pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -251422,9 +253393,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); - fts5NewTransaction((Fts5FullTable*)pVtab); - return SQLITE_OK; + int rc = fts5NewTransaction((Fts5FullTable*)pVtab); + if( rc==SQLITE_OK ){ + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); + } + return rc; } /* @@ -251478,17 +253451,40 @@ static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } +/* +** Implementation of xTokenize_v2() API. +*/ +static int fts5ApiTokenize_v2( + Fts5Context *pCtx, + const char *pText, int nText, + const char *pLoc, int nLoc, + void *pUserData, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + int rc = SQLITE_OK; + + sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pTab->pConfig, + FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken + ); + sqlite3Fts5SetLocale(pTab->pConfig, 0, 0); + + return rc; +} + +/* +** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0 +** passed as the locale. +*/ static int fts5ApiTokenize( Fts5Context *pCtx, const char *pText, int nText, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ - Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - return sqlite3Fts5Tokenize( - pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken - ); + return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken); } static int fts5ApiPhraseCount(Fts5Context *pCtx){ @@ -251501,6 +253497,49 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); } +/* +** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This +** function extracts the text value of column iCol of the current row. +** Additionally, if there is an associated locale, it invokes +** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller +** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point +** after this function returns. +** +** If successful, (*ppText) is set to point to a buffer containing the text +** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that +** buffer in bytes. It is not guaranteed to be nul-terminated. If an error +** occurs, an SQLite error code is returned. The final values of the two +** output parameters are undefined in this case. +*/ +static int fts5TextFromStmt( + Fts5Config *pConfig, + sqlite3_stmt *pStmt, + int iCol, + const char **ppText, + int *pnText +){ + sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1); + const char *pLoc = 0; + int nLoc = 0; + int rc = SQLITE_OK; + + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc); + }else{ + *ppText = (const char*)sqlite3_value_text(pVal); + *pnText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol); + nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol); + } + } + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + return rc; +} + static int fts5ApiColumnText( Fts5Context *pCtx, int iCol, @@ -251510,28 +253549,35 @@ static int fts5ApiColumnText( int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); if( iCol<0 || iCol>=pTab->pConfig->nCol ){ rc = SQLITE_RANGE; - }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) - || pCsr->ePlan==FTS5_PLAN_SPECIAL - ){ + }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){ *pz = 0; *pn = 0; }else{ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ - *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1); - *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn); + sqlite3Fts5ClearLocale(pTab->pConfig); } } return rc; } +/* +** This is called by various API functions - xInst, xPhraseFirst, +** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase +** of the current row. This function works for both detail=full tables (in +** which case the position-list was read from the fts index) or for other +** detail= modes if the row content is available. +*/ static int fts5CsrPoslist( - Fts5Cursor *pCsr, - int iPhrase, - const u8 **pa, - int *pn + Fts5Cursor *pCsr, /* Fts5 cursor object */ + int iPhrase, /* Phrase to find position list for */ + const u8 **pa, /* OUT: Pointer to position list buffer */ + int *pn /* OUT: Size of (*pa) in bytes */ ){ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; int rc = SQLITE_OK; @@ -251539,20 +253585,32 @@ static int fts5CsrPoslist( if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ rc = SQLITE_RANGE; + }else if( pConfig->eDetail!=FTS5_DETAIL_FULL + && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + ){ + *pa = 0; + *pn = 0; + return SQLITE_OK; }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; + aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); if( aPopulator==0 ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK ){ + rc = fts5SeekCursor(pCsr, 0); + } for(i=0; inCol && rc==SQLITE_OK; i++){ - int n; const char *z; - rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n); + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprPopulatePoslists( pConfig, pCsr->pExpr, aPopulator, i, z, n ); } + sqlite3Fts5ClearLocale(pConfig); } sqlite3_free(aPopulator); @@ -251577,7 +253635,6 @@ static int fts5CsrPoslist( *pn = 0; } - return rc; } @@ -251646,7 +253703,8 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); - if( aInst[1]<0 || aInst[1]>=nCol ){ + assert( aInst[1]>=0 ); + if( aInst[1]>=nCol ){ rc = FTS5_CORRUPT; break; } @@ -251724,7 +253782,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ if( pConfig->bColumnsize ){ i64 iRowid = fts5CursorRowid(pCsr); rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); - }else if( pConfig->zContent==0 ){ + }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ int i; for(i=0; inCol; i++){ if( pConfig->abUnindexed[i]==0 ){ @@ -251733,17 +253791,19 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ } }else{ int i; + rc = fts5SeekCursor(pCsr, 0); for(i=0; rc==SQLITE_OK && inCol; i++){ if( pConfig->abUnindexed[i]==0 ){ - const char *z; int n; - void *p = (void*)(&pCsr->aColumnSize[i]); + const char *z = 0; + int n = 0; pCsr->aColumnSize[i] = 0; - rc = fts5ApiColumnText(pCtx, i, &z, &n); + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5Tokenize( - pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX, + z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb ); } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -251823,11 +253883,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){ } static void fts5ApiPhraseNext( - Fts5Context *pUnused, + Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ - UNUSED_PARAM(pUnused); if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; @@ -251835,8 +253894,12 @@ static void fts5ApiPhraseNext( int iVal; pIter->a += fts5GetVarint32(pIter->a, iVal); if( iVal==1 ){ + /* Avoid returning a (*piCol) value that is too large for the table, + ** even if the position-list is corrupt. The caller might not be + ** expecting it. */ + int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; pIter->a += fts5GetVarint32(pIter->a, iVal); - *piCol = iVal; + *piCol = (iVal>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } @@ -251986,8 +254049,48 @@ static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); +/* +** The xColumnLocale() API. +*/ +static int fts5ApiColumnLocale( + Fts5Context *pCtx, + int iCol, + const char **pzLocale, + int *pnLocale +){ + int rc = SQLITE_OK; + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; + + *pzLocale = 0; + *pnLocale = 0; + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); + if( iCol<0 || iCol>=pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( + pConfig->abUnindexed[iCol]==0 + && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + && pConfig->bLocale + ){ + rc = fts5SeekCursor(pCsr, 0); + if( rc==SQLITE_OK ){ + const char *zDummy = 0; + int nDummy = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy); + if( rc==SQLITE_OK ){ + *pzLocale = pConfig->t.pLocale; + *pnLocale = pConfig->t.nLocale; + } + sqlite3Fts5ClearLocale(pConfig); + } + } + + return rc; +} + static const Fts5ExtensionApi sFts5Api = { - 3, /* iVersion */ + 4, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, @@ -252008,7 +254111,9 @@ static const Fts5ExtensionApi sFts5Api = { fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, fts5ApiQueryToken, - fts5ApiInstToken + fts5ApiInstToken, + fts5ApiColumnLocale, + fts5ApiTokenize_v2 }; /* @@ -252059,6 +254164,7 @@ static void fts5ApiInvoke( sqlite3_value **argv ){ assert( pCsr->pAux==0 ); + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); pCsr->pAux = pAux; pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); pCsr->pAux = 0; @@ -252072,6 +254178,21 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ return pCsr; } +/* +** Parameter zFmt is a printf() style formatting string. This function +** formats it using the trailing arguments and returns the result as +** an error message to the context passed as the first argument. +*/ +static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){ + char *zErr = 0; + va_list ap; + va_start(ap, zFmt); + zErr = sqlite3_vmprintf(zFmt, ap); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); + va_end(ap); +} + static void fts5ApiCallback( sqlite3_context *context, int argc, @@ -252087,12 +254208,13 @@ static void fts5ApiCallback( iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); - if( pCsr==0 || pCsr->ePlan==0 ){ - char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); + if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){ + fts5ResultError(context, "no such cursor: %lld", iCsrId); }else{ + sqlite3_vtab *pTab = pCsr->base.pVtab; fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); + sqlite3_free(pTab->zErrMsg); + pTab->zErrMsg = 0; } } @@ -252210,8 +254332,8 @@ static int fts5ColumnMethod( ** auxiliary function. */ sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ - /* The value of the "rank" column. */ + if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ fts5PoslistBlob(pCtx, pCsr); }else if( @@ -252222,20 +254344,32 @@ static int fts5ColumnMethod( fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); } } - }else if( !fts5IsContentless(pTab) ){ - pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - rc = fts5SeekCursor(pCsr, 1); - if( rc==SQLITE_OK ){ - sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + }else{ + if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){ + pConfig->pzErrmsg = &pTab->p.base.zErrMsg; + rc = fts5SeekCursor(pCsr, 1); + if( rc==SQLITE_OK ){ + sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1); + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n); + if( rc==SQLITE_OK ){ + sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT); + } + sqlite3Fts5ClearLocale(pConfig); + }else{ + sqlite3_result_value(pCtx, pVal); + } + } + + pConfig->pzErrmsg = 0; } - pConfig->pzErrmsg = 0; - }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ - char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " - "columns on fts5 contentless-delete table: %s", pConfig->zName - ); - sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); } + return rc; } @@ -252374,9 +254508,180 @@ static int fts5CreateAux( return rc; } +/* +** This function is used by xCreateTokenizer_v2() and xCreateTokenizer(). +** It allocates and partially populates a new Fts5TokenizerModule object. +** The new object is already linked into the Fts5Global context before +** returning. +** +** If successful, SQLITE_OK is returned and a pointer to the new +** Fts5TokenizerModule object returned via output parameter (*ppNew). All +** that is required is for the caller to fill in the methods in +** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native +** as appropriate. +** +** If an error occurs, an SQLite error code is returned and the final value +** of (*ppNew) undefined. +*/ +static int fts5NewTokenizerModule( + Fts5Global *pGlobal, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + void(*xDestroy)(void*), /* Destructor for pUserData */ + Fts5TokenizerModule **ppNew +){ + int rc = SQLITE_OK; + Fts5TokenizerModule *pNew; + sqlite3_int64 nName; /* Size of zName and its \0 terminator */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ + + nName = strlen(zName) + 1; + nByte = sizeof(Fts5TokenizerModule) + nName; + *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte); + if( pNew ){ + pNew->zName = (char*)&pNew[1]; + memcpy(pNew->zName, zName, nName); + pNew->pUserData = pUserData; + pNew->xDestroy = xDestroy; + pNew->pNext = pGlobal->pTok; + pGlobal->pTok = pNew; + if( pNew->pNext==0 ){ + pGlobal->pDfltTok = pNew; + } + } + + return rc; +} + +/* +** An instance of this type is used as the Fts5Tokenizer object for +** wrapper tokenizers - those that provide access to a v1 tokenizer via +** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer +** via the fts5_tokenizer API. +*/ +typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer; +struct Fts5VtoVTokenizer { + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ + Fts5Tokenizer *pReal; +}; + +/* +** Create a wrapper tokenizer. The context argument pCtx points to the +** Fts5TokenizerModule object. +*/ +static int fts5VtoVCreate( + void *pCtx, + const char **azArg, + int nArg, + Fts5Tokenizer **ppOut +){ + Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx; + Fts5VtoVTokenizer *pNew = 0; + int rc = SQLITE_OK; + + pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); + if( rc==SQLITE_OK ){ + pNew->x1 = pMod->x1; + pNew->x2 = pMod->x2; + pNew->bV2Native = pMod->bV2Native; + if( pMod->bV2Native ){ + rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + }else{ + rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); + pNew = 0; + } + } + + *ppOut = (Fts5Tokenizer*)pNew; + return rc; +} + +/* +** Delete an Fts5VtoVTokenizer wrapper tokenizer. +*/ +static void fts5VtoVDelete(Fts5Tokenizer *pTok){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + if( p ){ + if( p->bV2Native ){ + p->x2.xDelete(p->pReal); + }else{ + p->x1.xDelete(p->pReal); + } + sqlite3_free(p); + } +} + + +/* +** xTokenizer method for a wrapper tokenizer that offers the v1 interface +** (no support for locales). +*/ +static int fts5V1toV2Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native ); + return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken); +} + +/* +** xTokenizer method for a wrapper tokenizer that offers the v2 interface +** (with locale support). +*/ +static int fts5V2toV1Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native==0 ); + UNUSED_PARAM2(pLocale,nLocale); + return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken); +} + /* ** Register a new tokenizer. This is the implementation of the -** fts5_api.xCreateTokenizer() method. +** fts5_api.xCreateTokenizer_v2() method. +*/ +static int fts5CreateTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */ + void(*xDestroy)(void*) /* Destructor for pUserData */ +){ + Fts5Global *pGlobal = (Fts5Global*)pApi; + int rc = SQLITE_OK; + + if( pTokenizer->iVersion>2 ){ + rc = SQLITE_ERROR; + }else{ + Fts5TokenizerModule *pNew = 0; + rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew); + if( pNew ){ + pNew->x2 = *pTokenizer; + pNew->bV2Native = 1; + pNew->x1.xCreate = fts5VtoVCreate; + pNew->x1.xTokenize = fts5V1toV2Tokenize; + pNew->x1.xDelete = fts5VtoVDelete; + } + } + + return rc; +} + +/* +** The fts5_api.xCreateTokenizer() method. */ static int fts5CreateTokenizer( fts5_api *pApi, /* Global context (one per db handle) */ @@ -252385,37 +254690,29 @@ static int fts5CreateTokenizer( fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ void(*xDestroy)(void*) /* Destructor for pUserData */ ){ - Fts5Global *pGlobal = (Fts5Global*)pApi; - Fts5TokenizerModule *pNew; - sqlite3_int64 nName; /* Size of zName and its \0 terminator */ - sqlite3_int64 nByte; /* Bytes of space to allocate */ + Fts5TokenizerModule *pNew = 0; int rc = SQLITE_OK; - nName = strlen(zName) + 1; - nByte = sizeof(Fts5TokenizerModule) + nName; - pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte); + rc = fts5NewTokenizerModule( + (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew + ); if( pNew ){ - memset(pNew, 0, (size_t)nByte); - pNew->zName = (char*)&pNew[1]; - memcpy(pNew->zName, zName, nName); - pNew->pUserData = pUserData; - pNew->x = *pTokenizer; - pNew->xDestroy = xDestroy; - pNew->pNext = pGlobal->pTok; - pGlobal->pTok = pNew; - if( pNew->pNext==0 ){ - pGlobal->pDfltTok = pNew; - } - }else{ - rc = SQLITE_NOMEM; + pNew->x1 = *pTokenizer; + pNew->x2.xCreate = fts5VtoVCreate; + pNew->x2.xTokenize = fts5V2toV1Tokenize; + pNew->x2.xDelete = fts5VtoVDelete; } - return rc; } +/* +** Search the global context passed as the first argument for a tokenizer +** module named zName. If found, return a pointer to the Fts5TokenizerModule +** object. Otherwise, return NULL. +*/ static Fts5TokenizerModule *fts5LocateTokenizer( - Fts5Global *pGlobal, - const char *zName + Fts5Global *pGlobal, /* Global (one per db handle) object */ + const char *zName /* Name of tokenizer module to find */ ){ Fts5TokenizerModule *pMod = 0; @@ -252430,6 +254727,36 @@ static Fts5TokenizerModule *fts5LocateTokenizer( return pMod; } +/* +** Find a tokenizer. This is the implementation of the +** fts5_api.xFindTokenizer_v2() method. +*/ +static int fts5FindTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of tokenizer */ + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer /* Populate this object */ +){ + int rc = SQLITE_OK; + Fts5TokenizerModule *pMod; + + pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); + if( pMod ){ + if( pMod->bV2Native ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *ppTokenizer = &pMod->x2; + }else{ + *ppTokenizer = 0; + *ppUserData = 0; + rc = SQLITE_ERROR; + } + + return rc; +} + /* ** Find a tokenizer. This is the implementation of the ** fts5_api.xFindTokenizer() method. @@ -252445,55 +254772,75 @@ static int fts5FindTokenizer( pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); if( pMod ){ - *pTokenizer = pMod->x; - *ppUserData = pMod->pUserData; + if( pMod->bV2Native==0 ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *pTokenizer = pMod->x1; }else{ - memset(pTokenizer, 0, sizeof(fts5_tokenizer)); + memset(pTokenizer, 0, sizeof(*pTokenizer)); + *ppUserData = 0; rc = SQLITE_ERROR; } return rc; } -static int sqlite3Fts5GetTokenizer( - Fts5Global *pGlobal, - const char **azArg, - int nArg, - Fts5Config *pConfig, - char **pzErr -){ - Fts5TokenizerModule *pMod; +/* +** Attempt to instantiate the tokenizer. +*/ +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ + const char **azArg = pConfig->t.azArg; + const int nArg = pConfig->t.nArg; + Fts5TokenizerModule *pMod = 0; int rc = SQLITE_OK; - pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]); + pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]); if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; - if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); + sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]); }else{ - rc = pMod->x.xCreate( - pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok - ); - pConfig->pTokApi = &pMod->x; - if( rc!=SQLITE_OK ){ - if( pzErr && rc!=SQLITE_NOMEM ){ - *pzErr = sqlite3_mprintf("error in tokenizer constructor"); - } + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0; + if( pMod->bV2Native ){ + xCreate = pMod->x2.xCreate; + pConfig->t.pApi2 = &pMod->x2; }else{ - pConfig->ePattern = sqlite3Fts5TokenizerPattern( - pMod->x.xCreate, pConfig->pTok + pConfig->t.pApi1 = &pMod->x1; + xCreate = pMod->x1.xCreate; + } + + rc = xCreate(pMod->pUserData, + (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok + ); + + if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_NOMEM ){ + sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor"); + } + }else if( pMod->bV2Native==0 ){ + pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( + pMod->x1.xCreate, pConfig->t.pTok ); } } if( rc!=SQLITE_OK ){ - pConfig->pTokApi = 0; - pConfig->pTok = 0; + pConfig->t.pApi1 = 0; + pConfig->t.pApi2 = 0; + pConfig->t.pTok = 0; } return rc; } + +/* +** xDestroy callback passed to sqlite3_create_module(). This is invoked +** when the db handle is being closed. Free memory associated with +** tokenizers and aux functions registered with this db handle. +*/ static void fts5ModuleDestroy(void *pCtx){ Fts5TokenizerModule *pTok, *pNextTok; Fts5Auxiliary *pAux, *pNextAux; @@ -252514,6 +254861,10 @@ static void fts5ModuleDestroy(void *pCtx){ sqlite3_free(pGlobal); } +/* +** Implementation of the fts5() function used by clients to obtain the +** API pointer. +*/ static void fts5Fts5Func( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ @@ -252537,7 +254888,68 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e", -1, SQLITE_TRANSIENT); +} + +/* +** Implementation of fts5_locale(LOCALE, TEXT) function. +** +** If parameter LOCALE is NULL, or a zero-length string, then a copy of +** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as +** text, and the value returned is a blob consisting of: +** +** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER). +** * The LOCALE, as utf-8 text, followed by +** * 0x00, followed by +** * The TEXT, as utf-8 text. +** +** There is no final nul-terminator following the TEXT value. +*/ +static void fts5LocaleFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + const char *zLocale = 0; + int nLocale = 0; + const char *zText = 0; + int nText = 0; + + assert( nArg==2 ); + UNUSED_PARAM(nArg); + + zLocale = (const char*)sqlite3_value_text(apArg[0]); + nLocale = sqlite3_value_bytes(apArg[0]); + + zText = (const char*)sqlite3_value_text(apArg[1]); + nText = sqlite3_value_bytes(apArg[1]); + + if( zLocale==0 || zLocale[0]=='\0' ){ + sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT); + }else{ + Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx); + u8 *pBlob = 0; + u8 *pCsr = 0; + int nBlob = 0; + + nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText; + pBlob = (u8*)sqlite3_malloc(nBlob); + if( pBlob==0 ){ + sqlite3_result_error_nomem(pCtx); + return; + } + + pCsr = pBlob; + memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE); + pCsr += FTS5_LOCALE_HDR_SIZE; + memcpy(pCsr, zLocale, nLocale); + pCsr += nLocale; + (*pCsr++) = 0x00; + if( zText ) memcpy(pCsr, zText, nText); + assert( &pCsr[nText]==&pBlob[nBlob] ); + + sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free); + } } /* @@ -252632,10 +255044,22 @@ static int fts5Init(sqlite3 *db){ void *p = (void*)pGlobal; memset(pGlobal, 0, sizeof(Fts5Global)); pGlobal->db = db; - pGlobal->api.iVersion = 2; + pGlobal->api.iVersion = 3; pGlobal->api.xCreateFunction = fts5CreateAux; pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; pGlobal->api.xFindTokenizer = fts5FindTokenizer; + pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2; + pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2; + + /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector. + ** The constants below were generated randomly. */ + sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr); + pGlobal->aLocaleHdr[0] ^= 0xF924976D; + pGlobal->aLocaleHdr[1] ^= 0x16596E13; + pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA; + pGlobal->aLocaleHdr[3] ^= 0x9B03A67F; + assert( sizeof(pGlobal->aLocaleHdr)==16 ); + rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); @@ -252654,6 +255078,13 @@ static int fts5Init(sqlite3 *db){ p, fts5SourceIdFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_locale", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5LocaleFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -252728,13 +255159,40 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){ /* #include "fts5Int.h" */ +/* +** pSavedRow: +** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it +** does a by-rowid lookup to retrieve a single row from the %_content +** table or equivalent external-content table/view. +** +** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original +** values for a row being UPDATEd. In that case, the SQL statement is +** not reset and pSavedRow is set to point at it. This is so that the +** insert operation that follows the delete may access the original +** row values for any new values for which sqlite3_value_nochange() returns +** true. i.e. if the user executes: +** +** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1); +** ... +** UPDATE fts SET a=?, b=? WHERE rowid=?; +** +** then the value passed to the xUpdate() method of this table as the +** new.c value is an sqlite3_value_nochange() value. So in this case it +** must be read from the saved row stored in Fts5Storage.pSavedRow. +** +** This is necessary - using sqlite3_value_nochange() instead of just having +** SQLite pass the original value back via xUpdate() - so as not to discard +** any locale information associated with such values. +** +*/ struct Fts5Storage { Fts5Config *pConfig; Fts5Index *pIndex; int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ - sqlite3_stmt *aStmt[11]; + sqlite3_stmt *pSavedRow; + sqlite3_stmt *aStmt[12]; }; @@ -252748,14 +255206,15 @@ struct Fts5Storage { # error "FTS5_STMT_LOOKUP mismatch" #endif -#define FTS5_STMT_INSERT_CONTENT 3 -#define FTS5_STMT_REPLACE_CONTENT 4 -#define FTS5_STMT_DELETE_CONTENT 5 -#define FTS5_STMT_REPLACE_DOCSIZE 6 -#define FTS5_STMT_DELETE_DOCSIZE 7 -#define FTS5_STMT_LOOKUP_DOCSIZE 8 -#define FTS5_STMT_REPLACE_CONFIG 9 -#define FTS5_STMT_SCAN 10 +#define FTS5_STMT_LOOKUP2 3 +#define FTS5_STMT_INSERT_CONTENT 4 +#define FTS5_STMT_REPLACE_CONTENT 5 +#define FTS5_STMT_DELETE_CONTENT 6 +#define FTS5_STMT_REPLACE_DOCSIZE 7 +#define FTS5_STMT_DELETE_DOCSIZE 8 +#define FTS5_STMT_LOOKUP_DOCSIZE 9 +#define FTS5_STMT_REPLACE_CONFIG 10 +#define FTS5_STMT_SCAN 11 /* ** Prepare the two insert statements - Fts5Storage.pInsertContent and @@ -252785,6 +255244,7 @@ static int fts5StorageGetStmt( "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ + "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ @@ -252800,6 +255260,8 @@ static int fts5StorageGetStmt( Fts5Config *pC = p->pConfig; char *zSql = 0; + assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); + switch( eStmt ){ case FTS5_STMT_SCAN: zSql = sqlite3_mprintf(azStmt[eStmt], @@ -252816,6 +255278,7 @@ static int fts5StorageGetStmt( break; case FTS5_STMT_LOOKUP: + case FTS5_STMT_LOOKUP2: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); @@ -252823,20 +255286,35 @@ static int fts5StorageGetStmt( case FTS5_STMT_INSERT_CONTENT: case FTS5_STMT_REPLACE_CONTENT: { - int nCol = pC->nCol + 1; - char *zBind; + char *zBind = 0; int i; - zBind = sqlite3_malloc64(1 + nCol*2); - if( zBind ){ - for(i=0; ieContent==FTS5_CONTENT_NORMAL + || pC->eContent==FTS5_CONTENT_UNINDEXED + ); + + /* Add bindings for the "c*" columns - those that store the actual + ** table content. If eContent==NORMAL, then there is one binding + ** for each column. Or, if eContent==UNINDEXED, then there are only + ** bindings for the UNINDEXED columns. */ + for(i=0; rc==SQLITE_OK && i<(pC->nCol+1); i++){ + if( !i || pC->eContent==FTS5_CONTENT_NORMAL || pC->abUnindexed[i-1] ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z%s?%d", zBind, zBind?",":"",i+1); } - zBind[i*2-1] = '\0'; - zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); - sqlite3_free(zBind); } + + /* Add bindings for any "l*" columns. Only non-UNINDEXED columns + ** require these. */ + if( pC->bLocale && pC->eContent==FTS5_CONTENT_NORMAL ){ + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( pC->abUnindexed[i]==0 ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z,?%d", zBind, pC->nCol+i+2); + } + } + } + + zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind); + sqlite3_free(zBind); break; } @@ -252862,7 +255340,7 @@ static int fts5StorageGetStmt( rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; - if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; + if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; @@ -253022,9 +255500,11 @@ static int sqlite3Fts5StorageOpen( p->pIndex = pIndex; if( bCreate ){ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ int nDefn = 32 + pConfig->nCol*10; - char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); + char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -253033,8 +255513,20 @@ static int sqlite3Fts5StorageOpen( sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; inCol; i++){ - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); - iOff += (int)strlen(&zDefn[iOff]); + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->abUnindexed[i] + ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } + if( pConfig->bLocale ){ + for(i=0; inCol; i++){ + if( pConfig->abUnindexed[i]==0 ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } } rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } @@ -253111,15 +255603,49 @@ static int fts5StorageInsertCallback( return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } +/* +** This function is used as part of an UPDATE statement that modifies the +** rowid of a row. In that case, this function is called first to set +** Fts5Storage.pSavedRow to point to a statement that may be used to +** access the original values of the row being deleted - iDel. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** It is not considered an error if row iDel does not exist. In this case +** pSavedRow is not set and SQLITE_OK returned. +*/ +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){ + int rc = SQLITE_OK; + sqlite3_stmt *pSeek = 0; + + assert( p->pSavedRow==0 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + rc = sqlite3_reset(pSeek); + }else{ + p->pSavedRow = pSeek; + } + } + + return rc; +} + /* ** If a row with rowid iDel is present in the %_content table, add the ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. +** +** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left +** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access +** the original values of the row being deleted. This is used by UPDATE +** statements. */ static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, - sqlite3_value **apVal + sqlite3_value **apVal, + int bSaveRow /* True to set pSavedRow */ ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ @@ -253128,12 +255654,21 @@ static int fts5StorageDeleteFromIndex( int iCol; Fts5InsertCtx ctx; + assert( bSaveRow==0 || apVal==0 ); + assert( bSaveRow==0 || bSaveRow==1 ); + assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 ); + if( apVal==0 ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int64(pSeek, 1, iDel); - if( sqlite3_step(pSeek)!=SQLITE_ROW ){ - return sqlite3_reset(pSeek); + if( p->pSavedRow && bSaveRow ){ + pSeek = p->pSavedRow; + p->pSavedRow = 0; + }else{ + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + return sqlite3_reset(pSeek); + } } } @@ -253141,26 +255676,42 @@ static int fts5StorageDeleteFromIndex( ctx.iCol = -1; for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ - const char *zText; - int nText; + sqlite3_value *pVal = 0; + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + assert( pSeek==0 || apVal==0 ); assert( pSeek!=0 || apVal!=0 ); if( pSeek ){ - zText = (const char*)sqlite3_column_text(pSeek, iCol); - nText = sqlite3_column_bytes(pSeek, iCol); - }else if( ALWAYS(apVal) ){ - zText = (const char*)sqlite3_value_text(apVal[iCol-1]); - nText = sqlite3_value_bytes(apVal[iCol-1]); + pVal = sqlite3_column_value(pSeek, iCol); }else{ - continue; + pVal = apVal[iCol-1]; } - ctx.szCol = 0; - rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - zText, nText, (void*)&ctx, fts5StorageInsertCallback - ); - p->aTotalSize[iCol-1] -= (i64)ctx.szCol; - if( p->aTotalSize[iCol-1]<0 ){ - rc = FTS5_CORRUPT; + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pSeek ){ + pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + ctx.szCol = 0; + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, + pText, nText, (void*)&ctx, fts5StorageInsertCallback + ); + p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ + rc = FTS5_CORRUPT; + } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -253170,11 +255721,29 @@ static int fts5StorageDeleteFromIndex( p->nTotalRow--; } - rc2 = sqlite3_reset(pSeek); - if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && bSaveRow ){ + assert( p->pSavedRow==0 ); + p->pSavedRow = pSeek; + }else{ + rc2 = sqlite3_reset(pSeek); + if( rc==SQLITE_OK ) rc = rc2; + } return rc; } +/* +** Reset any saved statement pSavedRow. Zero pSavedRow as well. This +** should be called by the xUpdate() method of the fts5 table before +** returning from any operation that may have set Fts5Storage.pSavedRow. +*/ +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ + assert( pStorage->pSavedRow==0 + || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2] + ); + sqlite3_reset(pStorage->pSavedRow); + pStorage->pSavedRow = 0; +} + /* ** This function is called to process a DELETE on a contentless_delete=1 ** table. It adds the tombstone required to delete the entry with rowid @@ -253187,7 +255756,9 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ int rc = SQLITE_OK; assert( p->pConfig->bContentlessDelete ); - assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); + assert( p->pConfig->eContent==FTS5_CONTENT_NONE + || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ); /* Look up the origin of the document in the %_docsize table. Store ** this in stack variable iOrigin. */ @@ -253231,12 +255802,12 @@ static int fts5StorageInsertDocsize( rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); sqlite3_bind_int64(pReplace, 3, iOrigin); } - if( rc==SQLITE_OK ){ - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - sqlite3_bind_null(pReplace, 2); - } + } + if( rc==SQLITE_OK ){ + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -253290,7 +255861,12 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ /* ** Remove a row from the FTS table. */ -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ +static int sqlite3Fts5StorageDelete( + Fts5Storage *p, /* Storage object */ + i64 iDel, /* Rowid to delete from table */ + sqlite3_value **apVal, /* Optional - values to remove from index */ + int bSaveRow /* If true, set pSavedRow for deleted row */ +){ Fts5Config *pConfig = p->pConfig; int rc; sqlite3_stmt *pDel = 0; @@ -253306,8 +255882,14 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap if( rc==SQLITE_OK ){ if( p->pConfig->bContentlessDelete ){ rc = fts5StorageContentlessDelete(p, iDel); + if( rc==SQLITE_OK + && bSaveRow + && p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ + rc = sqlite3Fts5StorageFindDeleteRow(p, iDel); + } }else{ - rc = fts5StorageDeleteFromIndex(p, iDel, apVal); + rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow); } } @@ -253322,7 +255904,9 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap } /* Delete the %_content record */ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ if( rc==SQLITE_OK ){ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); } @@ -253354,8 +255938,13 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ ); if( rc==SQLITE_OK && pConfig->bColumnsize ){ rc = fts5ExecPrintf(pConfig->db, 0, - "DELETE FROM %Q.'%q_docsize';", - pConfig->zDb, pConfig->zName + "DELETE FROM %Q.'%q_docsize';", pConfig->zDb, pConfig->zName + ); + } + + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ + rc = fts5ExecPrintf(pConfig->db, 0, + "DELETE FROM %Q.'%q_content';", pConfig->zDb, pConfig->zName ); } @@ -253396,14 +255985,36 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); - int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pLoc in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -253469,6 +256080,7 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ */ static int sqlite3Fts5StorageContentInsert( Fts5Storage *p, + int bReplace, /* True to use REPLACE instead of INSERT */ sqlite3_value **apVal, i64 *piRowid ){ @@ -253476,7 +256088,9 @@ static int sqlite3Fts5StorageContentInsert( int rc = SQLITE_OK; /* Insert the new row into the %_content table. */ - if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent!=FTS5_CONTENT_NORMAL + && pConfig->eContent!=FTS5_CONTENT_UNINDEXED + ){ if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ *piRowid = sqlite3_value_int64(apVal[1]); }else{ @@ -253485,9 +256099,52 @@ static int sqlite3Fts5StorageContentInsert( }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ - rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); - for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ - rc = sqlite3_bind_value(pInsert, i, apVal[i]); + + assert( FTS5_STMT_INSERT_CONTENT+1==FTS5_STMT_REPLACE_CONTENT ); + assert( bReplace==0 || bReplace==1 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT+bReplace, &pInsert, 0); + if( pInsert ) sqlite3_clear_bindings(pInsert); + + /* Bind the rowid value */ + sqlite3_bind_value(pInsert, 1, apVal[1]); + + /* Loop through values for user-defined columns. i=2 is the leftmost + ** user-defined column. As is column 1 of pSavedRow. */ + for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ + int bUnindexed = pConfig->abUnindexed[i-2]; + if( pConfig->eContent==FTS5_CONTENT_NORMAL || bUnindexed ){ + sqlite3_value *pVal = apVal[i]; + + if( sqlite3_value_nochange(pVal) && p->pSavedRow ){ + /* This is an UPDATE statement, and user-defined column (i-2) was not + ** modified. Retrieve the value from Fts5Storage.pSavedRow. */ + pVal = sqlite3_column_value(p->pSavedRow, i-1); + if( pConfig->bLocale && bUnindexed==0 ){ + sqlite3_bind_value(pInsert, pConfig->nCol + i, + sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1) + ); + } + }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + const char *pLoc = 0; + int nText = 0; + int nLoc = 0; + assert( pConfig->bLocale ); + + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + if( rc==SQLITE_OK ){ + sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT); + if( bUnindexed==0 ){ + int iLoc = pConfig->nCol + i; + sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT); + } + } + + continue; + } + + rc = sqlite3_bind_value(pInsert, i, pVal); + } } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); @@ -253522,14 +256179,38 @@ static int sqlite3Fts5StorageIndexInsert( for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); - int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pText in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = apVal[ctx.iCol+2]; + if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ + pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol); + nLoc = sqlite3_column_bytes(p->pSavedRow, iCol); + } + }else{ + pVal = apVal[ctx.iCol+2]; + } + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -253693,29 +256374,61 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && inCol; i++){ - if( pConfig->abUnindexed[i] ) continue; - ctx.iCol = i; - ctx.szCol = 0; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - if( rc==SQLITE_OK ){ - const char *zText = (const char*)sqlite3_column_text(pScan, i+1); - int nText = sqlite3_column_bytes(pScan, i+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageIntegrityCallback - ); - } - if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ - rc = FTS5_CORRUPT; - } - aTotalSize[i] += ctx.szCol; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + if( pConfig->abUnindexed[i]==0 ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + sqlite3_value *pVal = sqlite3_column_value(pScan, i+1); + + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue( + pVal, &pText, &nText, &pLoc, &nLoc + ); + }else{ + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = i + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + ctx.iCol = i; + ctx.szCol = 0; + + if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageIntegrityCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } + + /* If this is not a columnsize=0 database, check that the number + ** of tokens in the value matches the aColSize[] value read from + ** the %_docsize table. */ + if( rc==SQLITE_OK + && pConfig->bColumnsize + && ctx.szCol!=aColSize[i] + ){ + rc = FTS5_CORRUPT; + } + aTotalSize[i] += ctx.szCol; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; + } } } sqlite3Fts5TermsetFree(ctx.pTermset); @@ -254022,7 +256735,7 @@ static int fts5AsciiCreate( int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); - for(i=0; rc==SQLITE_OK && i=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zInpTokenizer ){ - p->tokenizer.xDelete(p->pTokenizer); + p->tokenizer_v2.xDelete(p->pTokenizer); } sqlite3_free(p); } @@ -254530,6 +257240,7 @@ static int fts5PorterCreate( PorterTokenizer *pRet; void *pUserdata = 0; const char *zBase = "unicode61"; + fts5_tokenizer_v2 *pV2 = 0; if( nArg>0 ){ zBase = azArg[0]; @@ -254538,14 +257249,15 @@ static int fts5PorterCreate( pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); - rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer); + rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); }else{ rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ int nArg2 = (nArg>0 ? nArg-1 : 0); - const char **azArg2 = (nArg2 ? &azArg[1] : 0); - rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer); + const char **az2 = (nArg2 ? &azArg[1] : 0); + memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2)); + rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer); } if( rc!=SQLITE_OK ){ @@ -255196,6 +257908,7 @@ static int fts5PorterTokenize( void *pCtx, int flags, const char *pText, int nText, + const char *pLoc, int nLoc, int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) ){ PorterTokenizer *p = (PorterTokenizer*)pTokenizer; @@ -255203,8 +257916,8 @@ static int fts5PorterTokenize( sCtx.xToken = xToken; sCtx.pCtx = pCtx; sCtx.aBuf = p->aBuf; - return p->tokenizer.xTokenize( - p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb + return p->tokenizer_v2.xTokenize( + p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb ); } @@ -255234,41 +257947,46 @@ static int fts5TriCreate( Fts5Tokenizer **ppOut ){ int rc = SQLITE_OK; - TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + TrigramTokenizer *pNew = 0; UNUSED_PARAM(pUnused); - if( pNew==0 ){ - rc = SQLITE_NOMEM; + if( nArg%2 ){ + rc = SQLITE_ERROR; }else{ int i; - pNew->bFold = 1; - pNew->iFoldParam = 0; - for(i=0; rc==SQLITE_OK && ibFold = 1; + pNew->iFoldParam = 0; + + for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); + } + }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; + } }else{ - pNew->bFold = (zArg[0]=='0'); - } - }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ - if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; - }else{ - pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; } - }else{ + } + + if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; } - } - if( iiFoldParam!=0 && pNew->bFold==0 ){ - rc = SQLITE_ERROR; - } - - if( rc!=SQLITE_OK ){ - fts5TriDelete((Fts5Tokenizer*)pNew); - pNew = 0; + if( rc!=SQLITE_OK ){ + fts5TriDelete((Fts5Tokenizer*)pNew); + pNew = 0; + } } } *ppOut = (Fts5Tokenizer*)pNew; @@ -255373,6 +258091,16 @@ static int sqlite3Fts5TokenizerPattern( return FTS5_PATTERN_NONE; } +/* +** Return true if the tokenizer described by p->azArg[] is the trigram +** tokenizer. This tokenizer needs to be loaded before xBestIndex is +** called for the first time in order to correctly handle LIKE/GLOB. +*/ +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ + return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); +} + + /* ** Register all built-in tokenizers with FTS5. */ @@ -255383,7 +258111,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ } aBuiltin[] = { { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, - { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; @@ -255398,7 +258125,20 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ 0 ); } - + if( rc==SQLITE_OK ){ + fts5_tokenizer_v2 sPorter = { + 2, + fts5PorterCreate, + fts5PorterDelete, + fts5PorterTokenize + }; + rc = pApi->xCreateTokenizer_v2(pApi, + "porter", + (void*)pApi, + &sPorter, + 0 + ); + } return rc; } @@ -255768,6 +258508,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ default: return 1; } break; + + default: + return 1; } return 0; } @@ -256592,6 +259335,7 @@ struct Fts5VocabCursor { int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ + int colUsed; /* Copy of sqlite3_index_info.colUsed */ /* These are used by 'col' tables only */ int iCol; @@ -256618,9 +259362,11 @@ struct Fts5VocabCursor { /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ -#define FTS5_VOCAB_TERM_EQ 0x01 -#define FTS5_VOCAB_TERM_GE 0x02 -#define FTS5_VOCAB_TERM_LE 0x04 +#define FTS5_VOCAB_TERM_EQ 0x0100 +#define FTS5_VOCAB_TERM_GE 0x0200 +#define FTS5_VOCAB_TERM_LE 0x0400 + +#define FTS5_VOCAB_COLUSED_MASK 0xFF /* @@ -256797,11 +259543,13 @@ static int fts5VocabBestIndexMethod( int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; - int idxNum = 0; + int idxNum = (int)pInfo->colUsed; int nArg = 0; UNUSED_PARAM(pUnused); + assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); + for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; @@ -256893,7 +259641,7 @@ static int fts5VocabOpenMethod( if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl - ); + ); rc = SQLITE_ERROR; } }else{ @@ -257053,9 +259801,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ switch( pTab->eType ){ case FTS5_VOCAB_ROW: - if( eDetail==FTS5_DETAIL_FULL ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; + /* Do not bother counting the number of instances if the "cnt" + ** column is not being read (according to colUsed). */ + if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ + while( iPosaCnt[] */ + pCsr->aCnt[0]++; + } } } pCsr->aDoc[0]++; @@ -257153,6 +259911,7 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq);

+5Xtqf5StI38J!8P?=fI!yIilAn$yOGl-v>gdD^Lg+Pd8WRltTilt5r2HeEf&QeM;%K-= zfL6GUEef5Wh)iI7QlRAC1oqs8LK+4xR+PdRIJ&ZU23wGRr}&rpW`!o?hY5Ka@`5Uo zH)8yO>f)OTipci%KK43Vp-_mz0U}aZLj!uu)PR9C#S4f?Y%TG8R+J6*L%tiH%NFF; zmcHvkPDBpCLEN)8#UfUt=4o}`E?g$r8GHi0DWjz@@+C)4Q-UVmEeQ@vq zyd6%ozs<_b?}#S?35{j21237G&BP0GHNh79LtV{NKvL$m5a&E1`Q?`4U;Og>#Mj^h zVd88z_RNpnv-3OFqfn!@6vkpO8!l#mqmAUd(BB>*{*6ReY_D*f~vHHAQ>^ZowXojhEaxOY#-d#Sh_d_zdw@b2{yUf(MC* z6M@U#Vd|($(*1`d8_qHE43~TX2Aj_m2XL-;qko9fdjNKm)NjE>dyNAo$&bKW$vN+K z4A$V7oQF@NkWPepA>R$3K^{Fz4)sGm2R?zkhW$;2=J6o!3+HNq=JWq-DP%EVJ$!?6 zTnxWJM6#cizMBvh!%H`5h2OKn3?>YkEBzCU51c2i;u~+m8c)ZYOt@mc6cRDu$P^#M zKmyzt2M)s%w#k7re0co~dkq$9{N32ggs<8K+duzbL`N6D)1C0LR zjp83>ixZECTQUAe^xtH{@THP}f&T6f#SKjo`#%5wxJ(^^Wc9V>;;ViG+2T*^YqP2K zS9wi8dC0Iys*F@!F7pnEr@?u z4&*c8VXGxy1s~=mbTfP@Q}SH+mppr{j01b=2(>FTuh~vsvtJ~nK^qi-8GQCDM86gh z%VA6Alf+x#Jw$LXd2A7SJs0%v#u zIrA^WX2LBWXu_8$?Qu8|$@n%tduIPl`|$by89YpklR^bnaOM*k7&K4=a)Ts) zliTb94h-ek6&FeWE3;a=;^3juf3&AKc9=Mjcgl;Eyz2Pouu(88C}ss!F_?Ku2K(KK z!D#7wFpxW3{Bx@0iG9RL&l@&%ENJL^!%ihq1lHc&6@bFx9IMNi-D%|H4;UhCN z!NoC}U`v5v9~uKC;cn~gL}(>)BgBt z^DMGSW+rshk%Qq(c>av^W49Z*S@C@T0*Kg&r!~GQ<7+T}nJS^z;XEq?36#=&xZ7eG z{3t~ep3wkD@j2=LV9$L8^XG@q#pQ1N;3N^VFCi9@s+sLxMOdTwI~9IK8#l{;j?5{=e1+ zg%Bx>y+=HDtzomLt4LB8A&g~(cX0}Wt4V+6M5AvCRqtxrvI&;W0^*uWo-tkA@_uo^ z5qtle0Z~WP@n};S=uuS$9@%HuIIt84a(GK#0T1jY{od$r*(yHpuI#;?t?^^f|J`56 z?vwmLzS(~}!8{b^9F&2&7}!M)G!N5&|IIdXv!cE&#cN;C`0 zZD)Kp?;fLIB9Ov_o8A$>cvKU#v$fw$c(RpvRXxdjS677EwU&ISNAh`Rhv zqjEa>Y5WyVL4&@Q&Hm4~AvcvRkpU0ekQtr?C)$V@o&^uGY$7y<72cI^*sSOi9GYq! zF!B`SH>r%5kpIAZ%d9;!zvGncFaxGBU<|whUi@!Ou!u@_H!l=R;Wy_avl24zj z31)?h_reE*#fRZt+YFnCwVcA=|KE679pM-p&{hLd=E>kgb;Oh4G02nVOaAyU$ur@f z;>E#>CI8Sw*G3?4p}0bS@%Bt=`>}BtSR#cS^FKQv=s9r@Zo^>s@T|nJJ>>S6RoNA#ua!Io{jb-Ft8hxz zb4uPMVmFY#|ER`?ZIFJUj-l6aYNtB(w30#s3gzFE11UIQzwTolh~6yyuA{|Uc8j<5 z6_4F29@1Vs70!Fxu*rjLPF0{UN6h&<@TvwlDV>El^vPi}z?}QttZ3?6hD{VE;!tFs zI0H`DC7uE2jyG%^&fO#X`!+~^5_>=IHf;a?zkFTo;e$3&khk-~6Q-eqo{6e;cxQ>&f7{7sco6i#Jl3?&dG09>|gWKDZkC zF8Dj^u(22AXFhIsfIoXy@;G>w_kDHrqT_dRU?BVod;Taqk0hD~Pq#T@CY%LF+6Wq+ z2RFi@#c(hVt%SWlaLjV(7>on|hS$F$gKxo?*NY3_@5q_=;Ni<94{xXlcFz_!Y$R^Z z7B&`}_kZ@VISQ?LVaR|tydeW#xXWJg0(kUx@r&?oZp#gD4{pmHaJ?+)@Aa|S|Fg@~ zk&nXJ1>yp@nCta8yymFnAHp?oun6A6?RXmggxl^6+!zOcvux&fPIb0uZf`d&A+xZ=x{P!^mOUU{*@I5#f1^+>k#lnRo zSx-NcWCP*1$oj|NaU}id#@zp3lXMeMc!8{c3O=}7E0_-7vsJtRPUTdrgp)ZHFTss) zcmrG!hqpKODujPinO;TV1gBy@+z|)!;Vabsci;v%SO`DIsd*p%hEwwqT*#^U%uC0= zD6Pft6O__(a3T)=4!6X?8}Mo_r+`o`XebU=hP}HKv6}GtEn;sl9lh`{1irCK3iaV1 zIoA#0Q;Q`Jg+H7xZU!$rE^YxPUPmW7PVbaLJlqEl`@=ieNj?mI0tZLI z-EnX{+#UzhU>6R0;r|s{dnW%E&@mDZm%`WgX~HbHD-N!K_iUCt7p{qeyWtP0eEZ<7 z{>uwqYYU&f|BukIg4^o^+|TEs`QbEh0k_xZ@Z&i6HN0hq9QqNigM;VcbUw~sg~N@5 zzWe_lI;!Gf`6f!Da+Ky;@E>zEK?uC}n7A3-0tfGdk5j7Ma1|VU0G_kS-v1^7addn^ zt?mUcr&bSwCq1tThr>w=#pB>da4;1P!NF!I^wxZvfx$J>b0;7 z2Xo;79NYE0N;s&-QiX^*c*O|yJQ$#9S28= zy^dmP^Ajk%N^PFvXD*ZJ@MbQPXW{-_CJW(r56R&d;Agl?*1#|CmVBF!&Hh*4s*e3A z4COL;3x1f(qyVmn!zbX2lM;4T>kx5L3v@D56~cLE)K@Ng>pJhl2+ z_)Z*L3_pg0%i(%BxE8)jseT1MOR3%o7pqiz9sB86b4(F94DaFcI0;{-G=C1?w@mua zx6l^cM&K{zfuV!;3!IUXE+Rp`@{dG5+=eQQVA!(1(|05?fw4@9m}bNOW+FR z#6~!uN|*=#KqV}M`{Lkda4wbbM|dfv`YPPRi-!)kR_wyVYH*88A^=~Y61Ig$QK}z; z8{^<0xEl^8!mm*YQ($i`Je*F)5h~$x@HQ%84!n*^xC>rMB|HT8$H5cuyHvuj;MtVw z|BAhiS15&-P^gQCf5I8-6oK*)Le%fCN;Zsz?_3#QR;ZAt6|Gghhrc}RY+05^F6c0Z`!HI{(@Iq?!dH8-D z`~yyc$;7!Y9@2sD> zD=v7r|A*nxbreqUmU|PPh(m#q3h|O{GFTb@ipp6Pp2Ayh9XJk$>cMqzsF9bBLT;xp zxEl_*;BWS5!YKIft>X6ZLpabGK20U;3D2Qa4}qsqn!O|GxSQJiIGlY*6FdPwOlf`! z&e$#aEci5)Z$A70g{^6nB36!5)G0IgZf)coOdiY3*d-dy;NJ zocJx0ZUx)~j_2nEHSs4k9Ad9u`}uze9Yy3o0^H*{qfpuWwfZSdu#GL5)koZ$oY)7y z&K89BmApSWFc8kcf#LiZ&KIl$_Wn<#;}<)j;daAh;5+uHBb@WDMg@=*@Pr)}$>Gys9KmDjCe3Q#0B|$tbPZOrW)!5@~xY0|JzYJGk&tHKrP>NrL z|I1ymAKr1C`~M&vp*WBapIoO2Zon7FiR1hOg%gz4PvOIq)^FfXS#ewc&l4oVz2M`| zn*FySA4*3$r{D?rXHLNscnzmuHe9e<<8xpa$8sM$&Hq^vp2QX%hwt^WM}gGS5qs){Gk8G> zg~w-V{M~Q_4&DoIVoTe=qsggAvDdL+mkhK=;ScWrj__a{>a*ZDh|3K0` z27gJ?CBZKqmwu{`&Hh)$!zWQV${WgD_*W{|i|`{jxB))6P6ju_8N8qzg!|**+i(XQ z`oglA-*Mf4-=mPi3(3!LAP!xE`{K|Q_|467;4ioV4&8)LacYA2X7oNzO^9JTzvC5- zO#>7{G58SdU8@O3!0jl?vK$tgD+Pu6#Yr;zl$y>t|lRDI!&csLNgNKz%jr%0*^@Cma1 zY4{zIY#!_->z{{zBgedJ=-5S)y#jwulI?}N;NW5SWs>XzcsLIJ2X2ppXW%wCcnQ8+ z4tgDb(Q%qnP=2yPJO~eKz`yd=+XRlm!3cO0N!t~^$}86kX|i{0nQ|l>e$d{o_V-WO zuffq zUCBI+EM(D_Pt5cZpv!32iyJfw+0 zdBG0xFdWX`VZVQEo`gnH82Y0R9WC%UWtZfGUX}dD9`P?};*+PuBZ)|2Me#Ty(4msp z^OE!jRu-RN%c8vu=r>#nr|dG!b1ykD=}z%!lgw6>ZO*rSLdl8d8^j6haf1EEnR)CF z&$Rk0s)%31{;aCvM7GqsJxCqxyWzlL@uMN)8&v{)2Jd6V11pP{vLy!=OMgG7pkST& z$0QsmCtepL-u|h$g(B*8BowLR&yi9HbZCMLZN+={NnV95IDbG~l?hTNil0GVDOLOt z1uM_e(BHq|^SFdRDuLt-4Gxap#B+hvlbzuD_8Cb#!FK-sNBIIEeE8C zSG(PUy&I*!2K_+vub5%gZT=0cBm><{+YZQQK>PaQ8WKBJ&J+humO=Lb@u^+D9dgub zB0fw6(m4e!eU;99(Rr-oTUg-E6jOifgl7t6@T1;R2pS@8P*+?D`N?MD74J!Ye!94U zsTcN{9V^bZu{F;MGl6eG$Hk#d#VO~-t2>$c<8y$H6$w&UQC>^l5GOtfKM5yRkbGu; z$&1XjY@fN~#iv?|YmXAoDkuE{PSv#(IWVM-*?;T69Q!YZ%rjw@IHA1wB{=>|@v9h^ zK1N)7qx6&Rwxi8gIoXnMb6oAyh@{IViFZtvel8qmf5WkLAcbRengL1hd{z()pPGb& zJLJG=j#Z@`@gw(39t>}(BMy3B^5x`2(NM8>;KLX+*=wKlbn*0i#Luw8^@Q|XE6FP% zuS;DBYcBnyzLFOi$L;e+KXGzqBCK!W3 z=Mw2ZW?rMMLy6=>hx^3KxSX2YC5|?^W1m$-V9~t>%>0hUgm`+G6+0aExLSi9SmAn( zVdBe@H)anDM$4giE}x`dB`?BW`UP<u5m?tXRf#de5R8)3Epj1Y8}XgpWreIy{h*QM{Z>)L|>J`k4-_b1LEMu zgT$U|k~d(**?)@Hv*PveC@!;;ZyO`#>CUmt_U*a(`QIj)t^MqWZT&UR&{^up=iJYR zPjc=Lk~B#iyG~p#H`Z$W9UhHebWR-0DY!P;S~vfIsgC69IVIPKSe%zV9z0nJ4T4mu zvSTqwDSfy;a@lvZX2m}1=0Ahnl82F$-Qe?(I@>>~croDTamZ7sI{cGN!4_7hJvdu<;tIo5onczC=|?sbGFs^elW z4Twe|uabB>Jd0B>7Vb?>#K9AoFrQOYg&cAADd(HuFPH3PKB4(8jj?RbU-4im1QEhB zD9njs0Jq(qS>i?96&1~}>ZYpszpOsDljKu>lfARXj*Vz2rFe4_aS=HbYq!wm-w8Ta zzAA+zUcs&m6@QKVX|j4CS)KGC@;j6>Q6yFKK=F|~BzGb&Y9&qxko;q_Am9C;Sxz25 zNyt3^RfxQeH6ZY3ar{f-zHn@^cs;y4T%34T`aP)|(eMaLdm@FZTPpYeKoqXll!0Ol z_GCq8&d6Y`agxWP|22hVdvh(IkV2FGi}YtBPk=wHtnr0ENnSYI?7wf1{0`Xb)I?_k z|45`IS>L0E2HeL41tv1~sSV!<^`WCb=RSCp_!}Om@CGj-s_~pUz6p^- zL5s!Ta!zv>ia)C&`2n`<3M-1|(`~D9lCMV|;1plW)c8nF&1LL)Uob1P5jf1J-<|Na zV;XRAx8#Wh;=Ux|tRvz+EgTNDw8Afqyfj}e!#|n2QA+N0{5J8n4o5$8PD?2`0=wVN zKbJ8$*j%rr^8=;cF4dncorj!0iLpPPv`K%Ix9YWs)$XjKiOsm)g<}IC|X9(d3+een+1&Nw}zt z!N1BFj54LQ^aSOG+|Ivuyq&)lOxLn{gxBU8o?NKQ!}omDF*B%um= zwl{BVPRQXqD$&z5@80zx73*eo-XBsgtIJOz!CABShs1`CPEAVg`S8HxvSroiHKq^$$Yc38*_dH6>%h z#GX^Sr=}+LoS2k6wadtfN#pXKJQPD}1PGJS0Ck?Ety`seDCHT`->+j8!_z1KrF2L!m>dHrsLTrZb5=%0`= zNPu&-6`u=m?h2?9HKMH}rAyzQQ4#LEjpdy;%LTY1vRoYXxfb=1g|DXm?RSyyU1L#;tG#BZ=^uyb7Aj$r4+ zfUJ8$oYS**ggAH9i5lT?q&zgx`f6Kvo$7QB3;h4gzS}@%jjG@5Zw;KQ^Hw!ubaa$$8OttDl!wl!mea;gW4WviYfWaX3wBn{YSqjcYGRfb z+sxT7pj=em{JWib0bXO)%5t9W^T8?&$^?*(NU4M<#$Y-)-kn= z9XE38BVyZ9bX;zizt`pVxNeOK_cy~MN}8_l&6ip_P2xmk{oKlVKJT0RoDI!-vM%25 zoL4S7E2Xvb9k0hM%O!to^i0$2fiIA1+Qrf`D=ZP;YMRBGUM*JQ=$N*2xxyoTO=HqV z0I`XHS`jfGuV2&dl6qZkx4&uQ;_ozZq3Kf7Old=;&RZ>CgiNO|!qG1OAR8?8M!0Wv zM%4}XE7-XCCkW5#9PZ4?`z72t%y)RA-6neVBb>eN@Y?8v$Ha^XSD-x6zNT-owk6Gy zmWikoOBy!brppY7DCwhRjo3ZF^sQz@q<>6|H^SeHQp@@id8_Fuk-JMe?H0gXqSJ8r=;cb#6;qT%k5R$s76MY^m^1ZoiT0w zowgjXV2_$MimsAoWTaoy9q!lkl#Gb+HSGvbNz)vv5#i<+5SiYX=v%7hcqvB4xW6|h zvZT}Fxz&s)X}U`_&7qW|(XLzaaDS&OTun2pJ+x!}Ycg$3>+v^C-uRj}qOOwOXm^R+ z6<*TxM7#Z7+qzh?fRd&st6w{3ZLizo>oF#69gy0smN_4OakSenHoNKXH1~$zw5_hV z?h5xe+s3&3ogOt6@seJz$J7~|bC)#R`ujX;*?o`n_eGj=#0bx=rY%zHjfwEJ%$R6X zu5igy(zG?qKcU-I#ou;?yRzD}chzod1R_e)9o=Q;DQM3fJ92I##Ylac*{Lb^f@BjDwdmh@e*X6s` z`mXPNeb@H;?`G^@Ib%bpl8};+l#tZVusdpdcu+z=efxj?4Q+Mhk-=g8lTs2Al2cHd zt9i2M@wrdU8qj9}asFqKBZm5KDDiW?>}RgR+NG8$5rc#3c;|b?5`HZ%^&@{@V%Zsy z5OA+*s;fuoYn=(-e$F@C;;YqnExqpQ_zHE^rrhjIWc=jm|Mu-_$<^w+=x?}MRJ4uw zy`!_mqJ1#5*5N82`x7E@!!XI5r4nq z_f9WDCh+Bdb{=4Bai3UW5@q}}%RioV&ImRq_Hh?Yo^ zC40cn5-HdlmzYQC^}R19o%B=`%tc2@>fYS+2=C5AIvu|{AYfi&eBiuG(LwY0<4UJ+ z`a5qLpm3_hgvgo=;=`vXRYI+B!MLY)saIzmxiIa5BaR*`c1 zIjLNkfx5R?)g)S)qnsyw)f*nu#xc^_;x#5Ba1OEk+Lt)Yk}*}ci4+kPG1V=y3?8#o zHOGh=%YiY$5esSJ8m%$q(gK=DNoh_X{xRc!+vbOq; zELY#?OKdk}S`GZa+#mO8XZk@EZUr$Za4p5yL9c)W$(_M zG)l)=ejR_1j6^1@ro+34Ggps1iG-ApRHQHh}ki;8usIGduOacx^8e^4Z zMhn5VrBS8OJ+QadGHpUoNlZjn!y3TQQFTGZI$|Qk*h0RaG3`7M=k6-H%`+0yVU^LL zQ4zl*Dq_=X)01Q1HTC~I{v`={01oo?D&Zg z>}ELr#2hbSqv9e-N%>`vTr3t6Ly1i+CRGj}k=BV6RrjE#Noo=xI#!~*a;1OD#~{f; z0MM~rL3e5zg?2^$_ajHa?(14;k!Wk5LrkK70Rzb_GN#5nNRwUU6z8J(Kun+{oGh$Q zB&P3@Nlj&tF*QHAtHI{s!f>&M)>yus9NtONP*aA6THcr#Va!%s&@xlq(At67e2k7X znKaeuh(8H2F3I)53^Z6}F{u$iQ|}T1FhX^Un55g5Z46m5$7I8 zJ2x>MFQM4PPcg0GV6lz>Ke!|4$I@@I5?Wv2q#MTCIdEpVO;da{u%WE$TpG_$^3mzijz>veqNdL`-j97pT;10(3#hXQM5l4@XHA z9+trmzm&de+>0mv{@z>7zgWL&{`-%=G<%SbPh41ixVgvl%gvoi-#+nP(&6Uen=d!- zU+~I_SN6Q!ydUqA@!sG;Om^9GM6%_(hk42WDHJFNh%4fEMn@KA$)!0O2@FrygtlIk zQZL6F9hc`2hoaBbzC(zq8e;A8IVqJGXK0}#0t(vRBPl5{UH-!Jj*#~Xg=|Kr-v$_M z*V2r(v(ZM!Gb$2rTlTEhklEWj@BVh8gvMQ7PKjwc^=yp6CaP8D&`TH)dl_rTpdI@* z%3;-*V1Nd&v#Bu^@;y;g@xqBX|M#2Mh97N?d)D5ZPD|!&Bl;Oyje(frqBft%o^5L` zxNxMop!gS5y6W7M(O^K;L}H3ZyAfzth<1f&=QZW?6OZ?@H;cjRp>xxpihbDtS9I+9E~tYLmKD|z$2ABtt4R;0N5}bZDMk@&Ncud-kpH4 zng+a!e$L6I;T?5n0V6UdPYY$yvI4M(K2N*O(Q5hu@>|Hi9bl|LiPXHQDYZ<0G$L=s z_rx?el-TA%lIW>YCUn^$4_8~aknJcV*ESNGD0USgq0@JXq&Vhl}bRy$OZEV>klue%u>+5o>X%0sDAM}Fl)`ix6+2HU(!>SXW zzV9`Uc=mL2VL)SZ8`G6&J92KX^IJ}Q^~k|yuR&inuRCCGE`%5nOx7Uivje9VfKy>~ z2V}<*zZt|;Czw+(rl|9T2#JRXDT4@!hX`pKOzYIN8i zH(>yDWCDTRd&Hl0kNS-^LCiwyJ$k1#SP)n!gyIyLly{YH8Uz)WGNBVfs~1y}6i!1& z2!mCWFYiN4pQtSU`Nk5hlk~(0;fsmC*suFJL+oYOYSD?t6Vn^mmlQve7>>d0a@V-5 z!e>(s2av?qI+1c64R2fyRNj%5YB!A>*+WeG(PukQ?v{hAGKp#3;MFG{pR=pkt7PlX z&FgyHa!OhEzPhFDe-o4!ASfFE@c){ilpyAXpmYkk|D~XOQxF>j$@7V zpj3q=o4WyuQh{v%Q@G|%8|U8w%ig{x^};|9q17(#4|lTDw7adrF&%*DCE|o(r=-R$ zJp_z9_h5u~fFUG^i*5w#)gSh6-IoVy6EC@V7QgH?_`)@U-K8zWl<}4@RZ9G^huHIW zv-eG6GNA0QO47|zp5*Nljh_E(9$~aM4;3sKOU5}_3f$suBa|oH(*Us5IHJtedXkq< zcz*I>bK}}Cn~%*|N9C01env1NLkzBT33K zf3NY1IxImL=Yn6W-||nfy*c(s?Mi?Y4`DGy;64g!|te8Fo2w?knF%_rDXIKbjv2#K?8B3IX$6#bQD zN5BreWw3l)810Mc?UTBWP;Qr;6l!p=+yn6ZC6{Nq97k zX0SP)JIs5xJ>G*#xh0k_=Pi+blr0(a<4TUV>3Sg$4qa@q|g2*JkYeHegV@5i6wBykM7B_;0KB zBsC}E2b^qihfeMUdh%j--IBiv7pQZ~yEc1V9+geu7(v`TaUzp}% z+7u$H0lU|LVa4zncqdBw|1Y!rKX(rnwSey@WEYkh%;`%PGg4zCh<_Sl7-AY(5=pXuVYG>< zDX?)4B9eIn_KfAq{P6qYIcrD2SAjm-q>#kePFNqpn!?>hG_OUhPgz!)bLm`0YT7V!q6Plw0C5z zFhlQ?3>frW-yyMAgP{tikeU+V2L0=ePyuWv1`tmHs2DGBwP=%zwWYY7Vn}5K{wJ zM_h&%r2#D}{nvyFZz_|JGJ6B$n)Q2Ic z2I?CjkPQnTyBKf@vx{w;of#nYK_zzpy;Fu-bo}OcKv%;cUvp6eEWhddrr9 zPimzV%rfQ4p1lF#4x9nE#gpBWm>$8Fbo7|3dl1tkl$8+6OHW2mg1+zA<48AR%0%r* zIjn4y>{)h@dNpQ(#|mlK(QH{$HiCMVl~7G%<*ineriGMGr?hDZej`5I^kx7t!C*fD z>I$$tu_#Lf$v@Fp4lIiD_#6ul35HqN)pB={M*@yR0)#g&!liTJh6=eLVeW#A#B4gw zcWpQ^c~DD_XLOJa_r*~!hZ2(mkVHI8dH&)?+UA?h@@Py{ zPe0h2bj{HUUcJB1JDuH8ylW>W3~Eifh&CN(_ZFDI^4L>>-k5_hK=&cy`CVtr>ZjuF z`L;)}{5n(#V@vSFV(^+Uv?hDQ+M9$$f(RR+>y-D5j!G|56Y_!4;fNtM`_L{;4s29V zSC7SuzA-W>)6u}jEI*Jv%G8*?JN!{8X+{V{DU*n86(L;$5Ylz1RW979)sqdEd@Q4% z4vkxcxp-SfKf zk(N_WCqJ^iq1Ds{jOF$(#jL<40SaszH=?~eIT5{aLhsh31wdHGx_J=&uCVB}jT3sc zCe1;;m~|dtTE;%zRWDE@3f#+b(`+0%j>kY2-z9pVsxWxKmw+D{+ITq3GI+^gEe^l1 z<`Hbp=3AguY+M}P zpT+w|@g6axxCh<^ec~9)uK*mBMm3hQMc$Ugr33kV?is3SjGr*?>HyQc)*+USOV_LW z8*Q;@s_wrx?%BSy{ne7U?6&8duUYU%UJ zO!}K;<0~_z-!@tLz8+@zlKbq{zxp7h%rb3D8fAO8ZCNi-zrB54KkM&PUrK6zhXR0` z%45#71wjJouqb4eW2Yfy0qkEVDi|NR^Uh+lNzVzQyt3fT0EO4V076#grr} zpQNY8P{kmWQ@tGEWQ;!na|YVzR#Ka&S7aqw2_BMK2PJHN&WNKrC^t*d?hqPiDcjvU zN$i6Yo{-WfiOsw*y||L}GbsPY7^3Xot}-)8Nml;VR%W@nyBC!$p?kEwl{0N+XW;pE zm_u9nI0fap4YVkIGBLesnYE{H$UbQJC#710d85&`Ho<7i!YI>Wv8=UxuqRle;g&D= zXk*tW8yy@C>>&>oS4w(=FK{Dlhmlw+eB1IuoJ#7brm)oFy|=GlW-v+m2Wl>3cM&sT*g&c6$wTS=)*Dy&(q| zYP^Z*4`|^_4V}s_os+B904x1fTK~&16NI_rz`S*I)_P5jVJOfbJveLSb=fa7;5oEhy5n5P>Yq8#PI~8Q^K12TVQG3sI)QDZ!EC zxUJc0qoYywwOp@>F7Yi)hxOPng4k}#oe@Ctt`38qU-D$ccwy$8MVPc+hqxwe1BdME zq=nLCVypEeNxwleD{{I+4X9UPYaE^!yEP7wH9w@@)Py}$?3uYOC!2a|vT1k%f)vG} zo{}vV_4uhOvyp2n>ew zjSZ26lnXty{$4xFuU2g&l;C|})Un3mOFoKWE#gs_LxIuKf4?s3-azT3yZ}7}7H&Yb zwqwGQw?8U4UriE&K%&JfNVyixLP5?jNG)6UhtVw->;6%pdB_5YS-R+E=AG7kw}65M zh+-FTOO!2YaME996Wj6K4=gVe$6pr|bFYo%CENTggLsW3WZ|DU^Qss53ER?BD^(<^?#=Yne9O>}`|=<2JNcG~rgiTc9hZc72q89Q z72Y8$+ocHhrbAt3YwJEAOrzsWqfjrTR@9*HgPdqsT#AnoPKXrxuWk1*@=bAJuM4A9axeex-V?&ez{E)h_2q~ zIwj*?SK%ep=dre~u>AfqtXPlGm<=zr!I~nu#EO8WG8Wqh4!H*_SHOz$5U>Wn94in} zJ)~IU#Jr}UR8&fxoC9eDz%SbX4wQ@k+V+s8=(CWL&}xa4ZWNggmgfpl{Y zaR|y3K>|T$m*h2}Yal;k!boBz>|Z!aO=U2#>mkY;+SKeD=+nBH7R^v#GxPM+Oq?Mo z@xoakMIS(%2=ObC746MNUc-fGz43k4j8&CQ;oJD8mu`p3?6(}#7mFD zqsP+%eeAXJ85JIdDc%ju$rz_1d2g#|)2uW`S&fM&G3LGWm zd+>N-D+LahCqsMv*_v33DG0sPu{;vxA3LYpZbsc#|3_=$9@Impg*ug5$IA2@t%*BO zdD!x3ZLl(snzzh`)yg*{(g4eb+5nZkd|gfq_q#%)Enn4+r9pcm4h^6*fA6@@$Eamx z{R-as3hlY~$kCHdyHlKq#r5C&?y(iJsorueKfCvj-}eMr>piJjC4`m>3~%mzh2!%g!o`&<%FnXw6K3cQG>45uMS;SZs5%f}rb@7cl>a@09^Rve3 z=}f5ukj+svfvS}4V%^Ix(4M@)Og*f(qUix&mHCPj8=uoI{M$szq)k_>rxNJ{KD5Z{ zKZFK(c${6Ys%q%T`()9KkotHS*q%h>vpI9lkR|1?L#}q^YqDr`wmq6Sgh8?tCwm|g z{~-JZ!IVR6Zg?5b7^Jvek0*{horweaQwxaf@d1%l_+$8!@h9Pr;*U3H(IhtEL* z3gM~mhZAgJ+TTG|9N0&XgTboLjj36EQVh^UMY;UdY-*wd_^;XY>mCF9kbQ1>Z-)g! zDCBvdIJzR$l?hN3DkzG0?(u9V?dFkmKAprDjHG{;6d!ByC>loPFEn?!X*7M1#`BG% z=@j}YzdD+}Mx*)KF*HgwNFn>O`0g=ui1))#++!dCe)lvwUgdNw4PXPHm$=^`k1o8| zSlU&2RwnzR(PHxf54~jX%a@F$LjdT&So(*m?)TQDw|KfFM|0ytTxD zfHjL}3@?8bIIiSBy$aGci&jUaOmE(23k~J3y$%+*@*4ivZz~O#>b&?i0Hi*mR?E#> zsh3pg$474k;N4qk8pdtfN>h}1Qc)!0GO@h>YjhDR#vKZ+LD#JE4cin7ElG|;&U{Px~Ptu){I_igkkD#n-rWf8;EE9j4O zBiC-n_@nqV@%WB!+fJi(S4mMlnkWbftC!|4PQ!aH-bMLx*wVaoJB>iwyW6QwFY46y zx2=cH(aj)5`3Tdl;Sat^C!_J^H)(WNG_Lpy;N^N^+RKl>N&C4PX}SI_s)|8NJ+w;4 zDTtoBhmk^v=g9z^mVz3e3)ezpySRlT<8(ZLk61$8!4)QYGw!{1^C= z9rR$lbkoqX^k7vBgo8qaMx})>!XgpJ%4?7Z8>6qXgIxUow$oW z=OgJyTTgvP4NPj~RshZRmu9{qbVPS+=|8ETM+ZLIa+*Hb@ja-4&Q?KBTA#Z>KWCCT zLNLof{%j-NAXRFuc-bb?NdCcZG@5ej@!!BB!4=rrvwKPT`IV&nmzkuz9@cAv9K>H} zqD$I`;+keUr43*YzOI@2YRtd2?t2#t!6@%G(fsn1GJ@E)4QL!))_bGUMf{~<5)|a)%Yjv z9-(@g6q)n*{17FSKOZ1HMDOs!0n%`KnfnDwJ-ye);oN{ex(D{V<0n2eP}-#?-AN*B zApdo|B~S|UGxrsteOT!*AFe~dzRhu-MoflBh;P>UzWrT00Zl z_0C2cLgP3ab@UPEBhm!8<1=2%830nmxe-oBL~ftUg1a94M(9W}Mo*f-e+ZTg zKCyaIlON|Y$&Tu{wyQKT0;%T#c9?432&QK*C&z{DXGdt@@s?Io1269?rP0s$@vc%> zU~H&wGBA-7TO5H9e^`P#mK5LQG(;NGBNyS5wxLs%a2S!UX*eo6U@A9^7lcSX=sUbT z1Pl0z?+%f|=->Gu-VI@_FF;~9-!->iV?9J|Q=v>5*6(s5@ zEl-`y0#6jQJnyfLRfpm1;y&~`Q2@nxRmc&{K}1=^)Wy88K!*kGWBhI!#A2@_?jg#% z;H>CHl*c+A*@*p*a;(J*F}fTwVT=kYNJKOlr%z3P3pL)V<*$cI)1@Vy`Q1=yg`}c< zMVK^SixUFpSn+tOkspD;MiWjz5cwrddA{5yTuPvuczU?hWl%s{QLJRREn8pO?Xtg=t-woL+45}J?LWo+yabJY<=zt$>K{VbN}U_n@QH3<8WEr=yi#27nw4Bmx(YPyL-K}#X?{i#Awhl6j;^EcCmX z(lJV3Z+kE2^hGJyTDe|YCQB_ZTYFlh*%JNT`qCz;uPs9-nJk`8IqnCQgHWFk^+F89;4fbyww9$CRlko(uli%s7nQa0^i#;%NfdqT zfG66iv74f8S`#!L^gtYbXGb31;#nd+e0dq8OgSnmxJ}v;I2htLb+&Y z7jeKSV*8&4N=u?ea<)sprFjnuWRNGQr&goIry#f+h~ zjP$<)6>Rm_3Gof@OX0lYeaXxE&z;gwULC0O<4>e6PAk35YCrXv^tB|%q;BH}*GS#1 zU)4%pJyrHy%iVs-r|~K;E3-?v!LoV&a=xodj`L&@nh}#@(Cu{ukdNR)r3<&t+9i3Kr)=Du&vw zbT%S<8w-UF>3SV`b^M6{byvy4_}#uzP}eF%#1%UNAGAy3VR0z9INf3QKq8$!E+G6# zkspSF7>Vr5@8i;l`F)5@Bmjs8_zTpbJ`>rwf8}jwKa`6$3~kJ~h9(D#H(vF#9LDSI z^5gRLo2?ezhzP#;yd1;FwtDyC`T#Gr^}F-3A&Y*_z5B49aJ06kumL>359>u&@J)SK zG~H^o^Do)`CHLufDlSw9xmtryr?bZ&qagghzQA#7u$D9^*QRi@=aQ1L7M*b^l$L0sX^ z*@h30x<3!U>*>sGXG9PPhl6LzY0(g%V+@0k~A zkr`s~40aIGJQ;_Rr z`ir&#x)8NuRz6THS1-~%qma1V8;Q$qEPbsa{og`6Z|T}bXBo1gy>TH!{MLV!t3|v} zjBA~f#D+@A4WG7}#9fc`Ev>=pB1o5&hhWIHkwfx9~ ztdD>CK^f7+plWd^PiT!lBDiKS8gQ(fq<-)<@Ggl9}w>h$|0Vo5qGkp37t= zLi4t%>1^aI&)$Y(hsJc2RpR*3j2R5)tJ2sA**jFl|CPs5xtEc3m2!i447DzIKm&PM?P;{d^QH_oM*842o-u@t?oV#Bq*{bJm4}R}W@P>-Mwf9^ zw?{IG+aCx&pAcQeDRD(#IcY0DG=%kxH{N7PxT2PtUqurY46KItd<7^`_s2ousPx62 zh?GYz;VZhrrMU-Mogpusf|E0^AU@_H7Q!EYh&=?eboWCn zSTb+rM;>Bv-u1szC)J5byvylO7ABRx%C$q;v{CC`V5V!}0^}XVRfot18&23#Xh?y6 zg#^+GDX7O&k%>m^XZ}im!xLRez}iizhC78WiqMcKgD}$UyNK-wKRlF;=uu&3N#A+U z@e^_1wOLOBDx-5!6fH|iLNh@c_ULq5a3mi%jD>1&!NH{TAChV=<8dqGt~tJmnq)ZLFB6- zuI?<4JkPT;S)8<^kuS<*^S#&FsVNoSdUi`|VmfciWbuCb%a}cOO+PbctHA9T-aCuM zOSNC|DOqgT;2lp$rh;dU8>hpY$taL;R9brCsV+c>%!JG6FpER6!z{_kSy)gYPCTDJ z!fGl(OEE|I&spHU#wTTyx^t;bgJBv$9Pz#5wh9W3S|B?K`w}t?*Yk*M_5dyA4`;J@ zC38AU+KHe%*Jrb?{OxR(DaFo1)RP4z&wbp_pn!grsVwPEPn-wuGTILRt)wzmQ#$s{)S}+|{rB;_IMZk4`Qgm)H4;{%ur9QB?q8*eSz>ke#!TiH9EI?8Y@Gr-(K5G4AvdNGqC+c_$ zx`$?kM<QgQcT8fB&^P$R$ zn;JJ-%zZ^Zj#5~Q6H2Jn)Y$Jkzy=HfJM%7*_y9W?JFo6!?CgkrO|FT<8D!kU1^bU| z#M2#1Qre`rr{HQdKychC%E@?7GEMRE)pzLEaf)n zTo?$kn4Z}pas`OL=%SBerdt=0Fob$_VS4P85~IcJkDzp5XxT)trBFg?|Da72NB^EQ z!vArqO~{7w$v%{xS_U%-I=}D=2>4C79BYH+)ISl*FcW=pXF{e2h?h#LHvmYgn2hd* zTvYm#WYRUrMKksxofUc{stYnrfPX;=&h~eECJQws^hZkX%B>FUMGSa>ZZpC8yNnc`l{Nxp?^mSXXEPy96!;=kVv zruQiw(#{KE8oo9c(nx=r@5yCLSnD6qMY(7dS3j7VgdWpJ#yO?<4SYr529UIUtuaWVGjxx08+4_%pyIhV>mVNlg~puX8}lIb<|+JC9yqrCE{~hZhV|BrmQCNK z-cJ70gN$oMW|-#~a3AjdI^_yhUFv8})V++u|J$-@4u5?n)A`P8K=PP3DHe?Tm{{uA zg{+&pqL)i%%;Jujtgp8buWnh9$CDmohV&U9Vs|&=n+zY4nzf*gMvv0e!b?j}PMlkK z^A#8Z%Wx&k$-ZF7x_F#k2!*gLcIzcUQx{k1?%A*`*}g z{f()0JNezmSP*@J2hL(Jb9mA$79BO=b7^0l57Jniz^b;=KEG+1I|iMtxA^?)tHPge`gkp_pZRFAKc66#ebRwv$!_4y=WBon+@~FxQh>-%@X`# ztap=0fQwfIc0S_EXS3l_eFHx-nbr@8&dB%jJ!zT4{qn^ML&S1ic}!pNtbA7J{V$lV zZkgJHAIfJsKWY;>Auc0atSpo_<+GkXICQ^3A$khZcMo2F zs2%clK<1@|ETkK9wA?O7MJI8K8M#bL5SIy;YTO+Sd|4q2_g>zirHT(OWP_y$B9vYb zFMXW(YVg1bA_zOD6;OZ6P#y7MpX%-BqT_>hX}I>2~m<@Mo35?Wg_MyB*$gU zc?xJ~66P)RkkyllOSd`Gc;w><=+yJ9$3dWj`0+y4Gga^J8n8+-7H`0U%|~F}ZS87s zGVxok538(sKuTN#a|B7aW#)y{X=`-jhaYEYnp#M*3J7$MK<+;e5~Kp}Vy9Q}q4QYZ zxEU+(g@ra3FKP)=|DYCBxTUzg+L-Evr<30>O?zj)Z5~2HcHS_Lg?rJ^1htB!ibee_ zN_qzV^SWynr2)p&JZLKO2~ZV}n9stdkYnvz^7po8f!JiTPliosheAm8HKFN_EGE_L zn?-9XzUi-zvFAw81fmX)W3`;=ayE9OS)$oO|ONeB*qUFf;}Zw7O~8$*Aq5 zd^y^rFO+N6{3>$MY2)E#vT4l)*Y8;I`?Bk|B7SR!6i+AW#>!`9(?~N+Zqd9ub$2e7QhN`miX!gtWQF&;r^70hGYWgEU?<{GxVkzA8omW>4}V1{igr{G%sek6VA@r^T~k z55M~a)6&j7qKL&O;L}a_*b3J4sw=XYH4C2@!4(D7Yd=!j9 zbw#uI_6m7<6JLf`?^3+FJ6ibeg{;ez=aC5Bcy3IU`Yq#JfnEZaEe?O#K(S{2WP?-q z_Kv-8{MO;Kd7~eMJ`$uF^x3P-Hyz=rp&!k(hzIbQ|v7& z8O!;vPqQt<*5R`>bx348E~7vgC$Yd%EG(qhzwralu%Jgx zSZU>n_FLxqFI@h%(1A)%k&g_%`kW#N;_cjJk!C#_eUuY0U@nK;yPdAzf?x*r?Arhr zuM4Z~G2VYMOOtlQ^M#99f~1b)@8bFJ5G;d&KHYmNf)T$+IN=ofh2roQh!>kQ5bfMC zkg3FI$h=AoOV3h+9_?mgiAvUx)coJ1q*la5MEgFxe=#C5F-<(Xn1u%EpQ86Uw4zCP z6JJuyq9QAvq)7)nk=eM6)*#b+w;Gp*2+g`xzYweUKD6Z{{#h{#^Qj*tCn+Kxmn0Q6 zoZ%OW*+7rxYgqhf-eU<{p&kPd&VIY6VHDrJgmsZJL;06W*q(v)3!y;QJEQl0_VvWJ zzgkKb>dmYJPLbnpMr2JG6z1MijaaP1?`}=(7sk}Nz4@M{h;Odq-z{bF5r3N7#oRL( z6;Z%yq?rfgBE$ADk9d|nR6||_CC7bN{sFULhME~CBUq8!w_%Gi?O>3ZL22z)$eUx*LWh^c-H&sqriWEz8 zT&eA~m884`DV9g!RETwnO?t&TZW&9XL6x^!692&73-}{)U8=%3oxl4Wiz;c-0OO#a zm~}&LR#rkTub|~OU~CJzxrA~-2;%(i2dts;5$gP`i>Nz?e(rTxe`^gEj*19~b;1q` zNmKV1Nuz(YU0{e^uSOsA_i$3xdwf(0sO0E}e0B-Tlk}hRBPFnCpW{s>Y?8WugG)%f zz{i!c;Gww)X4bcv;~C&g5zrFBmAJ;1dlu;=K-VJ~CUPw7<+d-uy0a zTFwSY#EbV>!LsSkyl4f}mFSiB7AJoNp&~2S0PLN)ON(eGH3_Uegm-01h#?!&LAWNR zhh5Skws*BtGN=#J8n-Jcb|gkN7C+>JvyV0hPh-U? z_X?KPeN6>O3~EtaV~d425r$FzXCj$B0QomA1yIGaRx*QR)bSN7*|4BY3vnmq`iZ36 zOWF9=K_35kCCuvpeq$w@ED@QHd7gztj>odxw&Ga)7E6kO)Nq%Lu&#L?hXa!NApd+7 z8>X7{Sxcgod#`3;y{*{6+Y69+e$i-)1C6=)V69d*P5fG{+NH^Yk!`<#Pgo87#&qRt zS2GCZh3zD@fgfAVW|q`VcAiRa0ELzxhWHW@K1Ee(yMXXxjLH?Bhdb>IbdqN!goRvU z%5oKxev}x@|8AF_rAu79eiD5%A0Y<&>GnFkyAFHc4jmx8#CN^GLgvN@lS+$$J0ar{ zIqkYmNCu5EIx;_^HFlH>wz0oM_dSTEEAL~YGVUg-AAvP=dYSsScws< zTZ1hTf?NoB2~I)ec(M6`)xs5FZ5*-%7^|GwPK8DgiqlYP(@%$?bKD97L5kuoSbg10 zYKZx!9W%A_U08d%J>c8f@h0LAZWEjw=NW5QT#x#xF0O{03=s5Umq@V?974&}^?;It z*`RFa8`r>mAy|MJZ8EU{I|8=$rNkj@YGFj?j&xn1RzM&#_)lwCJZ*KLR8>(YIo+zta_S73iiuQVvLIfE!G{;DWf}d$VUNc= zJNl$uqDe8&4nL{Tkc1eSq{eh5{xO|Msu6ws(ME}Yd6!Pg|IL3|3o5mHasM(l8t1Gt z%3v^=$C7(NSu@{M#&m(1LkMz&;NHsZ`gJKkT*jiMk>B%Q(ODCP{EwJyWIcB0^Al8Y z{Mvcu#TTz*{p4Cn;yczMiu+F~N$}1`5xjXF>qEQo$QN0BQ0a%z!B7KE(+9_1LUaXO z;dw8zFsPfecK!mRG`PN|i({(gFShQG6(4c8Q* zo7n>!GmrnV9%BA69oN?-qr|4=$IDr;dX-Kb&RsiE%bW0;It#A^uLsd-0cX`bO9f_3!eD8xdoVnao#gWGe;+U!{o)M34_!CsQjWy^HSV zKijzPPhz|3E2OeWYIJ?}%*`((n-8|IpdgO+3Z_x%L2PT*x+Ia;5nf_;5PkvYF+jPukT^t<`{lqy&csI0pV5%G_sC zG9%T7JMlPt71stK6uTg}W-n;26fslNV13Kx#r*U?%>mn&hfk<`kN?X9Z6`sL5 z{^%<#OhvC#(@5*GSJ-eGmDg7?i9_zJ3@J%%!v-IAMQzuly9Au4KfmxQ)2hsi?p=`R zwuKE+izs?#XiMS|K6eYd7@PDWggz2e#oYcB7u-4|sJ?NfU2VR^i?^~8DR(KqwH4+? z=@M(uYizA1Nc{>tH+=X*jXNYk6Joa>erfp4tQ`K)yRZu@#<&h}mce>(j4(QW=*xe7 zmsNLHOca(tTQV%l#nHePw28qsLb5q&Y8n6RJ@y0=`}$NO_V45WOKY(EOH38}`JyVY zf31~osbX}vDexZux1o9KqDRaay!rc<2`vV_U z&E8N2ZN8KE7;ma(!M*>E4XOts1U;pGp)ae<5Xzs}G7pn|Fo~KnClOP!5U+sp5Kr2H zu*0VFE`vB0{T6)le_^t>xZf@o>|OUL)P%r* z?7zQ}C+!jz)!TgjE|%vv8wy?AW=z3)2%ZmG8+Nfbs8l;Z_lUt|1cp?fJ=%7h@-9jI9(Me8D2`+N z_+A#KjcwD?br4BC@LR;gY1_Q&-{hJaHZWGf^45U4oB^tMmxRc|utG8%^dQB;^%gYo z5T93rcxnAUzNH3JUcsAcSWgy$mi&o2){EyhF{ZhJL4=H*rttZ7tdFxWqzQ%YtB7P* zyY=@B-@cE9v08xG>`6nq;aPWg^hu?N?5lgOU1QgUx-@nsCccWd>|+a5b(AK3&Wk>R zq$lh7>W|pKsP{jhraR;DB~OjGNb6a67P-;F-?)P#XR!^XoA}v}*w^$)zT3*WBxL*( zA7lajI-r4+5je@f*=`~>!Fh56KNa~cMUlM_EXO5e;b$C;=YLpnj+PsF=U#ku0*~F# ztlhUSg{SKYxmJV&przCq=oQ%oK_5412j4TvrhJ12HW_TP*BEF!Ivdm9tjZL(UKZOx}CPGl!yD#4*MR3DoEc-iAA^ zO@YJPIEpDX(wdtx>0KR)FRTcTQ51ZEC%~Ah;9y7zAgRHFh>anTE{rvCyZJ0!SblyH zOYyS~axGhYEl(_cq;=INIREzl^Ni3}t}`#;5|KQ9`BS!&e#u|`jCG?~)&rlxm6s;X z;b#x9cl}48x%kTXkN9|n_-yqr4!-3ej&L4%l7D`X<#~5Qy&Lb5ynihlfeSawYS~nu zBR}6pz|}?KzyHiH)Uw(1G#_<{4e?YXiXDq|#n|3DzV#5BAkkC2`4HQvsqmtvOZeXN zTrd98=WMl9+lvQ%fpA|gPx=BvA~TTB|AKvqq{pPcAwUz;&${SuOe1?wif-THZ2sau z*m!S!3zG7{RAT7~)~o+uo>VFg=C|rVmAH&_m`y_FeB=?fQe~XjnmmP99bxOeZD+_m zdV7QqJqj!HpTF^fqbv`1HjW*IiQ4Z+m$(pW>H$u_Vk;$c3}5{f8_e$f8_bzIRTIH~ z`HD?S%Di@`M*ZT@n`%5o0Ja_h43T*p8)^!u`_v z`Z2bWYU{rxHB0DCgJK+5hD;|RU7;3SR(a_+eDF7H_CP~}Ysx}*inSUsiyPp=j-D{7 zCrOPUgVp#HhkNVmkMW_cyj_PpWt0kuY!*{i|^OgCG*qYA&UPY zzwsSQ3#>pjh0)};aYdJ{)~r)(yh_T?ZdMs?{5~Fy>1lMd% zPd%J_H>oGL{m5oY7yiYyKf%7=%CmmL0f>ed;i3M=zg*#hvB*Fk4w-uCC$`I*7qlb& zdH&ANtW~n+@^{a$jjSH#rRCdS9^$3-NZPBN%(v9DE#CRHElCOj4`O%z;OXzn!o zwIqE6SI*VYIF?s8u$>eB%x*~@8)8pxu8>>=6vTF9hF-k8A(>{c>DauA1TsT1Db_1#IfS6EXyI z3##r4fVGnA@G%g-%?4rO`iG8Fdic#dX2_>^Ynsl}>^V z4@P)^H+U&s0_|zSf+UXJ=xPOeu7mpj;JYs%k!9?8#^@D3;XEt!IWCyOjkQ$%^?BAO z@N<+23NnIGp{eEFnCG&1R{}+})hwX)+FW>6Z zWoSneYCb<{843hw&D?U4 zI?G)$RtzJ~1MXl~owEceadQcL`I4Q5`AzkRMS?p9bWJvu@Y!~jgXAQeojnk`3sA*G z1eEvj``*T9S$!_CEr|4W=hc^?+%E9Lmzl2fEhG=S_YQ5Hmom7%kwwszd~hQ&ldj+8 zs~cIf%KS^Y`-(vAY9BA_+gI459d9aWer2aTRdo-6Rh-%VAKhXv`>8TNzUPC9UcA;* zmH*d5tI13CDXvY7byALXP-oRYB`@>X7o0q&;1i4d+w-iKHPc`9K9v;0?{@PEngtX< zlsWIorPkr*8zp($^g_wlkDnwLVj!+F0&mLOUYSCb)R<(`EnSZRdj)_+Fr{Wi1*-drWRn%RT?%{6&yYo_-@O<=7DK30y9 z+7)nXK2RbuRr>Rv`m54#TPq?#6`U4@50OgVL;I0MPKKlU3ur?}7e+`d#GTiJFU?8dPQdU;Vx{ zNqqFHzU_k&4sb^OzwqHm2`8!GRe(Prjm7Ow&n=UusV*dP8s%i;R zr)afcEEC+wnfOSA@SN4*wJ9-3^vHVPrePAmRRN!u`Vu&|Qqj2wKq~za0bWMOU+RmX z8&!M0e3q0yfOc=-yFPP4l4rn~l~Qf08Zbn^{0DCu!eD9($$kfYM7z3y#FYOW{^1il zKCSZ-Ql2_PcH?tx8~pGGT~$u+?t&I08!`|p7auniHisA}7$0G>14yf+6rLT7V*}_O z9rY>DBNl1PekLU?o)o=_e|05IM~aNNP!f_MKA=g)r9px~ZI~)E29<%{eMjWaP03cL zc$OKF#jnuP)DsxQuIXy1$S{aRJ3w^#O$EJfNCg z5)(v{&xzFns2Wap?Cbd_H7Y#QHPv_)XRB+c#K%6qF>9Ic0F9q9_5Y#l-22R#Af)5cB=4Gcypq{oe2I_eV14>~qe3ti9fQ?X@d- z9+%8-XRc z5D>kWvWziW{tFBu3cXj)4-d3~%}B)sTK*8e!jsm7P7cQkeU1=6K}xNy4EV@CzeZlC zu&*STNxYK9d)mo{hFErZtk6BjR>Dd=Z+IUnpQG*mln?jQ^W%i^$kc8e4ZDhV=E^M@ zQ53kem~3OD?m2=9#&+Y-9G8~Qjua@gr#KyaYEK#}bjI`)oA{Y922(Lp8=F4fnYV@M zlWCb}yJ24SRMuI5Od}l)ERY=h<3PD$gZ} zJb$u)>6_!Nlf}!P3F_QZ+k}jN2|8BP%^s(Za|te&jR#;>%bMIiwY=1pam^{j3A1x% zGNNPqvFDqUw3>SvYjmPyyi;Atf-GIn7q{X*!Iq@Xqh!eWcDFQ)ZiwA)QoEqXH~PlVg*ylsB?Hu7J{`^{ zt`>#N@(rBaIMy4;kVLH{4Ho=tMDw)ZhnC8#Y+8Qs{|S?nbQ3qf-MIRZ*LIFSXDo&f zaES#bD}afc{p_1yKC#xzi~j#~rH>uvQH(ePerA3o0nI9 z2=1AZ?49izr4_LM^!PT+*o~xPW89T<{yCg~6CZTO_7sC#Od9^gmjEx z3mzpxg$HdiuC9o zu?xn5ILoj#n+$6*@B4nE-kEQk@6VC;8Eijo3lSWn{R-NT5<(e-ApMZRkL*W~Bz=FT zUSSEO#2G6&TIG6<^b0IE_nefkpN%sbq;V9cBNsQCVn(|yh`Wt7pNcZhw<|hn&8Q?U zQH>sB&lwZ^+9(=C03Qa=1?ALD3v6lrk>fe?!tjziBX5{4e%=x@OL(XAbk*A>Sf~zt z%Tnp{$o@J$8D8=f{q_AOY=Sv1))UxXm@54hp3%#-j6<$p<66cdgu=ZM+Dn1&H(j?} zWZOP+*K)=sw#j48?vm@OxYG7hmpWeI%yLMQM%g{C9II@1rr&XyH?S{8+tmvI`mLj$ z$58*wGpYB94gzg$vsiIExXPAW(1B9rW6{3Z%s?lnjD+?0IWk>GWR+73-F`$1vHd&= z;Fv4m7pTTgqj>XWZ`##O*V)cbKEdWTUvynSzQ+z4tDd{gmN~u$QXa*pR9_@+n5fU$ zN9UaChAxV+n3ldul}Xd;$Vro z<$7Dnv{N{Ra0hSlcyaF`f_)iU$p4aF>?87bw=A|LC$~6>WutHCFTk+{ zH@h>hAwZV6kjk#HCFysloEvP3ep%%?HQgKfl&%h;*GN5S$>Um5S!xgADkrJZu6~9> zP)8_xk~g%cDPxG;>7fo`q3MKN!?9)5?M+LEWP7WI=>G~X{V}>tR2K?+!^2sFi<#)7 z%&&)E-t%`t0im*sy~U?e$=A8o?g_ax0ewLkgGhheTbyzHJDyXdqnttqrD7^gl1^54 zUhMI((YhKJlMLEXN{S}u_^|*dFGxKj>y@d4jTcYLDIB2)EhV2W?NZqP!6B%^4vP=mv$WVDN=WW^u<>hUU8>> zwccl&H&b5v-#SoY&8W%Q_XKYCa1P7hEOpFho8o83ftN8!D3!2eb8zqL+*{lZf7IcRCh^gDwUyAL zKhF<18^j@~*MwZ^AJw+Wh14nW7BW8^NsupW#6K3tObJ_iK#Y2*qc5>%Ue(<{oqH!# zlFxI2;RUO0GpwwcnQSmSI%^W&90gb%wVXoipNbNUgPev1XYS$}P-ms3GbJjn#uk@U z1yTs${(#I7Y(4XM?$*eYlMvNcO!)730}gm76V|fcsuGg+jcr2p2ar$rjquz`d)Z$N7eu?hmHd9uYZ;P|cXWu+@*|W7LBjBS zWS-eEA$3K2*rXc2u;QS)$u^pt3h&(=-Tr@mt!~NGeL~0w_RtmInKQ&^4v7k zUVqw_=#nByGhmxA^P#~c^(Vh=s?C@9?f1s2vIg7xvE~DLyI9?F$U043*GRSPZB0?< zg^2L3FB)xLS2q5kT~Utj)>!d}Vh2!dSP5Ko$K86X>iMfRTm9%hTXG`2`8}+zPP}@9 zmSsZ)q##gR8|*n4tiQd_mYRL{vY~Y`+U_5K!z0(Y2Pxl8I<-aW^aHjfs{DRil0ng+ zd_JZrCTa8Erp0-xQOhOj%WVpfvr%8}Z&h}VdgFfEjhi2yJ|j(-5i*jG4qH|XIf7Rf-VS$bD?;XqtYR*RKgZz|g&-Rk&5*z=+;ecZOhlKO|PryjRWvsl}IV;1Li zoo=%!i>3WH>e2tO-OX=T#unT6Y%w2xLu>1L_~*75t1ajsi8fuJ*I%r*=9ZC#io&rf zxWo2y)3@@#Gd8l_w66z&1gl6kEK#M7h;kS$cXIC$S1}pH#6XFbJCd~oO#7q~kf#I2 z-o9S_WvA_2*O}*cY3jZCcvU1ZiMsGv+f%moFQUD9@mDsF?%(G;C`kZGTy#iUb-=~s zufHj#)uV5CzJCR2kF6O)?JsaxZ-RC(g?P30eU^ic9PMC#?wAgVbC1o@THBi}2c4xH z)3L+oc6J|4iWuqh<0r|JX*>Sz_W#Nm>i(#v> z_Oe(nZhpYsl3eZ$J#vW_I)U5dg4ucjTbTmQB&CV274_v)HWNnzsVE-iTTWRjXoeFy zFqB}=yN5TEx3o3V+e9C}3g#4PNM)jVjPfC5Bl$Hvi)77xR0HXJR<&!GgisMnvfP4r7A|9UHa zh!N2z)rhfZC;M*E3IuG9MjA#0N6WJ*7m|(MZ@pP7=xd?zB(`{9i1)^_SJAHJ3)qAi zmEy#qb9MV?nhU)(d*KxQEnYtwS$N6X8!iZWX2>??VXpjV>^1M zp{;>r{oCUbJIcV4;95P<*QCCF-j?F;c~Z-lim%Mjcjpt>Arq}3qosmoc4iK@=z-x` z_Tu4vnwdwl&+6LAIVAkW?(Dlm3uSZALp(v$Ljn!pI!m*(-NzhDvS~(3M!W8)JXWJYCb2HOKQ$-T z;=Nf$63Zy==Xrd;J8xVC!vK>t6l@4=f=++1*HBMF8<${>(DA+en#Qx6jmy+po$4Y*2t+ zH*Rc{{;*m?`_J_jL&z=tH0Z%0=X7d;$DrRWt8CqmUg_+J((kgq;rzWsN}i%4i+`Z) z-p3-8vj_v9?4-MxUXh5Q8gHnGeXh>QFrNol7oHLhC<#sxNOMR9_0RR+_4dcN!jSMi z2muBCS|}dqJ`&rrRHn6*6FiSD7GR~}<_hb>r&MV`7}C#jwSyu2F)x#F`PAxm=-!pYw)M&FLlL3q5{Yu94xDu3)z?>*rJPqk`_d(EAGyk zr4>henR#kBe-C`h_$9Pr&^Mc{k zd_?N~p*#3!pSuO{=0)+YfBWSfMD3y`u!d%Jvl7-v>n@S?U3&G-KZ|?wxy=Q$v70Lb&n-=z&l@Ca@G2EL$jDGpIXyxOH9@AZV#^4 zLizBX0;X@yWN+Q=mJHR_ZA-7I8s)gm9fv<1B-+Aa>4KZJC28!VE+3`kmy{Cjb)z@b zM8?#b(P=GtNXa-30s8m?*5KmfS}HEdYguiHZK-gw69l>R>dZ?|=5lUr-g$RE^aDMu zKr7zjijpR*I z^=h^9C0ptQc_xCxanF{FtQ>8P92O+>7yd@w|B@~3lFSy5o_@fyO*@DIblgHj1ZyUT z@Btj~jCQtA-kNuhcWCwc*+XfPBpgqh1dNCj@Bk1uz=?$=`P9d>PPCKpvTaiAEu&p6 zm+CG?tO{SYWjSGrS(f;L<15timu(YsWN;;QWKLwzWK1|DIYPu~Ex#YbA6KhwFWZv+ z$(yPPZz#V>t#hpNG58FETA<5g3WrOSSD%2Hp2Tu{>i$1|wTcJG`$AC=okt4i= zd~(#S>$c4EK9uD5Z+7_dYlByUzkBDlT&<0BiDIPJts9D-JtT0HLpgka(C7K<>>;P` zN44aHsC4pSUaq&e^S$AG_dJ%0i4|*q56WZ8`^j?giY+hYQ!FoOSbm)ecRiG5b+!y- zsb9Wgo0ias->M1fy7c2aAKD0DZtnWv6`UpG7}J|)<}_|#>%WGVtk%+s-mu5DT(6RU zYs=DaQU$-Y-8+vLKgrRaYb4M53VqbT-VcYD%#Tp(Rwh{@{N$ucCv6L{3gbRYu>z*ExhnMfGfQ{i&9R4nuc-s4!b*?Mz^ zi8EN+GKFdED+|H|9p}*zDArA7z3e9}cX2HhAzmJa!TxCdtnPM%tPgI_zz(&eD|L)Y zZ^=RXG~JkRJ6sMfVjmOa-C~1vA^Cs+q=D@q?HkOQurz7hha=-K_prG`{aaWGAnlNJ zCU}9yjuee`MepVzI95MA$PMBLQ?<}Bw2J!mcXqF^Ce@sWqj9rrDsyQG*ckyA&~i|> zK(D&y_HG2d%jd5t>=qCv*Ujx-YE7?{59N%h+fQtG+y83bzyMriOCkxovhlh^-c746 z>^`;wk-~SGb+2@ZW4Uq;9M|2HoBty?|2~^^M$__wR zUtQ2$4We~2`f|ChuI*k;!+=v3O1s5rh---;Dsq((6>tn4WhxyBrm|7kmf0dmD|)e; z?;N^%cAw4eck`VrpS=^Swe}oYQTy$F&_`DWI3xY|Jv>_YRt9aaq#rVPo$Fw(w3#{3 zz|uhvq5OT~ngMtkB>X;rippkz{3{S|Gbq%-x9+QaYWnYNE`MfCC#!5S>0gOjMH2$& zmXC**R3e}RBm0@;sTaEs%yDW52Xf_{7gwink&h6(GRbb&nJT-bT)3U&`0!)RN_}r2 z@Q5E?)57}j7l5gD{km=e#mjc>pwG{w%&qoyOP^*{x0^hBB{U^-?r(Fp@cjM9z5d$4ug=Q3^6&z#nOgaQpIM{5}D#u|GgpuTeZXb+d2qA*pJN{i% zx^(IY{teUpt}tDZ@pItMLLA`agHBy*U5~~UTnudC&r-%PTZ2{& zKQ<;>l#l=B-|_L%C?A(<$5HLbDo0io{9d^FDw@)10va_@v_k#yKW*p4zh!TAuha6k zH7)86wkZ35*(S#BUkk$TTio5eR?Yk`+qvhK6TH|DSI2-I*#ASGSsWbd=Nzc!I@+px zw%YJtwrT#mFvUbA6m8alN-cbF1qzS!vW7EEMA8hyKZCboq%1QN=u}F2x8Pbi5F|G5 z*T_N1BQ4UU#F{uD_h0aC6(@a(G67}}bYMj9qCB{{G|&$MmJpC?wQb43p!T;OSzvD+ zLX3%l5HSqm^*v@`W*%&7pO#fPzZ4hscpVE1x$~MeE zkwjK3`u8K2QPdn1%jmBxe80$`eWcp^evQL7l)TzKw4z3J_Sz=e#1HYZI@oKQevRnR zr|8Ew+Kc!#-m@eQ$U2E9d1FQi>5Zx~z4aQNgTHcM$^FzVM$U0K${CFKW9+{{vNMuh zV0|sw%M$o33cq3O@Zrg1<$?It0pH^gIoE3{Q5`?GCghcj)z;h%af0KAgo{get7-a7 zlg_wrHVHOGm5Y857VJ_jJ+^q)Qh~+o8y@Q4afvE=+g8d67^?nlTgHVgNJpu?kY4q{ zMnv0rhgl9XQCU`PpbvI0Vn2&ne+rg+43;7JB3$*WhvNRC4!v#5E2x4xlj?m#;wx)o zV$%OyJybx9VHn@xmrT3|L&o9UpP@6U4FEVpo%i2_4`leXIsr^n(#WH6ltty^Bg7>2 z!8|T7I5H042+|4gUI*?1JU87I8&ZCQ+y?=s48!r4sv*|lOzZvF6j7Vl?+boa>uE*9 zmV}yYhEifl_18FGed38@V6dldwMiWwD8%Cg*__fK6hYrfD^=`EL_9(fVkWo}!)J*K zt+R%(NCdoKyCj|emGz3D{u$olW4M-nfUYL8VlEoW2~M38AC_rIz3Lt~HU=3m-#>eR zJt<43pw8s^@7ny)(`6l~(JdT$+)@M3{dnmveQx6ukLupg?=jKeKt&p5O?3TUk8{cS zJs!L;75vG&kLmF)1pYu3>QjFk5JO)V8RGeKJ&His4l1XeIlMc%zJAEmO8k(L^svP0 ztl0!e`TO(@nN)w{WwJYR_8#IT*GhV`Y7w{Cy{ot4(%gQLY6Uu=w_n& zG~kH~=6LIb46`&xjRy>S*@4kfim`!ntq(}ZIeTC5J4fu^PY@8nWee*1ca#D~M@=~& zNJDZeX9x6#FTiAM2|ZN)#Th<@k4kD;Cr_^o$nA-WA=tpT_zoad=In!E0$O z+K`O@B(n2@3dRoRL}|Vj)D;2UPCOHQchQO5#T`MMKcXy!hk9TNliU5W-&#^mh%OZ|{c&27-RY+B-VTDSVD2$Votu& zkK+_tg2*Z+F0^9N1i)Sf%~S(=p&7YfpU6=PZ1Y)(o@x4N=ZZ@z)2vV`mq`~sass{T zeJYooEo0Q--?JVLnVI{LS#>q{Aq#B_K&21zN%9yiL3Ve`r@;mIr1gxNc7W)3t@(+5 z+&kb*%|`Csd$~uD$$fS79-zy8dGsEcBKN}M&G&bp21`M3A0MMKy5k)!js(WGub@Su zxw2=Joph6&`eJ5V#wBZn;*L8?=cJQc^R$8&EQu~oWlc!S)mkCZ<2j!Xo0}g(P+6Lu zUYTW0ui3%uiB1@G55;0sh+dhc``N<=6Oq|8#qShsDnx!TmwU)7ScErr`=SmBkV*kE zqSqe&t2c0jkB`z3>BKR9#qevGp%n;M?9WA&sGc)BY~$B=H=|3Iu>dcfh;~5y2GX&f zsYG+Z_19!v`PkARA3Cb*XS-P*=+=gc9>YK=i`ZMDRFW;;d<3mjfRgj|xXPmdMAljlv%O7# z@u)?s86cF;$H&gvti}3XPs`mW{cran!Q{D+z%c;$(GE$gAv!C1uAYQmo9<$f(q&<- z`wa#WtyjL0cL~d=6d)fv<;SDK%KeU4-7UeVFYZX!oh|Ma-dYDCn&LqoKo+r+d?5Ii z7FvbcUp-x{6X$?~>j4_}>v1)wrf8uGNX3uEz3%x<8SV91i~AY*1v9*%&oM2ka7*@5 zCXs1TIVp7dp$yi~i-+MHGX1Bxejl6Vg9tuKPmeJ|l7|(%V@Y;NgFr$Ka1_pSNI)(c zo!{afkW)IUjl>rG40VsdEIKT%nsd-XL<$^3qzDA_7-%MX`j=BB9JJ;7SI;7#7VmZ0U5>^5J1#b5vpZfZ_N`)lAVDLe8LkL$*CFojyT&Yb zv%@J`t*xYG$2bHwr@seiM;=t5GbX3P+Z%O_N+u7%klrko)rHd+h zg7KYEMLnZURrDN>7)#>V`j#$wCl$*_8~9a^{kP3MN;C_yz}6j@De8@S^S^Dk=e-QO zy8ug2_^W=tx6aCn#B1o3N3e*5@yiTLEvzZt@<&@nn!0p&S6{^6=F{9o@_Yqb=fv;k z|1KBNMOvbj5(xG%yD$=jF4C)tPYT!ISov72k|PlqMuR{Eb|b&J;FIBkt*jM3MaQD} zEuC5mJfiKPsl=OxWB>LrEL2aEbzIrVYDUTc!Nd=~98Q&KLEZta@)uI)w+4*BdST~GhT zcAjo2H`F_SwG}4!Ue{#$BctX5Do4jXD(7#o^rzr>(Z>!};_smCjq$i$&~dX9D(bHV z>zwpc&Yj3B!OLrnt+8My9GIVn+Ul*VfgCDID_xa*<7f3T7v9ndbGsW0@l3tEGFv)BZj6>_2Q7^85Nf zZ1?lqwe&q(J=;)9)H{8)Jo&X8w%st%R}!8D$0R)gj7d6kPYcpz-rIE8_SD!j<;7Zp z$qh@?g-2{DQqL7f*iYjt>Dq9__Pp-@l2A<1r&bdt=6nC54rg&g-~v4CM<#25#hT8# zm!;!QPFKSV5OUpzPgqZHDZ9p7du%jD6G98&R1<7!&Zt6o<)C;^)E$)rMhv6Z9&TSG zI!bEI&47aW=V(;C3Rj#hLy_{E$lJd3Y+*TwB0y?iezvTdGEpJguRU9~kuu>u?KgzW zM5}Y6)t$sqDQ8)K2|sNgM?;vB?jjaHU^07WB|!$`lhSPq=9q#x*&1y>k(^JJ}d z*fMUQ3CxVfY@sH%uD}XjO_{?=9%?kgDL5JXkuM&Msy{<^Wz!}_y!_{B38^&3`rM-4 zugl&ZfRWR&K=lkH$_%ZzKb4Qz;q$8xY~#mXVbh9B#*<${hR+A(lhi*xu;tmxq_Xfi zKIY!B{10ujbxZ9Jx^DTW?THxw4m$EV`)LQQ*3L{f$vKG&ZP#L4`^gbjqQ}%6Nz_7p znObNk1D7>I;eN!sE?UKJHPa^V$W+dyOju4evlcD8nlhQSYGy53b|+;rYt_seWfkVf zKci5lt(s|*7dyD0``X5g>dWS~6fso~-|5|)g5n~Id_=;w`bNoe)Q@U?1~`fsWFhe* z+a&*whTK|OONo}sbX|FJKcma$Bk>nw0UpTG(*|5HlBL$P10l>uU#u)YfAbsG6qqjZ zKH$6%gmqgp&&cL>5=0Hy5R0}|{rcP%&%y=}n*A;?h~^0x$K#ks-zdUw>A9>y zK$7NG*0LEtQA9LNQdJ+@#^@PcYd*HUH9^-@X`H8%SC(fw~)Rep#U3aJ1 zml~Fo1zrEhvY#4xqU@1L_L6BMUd&s+C<&T{H2`@Mbf|%x~_wG^y)v*V_|DhJK&8(cU$3)8dQO z_FE^!KWbSr#m^2s{z=qc&%%7vwfN?elPw(r-9iCM?OdWVzd1Y z{l{wj!}j%KzsuC7x$pxKb6IB1nwfR8diG)aeEmUn{9${o{;pd6h&`8|`ya6{)fcJ$ zN9@<>x2nq?wZE(1sLoaP$@;Bbmnr-3$ZlQnxcv!doG)AF@aCA#pfxE^{V?5;mRtfM zgb33p!HoJ+ez_l1p6&L`YyQQpo2|mQ>;nUG&4jqES>3_tHRT_0o!!(kH`}^p?hz@s zt{8GRjURfCYxa%>q`JRJxr>7m`1a3I&Uf#sZQJcxrEkfj?aOQ3{*sR0bDhI=G?u@Y zd#QTsgob&qaqUBAa?{IKxfV_!-P)t{pW73!2~Z?0NsC=v)9aA*Vi(sAbQk&TIj(aU z&BO=19n!=Hc>ScgiM-oK3Xif#l~0GiH%CoRL)+CFn(+UJ6mMTXn?cNO& ztE{Xg;<4DI2OiAEj&((M^!~@( z2c;`?xsmIMCcz|65FO041MWOq*qIY4BVhg)_C)D_S-_2w__8Dnj{Gm*Kp%I|1P2Pe>;{H6Wclpu2yox5!W6G~fKkEz?9wog3o zFFeZu!?r#jHgn#QcL8cHW#=?qV*(fWnF{h-YVXtb#p7S%m3Cflj@5Q|$>(7>o2>B# zHKX00IPY00Zn|bDG6m+N4$8ps?!3vR9*6EBSy^nJ;PrOOL5ZPl@(bo|QH|~3x8l|z zc*`pf%cqfR_FyKJ$u&T{pKEi*xyIuxpLcKMcTc^>QJ{z0nV$xAy4^mDgb6b`?5X@jm`hTFFlo}SP-5qd= zGWB=4W4=4=QxXn;sO{Pcj!cXo)hsomleVYIPue8wxS>f@1Ob zlthrrN88l#XY859>-jF5da{`xd0flA@TuN60icc_9K*5ZO=4#No-3Zte*k}|DiXk z`+jYoqBnL0ersFM$|3_UaVV8Y@zEXXEmwg!>dTtl|$+^-l>l+P+_Nl{N_UV?D z}!$-YA0*46)#z00Dz)wbV2TkfvF zZ|r33IZSTu-`XdRktvu6>Kt}7EXoC!yM}&ipKEo_cZG-Yb2aZ(YW}&Ze$~EN@9jGM zDs|{NUCFTRl0t@TE5@@v_7-T{<{4go4&E@?{C@1>FhW=`3L(nOUx*hchEjl?@-qq z1Ov9I)`Rw&c=+`}`%hH%pu?sb5733Z>d8a)OUYe!>=688X4lxa?Uk-%^t*Iaq)ZmS z>uyQ#WMJCX&*{4DANIFLp5uO5pZybyI`6QNHMUHP>GY9!T@Ff4`n5NdRHSY>YR^}f zePCpCy>is<)6Xj-;15T-x%MkDh0Wvfy#c(3vCZ6*#}o}N);glk=c$Ds*e_Y)L2U{R zKQOitC2}t`7i_Y$4rA++FXz_2rslbQO+THhHClG|HQD*I?d+SQzQxAuy1G1V~tdU#wH{fw?Rg&3C6wpYh4q@8e8=2Z`JN|;0}(| zzLM6e)!!41aeR9+(a6=GR1=bn5{@5Po2&_u3OTK z&AJo3z-UN#WlmRYhOxjgLJ7ZOqOsntf2L4Fk`0H|hvymRTD*N~)HI_r=3Ro|)aBES zH1*%pjH%A8q=+~|k8V*1e>y6&>zwIEdyK{Vyn1t%aYIZkA!+LJ^NpmgOY@C1-7@vG z`t35;#IEK7qgrQbKPxmo(a+y!XU~O&r8K=$(0=%*T8Nwop;W+)4{6uKY+s89fqhHG zP}O#0+ZG$CnZgx+#A6@BY-W{B9Gem+Fuc#MNbI(E< zX%*Jf(90^J*)h3ByorzD)|A)knG{)==>6rZ9V`TfdU-AQw6miZGdftQg;?8Xn-ED7 zkd-17%nfPm6e)We)sKwR{lL?it_1`(VS`W$+(OdWtl9~;u@0`b)H>4(1n9+dyYIu{ zf--)!5ta2EAT@uB77!+bXMJb3Ro_`Mi`@sRb*`~2rpKb~RA067FNaVIypPhj^zbbGbl%P*8VQG zw4Qlgvdy}1=;Si;1c1n*Z#UED5q;>`HlhpCbhJDDbb;p8^b3ud=_Bg>`G|VITA?;v zXq2S!IC-VULTp;6Y=L#cV5&Fck5r8h#%B88ndl8Y%Ek}be`A4t$c_a^x*S=VUGz6( z0#p*1#AkapXdTkCpg<@0{Ek=XSrm6a&y7DD*|b(;D^!fR>tH@W!H*PJAwjTsV6M(4 z407+0)q;svLi?=`t8r;`^n+MVq|&bJ~|+<*k}crN!#XF<56r_pLPyR*h=}n z<)8)v+BZiF^j-_POkU)X=ur9gQnk`+q>dNZz4Q6-?hnB#y0@EIG&4vD{U9^EM&fvR zBs<53tst}M#u?Xn1Q5ReKzYXpYOmKwx;kQ-4Yqg#Cl;^`ivy9fV>J9_+G(K?t>MRW zwT1@%8u@GD@1D6?`3UKTyXT7Fb(CRN-l=y$IH8O*gz@DU)jHTq?YKOqcCRWeHKt$D zZW%weoDdrEgtO=x_-X~gR<>}=zpl;S>A;0+iR+m+adg8xOPqISjH72>?q+T0L@V+h z(#)}1cDiRlEu>E7KF|vfNl#X(C z+LxLv2b*E7KK=3{ans7?pS?5`4NZF&yS2-jGCTTSuYP&qBdAL3p*k)btT#b=d7w`* z9T*>+G8;0=!q}`rTk&lvE%yCN%TH$2e%po( zo6l@6COV)GiHI9HK#Kk~CwF)QHLNqcb2**DUZNdbF+)4Pj}2U|FFvs2lh^ZYEzn^1o~|;q)1qzqz|QanFY%COb`qbf zSYr+K&C|&nq;=McDGzwdwrRUYVw_-G3JH0Kc~?d@mR=0Qx*JKG`_h6dy7g<+a~B)= z-{)~~JBTl_x=lnmW?9wYlHUd1>*A5LMLfWzJM0|(@5a+G%51*Fe65bI!_blHy z%DeFos(&pvQdHd6jxqlAd?BuK}E`yE5R z6~GBS*H3Solc2YX7Uo`;F}BRAh3kXWM9E(2lkX%_ZRvKsb&o`=0l9LNuj=7(lMBng z&MNfOWsWW9<1bMage5z!|5cl#RsHr7Bh8;ayJC29;iD&pcR6nDsoM{bJpfs{v9by5 zW$X?t_jb)&XkHgEW|BcTh^p*`BzwQeDtZ;6FcF?0a-DBU^{MUl$WYj==wc{A{ZB=` z;8Hsn$fna`A5ncK>^8F3R$X6aB>5S{duR``hQ`8k0Y}Rf2Q6cY>Y%m4Rh&CaS`fjq zUTS`j9i3GRrnjZVEf{iKfX;*r6n^H0&VmmQ7d+1MAbgS~v*N5t+L{GyQW5%N>Z#zuPxP+Y7|CU@mX~@A;*4$>PlyYO*h4Daq=P9G; z0F1Z4jZI#svWlE+Xe*(Tk64a~4!xS^qb7Spmz^Bm{V(3T1*gfV$?EQM<6M8=bS-pz zl@|E)5-oHy1K9E1i)Mce6S&!ydE3W+QokZEw@{zV=%s9jx-{7vx)*Pnl-20t#=3NE zRu$0&D^CnBnF2NqT&bB+FvI+Afq}?(HOzcPLTPcuU{R59xjdJ)>lppunSW6ya}`VH zR(~7Egt(uF&IFOT~LXV-FA9a1#T( z3CM1NU*u4B6P>&deAz=MIg4sZ4eYe$`0(x)Ix*#VQPBXbmHZaF6Ezn0DkGH=Mq^f* z^C?mKRN6wNmqsd;Jw@iosZ>Vp;+~y6k_}HaaNfdwxnx=moVWU-Adk= z@G_E=RedyE0F{~Nn~Sz6W$z5^De^r^*+FB?O#{Tp6gC7LgB#w~6J!A>EFdKqbt}CQ z)wLhwa_bQoQ|_RS*nS#Y#~E1dqtvEKV}if_x2UH?3H6G+%+*5MkPOkvwxRK#xrVNy z*CNUHe64rvi6t(KNqP~fB9%+sJ~>}&8}e}hDlhy>b_Ys!JlWqhgr`pKoAb2LJ3KpK z)BL+cp(U&^^aKPph<3xMO)~@87uqsY3km9H;c1h`B|sv|hn|pUiyF3^HAC-@#k%#DH50ucvVo{$=(NZt&;NCnyDI;iXAe#=mvvX53D`rQ34@G4MIipv{qu(iY2H;f z)$G(79dhxh;_reKu+Cs5UF2<_-`z%fCAKs)j2&dSQX|jIu%X=oPlhN`UCNTvz6E!1 zwx8!7aJnCm&IJXD^$875c698qBn?zST*GTg3Qo`Zi%ecu+|RwA0MoG|_P3yRx6rM- ziMum(Q6}_gWjFw*532890P9M^4Me#+nFR$Z63W#jY8y!>*wLY^m6hu~KkQED$(6Ney(Kzq$(4|p1Awr@70zQY14&Ivb7G0%Tn+>BBstq5WVV3Xp)_J@QK2zz*#;fd(h{u{)VZ1Cj zsvVRDQfNS!k!+cD6H~#67Vai#Oct>fu`{vBZ%k<`1AoidlkVU;lc{<6>)~BauHE-7 z=$2EZAuM%ZA<#BkUWqzqsVb5eJZKqC-CJm0gV=d!8JqC+pi!7&cB&8-BMbLl!g$k( zMht^DTGvtt#i#v&5r#bys}SWL${dqZ+8j=}E8JQPi8#O4zu7stu+0-9rPBkkgbHef z8?Wa++Hich;T5Pb=cHpNii8AjcZ()K15U4|(#n(I%1 z$R}S~(n?px7lX7HP3Nf;2X>vP;Epko~a!Mwhz*`>afv$Hh4 zW-nncpHTk{RKz~SY!2#YmY)ZbI>bw`;IC1uzL($){DHq=eN0U$HrJbs=CYGUQ6BRx zb7`RiPklPPOGfV=WRAJcW9>Hf)8T^Ec*R~P$S#)mE&|NiA#dn(O4CJ35xV`f|L@{4MN7H^@0>kOuJ0qUEd#w$?; z=DP?7x2F0#OHprxQOHXcnBs!bI8rogjbM2LBqNbTDoP3yZqqD8-Eh}rsshv5I&d1`+7cm~In_h!D5_-1#r%@zcOC7s9nOZgjMjVc=}!h5iNB;^8~sZ11wy=~j~097XOk(x6o{ zNlzB|qu4CaI|7pul9UmPf%y5*u<{YqP;Om5#GbgiQ%wYiGrdel$cbAb%I(zezi-6( zeYqU1{SYg}PFjKIS|D~4?kq+fZ3#=xAkX{xI*+fNU=y_33WqP~{|>{(-W4^rdQx7S zn>zd(I59Ra0*ail8J4BTtP!{$hSUW14iG}5X}0e5pVmsXugW1}XS^oc;0O)lK;9g! zZZ6;nKGYyvIYJqt0x=f^T_;@2TnNZg0NJY-YT?cTHdg%>y&vH^G9MW-9~YuO{I4J_ z``=+I@cfSmJoiKN0?*z>7u7oS%$dE5Vrql$c>}%kwZPsBRmNf?V^#-H2?7=IwjEh?}|Zt>GnX>8y1o`ftzB0`kcnJQDBI zVPbUK&}E;vZ9zx#M9^Ycn4>zeCpvJ!co?tPzFAP{UZ`!W_3|MZ283eT&e=#|vE+hc z3&M$sM>qZMeK&^DCn|u&rPnY)(?jZ+9~o)aY|GYmtzw!4)1t2sF4K7}dOCW9>0W+n z-{H838*JcM4e0F z4GJlp6Dbpf7hgY0+40_t()u0nCrL}Ut|=NrCREyK*! zbaDq>&dee&KL^MHAyXaNSh^hdfxBoUD(XhjuxU(o;#R`0{p@ks20uDRGD~3x9uJFc zIHhFI&U`Wx%e&;_4fLYLV;%&);=6wd`f@!?x!fO9jr}o+aV035ZoT=5P_EXYe%Ndz z>5r&+KQN}m)U#Ded4FJ>Gd>;WlZFiM{(5-#&2mb^^7$PZK(scNoi%FBHbCCe>&xNBhTxQ?sB&@S1y&#cm-yjYW|n%y79mzY1RpR>?*T^CKT&VZ zJGi3u_2%=7NcVpx4Tpe#K8_nvFEhYp$qee0ky~l!`Z;Y`cj*-!P@`$wr0b|qH_mC3 zT`?)eTAjHQL3{z14Ht;ZNYFtxJ>PWM@RBUXU&)*~sMv!$E$^Pv+V|AsR~hHz*TCxj zss+OAEVFZEVwk372t8Z1UE<(�XL)&vg7r^Wa|H zMIK_LYVIRTxPu5yCm6r~AuX_9IH3A?X{<4MzxZ9NHBZ)Qtpi6wl2lPf6(c{7m(y66 z#-{s6zRbpa2{RqLwJD+djN4>}wnoHh&J&;~L~lV84pU#4lBEC593|v_JgsmYl(q-Q z-W!iozvzG1ir)0-Je>shPcppVJMLO$+!n2KYyh0a@FZ1Yelj;@2%r;7^PV$`%{M%IK8nE%KW4sD-;aXpQ_ zwB}r-t5wU4nHR&PM2S9%-&mT6&cl(Wu!NDsPvUvZ!4cXV>kSO@o|}D<)iC`+@UDPW zigk0;UzQm!5b<>X)kf;~c|zu{gbohrY9EUTM%;=ovK{t^i@W&P0k%7d1VxgXi~YB1 zr$v&sTN7vZ@6!Su3lh8cG$jpfZA$!V4@O8cDw*R0b@FOse!@v+`y!?;3%Zvzlrr_* zYgoiRpf)TwGE)zn&EYA^MhMnj=psJ!!CQ^w(GgiJIooeLF|1VIa>Fx&FIuC4Q9c*MTY*VZoaIp&%Z+o-EkiV)1VAqmCJ^h?0v7>@APxaCMAYo0TgN7A zp|ZQwW!D&~`aZL7nfuQ6t&gWcjK5}l$;}&dPuTPP`{hO);ah)RZk+Gu<$v3)NG1QX zTT$W+8!v<4rR?N;pSc1Efe#q-hoI3vBkWg{95L3}cFwwimjBcONfHbpFuk#iy!DZ zCb&iWJHqp$Jd2L&l=^O!F%`(wR~ec7JX&R3s2;q|ILF>>@2TrwroOH+GD>SWT_yG| zjlCSsn%5dEU__xjtl zhV%bxBPY#99Mmp&lBr5p8A;)`GR?N8s^3=`4x6}_ovL+}kv5mBXb;Wd<8y69Y|05v zC+J{4!xWJ09Z@Dc|0IZUp8ETB#?-ToHC7o(S?0hpJEL_<%v*HvMCw%8HyY!<-HGfG zod}_c3q1wdh8$)E={0Ytz1JF9Ggzj6Qf-v@X9};?)(pv+Y7*S20|lJD z>yhkr%yOMXR0w6EN6M1fVX$DB15bS-{hyB7F}1o)B7$fKfCFpehsIwQ zibATOhJckb;w_^y_VZ!21V3-KPu$RHosFCwVb=UY#NE1CIC)y9E-{}w!ev)h;W0%0 z3>yXXhUt`V-lx+tPe6zmk#K;Yhzcn~Vz46AGCyOg$-VBV0^P(M4+Ujf-_CwKZT(jpTq|0e_jpkzCM0XwkR1Ao7-wjI)_- zA_lmcevJ|DKg-FJI`@1wtb_$WjvcY(Uojm~1lb01G{7}i8a;JpN8pr=u;G=Wk)fGM z*&`7RU6yGZd=Zx+R-zjai>9B6QZ~q7BrVaMX#5drs`lMvjA!e|;hT)`_J=H5lfY42#=D~OUV?t5RnhI-7@+M<3%i3H{@9O>=wXB#5nNI5 zn$CTdaJw-*UMLM;jHyGvtiF4@F@8c={}rT>UJDFZKYX_M~n(;1|VEsLXS5mCPdMJ?fgGJa^bvTKW@~oxBE=aB7`W
k1N4A!i}H=DRM*K+lS@*C2>_0 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