From 942b0a68ea6ecea7b1e9b8c98139136b8015c99a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 19 Feb 2015 19:59:35 +0000 Subject: [PATCH] Ensure the mutex used to protect the linked list of all main database files opened by a single ota vfs is allocated. FossilOrigin-Name: 9c8682d6650a94e11f9bec5baff69ed9668874fa --- ext/ota/ota1.test | 5 +- ext/ota/sqlite3ota.c | 289 ++++++++++++++++++++++++++----------------- manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 185 insertions(+), 125 deletions(-) diff --git a/ext/ota/ota1.test b/ext/ota/ota1.test index d0e7890ed2..a2ebd56c42 100644 --- a/ext/ota/ota1.test +++ b/ext/ota/ota1.test @@ -100,7 +100,10 @@ proc create_ota5 {filename} { # proc run_ota {target ota} { sqlite3ota ota $target $ota - while { [ota step]=="SQLITE_OK" } {} + while 1 { + set rc [ota step] + if {$rc!="SQLITE_OK"} break + } ota close } diff --git a/ext/ota/sqlite3ota.c b/ext/ota/sqlite3ota.c index 6351dfe852..2510f33f03 100644 --- a/ext/ota/sqlite3ota.c +++ b/ext/ota/sqlite3ota.c @@ -103,12 +103,12 @@ ** keys mapped to values as follows: ** ** OTA_STATE_STAGE: -** May be set to integer values 1, 2 or 3. As follows: -** 0: Nothing at all has been done. +** May be set to integer values 1, 2, 4 or 5. As follows: ** 1: the *-ota file is currently under construction. ** 2: the *-ota file has been constructed, but not yet moved ** to the *-wal path. -** 3: the checkpoint is underway. +** 4: the checkpoint is underway. +** 5: the ota update has been checkpointed. ** ** OTA_STATE_TBL: ** Only valid if STAGE==1. The target database name of the table @@ -128,8 +128,11 @@ ** ota update. ** ** OTA_STATE_CKPT: -** Valid if STAGE==3. The blob to pass to sqlite3ckpt_start() to resume -** the incremental checkpoint. +** Valid if STAGE==4. The 64-bit checksum associated with the wal-index +** header created by recovering the *-wal file. This is used to detect +** cases when another client appends frames to the *-wal file in the +** middle of an incremental checkpoint (an incremental checkpoint cannot +** be continued if this happens). ** ** OTA_STATE_COOKIE: ** Valid if STAGE==1. The current change-counter cookie value in the @@ -153,8 +156,9 @@ #define OTA_CREATE_STATE "CREATE TABLE IF NOT EXISTS ota.ota_state" \ "(k INTEGER PRIMARY KEY, v)" -typedef struct OtaState OtaState; +typedef struct OtaFrame OtaFrame; typedef struct OtaObjIter OtaObjIter; +typedef struct OtaState OtaState; typedef struct ota_vfs ota_vfs; typedef struct ota_file ota_file; @@ -213,7 +217,6 @@ struct OtaObjIter { int iTnum; /* Root page of current object */ int iPkTnum; /* If eType==EXTERNAL, root of PK index */ int bUnique; /* Current index is unique */ - int iVisit; /* Number of points visited, incl. current */ /* Statements created by otaObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ @@ -244,7 +247,21 @@ struct OtaObjIter { #define OTA_PK_VTAB 5 -typedef struct OtaFrame OtaFrame; +/* +** Within the OTA_STAGE_OAL stage, each call to sqlite3ota_step() performs +** one of the following operations. +*/ +#define OTA_INSERT 1 /* Insert on a main table b-tree */ +#define OTA_DELETE 2 /* Delete a row from a main table b-tree */ +#define OTA_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */ +#define OTA_IDX_INSERT 4 /* Insert on an aux. index b-tree */ +#define OTA_UPDATE 5 /* Update a row in a main table b-tree */ + + +/* +** A single step of an incremental checkpoint - frame iWalFrame of the wal +** file should be copied to page iDbPage of the database file. +*/ struct OtaFrame { u32 iDbPage; u32 iWalFrame; @@ -279,6 +296,9 @@ struct sqlite3ota { i64 iWalCksum; }; +/* +** An ota VFS is implemented using an instance of this structure. +*/ struct ota_vfs { sqlite3_vfs base; /* ota VFS shim methods */ sqlite3_vfs *pRealVfs; /* Underlying VFS */ @@ -286,6 +306,10 @@ struct ota_vfs { ota_file *pMain; /* Linked list of main db files */ }; +/* +** Each file opened by an ota VFS is represented by an instance of +** the following structure. +*/ struct ota_file { sqlite3_file base; /* sqlite3_file methods */ sqlite3_file *pReal; /* Underlying file handle */ @@ -459,7 +483,7 @@ static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){ pIter->bCleanup = 0; rc = sqlite3_step(pIter->pTblIter); if( rc!=SQLITE_ROW ){ - rc = sqlite3_reset(pIter->pTblIter); + rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); pIter->zTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); @@ -474,7 +498,7 @@ static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){ if( rc==SQLITE_OK ){ rc = sqlite3_step(pIter->pIdxIter); if( rc!=SQLITE_ROW ){ - rc = sqlite3_reset(pIter->pIdxIter); + rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg); pIter->bCleanup = 1; pIter->zIdx = 0; }else{ @@ -492,7 +516,6 @@ static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){ otaObjIterFinalize(pIter); p->rc = rc; } - pIter->iVisit++; return rc; } @@ -528,6 +551,30 @@ static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){ return otaObjIterNext(p, pIter); } +/* +** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, +** an error code is stored in the OTA handle passed as the first argument. +** +** If an error has already occurred (p->rc is already set to something other +** than SQLITE_OK), then this function returns NULL without modifying the +** stored error code. In this case it still calls sqlite3_free() on any +** printf() parameters associated with %z conversions. +*/ +static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){ + char *zSql = 0; + va_list ap; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zSql==0 ) p->rc = SQLITE_NOMEM; + }else{ + sqlite3_free(zSql); + zSql = 0; + } + va_end(ap); + return zSql; +} + /* ** Argument zFmt is a sqlite3_mprintf() style format string. The trailing ** arguments are the usual subsitution values. This function performs @@ -541,19 +588,29 @@ static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){ static int otaMPrintfExec(sqlite3ota *p, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); + char *zSql = sqlite3_vmprintf(zFmt, ap); if( p->rc==SQLITE_OK ){ - char *zSql = sqlite3_vmprintf(zFmt, ap); if( zSql==0 ){ p->rc = SQLITE_NOMEM; }else{ p->rc = sqlite3_exec(p->db, zSql, 0, 0, &p->zErrmsg); - sqlite3_free(zSql); } } + sqlite3_free(zSql); va_end(ap); return p->rc; } +/* +** Attempt to allocate and return a pointer to a zeroed block of nByte +** bytes. +** +** If an error (i.e. an OOM condition) occurs, return NULL and leave an +** error code in the ota handle passed as the first argument. Or, if an +** error has already occurred when this function is called, return NULL +** immediately without attempting the allocation or modifying the stored +** error code. +*/ static void *otaMalloc(sqlite3ota *p, int nByte){ void *pRet = 0; if( p->rc==SQLITE_OK ){ @@ -587,6 +644,16 @@ static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){ } } +/* +** The first argument must be a nul-terminated string. This function +** returns a copy of the string in memory obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free this memory +** using sqlite3_free(). +** +** If an OOM condition is encountered when attempting to allocate memory, +** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, +** if the allocation succeeds, (*pRc) is left unchanged. +*/ static char *otaStrndup(const char *zStr, int *pRc){ char *zRet = 0; @@ -604,6 +671,22 @@ static char *otaStrndup(const char *zStr, int *pRc){ return zRet; } +/* +** Finalize the statement passed as the second argument. +** +** If the sqlite3_finalize() call indicates that an error occurs, and the +** ota handle error code is not already set, set the error code and error +** message accordingly. +*/ +static void otaFinalize(sqlite3ota *p, sqlite3_stmt *pStmt){ + sqlite3 *db = sqlite3_db_handle(pStmt); + int rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ + p->rc = rc; + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } +} + /* Determine the type of a table. ** ** peType is of type (int*), a pointer to an output parameter of type @@ -716,8 +799,7 @@ static void otaTableType( otaTableType_end: { int i; for(i=0; irc==SQLITE_OK ) p->rc = rc2; + otaFinalize(p, aStmt[i]); } } } @@ -737,7 +819,6 @@ static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){ sqlite3_stmt *pStmt = 0; int nCol = 0; int i; /* for() loop iterator variable */ - int rc2; /* sqlite3_finalize() return value */ int bOtaRowid = 0; /* If input table has column "ota_rowid" */ int iOrder = 0; @@ -821,37 +902,12 @@ static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){ } } - rc2 = sqlite3_finalize(pStmt); - if( p->rc==SQLITE_OK ) p->rc = rc2; + otaFinalize(p, pStmt); } return p->rc; } -/* -** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, -** an error code is stored in the OTA handle passed as the first argument. -** -** If an error has already occurred (p->rc is already set to something other -** than SQLITE_OK), then this function returns NULL without modifying the -** stored error code. In this case it still calls sqlite3_free() on any -** printf() parameters associated with %z conversions. -*/ -static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){ - char *zSql = 0; - va_list ap; - va_start(ap, zFmt); - zSql = sqlite3_vmprintf(zFmt, ap); - if( p->rc==SQLITE_OK ){ - if( zSql==0 ) p->rc = SQLITE_NOMEM; - }else{ - sqlite3_free(zSql); - zSql = 0; - } - va_end(ap); - return zSql; -} - /* ** This function constructs and returns a pointer to a nul-terminated ** string containing some SQL clause or list based on one or more of the @@ -1082,6 +1138,23 @@ static void otaBadControlError(sqlite3ota *p){ } +/* +** Return a nul-terminated string containing the comma separated list of +** assignments that should be included following the "SET" keyword of +** an UPDATE statement used to update the table object that the iterator +** passed as the second argument currently points to if the ota_control +** column of the data_xxx table entry is set to zMask. +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the ota handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ static char *otaObjIterGetSetlist( sqlite3ota *p, OtaObjIter *pIter, @@ -1115,6 +1188,21 @@ static char *otaObjIterGetSetlist( return zList; } +/* +** Return a nul-terminated string consisting of nByte comma separated +** "?" expressions. For example, if nByte is 3, return a pointer to +** a buffer containing the string "?,?,?". +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the ota handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ static char *otaObjIterGetBindlist(sqlite3ota *p, int nBind){ char *zRet = 0; int nByte = nBind*2 + 1; @@ -1149,8 +1237,6 @@ static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){ const char *zSep = "PRIMARY KEY("; sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ - int rc; /* sqlite3_finalize() return code */ - p->rc = prepareFreeAndCollectError(p->db, &pXList, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) @@ -1167,8 +1253,7 @@ static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){ break; } } - rc = sqlite3_finalize(pXList); - if( p->rc==SQLITE_OK ) p->rc = rc; + otaFinalize(p, pXList); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ if( sqlite3_column_int(pXInfo, 5) ){ @@ -1180,17 +1265,11 @@ static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){ } } z = otaMPrintf(p, "%z)", z); - rc = sqlite3_finalize(pXInfo); - if( p->rc==SQLITE_OK ) p->rc = rc; + otaFinalize(p, pXInfo); } return z; } -static void otaFinalize(sqlite3ota *p, sqlite3_stmt *pStmt){ - int rc = sqlite3_finalize(pStmt); - if( p->rc==SQLITE_OK ) p->rc = rc; -} - /* ** This function creates the second imposter table used when writing to ** a table b-tree where the table has an external primary key. If the @@ -1216,13 +1295,9 @@ static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){ sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ const char *zIdx = 0; /* Name of PK index */ sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ - int rc; - const char *zComma = ""; - char *zCols = 0; /* Used to build up list of table cols */ char *zPk = 0; /* Used to build up table PK declaration */ - char *zSql = 0; /* CREATE TABLE statement */ /* Figure out the name of the primary key index for the current table. ** This is needed for the argument to "PRAGMA index_xinfo". Set @@ -1257,20 +1332,14 @@ static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){ } } zCols = otaMPrintf(p, "%z, id INTEGER", zCols); - rc = sqlite3_finalize(pXInfo); - if( p->rc==SQLITE_OK ) p->rc = rc; + otaFinalize(p, pXInfo); - zSql = otaMPrintf(p, + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); + otaMPrintfExec(p, "CREATE TABLE ota_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", zCols, zPk ); - assert( (zSql==0)==(p->rc!=SQLITE_OK) ); - if( zSql ){ - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); - p->rc = sqlite3_exec(p->db, zSql, 0, 0, &p->zErrmsg); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); - } - sqlite3_free(zSql); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); } } @@ -1283,26 +1352,16 @@ static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){ ** ** The iterator passed as the second argument is guaranteed to point to ** a table (not an index) when this function is called. This function -** attempts to create any imposter tables required to write to the main +** attempts to create any imposter table required to write to the main ** table b-tree of the table before returning. Non-zero is returned if -** imposter tables are created, or zero otherwise. +** an imposter table are created, or zero otherwise. ** -** The required imposter tables depend on the type of table that the -** iterator currently points to. -** -** OTA_PK_NONE, OTA_PK_IPK, OTA_PK_WITHOUT_ROWID: -** A single imposter table is required. With the same schema as -** the actual target table (less any UNIQUE constraints). More -** precisely, the "same schema" means the same columns, types, collation -** sequences and primary key declaration. -** -** OTA_PK_VTAB: -** No imposters required. -** -** OTA_PK_EXTERNAL: -** Two imposters are required. The first has the same schema as the -** target database table, with no PRIMARY KEY or UNIQUE clauses. The -** second is used to access the PK b-tree index on disk. +** An imposter table is required in all cases except OTA_PK_VTAB. Only +** virtual tables are written to directly. The imposter table has the +** same schema as the actual target table (less any UNIQUE constraints). +** More precisely, the "same schema" means the same columns, types, +** collation sequences. For tables that do not have an external PRIMARY +** KEY, it also means the same PRIMARY KEY declaration. */ static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){ if( p->rc==SQLITE_OK && pIter->eType!=OTA_PK_VTAB ){ @@ -1340,16 +1399,12 @@ static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){ } } - zSql = otaMPrintf(p, "CREATE TABLE \"ota_imp_%w\"(%z)%s", + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); + otaMPrintfExec(p, "CREATE TABLE \"ota_imp_%w\"(%z)%s", pIter->zTbl, zSql, (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") ); - if( p->rc==SQLITE_OK ){ - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); - p->rc = sqlite3_exec(p->db, zSql, 0, 0, &p->zErrmsg); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); - } - sqlite3_free(zSql); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); } } @@ -1547,17 +1602,17 @@ static int otaObjIterPrepareAll( return p->rc; } -#define OTA_INSERT 1 -#define OTA_DELETE 2 -#define OTA_IDX_DELETE 3 -#define OTA_IDX_INSERT 4 -#define OTA_UPDATE 5 - +/* +** Set output variable *ppStmt to point to an UPDATE statement that may +** be used to update the imposter table for the main table b-tree of the +** table object that pIter currently points to, assuming that the +** ota_control column of the data_xyz table contains zMask. +*/ static int otaGetUpdateStmt( - sqlite3ota *p, - OtaObjIter *pIter, - const char *zMask, - sqlite3_stmt **ppStmt + sqlite3ota *p, /* OTA handle */ + OtaObjIter *pIter, /* Object iterator */ + const char *zMask, /* ota_control value ('x.x.') */ + sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ ){ if( pIter->pUpdate && strcmp(zMask, pIter->zMask)==0 ){ *ppStmt = pIter->pUpdate; @@ -2007,7 +2062,7 @@ static void otaIncrSchemaCookie(sqlite3ota *p){ if( SQLITE_ROW==sqlite3_step(pStmt) ){ iCookie = sqlite3_column_int(pStmt, 0); } - p->rc = sqlite3_finalize(pStmt); + otaFinalize(p, pStmt); } if( p->rc==SQLITE_OK ){ otaMPrintfExec(p, "PRAGMA schema_version = %d", iCookie+1); @@ -2039,19 +2094,14 @@ static void otaSaveState(sqlite3ota *p, int eStage){ OTA_STATE_CKPT, p->iWalCksum, OTA_STATE_COOKIE, (i64)p->pTargetFd->iCookie ) - ); + ); assert( pInsert==0 || rc==SQLITE_OK ); if( rc==SQLITE_OK ){ sqlite3_step(pInsert); rc = sqlite3_finalize(pInsert); - }else{ - sqlite3_finalize(pInsert); - } - - if( rc!=SQLITE_OK ){ - p->rc = rc; } + if( rc!=SQLITE_OK ) p->rc = rc; } } @@ -3103,6 +3153,7 @@ static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ void sqlite3ota_destroy_vfs(const char *zName){ sqlite3_vfs *pVfs = sqlite3_vfs_find(zName); if( pVfs && pVfs->xOpen==otaVfsOpen ){ + sqlite3_mutex_free(((ota_vfs*)pVfs)->mutex); sqlite3_vfs_unregister(pVfs); sqlite3_free(pVfs); } @@ -3158,18 +3209,24 @@ int sqlite3ota_create_vfs(const char *zName, const char *zParent){ pNew->base.mxPathname = pParent->mxPathname; pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile; pNew->pRealVfs = pParent; - pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]); memcpy(zSpace, zName, nName); - /* Register the new VFS (not as the default) */ - rc = sqlite3_vfs_register(&pNew->base, 0); + /* Allocate the mutex and register the new VFS (not as the default) */ + pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); + if( pNew->mutex==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_vfs_register(&pNew->base, 0); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3_mutex_free(pNew->mutex); + sqlite3_free(pNew); } } - if( rc!=SQLITE_OK ){ - sqlite3_free(pNew); - } return rc; } diff --git a/manifest b/manifest index 837a4081da..a022fbaa87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\svarious\sdocumentation\scomments\sin\ssqlite3ota.c\sand\ssqlite3ota.h. -D 2015-02-19T18:06:40.917 +C Ensure\sthe\smutex\sused\sto\sprotect\sthe\slinked\slist\sof\sall\smain\sdatabase\sfiles\sopened\sby\sa\ssingle\sota\svfs\sis\sallocated. +D 2015-02-19T19:59:35.500 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -124,7 +124,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91 -F ext/ota/ota1.test ba408c5e777c320ef72f328e20cd2ae2a8888cda +F ext/ota/ota1.test 66cf5cb7fb1b2fcf74b9ec3fca2b5bf0286ae330 F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4 F ext/ota/ota11.test 2f606cd2b4af260a86b549e91b9f395450fc75cb F ext/ota/ota12.test 0dff44474de448fb4b0b28c20da63273a4149abb @@ -137,7 +137,7 @@ F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b F ext/ota/otaA.test ef4bfa8cfd4ed814ae86f7457b64aa2f18c90171 F ext/ota/otafault.test 8c43586c2b96ca16bbce00b5d7e7d67316126db8 F ext/ota/otafault2.test fa202a98ca221faec318f3e5c5f39485b1256561 -F ext/ota/sqlite3ota.c a8e19ef2a297627fdc1e18f8679110afeaa5cd4b +F ext/ota/sqlite3ota.c 692de0a8c43dbe7a98e0cb6760c55635c3d58b5a F ext/ota/sqlite3ota.h 69106b04616f4e7e565aa4dc2092a2f095212cc2 F ext/ota/test_ota.c 9ec6ea945282f65f67f0e0468dad79a489818f44 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 @@ -1257,7 +1257,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6f5888a5e430feb5d9a50009a2eb103d9945bd22 -R 536b36bcdeeeb4de103e032d97a52335 +P 60e0a46b82dd9c704e8aa977d1ccdd73d388422f +R 24048fcc0c09eb0db3eb9c1d038269b2 U dan -Z 4148e3e31feb6bcdc60726ac41a858b3 +Z 33143372b71a8b702a8cbb544384d97d diff --git a/manifest.uuid b/manifest.uuid index 48aabc2dfe..de388b6f0e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60e0a46b82dd9c704e8aa977d1ccdd73d388422f \ No newline at end of file +9c8682d6650a94e11f9bec5baff69ed9668874fa \ No newline at end of file