1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

Ensure that the accumulator for an aggregate always gets initialized,

even when the aggregate is on the right side of a LEFT JOIN and never
gets evaluated.  This fixes a problem introduced by [663f5dd32d9db832]
and found by dbsqlfuzz.  Test cases in TH3.

FossilOrigin-Name: 235cf6586b9ac914a32bd8adfd460daae998687f02f0998a7aa3c6bfc857d1c9
This commit is contained in:
drh
2025-07-18 12:10:15 +00:00
parent 01a2953350
commit 74cc109780
5 changed files with 38 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
C Pedantic\sinternal\sbuild\sdoc\sfix. C Ensure\sthat\sthe\saccumulator\sfor\san\saggregate\salways\sgets\sinitialized,\neven\swhen\sthe\saggregate\sis\son\sthe\sright\sside\sof\sa\sLEFT\sJOIN\sand\snever\ngets\sevaluated.\s\sThis\sfixes\sa\sproblem\sintroduced\sby\s[663f5dd32d9db832]\nand\sfound\sby\sdbsqlfuzz.\s\sTest\scases\sin\sTH3.
D 2025-07-17T19:18:01.321 D 2025-07-18T12:10:15.193
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -737,7 +737,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9
F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
F src/expr.c 12d8a79f6a0eb9bfae2d468a6d5bd7b9a0ff00988b3f5326ec9bbaad61bbf385 F src/expr.c 974d5fc1969f0ac2cf1222ef6fa30925ec487e95979b03f622962127ecdbe143
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6 F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6
@@ -786,12 +786,12 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0 F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c fc003cad96a105765261f7b6c5f4596e505894262bb5593cb29e10b682800d12 F src/select.c 40bf8b15afca243a7222ab6301f1a283cc862c59aead7d22fc569e1843430fd3
F src/shell.c.in 2be7d0b2ba7221bd991f96d0c72728c06cead09bec3965e230ad703c9daf0c8a F src/shell.c.in 2be7d0b2ba7221bd991f96d0c72728c06cead09bec3965e230ad703c9daf0c8a
F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
F src/sqliteInt.h 984e80f6cfdb1cd65ab465d14d82b6b56af4f7dc308c4bc1da85074a5b4ca755 F src/sqliteInt.h a54f83985985655d1276e9e356dd6ae19b8d0b62c2abc75cc9e8f402ea141207
F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 14ca18f72a7edde7c65a6c6b23fdc3f5ed6860371795926045c987f7b2c75e1b P 9ef429a8507745e0a6fae4f0ec1dc2b142dad1357f9a7ff576e7834c8ff5c6fe
R 0b4adce6a943b41acc2e8bb2b3588d1f R 5b5c9cb6b9ce77b587db8e381a28aaff
U stephan U drh
Z 34c7bd606279d40db5c4d57cf244243a Z a18dc761ea47a89b3ee7f856b07c4aa2
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
9ef429a8507745e0a6fae4f0ec1dc2b142dad1357f9a7ff576e7834c8ff5c6fe 235cf6586b9ac914a32bd8adfd460daae998687f02f0998a7aa3c6bfc857d1c9

View File

@@ -4989,6 +4989,12 @@ expr_code_doover:
sqlite3VdbeLoadString(v, target, pExpr->u.zToken); sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
return target; return target;
} }
case TK_NULLS: {
/* Set a range of registers to NULL. pExpr->y.nReg registers starting
** with target */
sqlite3VdbeAddOp3(v, OP_Null, 0, target, target + pExpr->y.nReg - 1);
return target;
}
default: { default: {
/* Make NULL the default case so that if a bug causes an illegal /* Make NULL the default case so that if a bug causes an illegal
** Expr node to be passed into this function, it will be handled ** Expr node to be passed into this function, it will be handled
@@ -5698,6 +5704,25 @@ int sqlite3ExprCodeRunJustOnce(
return regDest; return regDest;
} }
/*
** Make arrangements to invoke OP_Null on a range of registers
** during initialization.
*/
SQLITE_NOINLINE void sqlite3ExprNullRegisterRange(
Parse *pParse, /* Parsing context */
int iReg, /* First register to set to NULL */
int nReg /* Number of sequential registers to NULL out */
){
u8 okConstFactor = pParse->okConstFactor;
Expr t;
memset(&t, 0, sizeof(t));
t.op = TK_NULLS;
t.y.nReg = nReg;
pParse->okConstFactor = 1;
sqlite3ExprCodeRunJustOnce(pParse, &t, iReg);
pParse->okConstFactor = okConstFactor;
}
/* /*
** Generate code to evaluate an expression and store the results ** Generate code to evaluate an expression and store the results
** into a register. Return the register number where the results ** into a register. Return the register number where the results

View File

@@ -8482,6 +8482,7 @@ int sqlite3Select(
sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
VdbeComment((v, "clear abort flag")); VdbeComment((v, "clear abort flag"));
sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
sqlite3ExprNullRegisterRange(pParse, iAMem, pGroupBy->nExpr);
/* Begin a loop that will extract all source rows in GROUP BY order. /* Begin a loop that will extract all source rows in GROUP BY order.
** This might involve two separate loops with an OP_Sort in between, or ** This might involve two separate loops with an OP_Sort in between, or

View File

@@ -3082,6 +3082,7 @@ struct Expr {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
** for a column of an index on an expression */ ** for a column of an index on an expression */
Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */
int nReg; /* TK_NULLS: Number of registers to NULL out */
struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ struct { /* TK_IN, TK_SELECT, and TK_EXISTS */
int iAddr; /* Subroutine entry address */ int iAddr; /* Subroutine entry address */
int regReturn; /* Register used to hold return address */ int regReturn; /* Register used to hold return address */
@@ -5119,6 +5120,7 @@ void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int);
void sqlite3ExprCodeFactorable(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
void sqlite3ExprNullRegisterRange(Parse*, int, int);
int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeTarget(Parse*, Expr*, int);
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);