]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make it so that any Parse object is always linked into the database conenction
authordrh <>
Mon, 24 Jan 2022 15:34:55 +0000 (15:34 +0000)
committerdrh <>
Mon, 24 Jan 2022 15:34:55 +0000 (15:34 +0000)
while it is active.  Hence, an OOM will cause Parse.nErr to be set.

FossilOrigin-Name: 6a45d8fe8bfbc11a5b86d25237e1f8bccfb0f22f3dcaf004ba797aeb57b365ec

manifest
manifest.uuid
src/alter.c
src/backup.c
src/prepare.c
src/sqliteInt.h
src/trigger.c
src/util.c
src/vdbeblob.c
src/vtab.c

index f1918bccb321db4b334da9c1ef9cb7450c1207b4..61845611c083c130aaf5938d1251e5f5f0010573 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\stestcase\sfor\sCLI\s.read\srecursion.
-D 2022-01-24T14:01:31.089
+C Make\sit\sso\sthat\sany\sParse\sobject\sis\salways\slinked\sinto\sthe\sdatabase\sconenction\nwhile\sit\sis\sactive.\s\sHence,\san\sOOM\swill\scause\sParse.nErr\sto\sbe\sset.
+D 2022-01-24T15:34:55.523
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -485,11 +485,11 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c e3943d8fbcaf60f79f39d4aecc56a6a8092f51f93d6a7c5b1db2633c5fa10c30
+F src/alter.c d5b1083127d4e1c5b0a50155d6b15c009db81d1fab17e39d28a9268922c2f752
 F src/analyze.c 7518b99e07c5494111fe3bd867f28f804b6c5c1ad0703ec3d116de9bab3fa516
 F src/attach.c e3f9d9a2a4a844750f3f348f37afb244535f21382cbfcd840152cb21cb41cfaf
 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
-F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
+F src/backup.c 58880b9a9adf88f1a57cb3b0db6b891626ae76113ebd0f2417a87c2634edfc65
 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c ddab31c38d5f16114bc68392430556b1063fe14e0020f9a56d2c35ddd58ba7e3
@@ -547,7 +547,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
 F src/pragma.c c536665ce8431c8b1efbf7e0a5c01852f49f7bf28f1954f8118b2d28e4a3797f
 F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad
-F src/prepare.c 45fe7408eb78d80eca8392669070a6e5caf231b09e5c7b1ff65c1ad64a3734c5
+F src/prepare.c 4ab9c3c716aaaa98b7985870e0b7631045dff1cea6ce814165ba8f4363dd43f7
 F src/printf.c 975f1f5417f2526365b6e6d7f22332e3e11806dad844701d92846292b654ba9a
 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c 359bc0e445d427583d2ab6110433a5dc777f64a0ecdf8d24826d8b475233ead9
@@ -557,7 +557,7 @@ F src/shell.c.in e80a140e92e342e2f92d405a77155c8e3a67c9b1d0bdbacb92885960cd4fc8f
 F src/sqlite.h.in 31c2c8d737814369bd3b71f3849c4a97ef7ede0aa3ce976ecb11632fa5f1f863
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 5d54cf13d3406d8eb65d921a0d3c349de6126b732e695e79ecd4830ce86b4f8a
-F src/sqliteInt.h 911022922c6f365d094251be68e57c3bef0cdaed587924fe1317a105f1f948de
+F src/sqliteInt.h 33fbafb55b48f63b791c563378345ebdbbcb73e8fd63a1c22e4df05f435d4714
 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -618,23 +618,23 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c b74d878aa7c82ec8460779468061a96185e22257f68ab785b69abce354b70446
 F src/treeview.c 9dfdb7ff7f6645d0a6458dbdf4ffac041c071c4533a6db8bb6e502b979ac67bc
-F src/trigger.c d10464bac5f1a54479be3976c9e3cbc5b5385608c2aa9c880938dbef88cd0289
+F src/trigger.c 6732a95d132e5fe30e02f87fe94fdb245840c2a870d8ce08c37aab3a2f13f387
 F src/update.c d6f5c7b9e072660757ac7d58175aca11c07cb95ebbb297ae7f38853700f52328
 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
-F src/util.c 89e51820bcb468ff3877a8d942f5cc807208087f021227e0927693e928a195bc
+F src/util.c 0d0b9c58f117fa98192c6d340c20fd73ce58ae33687e3a133b1fb623b96e0cbd
 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
 F src/vdbe.c cfe1980fbeb87eb35297b4a41808034761f26277cf45c9cf3e4eac20edcba1d5
 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
 F src/vdbeInt.h d89d5d2150500cfb08615329fd20aea9d746bba5f2c3ecb8a17e2d2d9be029e5
 F src/vdbeapi.c 22c79072ae7d8a01e9bcae8ba16e918d60d202eaa9553b5fda38f99f7464d99a
 F src/vdbeaux.c c1b452cc17f5887b3d36bc277a2181914d6bed508ea45827b5f348160491e6a6
