From ecaa9539a8f90e6e6abcef017815d8b0696ab075 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 10 Jun 2020 11:18:28 +0000 Subject: [PATCH] Ensure that aggregate functions that (a) are part of SELECT statements with no FROM clause and (b) have one or more scalar sub-selects as arguments are assigned to the correct aggregate context. Fix for ticket [7c6d876f84e6e7e2] FossilOrigin-Name: dafd2466a10f68acbe129010216f017a5fcfc048ffbc0da806d04f04e58cfcbb --- manifest | 18 ++++++++--------- manifest.uuid | 2 +- src/expr.c | 20 +++++++++++++++++-- test/aggnested.test | 47 +++++++++++++++++++++++++++++++++++++++++++++ test/window9.test | 4 ++-- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 0cb3ae727e..84f9b2a8f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\s"push-down"\soptimization\sdoes\snot\spush\sconstraints\sdown\sinto\scompound\squeries\sif\sany\sof\sthe\scomponent\squeries\suses\swindow\sfunctions. -D 2020-06-10T11:01:58.755 +C Ensure\sthat\saggregate\sfunctions\sthat\s(a)\sare\spart\sof\sSELECT\sstatements\swith\s\nno\sFROM\sclause\sand\s(b)\shave\sone\sor\smore\sscalar\ssub-selects\sas\sarguments\sare\nassigned\sto\sthe\scorrect\saggregate\scontext.\nFix\sfor\sticket\s[7c6d876f84e6e7e2] +D 2020-06-10T11:18:28.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,7 +485,7 @@ F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f F src/delete.c 88047c8e59878c920fce14582bc1dde4d81157d1ca5ffdf36c2907e6d41996c4 -F src/expr.c 6ac12b2880d67cacb18a0164abc9ad7bce8143a29161d1a6ae38232eceb38ee1 +F src/expr.c 516522463b0ac0d02a9ce3842a5167ab54e876628e1c08551d6db90359bb07ec F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41 F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0 @@ -629,7 +629,7 @@ F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54 +F test/aggnested.test 2f65ec8132e0ca896de550b9908094d49ad65a99116a9d79deeb6017604ad4f6 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test 25e109787dc5e631e117eb6e1c57f96a572bb51228db3b4f8b5f41d665e2ccaa @@ -1740,7 +1740,7 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b -F test/window9.test c22c25377c820613e1842fe7ad4af7c03df625f6a7caee99e6fdb4fcd52e0a8b +F test/window9.test 4d8c875b73febdbac9b8f2b52ec132b98f48261cdafd6b08db62bc6d8ff913fc F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 @@ -1866,8 +1866,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7e2833fb2be8e7df5b25b8db73aed60ec81780bbd3e4f11a43b5eacbd5bd01a7 -Q +094dcfe779613301521e8bb990432df187b3686add75a3420b4a193f02f3467f -R 9454a807e31316909ba248e12e498e73 +P d31850fe50420cb0d2c48f19741b889700c52d0d0273967eb4b81571a4ee63a7 +Q +c29a9e484e1dd245962afbbf511b183462af5e86c511261ccf018345e773f940 +R 7e95df3de7e9a7c65233ec0806a776cb U dan -Z bdd9d69ac053dbc3f361f19e896ab22a +Z 91486ec5aea286575c688d300b3796d3 diff --git a/manifest.uuid b/manifest.uuid index 95150959c1..da83a48f43 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d31850fe50420cb0d2c48f19741b889700c52d0d0273967eb4b81571a4ee63a7 \ No newline at end of file +dafd2466a10f68acbe129010216f017a5fcfc048ffbc0da806d04f04e58cfcbb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index da22eece70..774fc632f0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5655,10 +5655,25 @@ int sqlite3ExprCoveredByIndex( */ struct SrcCount { SrcList *pSrc; /* One particular FROM clause in a nested query */ + int iSrcInner; /* Smallest cursor number in this context */ int nThis; /* Number of references to columns in pSrcList */ int nOther; /* Number of references to columns in other FROM clauses */ }; +/* +** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first +** SELECT with a FROM clause encountered during this iteration, set +** SrcCount.iSrcInner to the cursor number of the leftmost object in +** the FROM cause. +*/ +static int selectSrcCount(Walker *pWalker, Select *pSel){ + struct SrcCount *p = pWalker->u.pSrcCount; + if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){ + pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor; + } + return WRC_Continue; +} + /* ** Count the number of references to columns. */ @@ -5679,7 +5694,7 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ } if( inThis++; - }else if( nSrc==0 || pExpr->iTablea[0].iCursor ){ + }else if( pExpr->iTableiSrcInner ){ /* In a well-formed parse tree (no name resolution errors), ** TK_COLUMN nodes with smaller Expr.iTable values are in an ** outer context. Those are the only ones to count as "other" */ @@ -5701,9 +5716,10 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ assert( pExpr->op==TK_AGG_FUNCTION ); memset(&w, 0, sizeof(w)); w.xExprCallback = exprSrcCount; - w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback = selectSrcCount; w.u.pSrcCount = &cnt; cnt.pSrc = pSrcList; + cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF; cnt.nThis = 0; cnt.nOther = 0; sqlite3WalkExprList(&w, pExpr->x.pList); diff --git a/test/aggnested.test b/test/aggnested.test index d712c840f1..dcb1f95c99 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix aggnested do_test aggnested-1.1 { db eval { @@ -259,6 +260,52 @@ do_execsql_test aggnested-4.4 { SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx; } {3} +#-------------------------------------------------------------------------- +# +reset_db +do_execsql_test 5.0 { + CREATE TABLE x1(a, b); + INSERT INTO x1 VALUES(1, 2); + CREATE TABLE x2(x); + INSERT INTO x2 VALUES(NULL), (NULL), (NULL); +} + +# At one point, aggregate "total()" in the query below was being processed +# as part of the outer SELECT, not as part of the sub-select with no FROM +# clause. +do_execsql_test 5.1 { + SELECT ( SELECT total( (SELECT b FROM x1) ) ) FROM x2; +} {2.0 2.0 2.0} + +do_execsql_test 5.2 { + SELECT ( SELECT total( (SELECT 2 FROM x1) ) ) FROM x2; +} {2.0 2.0 2.0} + +do_execsql_test 5.3 { + CREATE TABLE t1(a); + CREATE TABLE t2(b); +} + +do_execsql_test 5.4 { + SELECT( + SELECT max(b) LIMIT ( + SELECT total( (SELECT a FROM t1) ) + ) + ) + FROM t2; +} {{}} + +do_execsql_test 5.5 { + CREATE TABLE a(b); + WITH c AS(SELECT a) + SELECT(SELECT(SELECT group_concat(b, b) + LIMIT(SELECT 0.100000 * + AVG(DISTINCT(SELECT 0 FROM a ORDER BY b, b, b)))) + FROM a GROUP BY b, + b, b) FROM a EXCEPT SELECT b FROM a ORDER BY b, + b, b; +} + diff --git a/test/window9.test b/test/window9.test index 46d746c4ff..c342a4d790 100644 --- a/test/window9.test +++ b/test/window9.test @@ -255,7 +255,7 @@ do_execsql_test 8.2 { do_catchsql_test 8.3 { SELECT min( max((SELECT x FROM v1)) ) OVER() -} {1 {misuse of aggregate: max()}} +} {0 0} do_execsql_test 8.4 { SELECT( @@ -263,6 +263,6 @@ do_execsql_test 8.4 { SELECT sum( avg((SELECT x FROM v1)) ) OVER() ) FROM v1; -} {0.0} +} {0.0 0.0} finish_test -- 2.47.2