aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordan <dan@noemail.net>2020-06-09 17:45:48 +0000
committerdan <dan@noemail.net>2020-06-09 17:45:48 +0000
commited41a96bc1e3a6eb011330b0a109ae4fc703a14c (patch)
tree42785e67f3f092e33289b83b2eb768c1af9784b0
parentcfb8bf6a501ccc5f67b9ae84ad1b6aa40bc1a374 (diff)
downloadsqlite-ed41a96bc1e3a6eb011330b0a109ae4fc703a14c.tar.gz
sqlite-ed41a96bc1e3a6eb011330b0a109ae4fc703a14c.zip
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.
FossilOrigin-Name: 16a41fa8c4c74bba4e908a9c19e6cf5a927cac140e2070c9abf303158be7257b
-rw-r--r--manifest19
-rw-r--r--manifest.uuid2
-rw-r--r--src/expr.c20
-rw-r--r--test/aggnested.test47
-rw-r--r--test/window9.test4
5 files changed, 79 insertions, 13 deletions
diff --git a/manifest b/manifest
index b8ba79ee6..cb430643e 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Modify\sa\stest\sfile\sto\savoid\scausing\sTcl\sto\sallocate\stoo\smuch\smemory.
-D 2020-06-09T13:53:56.924
+C Ensure\sthat\saggregate\sfunctions\sthat\s(a)\sare\spart\sof\sSELECT\sstatements\swith\sno\sFROM\sclause\sand\s(b)\shave\sone\sor\smore\sscalar\ssub-selects\sas\sarguments\sare\sassigned\sto\sthe\scorrect\saggregate\scontext.
+D 2020-06-09T17:45:48.153
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 5afb8dd59d5617e0eb25f91143ed042b6cd99c006352bdbd441cb9638d2602d8
+F src/expr.c a72ee44af014cade90746871e90f57a16f97ce5e5d1502e29a556490fd267a15
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
@@ -1741,7 +1741,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
@@ -1867,7 +1867,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a53bdd311c4154fd5e1131efbb9665362f79db5a35ce9f7b1547f74b8ee2d8ba
-R 8d5a1a9f2ed9a4fff418950bdfdce962
+P 232431f32ef77a9dfc4eeb7765dca24af72051fd5460f648d0c5ba318c8a01fc
+R 0227801129ea01db7bd6b8fdef42c443
+T *branch * agg-context-fix
+T *sym-agg-context-fix *
+T -sym-trunk *
U dan
-Z f464d78ab773b9580c31ba7ad2e586ff
+Z b0984ce04348fe30b8ef7dbc168a8647
diff --git a/manifest.uuid b/manifest.uuid
index 3aa4f6d09..0f7761b1d 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-232431f32ef77a9dfc4eeb7765dca24af72051fd5460f648d0c5ba318c8a01fc \ No newline at end of file
+16a41fa8c4c74bba4e908a9c19e6cf5a927cac140e2070c9abf303158be7257b \ No newline at end of file
diff --git a/src/expr.c b/src/expr.c
index 555b2a8d8..87dbe617a 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -5654,11 +5654,26 @@ 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 && pSel->pSrc && pSel->pSrc->nSrc ){
+ pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
+ }
+ return WRC_Continue;
+}
+
+/*
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
@@ -5678,7 +5693,7 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
}
if( i<nSrc ){
p->nThis++;
- }else if( nSrc==0 || pExpr->iTable<pSrc->a[0].iCursor ){
+ }else if( pExpr->iTable<p->iSrcInner ){
/* 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" */
@@ -5700,9 +5715,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 d712c840f..dcb1f95c9 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 46d746c4f..c342a4d79 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