-F src/vdbeblob.c 29c4118f7ee615cdee829e8401f6ead1b96b95d545b4de0042f6de39c962c652
+F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
 F src/vdbemem.c da4d594084d581be6436582bb44bb128feeb138a3e6c313eda6749ebdc3a65ec
 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
-F src/vtab.c a47cc12ebaa350800c0c87b6b0095debbb5a6ed32727bcab9d82ad070a81b738
+F src/vtab.c e0eaf5b8f7f8929088485a76bea2ff6124adb12e0eb5c0997287ff5e0e4c0517
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
@@ -1941,8 +1941,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ad7aace761c6b21ba453eaf43c68d985be7cbd5a200fe0d2e27a0c7150f99874
-R 58fcdcfd00f4bb8a2367d551006829a9
-U larrybr
-Z bbbe6164ac758b645539901355118a69
+P 53d4404458fb6f0b6b2b69c2225d66b39f09099c356ba3c3e990474f14aba31a
+R db714556249a893e75568fc6543a6157
+U drh
+Z 5562b6696e73f05014591d4075c2e3ff
 # Remove this line to create a well-formed Fossil manifest.
index 0d6cbc5cc3a0d6b439b0b08472ef3749fb972922..54f0236036108c3cace1cee9c87773127ce9ec79 100644 (file)
@@ -1 +1 @@
-53d4404458fb6f0b6b2b69c2225d66b39f09099c356ba3c3e990474f14aba31a
\ No newline at end of file
+6a45d8fe8bfbc11a5b86d25237e1f8bccfb0f22f3dcaf004ba797aeb57b365ec
\ No newline at end of file
index 28efd2872237e653267950f35d581427f162c434..096b54c042ac664ce207468889c9f4e08b5a39a6 100644 (file)
@@ -1132,7 +1132,7 @@ static int renameParseSql(
   /* Parse the SQL statement passed as the first argument. If no error
   ** occurs and the parse does not result in a new table, index or
   ** trigger object, the database must be corrupt. */
-  memset(p, 0, sizeof(Parse));
+  sqlite3ParseObjectInit(p, db);
   p->eParseMode = PARSE_MODE_RENAME;
   p->db = db;
   p->nQueryLoop = 1;
@@ -1417,7 +1417,7 @@ static void renameParseCleanup(Parse *pParse){
   sqlite3DeleteTrigger(db, pParse->pNewTrigger);
   sqlite3DbFree(db, pParse->zErrMsg);
   renameTokenFree(db, pParse->pRename);
-  sqlite3ParserReset(pParse);
+  sqlite3ParseObjectReset(pParse);
 }
 
 /*
index 2b286de6bda0d2ef213d97b957d7ac62d80f5733..bfd155bcacff0c004cf6bbf63cc36e0495c685c2 100644 (file)
@@ -85,14 +85,13 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
   if( i==1 ){
     Parse sParse;
     int rc = 0;
-    memset(&sParse, 0, sizeof(sParse));
-    sParse.db = pDb;
+    sqlite3ParseObjectInit(&sParse,pErrorDb);
     if( sqlite3OpenTempDatabase(&sParse) ){
       sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
       rc = SQLITE_ERROR;
     }
     sqlite3DbFree(pErrorDb, sParse.zErrMsg);
-    sqlite3ParserReset(&sParse);
+    sqlite3ParseObjectReset(&sParse);
     if( rc ){
       return 0;
     }
index d2cc2d098cf73ca53884460065bf20e753c28157..56505a71742b67dbad23c74177d39507f19a33ac 100644 (file)
@@ -568,7 +568,7 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
 /*
 ** Free all memory allocations in the pParse object
 */
-void sqlite3ParserReset(Parse *pParse){
+void sqlite3ParseObjectReset(Parse *pParse){
   sqlite3 *db = pParse->db;
   assert( pParse->nested==0 );
 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -588,6 +588,9 @@ void sqlite3ParserReset(Parse *pParse){
     assert( db->lookaside.bDisable >= pParse->disableLookaside );
     db->lookaside.bDisable -= pParse->disableLookaside;
     db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
+    assert( pParse->db->pParse==pParse );
+    pParse->db->pParse = pParse->pOuterParse;
+    pParse->db = 0;
   }
   pParse->disableLookaside = 0;
 }
@@ -601,7 +604,7 @@ void sqlite3ParserReset(Parse *pParse){
 ** cost for this mechansim (an extra malloc), so it should not be used
 ** for common cleanups that happen on most calls.  But for less
 ** common cleanups, we save a single NULL-pointer comparison in
-** sqlite3ParserReset(), which reduces the total CPU cycle count.
+** sqlite3ParseObjectReset(), which reduces the total CPU cycle count.
 **
 ** If a memory allocation error occurs, then the cleanup happens immediately.
 ** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the
@@ -641,6 +644,24 @@ void *sqlite3ParserAddCleanup(
   return pPtr;
 }
 
+/*
+** Turn bulk memory into a valid Parse object and link that Parse object
+** into database connection db.
+**
+** Call sqlite3ParseObjectReset() to undo this operation.
+**
+** Caution:  Do not confuse this routine with sqlite3ParseObjectInit() which
+** is generated by Lemon.
+*/
+void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){
+  memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ);
+  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
+  assert( db->pParse!=pParse );
+  pParse->pOuterParse = db->pParse;
+  db->pParse = pParse;
+  pParse->db = db;
+}
+
 /*
 ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
 */
@@ -657,8 +678,12 @@ static int sqlite3Prepare(
   int i;                    /* Loop counter */
   Parse sParse;             /* Parsing context */
 
-  memset(&sParse, 0, PARSE_HDR_SZ);
+  /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */
+  memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ);
   memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
+  sParse.pOuterParse = db->pParse;
+  db->pParse = &sParse;
+  sParse.db = db;
   sParse.pReprepare = pReprepare;
   assert( ppStmt && *ppStmt==0 );
   /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
@@ -714,7 +739,6 @@ static int sqlite3Prepare(
 
   sqlite3VtabUnlockList(db);
 
-  sParse.db = db;
   if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
     char *zSqlCopy;
     int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -781,7 +805,7 @@ static int sqlite3Prepare(
 
 end_prepare:
 
-  sqlite3ParserReset(&sParse);
+  sqlite3ParseObjectReset(&sParse);
   return rc;
 }
 static int sqlite3LockAndPrepare(
index 7fd0d81d096b86f4dc896074d4dfb28da11b171e..7a266403fb46abe90d317471d14bbcff7b8129c1 100644 (file)
@@ -3585,6 +3585,7 @@ struct Parse {
   **************************************************************************/
 
   int aTempReg[8];        /* Holding area for temporary registers */
+  Parse *pOuterParse;     /* Outer Parse object when nested */
   Token sNameToken;       /* Token with unqualified schema object name */
 
   /************************************************************************
@@ -3635,7 +3636,8 @@ struct Parse {
 /*
 ** Sizes and pointers of various parts of the Parse object.
 */
-#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
+#define PARSE_HDR(X)  (((char*)(X))+offsetof(Parse,zErrMsg))
+#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/
 #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken)    /* Recursive part */
 #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
 #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */
@@ -5096,7 +5098,8 @@ FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
 sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
 int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
 int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
-void sqlite3ParserReset(Parse*);
+void sqlite3ParseObjectInit(Parse*,sqlite3*);
+void sqlite3ParseObjectReset(Parse*);
 void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*);
 #ifdef SQLITE_ENABLE_NORMALIZE
 char *sqlite3Normalize(Vdbe*, const char*);
index 3abfb1ba62c1439d2b6556de031ac0ac15001afc..19e22abcfd76207316df14f9ff526611b47a14c2 100644 (file)
@@ -1110,8 +1110,8 @@ static TriggerPrg *codeRowTrigger(
   Vdbe *v;                    /* Temporary VM */
   NameContext sNC;            /* Name context for sub-vdbe */
   SubProgram *pProgram = 0;   /* Sub-vdbe for trigger program */
-  Parse *pSubParse;           /* Parse context for sub-vdbe */
   int iEndTrigger = 0;        /* Label to jump to if WHEN is false */
+  Parse sSubParse;            /* Parse context for sub-vdbe */
 
   assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
   assert( pTop->pVdbe );
@@ -1133,19 +1133,17 @@ static TriggerPrg *codeRowTrigger(
 
   /* Allocate and populate a new Parse context to use for coding the 
   ** trigger sub-program.  */
-  pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
-  if( !pSubParse ) return 0;
+  sqlite3ParseObjectInit(&sSubParse, db);
   memset(&sNC, 0, sizeof(sNC));
-  sNC.pParse = pSubParse;
-  pSubParse->db = db;
-  pSubParse->pTriggerTab = pTab;
-  pSubParse->pToplevel = pTop;
-  pSubParse->zAuthContext = pTrigger->zName;
-  pSubParse->eTriggerOp = pTrigger->op;
-  pSubParse->nQueryLoop = pParse->nQueryLoop;
-  pSubParse->disableVtab = pParse->disableVtab;
-
-  v = sqlite3GetVdbe(pSubParse);
+  sNC.pParse = &sSubParse;
+  sSubParse.pTriggerTab = pTab;
+  sSubParse.pToplevel = pTop;
+  sSubParse.zAuthContext = pTrigger->zName;
+  sSubParse.eTriggerOp = pTrigger->op;
+  sSubParse.nQueryLoop = pParse->nQueryLoop;
+  sSubParse.disableVtab = pParse->disableVtab;
+
+  v = sqlite3GetVdbe(&sSubParse);
   if( v ){
     VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
       pTrigger->zName, onErrorText(orconf),
@@ -1171,15 +1169,14 @@ static TriggerPrg *codeRowTrigger(
       if( db->mallocFailed==0
        && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
       ){
-        iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
-        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
+        iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse);
+        sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
       }
       sqlite3ExprDelete(db, pWhen);
     }
 
     /* Code the trigger program into the sub-vdbe. */
-    codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
-    transferParseError(pParse, pSubParse);
+    codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf);
 
     /* Insert an OP_Halt at the end of the sub-program. */
     if( iEndTrigger ){
@@ -1187,22 +1184,21 @@ static TriggerPrg *codeRowTrigger(
     }
     sqlite3VdbeAddOp0(v, OP_Halt);
     VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
+    transferParseError(pParse, &sSubParse);
 
     if( db->mallocFailed==0 && pParse->nErr==0 ){
       pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
     }
-    pProgram->nMem = pSubParse->nMem;
-    pProgram->nCsr = pSubParse->nTab;
+    pProgram->nMem = sSubParse.nMem;
+    pProgram->nCsr = sSubParse.nTab;
     pProgram->token = (void *)pTrigger;
-    pPrg->aColmask[0] = pSubParse->oldmask;
-    pPrg->aColmask[1] = pSubParse->newmask;
+    pPrg->aColmask[0] = sSubParse.oldmask;
+    pPrg->aColmask[1] = sSubParse.newmask;
     sqlite3VdbeDelete(v);
   }
 
-  assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
-  sqlite3ParserReset(pSubParse);
-  sqlite3StackFree(db, pSubParse);
-
+  assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg );
+  sqlite3ParseObjectReset(&sSubParse);
   return pPrg;
 }
     
index dec205df4301ef03be57ed7c0737e3aea3cc52d5..002cf6573929742ae671557edba6d19a3d004e7c 100644 (file)
@@ -189,6 +189,8 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
   char *zMsg;
   va_list ap;
   sqlite3 *db = pParse->db;
+  assert( db!=0 );
+  assert( db->pParse==pParse );
   db->errByteOffset = -2;
   va_start(ap, zFormat);
   zMsg = sqlite3VMPrintf(db, zFormat, ap);
index 512442fd2a784a8edb140f33bb00f59c0fa568f7..a18ee05b52b413d3db062b21bb968612bd7507f3 100644 (file)
@@ -152,10 +152,9 @@ int sqlite3_blob_open(
   sqlite3_mutex_enter(db->mutex);
 
   pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
-  do {
-    memset(&sParse, 0, sizeof(Parse));
+  while(1){
+    sqlite3ParseObjectInit(&sParse,db);
     if( !pBlob ) goto blob_open_out;
-    sParse.db = db;
     sqlite3DbFree(db, zErr);
     zErr = 0;
 
@@ -332,7 +331,9 @@ int sqlite3_blob_open(
       goto blob_open_out;
     }
     rc = blobSeekToRow(pBlob, iRow, &zErr);
-  } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
+    if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break;
+    sqlite3ParseObjectReset(&sParse);
+  }
 
 blob_open_out:
   if( rc==SQLITE_OK && db->mallocFailed==0 ){
@@ -343,7 +344,7 @@ blob_open_out:
   }
   sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
   sqlite3DbFree(db, zErr);
-  sqlite3ParserReset(&sParse);
+  sqlite3ParseObjectReset(&sParse);
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
index ef86dd6bd43bc7e871a2e6e50c510165b05f18b7..11c076e4e6ad8e176d6960ea8ba0a13bc34a9d53 100644 (file)
@@ -825,9 +825,8 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
   pTab = pCtx->pTab;
   assert( IsVirtual(pTab) );
 
-  memset(&sParse, 0, sizeof(sParse));
+  sqlite3ParseObjectInit(&sParse, db);
   sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
-  sParse.db = db;
   /* We should never be able to reach this point while loading the
   ** schema.  Nevertheless, defend against that (turn off db->init.busy)
   ** in case a bug arises. */
@@ -881,7 +880,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
     sqlite3VdbeFinalize(sParse.pVdbe);
   }
   sqlite3DeleteTable(db, sParse.pNewTable);
-  sqlite3ParserReset(&sParse);
+  sqlite3ParseObjectReset(&sParse);
   db->init.busy = initBusy;
 
   assert( (rc&0xff)==rc );