]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the way SubProgram objects are deleted so that the code is the same for deleti...
authordan <dan@noemail.net>
Mon, 26 Jul 2010 12:05:17 +0000 (12:05 +0000)
committerdan <dan@noemail.net>
Mon, 26 Jul 2010 12:05:17 +0000 (12:05 +0000)
FossilOrigin-Name: 00e55102a8309eb6df08ad4a8937ba02688bac62

manifest
manifest.uuid
src/prepare.c
src/sqliteInt.h
src/status.c
src/trigger.c
src/vdbe.h
src/vdbeInt.h
src/vdbeaux.c

index 339551f8384a702f57860567ceebb4f869bd152b..2314cb61682eafd5f087d9f4750a511c19f99ecc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Update\scomments\sto\sbetter\sdocumentation\sthe\snew\smemory\smeasurement\sfunctions.
-D 2010-07-26T11:59:41
+C Change\sthe\sway\sSubProgram\sobjects\sare\sdeleted\sso\sthat\sthe\scode\sis\sthe\ssame\sfor\sdeletion\sand\smeasurement.
+D 2010-07-26T12:05:17
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -166,7 +163,7 @@ F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
 F src/pcache1.c 3a7c28f46a61b43ff0b5c087a7983c154f4b264c
 F src/pragma.c 8b24ce00a93de345b6c3bd1e1e2cfba9f63d2325
-F src/prepare.c f045aeff869d6409a2eae2fe08f7dc2df9528195
+F src/prepare.c ce4c35a2b1d5fe916e4a46b70d24a6e997d7c4c6
 F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
@@ -175,9 +172,9 @@ F src/select.c 74fef1334bec27e606ef0b19e5c41cd0a639e69c
 F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
 F src/sqlite.h.in e789728101d821fd4307208aa11e332e51eedbf9
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
-F src/sqliteInt.h 2a057459f689e23514f0ac2c414ef900f5d02a71
+F src/sqliteInt.h a9be6badc6cd6a3c1ae54475a98661cf351ecad5
 F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
-F src/status.c 0fb0feca10d0b991b573a2d0cec909507388c9aa
+F src/status.c ff0f61918f0c340ef5bc46154fdaadfd2646c196
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4
 F src/test1.c ff3b4533fc4d78d1bff2ef831a5791db55096ed3
@@ -216,16 +213,16 @@ F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
 F src/test_vfs.c 7e291f85256516ebde6633bc381ff7eedfa30234
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
-F src/trigger.c 67e95c76d625b92d43409ace771c8e0d02a09ac2
+F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852
 F src/update.c 19c899c23cd29fd102c9068e0b0ff5b087204beb
 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
 F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
 F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f
 F src/vdbe.c cefff41564b68a412e65e6a1013ec1b1c1ece6c4
-F src/vdbe.h 7c5de1c7e2e6bc1f301bb95297aeb5d1b8455764
-F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
+F src/vdbe.h e1b91019c807519b8060199f6341ad4255066ae8
+F src/vdbeInt.h ffd68c4d4229227a5089bec53a1c635146177abc
 F src/vdbeapi.c dc3138f10afbc95ed3c21dd25abb154504b1db9d
-F src/vdbeaux.c 1616d797183a7b803124697bb4dfa883b3b6c12a
+F src/vdbeaux.c 41a4b2f9cd5fd5d459bee9095edd6b3072a12831
 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
