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:
16
manifest
16
manifest
@@ -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.
|
||||
|
||||
@@ -1 +1 @@
|
||||
2fdd752dc92692e08c805eb10bf78d97e93c8436433c8175fbff310513f340d7
|
||||
7522512ff96d869c46596e7d514b65f210530db09e6359c2f37911d45f34979d
|
||||
|
||||
28
src/window.c
28
src/window.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user