1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-10-23 21:49:02 +03:00

Correctly handle aggregate functions that aggregate over the rows of a window function query, even if they are nested within sub-selects. Report [bugs:/info/2026-10-16T08:07:09Z | 2026-10-16T08:07:09Z].

FossilOrigin-Name: 7522512ff96d869c46596e7d514b65f210530db09e6359c2f37911d45f34979d
This commit is contained in:
dan
2026-10-20 14:07:59 +00:00
parent 4855cb2a31
commit 4f5062f0ba
4 changed files with 82 additions and 17 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sthe\sCLI\sto\scorrectly\shandle\sa\s".exit"\simmediately\sfollowing\s\na\s".output\smemory".\s[bugs:/info/2026-10-20T13:13:50Z|Bug\s2026-10-20T13:13:50Z]
D 2026-10-20T13:45:54.887
C Correctly\shandle\saggregate\sfunctions\sthat\saggregate\sover\sthe\srows\sof\sa\swindow\sfunction\squery,\seven\sif\sthey\sare\snested\swithin\ssub-selects.\sReport\s[bugs:/info/2026-10-16T08:07:09Z\s|\s2026-10-16T08:07:09Z].
D 2026-10-20T14:07:59.158
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -888,7 +888,7 @@ F src/where.c c8e8de067a8f6401dd7cde59b9cfbbe49ad13d5ae60d529110d2bd52df8b9a8b
F src/whereInt.h f039ad303bc2913de673e431821ef8db3b619d249e6e5548d90072a684e72285
F src/wherecode.c 1a6d2999159b28d8c0b968458b90ec183b3813cb332c11515ab60a73db5c07fd
F src/whereexpr.c 76f72a95c5cf0e8a8edb679ca4fb7afa17ba45ff4effe73c414266510109e701
F src/window.c 79a17de595e62aa45961ef1cbe3392e7ebae69fdde3fd0b0200254bc4647025e
F src/window.c 88ae7299cabf3124639236accbc2fa461a81473232e758c85d016922bf5061ab
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
F test/affinity3.test 9b7d1133e11d5edd7805573c4ab6f3ba73b0b74a1f280d5b130d4bf3506a93ff
@@ -2147,7 +2147,7 @@ F test/win32lock.test e56d7a9b6cf9d5f3867c2dd19ff36c5326881e4038c6867610ecb3a986
F test/win32longpath.test 2641e3a5dbb59f49456f6caf78c0acd6ec7dbba27cb56363bab8fbfe93995caa
F test/win32nolock.test 95854dc0206b8a95e4aee15a76acc082767b38f079b2e24676aed6cbb0f32798
F test/win32shm.test 7fe1aba2287033af64187597b6e9afd9878431d0ab4391da94f8ed85b0fea228
F test/window1.test b46d28b9698559e66aa4adafd8074b940faee498bf0c4fbdb62548bfcccc67e7
F test/window1.test 62864c1d6dd0f446908ec6eb13b08f2806a3cd93ba6d19f7f7b3be0b1945fc95
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -2287,8 +2287,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P 10b8f4166da26908aef9182824b0c967af7d861ff6c83daed7cd50321ee563b3
R ca4dc3eb2fbea5aa3011790dd25c24ba
U drh
Z ef34b785826a1f9d21d718f271f1c2cb
P 2fdd752dc92692e08c805eb10bf78d97e93c8436433c8175fbff310513f340d7
R 8853bfb7529eba79f848109b3f25e41a
U dan
Z 0c52888c8f52d7499ce6e91f05521555
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
2fdd752dc92692e08c805eb10bf78d97e93c8436433c8175fbff310513f340d7
7522512ff96d869c46596e7d514b65f210530db09e6359c2f37911d45f34979d

View File

