]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make sure every co-routines has its own set of temporary registers and does
authordrh <drh@noemail.net>
Tue, 9 Feb 2016 02:12:20 +0000 (02:12 +0000)
committerdrh <drh@noemail.net>
Tue, 9 Feb 2016 02:12:20 +0000 (02:12 +0000)
not share temporaries, since a co-routine might expect the content of a
temporary register to be preserved across an OP_Yield.
Proposed fix for ticket [d06a25c84454a].

FossilOrigin-Name: ca72be8618e5d466d6f35819ca8bbd2b84269959

manifest
manifest.uuid
src/build.c
src/insert.c
src/select.c
src/vdbe.h
src/vdbeaux.c
test/select4.test

index 23d68d6a6c3a9413e9b3984f34d2a2df8162a863..69b6e1ba9ff3d54c67f04829d44e5a36e924fe99 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sspelling\serror\sin\sMSVC\smakefile\scomments.
-D 2016-02-08T20:45:37.407
+C Make\ssure\severy\sco-routines\shas\sits\sown\sset\sof\stemporary\sregisters\sand\sdoes\nnot\sshare\stemporaries,\ssince\sa\sco-routine\smight\sexpect\sthe\scontent\sof\sa\ntemporary\sregister\sto\sbe\spreserved\sacross\san\sOP_Yield.\nProposed\sfix\sfor\sticket\s[d06a25c84454a].
+D 2016-02-09T02:12:20.490
 F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b0493f10caddb8adf992a4e6f1943141fc7c6816
@@ -294,7 +294,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
 F src/btree.c 4c8caaeed7878aafdb607c3d2bcbc365bb0d19a1
 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e
 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
-F src/build.c 198eaa849c193f28b802ed135b2483c68ef7a35c
+F src/build.c 54866fbafa09d494269bdefc79995eb7207003a6
 F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce
 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
 F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
@@ -309,7 +309,7 @@ F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c b84359365bace233919db550a15f131923190efc
+F src/insert.c 046199e085e69e05af7bef197d53c5b4b402b6fa
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902
 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
@@ -348,7 +348,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
 F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
-F src/select.c 57646a44ba9a0bc4aa926ae9c79b8199c246844b
+F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4
 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -414,10 +414,10 @@ F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18
 F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6
 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
 F src/vdbe.c c193299e595a13eba247738e22fce25c49346a6c
-F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337
+F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79
 F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459
-F src/vdbeaux.c 49b536284c2b8a823dd342d653e18145ca2b393a
+F src/vdbeaux.c deae5d3bd45da0e57c7d9e1d7436333d142dc3bb
 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db
 F src/vdbemem.c 68fcfac37dc6601d98c32cc5adee4d39f2c1b7b4
 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
@@ -992,7 +992,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
 F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
-F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650
+F test/select4.test 453631158540e5f685b81cac5b7e8bd8c6b4c5fc
 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
 F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