@@ -841,14 +838,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 629e38a8c9e31111e351fe4625a5835576d23584
-R 80a7d5f9fa365532b65c8e170e351383
-U drh
-Z b16bb922413ea0fca9b19fe4f93e9874
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMTXixoxKgR168RlERAl/DAJ9boDTlwMhZR5i1jAV24nxPvAFe6QCffw/4
-5JpbTS+Stpy5Ry5GR8Rpung=
-=Daaj
------END PGP SIGNATURE-----
+P 620bad035755449c4e6a762f01ef2b1d9e521c7c
+R 14493e17a0baceac42c57619039e3d05
+U dan
+Z 639bb9e1b1cea8e0a9149dd70998905a
index dc43a1dbf64316a092740121b520f0b9730e124b..195b31931e88c80af1fd59ca7965ae387377baa8 100644 (file)
@@ -1 +1 @@
-620bad035755449c4e6a762f01ef2b1d9e521c7c
\ No newline at end of file
+00e55102a8309eb6df08ad4a8937ba02688bac62
\ No newline at end of file
index e51000120c24cb5569e6f85136b59c67d2fb41df..74accd761f00e0fab8a75b26b0829c2b609e4638 100644 (file)
@@ -670,7 +670,6 @@ static int sqlite3Prepare(
   while( pParse->pTriggerPrg ){
     TriggerPrg *pT = pParse->pTriggerPrg;
     pParse->pTriggerPrg = pT->pNext;
-    sqlite3VdbeProgramDelete(db, pT->pProgram, 0);
     sqlite3DbFree(db, pT);
   }
 
index 02705769c383731b2f286ce9858aca6cba3d5b00..45b893b2dc3d5c26bdc9ff64b035862ac927dd7a 100644 (file)
@@ -861,7 +861,6 @@ struct sqlite3 {
   u8 isTransactionSavepoint;    /* True if the outermost savepoint is a TS */
   i64 nDeferredCons;            /* Net deferred constraints this transaction. */
   int *pnBytesFreed;            /* If not NULL, increment this in DbFree() */
-  SubProgram *pSubProgram;      /* List of sub-programs already visited*/
 
 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
   /* The following variables are all protected by the STATIC_MASTER 
index fce355b8f4108b2adf5dec0b05c57323288f36b4..3ea8a95cbb855f3b985bc617905155f6d44f56ea 100644 (file)
@@ -191,13 +191,7 @@ int sqlite3_db_status(
 
       db->pnBytesFreed = &nByte;
       for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
-        SubProgram *pSub, *pNext;
        sqlite3VdbeDeleteObject(db, pVdbe);
-        for(pSub=db->pSubProgram; pSub; pSub=pNext){
-         pNext = pSub->pNext;
-         pSub->pNext = 0;
-        }
-       db->pSubProgram = 0;
       }
       db->pnBytesFreed = 0;
 
index 27fc708d7ce58f5f4cc7e140b7b61bfdc609f121..b1d43d06d2b7e486ef90103af2517dd3015ee245 100644 (file)
@@ -800,6 +800,7 @@ static TriggerPrg *codeRowTrigger(
   int iEndTrigger = 0;        /* Label to jump to if WHEN is false */
 
   assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
+  assert( pTop->pVdbe );
 
   /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
   ** are freed if an error occurs, link them into the Parse.pTriggerPrg 
@@ -810,7 +811,7 @@ static TriggerPrg *codeRowTrigger(
   pTop->pTriggerPrg = pPrg;
   pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram));
   if( !pProgram ) return 0;
-  pProgram->nRef = 1;
+  sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram);
   pPrg->pTrigger = pTrigger;
   pPrg->orconf = orconf;
   pPrg->aColmask[0] = 0xffffffff;
