Fix an incorrect answer that might arise if a scalar query is both
DISTINCT and contains an OFFSET clause. [forum:/forumpost/2025-12-03T09:25:59Z|Forum post 2025-12-03T09:25:59Z]. FossilOrigin-Name: aef5397569d65d2971367b0278fe3a6f42544cf771572e7d046e2472f052364d
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
||||
C More\saggressive\soptimization\sof\sIS\sNULL\sand\sIS\sNOT\sNULL\soperators\sin\nthe\sparser.\s\sNew\ssqlite3ExprInt32()\sinternal\sinterface\sfor\screating\ninteger\snodes\sin\san\sexpression\stree.
|
||||
D 2025-12-03T21:31:53.753
|
||||
C Fix\san\sincorrect\sanswer\sthat\smight\sarise\sif\sa\sscalar\squery\sis\sboth\nDISTINCT\sand\scontains\san\sOFFSET\sclause.\n[forum:/forumpost/2025-12-03T09:25:59Z|Forum\spost\s2025-12-03T09:25:59Z].
|
||||
D 2025-12-04T00:05:49.341
|
||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
@@ -687,7 +687,7 @@ F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
|
||||
F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
|
||||
F src/expr.c a8f43b1a61b7083a5bba00a70df0aa13cd33e9422a81405135d8d6c9b63bb990
|
||||
F src/expr.c b4530f3e23d8ea38c7de4c7b55af52d43156c79128c042a580e670776f59a9bc
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
|
||||
F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
|
||||
@@ -736,7 +736,7 @@ F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 8d53771eb51a4ab5f970150c3a70969d8db79cd04a8774c2d296bbcf471a0dd0
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 9d4704ac072fdc86cf1b4184353ee7cca73aae4176bb30bb71c49aeb2901e427
|
||||
F src/select.c 344518c1bba9c4636bf651b7642304abd2e7075ba35feb4bae42a51e5efe991f
|
||||
F src/shell.c.in 62b286951404fd72c116bb3b96b5ee9330de4dc4c8753ca33967ca1a47b3b972
|
||||
F src/sqlite.h.in 706cacea5308b0244fb6cec92e08310fb427a125375c64137cc1f878ae4cf5c0
|
||||
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
|
||||
@@ -1675,7 +1675,7 @@ F test/strict1.test a7f9091603fe71cdc62baab0766684cba12a97ec69bfbb70be965532669c
|
||||
F test/strict2.test b22c7a98b5000aef937f1990776497f0e979b1a23bc4f63e2d53b00e59b20070
|
||||
F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49
|
||||
F test/subquery.test 23087f9b1c15ab9cc5231d04946bdebc51db527c95eb9d7434a2222127e17a84
|
||||
F test/subquery2.test 5f06ec2dbce42a3f595ab1b73b146592f9ce001cd4ff023d887d643d3560c281
|
||||
F test/subquery2.test ab96ff3fa9c4e3dce0d699f74e61c50250ed4335bc8f400e127707d552a8999e
|
||||
F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303
|
||||
F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b
|
||||
F test/subtype1.test 96fd2a59bfc845c955b5f339d23b37ef4d50de5f8a04acd1450a68605fa2e3e7
|
||||
@@ -2183,9 +2183,9 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
|
||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P afe5ee64f1cde4945c878220b029f2a22578c2bccda4fddc005c4e6a4718c6cd c69eec9909af40e1e22d44a6859ef52378ebe06a587373f332f9d379cb39a84d
|
||||
R e345b725a39db244a730c4ef212bf292
|
||||
T +closed c69eec9909af40e1e22d44a6859ef52378ebe06a587373f332f9d379cb39a84d
|
||||
P 560082d61f5b73ae68a86ce4d7e96d072d4f0996d82ec62d639847353bb8bf15 496bbff910b73775b16c1ccb95dadf37416d3f3032722a1140f2a9134666d7f1
|
||||
R f21a86d3146104bf72ac01ccd6b4f8b6
|
||||
T +closed 496bbff910b73775b16c1ccb95dadf37416d3f3032722a1140f2a9134666d7f1
|
||||
U drh
|
||||
Z 25e7954f74fccfd8d096164eadd24bf3
|
||||
Z 23e97f8b5553d5cafcf6705d7f74e35b
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
560082d61f5b73ae68a86ce4d7e96d072d4f0996d82ec62d639847353bb8bf15
|
||||
aef5397569d65d2971367b0278fe3a6f42544cf771572e7d046e2472f052364d
|
||||
|
||||
17
src/expr.c
17
src/expr.c
@@ -3897,9 +3897,22 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
pParse->nMem += nReg;
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
dest.eDest = SRT_Mem;
|
||||
dest.iSdst = dest.iSDParm;
|
||||
if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){
|
||||
/* If there is both a DISTINCT and an OFFSET clause, then allocate
|
||||
** a separate dest.iSdst array for sqlite3Select() and other
|
||||
** routines to populate. In this case results will be copied over
|
||||
** into the dest.iSDParm array only after OFFSET processing. This
|
||||
** ensures that in the case where OFFSET excludes all rows, the
|
||||
** dest.iSDParm array is not left populated with the contents of the
|
||||
** last row visited - it should be all NULLs if all rows were
|
||||
** excluded by OFFSET. */
|
||||
dest.iSdst = pParse->nMem+1;
|
||||
pParse->nMem += nReg;
|
||||
}else{
|
||||
dest.iSdst = dest.iSDParm;
|
||||
}
|
||||
dest.nSdst = nReg;
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
|
||||
sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem);
|
||||
VdbeComment((v, "Init subquery result"));
|
||||
}else{
|
||||
dest.eDest = SRT_Exists;
|
||||
|
||||
@@ -1445,9 +1445,14 @@ static void selectInnerLoop(
|
||||
assert( nResultCol<=pDest->nSdst );
|
||||
pushOntoSorter(
|
||||
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
|
||||
pDest->iSDParm = regResult;
|
||||
}else{
|
||||
assert( nResultCol==pDest->nSdst );
|
||||
assert( regResult==iParm );
|
||||
if( regResult!=iParm ){
|
||||
/* This occurs in cases where the SELECT had both a DISTINCT and
|
||||
** an OFFSET clause. */
|
||||
sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1);
|
||||
}
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -215,4 +215,72 @@ do_execsql_test 5.1 {
|
||||
SELECT ( SELECT y FROM t2 WHERE x = y ORDER BY y, z) FROM t1;
|
||||
} {ALFKI ANATR}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(1234);
|
||||
}
|
||||
|
||||
do_execsql_test 6.1 {
|
||||
SELECT DISTINCT 'string' FROM t1 LIMIT 1 OFFSET 5;
|
||||
}
|
||||
|
||||
do_execsql_test 6.2 {
|
||||
SELECT (
|
||||
SELECT 'string' FROM t1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.3 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.4 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.5 {
|
||||
SELECT (
|
||||
SELECT 'string' FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 6.6 {
|
||||
SELECT (SELECT DISTINCT x, x FROM t1 LIMIT 1 OFFSET 5)==(1234, 1234)
|
||||
} {{}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 7.0 {
|
||||
CREATE TABLE t1(x);
|
||||
CREATE INDEX i1 ON t1(x);
|
||||
INSERT INTO t1 VALUES(1234);
|
||||
}
|
||||
|
||||
do_execsql_test 7.1 {
|
||||
SELECT (
|
||||
SELECT DISTINCT 'string' FROM t1 ORDER BY x LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 7.2 {
|
||||
DROP INDEX i1;
|
||||
CREATE UNIQUE INDEX i1 ON t1(x);
|
||||
}
|
||||
|
||||
do_execsql_test 7.3 {
|
||||
SELECT (
|
||||
SELECT DISTINCT x FROM t1 ORDER BY 1 LIMIT 1 OFFSET 5
|
||||
);
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 7.4 {
|
||||
SELECT (SELECT DISTINCT x FROM t1 ORDER BY +x LIMIT 1 OFFSET 0);
|
||||
} {1234}
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user