Do not allow temporary registers to be in use across an OP_Yield within a

co-routine.  Fix for ticket [8c63ff0eca81a9132d8].

FossilOrigin-Name: 97a8c9733cba97c78e979dfd5c66610c23e90288
This commit is contained in:
drh 2014-02-25 21:55:16 +00:00
parent e8c1eba9a9
commit 0baa035a1e
5 changed files with 61 additions and 13 deletions

View File

@ -1,5 +1,5 @@
C Also\sadjust\sthe\sorder\sof\sfiles\sin\sthe\samalgamation\sto\sensure\sthat\n_FILE_OFFSET_BITS\sis\sdefined\sbefore\sany\s#include,\sfor\sQNX.
D 2014-02-25T18:12:58.878
C Do\snot\sallow\stemporary\sregisters\sto\sbe\sin\suse\sacross\san\sOP_Yield\swithin\sa\nco-routine.\s\sFix\sfor\sticket\s[8c63ff0eca81a9132d8].
D 2014-02-25T21:55:16.402
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -221,7 +221,7 @@ F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 6725dc99b3985a97bad315910e59c3f7f5058916
F src/sqliteInt.h 46dfbe0b58282421188a6c25b6c0c0fae18e0134
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@ -290,7 +290,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c d622974f30d3347c7b71bfe49ce1f1e9b6570980
F src/where.c 0b5a4d45fdf05ad541893d986abd2f660f6e0094
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -881,6 +881,7 @@ F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
@ -1151,7 +1152,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 953cdd6adadfd46b51ad61d7939cecca154a02cb
R d169e5164f16cb0355a3972eba04326c
P 23001a85cd334090cf6c70d4d7e722a01f4f6899
R 53d871612a374a058c13125cf02ae108
U drh
Z 6c6f89e1dd41d2a146386cfa06ae53d9
Z 196bbfe69fc9298304e0610559f3cd1e

View File

@ -1 +1 @@
23001a85cd334090cf6c70d4d7e722a01f4f6899
97a8c9733cba97c78e979dfd5c66610c23e90288

View File

@ -2358,7 +2358,6 @@ struct Parse {
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
u8 nColCache; /* Number of entries in aColCache[] */
u8 iColCache; /* Next entry in aColCache[] to replace */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */

View File

@ -2853,13 +2853,14 @@ static Bitmask codeOneLoopStart(
** construct.
*/
assert( pLoop->u.btree.nEq==1 );
iReleaseReg = sqlite3GetTempReg(pParse);
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
iReleaseReg = ++pParse->nMem;
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
@ -2948,7 +2949,7 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = start;
assert( pLevel->p5==0 );
if( testOp!=OP_Noop ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
@ -3181,7 +3182,7 @@ static Bitmask codeOneLoopStart(
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
@ -3529,7 +3530,6 @@ static Bitmask codeOneLoopStart(
pTerm->wtFlags |= TERM_CODED;
}
}
sqlite3ReleaseTempReg(pParse, iReleaseReg);
return pLevel->notReady;
}

48
test/tkt-8c63ff0ec.test Normal file
View File

@ -0,0 +1,48 @@
# 2014-02-25
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test cases to show that ticket [8c63ff0eca81a9132d8d67b31cd6ae9712a2cc6f]
# "Incorrect query result on a UNION ALL" which was caused by using the same
# temporary register in concurrent co-routines, as been fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix tkt-8c63ff0ec
do_execsql_test 1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e);
INSERT INTO t1 VALUES(1,20,30,40,50),(3,60,70,80,90);
CREATE TABLE t2(x INTEGER PRIMARY KEY);
INSERT INTO t2 VALUES(2);
CREATE TABLE t3(z);
INSERT INTO t3 VALUES(2),(2),(2),(2);
SELECT a, b+c FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 50 2 5 2 5 2 5 2 5 3 130}
do_execsql_test 1.2 {
SELECT a, b+c+d FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 90 2 5 2 5 2 5 2 5 3 210}
do_execsql_test 1.3 {
SELECT a, b+c+d+e FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 140 2 5 2 5 2 5 2 5 3 300}
finish_test