@@ -944,8 +945,9 @@ void sqlite3CodeRowTriggerDirect(
   /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program 
   ** is a pointer to the sub-vdbe containing the trigger program.  */
   if( pPrg ){
+    int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
+
     sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem);
-    pPrg->pProgram->nRef++;
     sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
     VdbeComment(
         (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
@@ -955,7 +957,7 @@ void sqlite3CodeRowTriggerDirect(
     ** invocation is disallowed if (a) the sub-program is really a trigger,
     ** not a foreign key action, and (b) the flag to enable recursive triggers
     ** is clear.  */
-    sqlite3VdbeChangeP5(v, (u8)(p->zName && !(pParse->db->flags&SQLITE_RecTriggers)));
+    sqlite3VdbeChangeP5(v, (u8)bRecursive);
   }
 }
 
index be77e2ff6b61555cdf068939bdfad6a0c80c2edf..b22a85a53b75382c79c597a1e46b0ab52da77463 100644 (file)
@@ -81,7 +81,6 @@ struct SubProgram {
   int nOp;                      /* Elements in aOp[] */
   int nMem;                     /* Number of memory cells required */
   int nCsr;                     /* Number of cursors required */
-  int nRef;                     /* Number of pointers to this structure */
   void *token;                  /* id that may be used to recursive triggers */
   SubProgram *pNext;            /* Next sub-program already visited */
 };
@@ -214,6 +213,10 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,char*,int);
 void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
 int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
 
+#ifndef SQLITE_OMIT_TRIGGER
+void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
+#endif
+
 
 #ifndef NDEBUG
   void sqlite3VdbeComment(Vdbe*, const char*, ...);
index e8e158544903412d81dc778c75528d9d2a9e87a7..4a19f14c2d152ce987cb58b326ad2d2ea5e52824 100644 (file)
@@ -323,6 +323,7 @@ struct Vdbe {
   VdbeFrame *pFrame;      /* Parent frame */
   int nFrame;             /* Number of frames in pFrame list */
   u32 expmask;            /* Binding to these vars invalidates VM */
+  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
 };
 
 /*
index 7359d18ab0ada0ce3c02e1f3804ede4f8e475731..7d9f8c060aad4fa9447b2195c9e76cbe043ef071 100644 (file)
@@ -614,24 +614,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
         if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
         break;
       }
-      case P4_SUBPROGRAM : {
-        if( db->pnBytesFreed ){
-         SubProgram *p = (SubProgram *)p4;
-         SubProgram *pDone;
-         for(pDone=db->pSubProgram; pDone; pDone=pDone->pNext){
-           if( pDone==p ) break;
-         }
-         if( !pDone ){
-           p->pNext = db->pSubProgram;
-           db->pSubProgram = p;
-            vdbeFreeOpArray(db, p->aOp, p->nOp);
-            sqlite3DbFree(db, p);
-         }
-       }else{
-         sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1);
-       }
-        break;
-      }
     }
   }
 }
@@ -655,35 +637,15 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
 }
 
 /*
-** Decrement the ref-count on the SubProgram structure passed as the
-** second argument. If the ref-count reaches zero, free the structure.
-**
-** The array of VDBE opcodes stored as SubProgram.aOp is freed if
-** either the ref-count reaches zero or parameter freeop is non-zero.
-**
-** Since the array of opcodes pointed to by SubProgram.aOp may directly
-** or indirectly contain a reference to the SubProgram structure itself.
-** By passing a non-zero freeop parameter, the caller may ensure that all
-** SubProgram structures and their aOp arrays are freed, even when there
-** are such circular references.
+** Link the SubProgram object passed as the second argument into the linked
+** list at Vdbe.pSubProgram. This list is used to delete all sub-program
+** objects when the VM is no longer required.
 */
-void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){
-  if( p ){
-    assert( p->nRef>0 );
-    if( freeop || p->nRef==1 ){
-      Op *aOp = p->aOp;
-      p->aOp = 0;
-      vdbeFreeOpArray(db, aOp, p->nOp);
-      p->nOp = 0;
-    }
-    p->nRef--;
-    if( p->nRef==0 ){
-      sqlite3DbFree(db, p);
-    }
-  }
+void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
+  p->pNext = pVdbe->pProgram;
+  pVdbe->pProgram = p;
 }
 
-
 /*
 ** Change N opcodes starting at addr to No-ops.
 */
@@ -2367,9 +2329,15 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
 ** the database connection.
 */
 void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
+  SubProgram *pSub, *pNext;
   assert( p->db==0 || p->db==db );
   releaseMemArray(p->aVar, p->nVar);
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+  for(pSub=p->pProgram; pSub; pSub=pNext){
+    pNext = pSub->pNext;
+    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
+    sqlite3DbFree(db, pSub);
+  }
   vdbeFreeOpArray(db, p->aOp, p->nOp);
   sqlite3DbFree(db, p->aLabel);
   sqlite3DbFree(db, p->aColName);