@@ -756,11 +756,16 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
/* If this function is being called from within a scalar sub-select
** that used by the SELECT statement being processed, only process
** TK_COLUMN expressions that refer to it (the outer SELECT). Do
** not process aggregates or window functions at all, as they belong
** to the scalar sub-select. */
** TK_COLUMN and TK_AGGREGATE expressions that refer to it (the outer
** SELECT). Do not process window functions at all, as they belong to the
** scalar sub-select. */
if( p->pSubSelect ){
if( pExpr->op!=TK_COLUMN ){
if( pExpr->op==TK_AGG_FUNCTION ){
/* If op2==walkerDepth, then this expression aggregates over the rows
** of the SELECT being processed, even though it is within a scalar
** sub-select. In that case proceed, otherwise skip this node. */
if( pExpr->op2!=pWalker->walkerDepth ) return WRC_Continue;
}else if( pExpr->op!=TK_COLUMN ){
return WRC_Continue;
}else{
int nSrc = p->pSrc->nSrc;
@@ -841,7 +846,9 @@ static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
return WRC_Continue;
}else{
p->pSubSelect = pSelect;
pWalker->walkerDepth++;
sqlite3WalkSelect(pWalker, pSelect);
pWalker->walkerDepth--;
p->pSubSelect = pSave;
}
return WRC_Prune;
@@ -945,8 +952,15 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
/*
** Walker callback used to detect aggregate functions in the ORDER BY
** clause of an otherwise non-aggregate SELECT.
*/
static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
if( pExpr->op==TK_AGG_FUNCTION
&& pExpr->pAggInfo==0
&& pExpr->op2==pWalker->walkerDepth
){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pWalker->pParse,
"misuse of aggregate: %s()", pExpr->u.zToken);
@@ -993,7 +1007,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3WalkSelect(&w, p);
if( (p->selFlags & SF_Aggregate)==0 ){
w.xExprCallback = disallowAggregatesInOrderByCb;
w.xSelectCallback = 0;
w.xSelectCallback = sqlite3WalkerDepthIncrease;
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
w.walkerDepth = 0;
sqlite3WalkExprList(&w, p->pOrderBy);
}

View File

@@ -1894,7 +1894,7 @@ do_execsql_test 58.1 {
} {347 678.0}
# 2020-06-06 ticket e5504e987e419fb0
do_catchsql_test 59.1 {
do_catchsql_test 59.1.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (123);
@@ -1902,7 +1902,16 @@ do_catchsql_test 59.1 {
ntile( (SELECT sum(x)) ) OVER(ORDER BY x),
min(x) OVER(ORDER BY x)
FROM t1;
} {1 {misuse of aggregate: sum()}}
} {0 {1 123}}
do_catchsql_test 59.1.2 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (123);
SELECT
ntile( sum(x) ) OVER(ORDER BY x),
min(x) OVER(ORDER BY x)
FROM t1;
} {0 {1 123}}
# 2020-06-07 ticket f7d890858f361402
do_execsql_test 60.1 {
@@ -2424,4 +2433,44 @@ do_execsql_test 79.3 {
FROM t0;
} {6 1}
#-------------------------------------------------------------------------
# Test aggregates within scalar queries in window functions are handled
# correctly. Report
#
reset_db
do_execsql_test 80.0 {
DROP TABLE IF EXISTS pst_agg_scope;
CREATE TABLE pst_agg_scope(x);
INSERT INTO pst_agg_scope VALUES(456);
}
do_execsql_test 80.2 {
SELECT (SELECT MIN(t.x)) FROM pst_agg_scope AS t;
} {456}
do_execsql_test 80.3 {
SELECT COUNT(*) OVER (), MIN(t.x) FROM pst_agg_scope AS t;
} {1 456}
do_execsql_test 80.4 {
SELECT COUNT(*) OVER (), (SELECT MIN(t.x)) FROM pst_agg_scope AS t
} {1 456}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 81.0 {
CREATE TABLE t1(a INT,b TEXT,c BLOB,d REAL);
CREATE INDEX t1a ON t1(a);
CREATE TABLE t2(x,y,z PRIMARY KEY) WITHOUT ROWID;
}
do_execsql_test 81.1 {
SELECT json_group_object(
(SELECT json_group_object( a NOTNULL , a ) FILTER(WHERE a) OVER FROM t2 GROUP BY 1 HAVING d+7<10)
, b IN(1,2 IN(SELECT 0),3))
OVER ( ORDER BY d RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) AS d
FROM t1 NATURAL FULL JOIN t1 a;
} {"{}"}
finish_test