@@ -1427,7 +1427,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1e563c6ebbb02d2e89760c7a7f95aa69964629c6
-R 8450aebd4fe3e5df6689a15f6b4c74a5
-U mistachkin
-Z fa8db5a9236f4356c9f0e0ef9af9fdef
+P 6eab74c9ae57676044b5bc82fa14e92fd2448008
+R 28a5285fd29b59b5a769fa2b98c8137d
+U drh
+Z 50a93197f1857fe46bad3c49957d1f43
index def0c6f0831df690a9da220d756e72f09e135fe5..9e7ed6ea0867335bed60efdec1b95d62d1fbbde9 100644 (file)
@@ -1 +1 @@
-6eab74c9ae57676044b5bc82fa14e92fd2448008
\ No newline at end of file
+ca72be8618e5d466d6f35819ca8bbd2b84269959
\ No newline at end of file
index 476fc28c41714e99ad6f2b7e6102fd708ffdb6c3..250dc20d20ff7ae765014eb4aae714bf1e366d19 100644 (file)
@@ -1954,7 +1954,7 @@ void sqlite3EndTable(
       sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
       sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
       sqlite3Select(pParse, pSelect, &dest);
-      sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+      sqlite3VdbeEndCoroutine(v, regYield);
       sqlite3VdbeJumpHere(v, addrTop - 1);
       if( pParse->nErr ) return;
       pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
index 729e0fedce697bae5c0b300a6f1c1ae7425ab5d3..650f397de0642ad50c39fe08372c4f4d5559bcbd 100644 (file)
@@ -685,7 +685,7 @@ void sqlite3Insert(
     rc = sqlite3Select(pParse, pSelect, &dest);
     regFromSelect = dest.iSdst;
     if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
-    sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+    sqlite3VdbeEndCoroutine(v, regYield);
     sqlite3VdbeJumpHere(v, addrTop - 1);                       /* label B: */
     assert( pSelect->pEList );
     nColumn = pSelect->pEList->nExpr;
index ea3e920b9ff5ecdc31d157204a82c1cae189109e..c3132c232585b05eaf7e0961f09932851ae4425c 100644 (file)
@@ -2952,7 +2952,7 @@ static int multiSelectOrderBy(
   pPrior->iLimit = regLimitA;
   explainSetInteger(iSub1, pParse->iNextSelectId);
   sqlite3Select(pParse, pPrior, &destA);
-  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
+  sqlite3VdbeEndCoroutine(v, regAddrA);
   sqlite3VdbeJumpHere(v, addr1);
 
   /* Generate a coroutine to evaluate the SELECT statement on 
@@ -2969,7 +2969,7 @@ static int multiSelectOrderBy(
   sqlite3Select(pParse, p, &destB);
   p->iLimit = savedLimit;
   p->iOffset = savedOffset;
-  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB);
+  sqlite3VdbeEndCoroutine(v, regAddrB);
 
   /* Generate a subroutine that outputs the current row of the A
   ** select as the next output row of the compound select.
@@ -4990,7 +4990,7 @@ int sqlite3Select(
       pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
       pItem->fg.viaCoroutine = 1;
       pItem->regResult = dest.iSdst;
-      sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
+      sqlite3VdbeEndCoroutine(v, pItem->regReturn);
       sqlite3VdbeJumpHere(v, addrTop-1);
       sqlite3ClearTempRegCache(pParse);
     }else{
index f09997bf942c306bf88e8bd63df6e1aa3db40127..4c02f5844db2502ebe6021dda950963e41f65b3e 100644 (file)
@@ -180,6 +180,7 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
 int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
 int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
 int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
+void sqlite3VdbeEndCoroutine(Vdbe*,int);
 #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
   void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
 #else
index 8eb3141dafcfda00c3bd1a46e6842fa9f8c63039..ce98edd0a58f1c7f6bebf6d51f6c34064aee52f8 100644 (file)
@@ -324,6 +324,21 @@ int sqlite3VdbeAddOp4Int(
   return addr;
 }
 
+/* Insert the end of a co-routine
+*/
+void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
+  sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+
+  /* Clear the temporary register cache, thereby ensuring that each
+  ** co-routine has its own independent set of registers, because co-routines
+  ** might expect their registers to be preserved across an OP_Yield, and
+  ** that could cause problems if two or more co-routines are using the same
+  ** temporary register.
+  */
+  v->pParse->nTempReg = 0;
+  v->pParse->nRangeReg = 0;
+}
+
 /*
 ** Create a new symbolic label for an instruction that has yet to be
 ** coded.  The symbolic label is really just a negative number.  The
index a7b1af20a554f8f85e09b1d254e87f064f7338a5..be8d0e0ab180d8a7d3eba9950175dad4bc6376cd 100644 (file)
@@ -916,4 +916,24 @@ do_execsql_test select4-14.17 {
   VALUES(1),(2),(3),(4) UNION ALL SELECT 5 LIMIT 3;
 } {1 2 3}
 
+# Ticket https://www.sqlite.org/src/info/d06a25c84454a372
+# Incorrect answer due to two co-routines using the same registers and expecting
+# those register values to be preserved across a Yield.
+#
+do_execsql_test select4-15.1 {
+  DROP TABLE IF EXISTS tx;
+  CREATE TABLE tx(id INTEGER PRIMARY KEY, a, b);
+  INSERT INTO tx(a,b) VALUES(33,456);
+  INSERT INTO tx(a,b) VALUES(33,789);
+
+  SELECT DISTINCT t0.id, t0.a, t0.b
+    FROM tx AS t0, tx AS t1
+   WHERE t0.a=t1.a AND t1.a=33 AND t0.b=456
+  UNION
+  SELECT DISTINCT t0.id, t0.a, t0.b
+    FROM tx AS t0, tx AS t1
+   WHERE t0.a=t1.a AND t1.a=33 AND t0.b=789
+   ORDER BY 1;
+} {1 33 456 2 33 789}
+
 finish_test