]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the behavior of sqlite_dbpage so that the null-INSERT that truncates
authordrh <>
Wed, 2 Oct 2024 18:54:40 +0000 (18:54 +0000)
committerdrh <>
Wed, 2 Oct 2024 18:54:40 +0000 (18:54 +0000)
a database must be the very last INSERT operation within a transaction in order
to be effective.  This simplifies the code and also makes the behavior
easier to document and understand.

FossilOrigin-Name: b869a7d9ce9567a61d2257272032aaee705bbc6158c7f2cd36e7f3ee66d72722

manifest
manifest.uuid
src/dbpage.c

index 2f603be8f6fa9820e536c19a09b5b9d4f0e112eb..23af5a0848ac016fb644e1306a2e2b5677e6de74 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\stypo\sin\sfts5delete.test.
-D 2024-10-02T17:43:06.145
+C Modify\sthe\sbehavior\sof\ssqlite_dbpage\sso\sthat\sthe\snull-INSERT\sthat\struncates\na\sdatabase\smust\sbe\sthe\svery\slast\sINSERT\soperation\swithin\sa\stransaction\sin\sorder\nto\sbe\seffective.\s\sThis\ssimplifies\sthe\scode\sand\salso\smakes\sthe\sbehavior\neasier\sto\sdocument\sand\sunderstand.
+D 2024-10-02T18:54:40.278
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -716,7 +716,7 @@ F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d49
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
 F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
-F src/dbpage.c 9da735cb2eef4ab6941ddb235c8d2c2764e0bb5bd20f7ca3003be1d4ab8d49c9
+F src/dbpage.c 6199d8c8d6d37a405a92a5da4ed9a69829d7453e6d5ea7b852d58d1fd41d549c
 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
 F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
 F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
@@ -2215,8 +2215,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 58313ac59e0bd164f601d68a1474f658c5d1c038638e00f3dc15eb58202e661c
-R c9854e52c5a2262f4abddd59c7216292
-U dan
-Z 46008f325e9f0a47cd9f68f44b346532
+P b1f001435eff72c2119ecee973194385f70fd1b66ef0be8a66c0b0ad02ae43df
+R cb980b8ea9ae6c90e71d1e6639808d4a
+U drh
+Z 0bd24346b1d9b6d9280a2c12dd94f943
 # Remove this line to create a well-formed Fossil manifest.
index 28469eeaae02c14910c4b489f25d0990d84b410e..93c98294524b5f1df578ea43e14790467b4733a8 100644 (file)
@@ -1 +1 @@
-b1f001435eff72c2119ecee973194385f70fd1b66ef0be8a66c0b0ad02ae43df
+b869a7d9ce9567a61d2257272032aaee705bbc6158c7f2cd36e7f3ee66d72722
index 136c8b0b3921adc23ca4514d57d7c3e7eef67b06..0a2020883f8d44280ade88d04c9c1968e78203ed 100644 (file)
@@ -57,8 +57,8 @@ struct DbpageCursor {
 struct DbpageTable {
   sqlite3_vtab base;              /* Base class.  Must be first */
   sqlite3 *db;                    /* The database */
-  int nTrunc;                     /* Entries in aTrunc[] */
-  Pgno *aTrunc;                   /* Truncation size for each database */
+  int iDbTrunc;                   /* Database to truncate */
+  Pgno pgnoTrunc;                 /* Size to truncate to */
 };
 
 /* Columns */
@@ -107,8 +107,6 @@ static int dbpageConnect(
 ** Disconnect from or destroy a dbpagevfs virtual table.
 */
 static int dbpageDisconnect(sqlite3_vtab *pVtab){
-  DbpageTable *pTab = (DbpageTable *)pVtab;
-  sqlite3_free(pTab->aTrunc);
   sqlite3_free(pVtab);
   return SQLITE_OK;
 }
@@ -378,19 +376,9 @@ static int dbpageUpdate(
     if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){
       /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and
       ** all subsequent pages to be deleted. */
-      if( iDb>=pTab->nTrunc ){
-        testcase( pTab->aTrunc!=0 );
-        pTab->aTrunc = sqlite3_realloc(pTab->aTrunc, (iDb+1)*sizeof(Pgno));
-        if( pTab->aTrunc ){
-          int j;
-          for(j=pTab->nTrunc; j<iDb; j++) pTab->aTrunc[j] = 0;
-          pTab->nTrunc = iDb+1;
-        }else{
-          return SQLITE_NOMEM;
-        }
-      }
+      pTab->iDbTrunc = iDb;
       pgno--;
-      pTab->aTrunc[iDb] = pgno;
+      pTab->pgnoTrunc = pgno;
     }else{
       zErr = "bad page value";
       goto update_fail;
@@ -403,6 +391,7 @@ static int dbpageUpdate(
     if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
       unsigned char *aPage = sqlite3PagerGetData(pDbPage);
       memcpy(aPage, pData, szPage);
+      pTab->pgnoTrunc = 0;
     }
   }
   sqlite3PagerUnref(pDbPage);
@@ -426,29 +415,30 @@ static int dbpageBegin(sqlite3_vtab *pVtab){
     Btree *pBt = db->aDb[i].pBt;
     if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
   }
-  if( pTab->nTrunc>0 ){
-    memset(pTab->aTrunc, 0, sizeof(pTab->aTrunc[0])*pTab->nTrunc);
-  }
+  pTab->pgnoTrunc = 0;
   return SQLITE_OK;
 }
 
 /* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
 */
 static int dbpageSync(sqlite3_vtab *pVtab){
-  int iDb;
   DbpageTable *pTab = (DbpageTable *)pVtab;
-
-  for(iDb=0; iDb<pTab->nTrunc; iDb++){
-    if( pTab->aTrunc[iDb]>0 ){
-      Btree *pBt = pTab->db->aDb[iDb].pBt;
-      Pager *pPager = sqlite3BtreePager(pBt);
-      sqlite3PagerTruncateImage(pPager, pTab->aTrunc[iDb]);
-      pTab->aTrunc[iDb] = 0;
-    }
+  if( pTab->pgnoTrunc>0 ){
+    Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt;
+    Pager *pPager = sqlite3BtreePager(pBt);
+    sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc);
   }
+  pTab->pgnoTrunc = 0;
   return SQLITE_OK;
 }
 
+/* Cancel any pending truncate.
+*/
+static dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){
+  DbpageTable *pTab = (DbpageTable *)pVtab;
+  pTab->pgnoTrunc = 0;
+  (void)notUsed1;
+}
 
 /*
 ** Invoke this routine to register the "dbpage" virtual table module
@@ -477,7 +467,7 @@ int sqlite3DbpageRegister(sqlite3 *db){
     0,                            /* xRename */
     0,                            /* xSavepoint */
     0,                            /* xRelease */
-    0,                            /* xRollbackTo */
+    dbpageRollbackTo,             /* xRollbackTo */
     0,                            /* xShadowName */
     0                             /* xIntegrity */
   };