From: drh Date: Fri, 24 Mar 2017 15:09:47 +0000 (+0000) Subject: Merge all recent enhancements from trunk. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d55d35df6419a0119ac38a4ed44a87b9970c0e4;p=thirdparty%2Fsqlite.git Merge all recent enhancements from trunk. FossilOrigin-Name: fd5676fe7f55b3d4fa15ca119af7c064c6f9d053affdfd5e748785e300affbeb --- 4d55d35df6419a0119ac38a4ed44a87b9970c0e4 diff --cc ext/session/sqlite3changebatch.c index 0490d5f977,0000000000..926a7d7785 mode 100644,000000..100644 --- a/ext/session/sqlite3changebatch.c +++ b/ext/session/sqlite3changebatch.c @@@ -1,486 -1,0 +1,485 @@@ + +#if !defined(SQLITE_TEST) || (defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)) + +#include "sqlite3session.h" +#include "sqlite3changebatch.h" + +#include +#include + +typedef struct BatchTable BatchTable; +typedef struct BatchIndex BatchIndex; +typedef struct BatchIndexEntry BatchIndexEntry; +typedef struct BatchHash BatchHash; + +struct sqlite3_changebatch { + sqlite3 *db; /* Database handle used to read schema */ + BatchTable *pTab; /* First in linked list of tables */ + int iChangesetId; /* Current changeset id */ + int iNextIdxId; /* Next available index id */ + int nEntry; /* Number of entries in hash table */ + int nHash; /* Number of hash buckets */ + BatchIndexEntry **apHash; /* Array of hash buckets */ +}; + +struct BatchTable { + BatchIndex *pIdx; /* First in linked list of UNIQUE indexes */ + BatchTable *pNext; /* Next table */ + char zTab[1]; /* Table name */ +}; + +struct BatchIndex { + BatchIndex *pNext; /* Next index on same table */ + int iId; /* Index id (assigned internally) */ + int bPk; /* True for PK index */ + int nCol; /* Size of aiCol[] array */ + int *aiCol; /* Array of columns that make up index */ +}; + +struct BatchIndexEntry { + BatchIndexEntry *pNext; /* Next colliding hash table entry */ + int iChangesetId; /* Id of associated changeset */ + int iIdxId; /* Id of index this key is from */ + int szRecord; + char aRecord[1]; +}; + +/* +** Allocate and zero a block of nByte bytes. Must be freed using cbFree(). +*/ +static void *cbMalloc(int *pRc, int nByte){ + void *pRet; + + if( *pRc ){ + pRet = 0; + }else{ + pRet = sqlite3_malloc(nByte); + if( pRet ){ + memset(pRet, 0, nByte); + }else{ + *pRc = SQLITE_NOMEM; + } + } + + return pRet; +} + +/* +** Free an allocation made by cbMalloc(). +*/ +static void cbFree(void *p){ + sqlite3_free(p); +} + +/* +** Return the hash bucket that pEntry belongs in. +*/ +static int cbHash(sqlite3_changebatch *p, BatchIndexEntry *pEntry){ + unsigned int iHash = (unsigned int)pEntry->iIdxId; + unsigned char *pEnd = (unsigned char*)&pEntry->aRecord[pEntry->szRecord]; + unsigned char *pIter; + + for(pIter=(unsigned char*)pEntry->aRecord; pIternHash); +} + +/* +** Resize the hash table. +*/ +static int cbHashResize(sqlite3_changebatch *p){ + int rc = SQLITE_OK; + BatchIndexEntry **apNew; + int nNew = (p->nHash ? p->nHash*2 : 512); + int i; + + apNew = cbMalloc(&rc, sizeof(BatchIndexEntry*) * nNew); + if( rc==SQLITE_OK ){ + int nHash = p->nHash; + p->nHash = nNew; + for(i=0; iapHash[i])!=0 ){ + int iHash = cbHash(p, pEntry); + p->apHash[i] = pEntry->pNext; + pEntry->pNext = apNew[iHash]; + apNew[iHash] = pEntry; + } + } + + cbFree(p->apHash); + p->apHash = apNew; + } + + return rc; +} + + +/* +** Allocate a new sqlite3_changebatch object. +*/ +int sqlite3changebatch_new(sqlite3 *db, sqlite3_changebatch **pp){ + sqlite3_changebatch *pRet; + int rc = SQLITE_OK; + *pp = pRet = (sqlite3_changebatch*)cbMalloc(&rc, sizeof(sqlite3_changebatch)); + if( pRet ){ + pRet->db = db; + } + return rc; +} + +/* +** Add a BatchIndex entry for index zIdx to table pTab. +*/ +static int cbAddIndex( + sqlite3_changebatch *p, + BatchTable *pTab, + const char *zIdx, + int bPk +){ + int nCol = 0; + sqlite3_stmt *pIndexInfo = 0; + BatchIndex *pNew = 0; + int rc; + char *zIndexInfo; + + zIndexInfo = (char*)sqlite3_mprintf("PRAGMA main.index_info = %Q", zIdx); + if( zIndexInfo ){ + rc = sqlite3_prepare_v2(p->db, zIndexInfo, -1, &pIndexInfo, 0); + sqlite3_free(zIndexInfo); + }else{ + rc = SQLITE_NOMEM; + } + + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==sqlite3_step(pIndexInfo) ){ nCol++; } + rc = sqlite3_reset(pIndexInfo); + } + + pNew = (BatchIndex*)cbMalloc(&rc, sizeof(BatchIndex) + sizeof(int) * nCol); + if( rc==SQLITE_OK ){ - int rc2; + pNew->nCol = nCol; + pNew->bPk = bPk; + pNew->aiCol = (int*)&pNew[1]; + pNew->iId = p->iNextIdxId++; + while( SQLITE_ROW==sqlite3_step(pIndexInfo) ){ + int i = sqlite3_column_int(pIndexInfo, 0); + int j = sqlite3_column_int(pIndexInfo, 1); + pNew->aiCol[i] = j; + } + rc = sqlite3_reset(pIndexInfo); + } + + if( rc==SQLITE_OK ){ + pNew->pNext = pTab->pIdx; + pTab->pIdx = pNew; + }else{ + cbFree(pNew); + } + sqlite3_finalize(pIndexInfo); + + return rc; +} + +/* +** Free the object passed as the first argument. +*/ +static void cbFreeTable(BatchTable *pTab){ + BatchIndex *pIdx; + BatchIndex *pIdxNext; + for(pIdx=pTab->pIdx; pIdx; pIdx=pIdxNext){ + pIdxNext = pIdx->pNext; + cbFree(pIdx); + } + cbFree(pTab); +} + +/* +** Find or create the BatchTable object named zTab. +*/ +static int cbFindTable( + sqlite3_changebatch *p, + const char *zTab, + BatchTable **ppTab +){ + BatchTable *pRet = 0; + int rc = SQLITE_OK; + + for(pRet=p->pTab; pRet; pRet=pRet->pNext){ + if( 0==sqlite3_stricmp(zTab, pRet->zTab) ) break; + } + + if( pRet==0 ){ + int nTab = strlen(zTab); + pRet = (BatchTable*)cbMalloc(&rc, nTab + sizeof(BatchTable)); + if( pRet ){ + sqlite3_stmt *pIndexList = 0; + char *zIndexList = 0; + int rc2; + memcpy(pRet->zTab, zTab, nTab); + + zIndexList = sqlite3_mprintf("PRAGMA main.index_list = %Q", zTab); + if( zIndexList==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(p->db, zIndexList, -1, &pIndexList, 0); + sqlite3_free(zIndexList); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pIndexList) ){ + if( sqlite3_column_int(pIndexList, 2) ){ + const char *zIdx = (const char*)sqlite3_column_text(pIndexList, 1); + const char *zTyp = (const char*)sqlite3_column_text(pIndexList, 3); + rc = cbAddIndex(p, pRet, zIdx, (zTyp[0]=='p')); + } + } + rc2 = sqlite3_finalize(pIndexList); + if( rc==SQLITE_OK ) rc = rc2; + + if( rc==SQLITE_OK ){ + pRet->pNext = p->pTab; + p->pTab = pRet; + }else{ + cbFreeTable(pRet); + pRet = 0; + } + } + } + + *ppTab = pRet; + return rc; +} + +/* +** Extract value iVal from the changeset iterator passed as the first +** argument. Set *ppVal to point to the value before returning. +** +** This function attempts to extract the value using function xVal +** (which is always either sqlite3changeset_new or sqlite3changeset_old). +** If the call returns SQLITE_OK but does not supply an sqlite3_value* +** pointer, an attempt to extract the value is made using the xFallback +** function. +*/ +static int cbGetChangesetValue( + sqlite3_changeset_iter *pIter, + int (*xVal)(sqlite3_changeset_iter*,int,sqlite3_value**), + int (*xFallback)(sqlite3_changeset_iter*,int,sqlite3_value**), + int iVal, + sqlite3_value **ppVal +){ + int rc = xVal(pIter, iVal, ppVal); + if( rc==SQLITE_OK && *ppVal==0 && xFallback ){ + rc = xFallback(pIter, iVal, ppVal); + } + return rc; +} + +static int cbAddToHash( + sqlite3_changebatch *p, + sqlite3_changeset_iter *pIter, + BatchIndex *pIdx, + int (*xVal)(sqlite3_changeset_iter*,int,sqlite3_value**), + int (*xFallback)(sqlite3_changeset_iter*,int,sqlite3_value**), + int *pbConf +){ + BatchIndexEntry *pNew; + int sz = pIdx->nCol; + int i; + int iOut = 0; + int rc = SQLITE_OK; + + for(i=0; rc==SQLITE_OK && inCol; i++){ + sqlite3_value *pVal; + rc = cbGetChangesetValue(pIter, xVal, xFallback, pIdx->aiCol[i], &pVal); + if( rc==SQLITE_OK ){ + int eType = 0; + if( pVal ) eType = sqlite3_value_type(pVal); + switch( eType ){ + case 0: + case SQLITE_NULL: + return SQLITE_OK; + + case SQLITE_INTEGER: + sz += 8; + break; + case SQLITE_FLOAT: + sz += 8; + break; + + default: + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + sz += sqlite3_value_bytes(pVal); + break; + } + } + } + + pNew = cbMalloc(&rc, sizeof(BatchIndexEntry) + sz); + if( pNew ){ + pNew->iChangesetId = p->iChangesetId; + pNew->iIdxId = pIdx->iId; + pNew->szRecord = sz; + + for(i=0; inCol; i++){ + int eType; + sqlite3_value *pVal; + rc = cbGetChangesetValue(pIter, xVal, xFallback, pIdx->aiCol[i], &pVal); + if( rc!=SQLITE_OK ) break; /* coverage: condition is never true */ + eType = sqlite3_value_type(pVal); + pNew->aRecord[iOut++] = eType; + switch( eType ){ + case SQLITE_INTEGER: { + sqlite3_int64 i64 = sqlite3_value_int64(pVal); + memcpy(&pNew->aRecord[iOut], &i64, 8); + iOut += 8; + break; + } + case SQLITE_FLOAT: { + double d64 = sqlite3_value_double(pVal); + memcpy(&pNew->aRecord[iOut], &d64, sizeof(double)); + iOut += sizeof(double); + break; + } + + default: { + int nByte = sqlite3_value_bytes(pVal); + const char *z = (const char*)sqlite3_value_blob(pVal); + memcpy(&pNew->aRecord[iOut], z, nByte); + iOut += nByte; + break; + } + } + } + } + + if( rc==SQLITE_OK && p->nEntry>=(p->nHash/2) ){ + rc = cbHashResize(p); + } + + if( rc==SQLITE_OK ){ + BatchIndexEntry *pIter; + int iHash = cbHash(p, pNew); + + assert( iHash>=0 && iHashnHash ); + for(pIter=p->apHash[iHash]; pIter; pIter=pIter->pNext){ + if( pNew->szRecord==pIter->szRecord + && 0==memcmp(pNew->aRecord, pIter->aRecord, pNew->szRecord) + ){ + if( pNew->iChangesetId!=pIter->iChangesetId ){ + *pbConf = 1; + } + cbFree(pNew); + pNew = 0; + break; + } + } + + if( pNew ){ + pNew->pNext = p->apHash[iHash]; + p->apHash[iHash] = pNew; + p->nEntry++; + } + }else{ + cbFree(pNew); + } + + return rc; +} + + +/* +** Add a changeset to the current batch. +*/ +int sqlite3changebatch_add(sqlite3_changebatch *p, void *pBuf, int nBuf){ + sqlite3_changeset_iter *pIter; /* Iterator opened on pBuf/nBuf */ + int rc; /* Return code */ + int bConf = 0; /* Conflict was detected */ + + rc = sqlite3changeset_start(&pIter, nBuf, pBuf); + if( rc==SQLITE_OK ){ + int rc2; + for(rc2 = sqlite3changeset_next(pIter); + rc2==SQLITE_ROW; + rc2 = sqlite3changeset_next(pIter) + ){ + BatchTable *pTab; + BatchIndex *pIdx; + const char *zTab; /* Table this change applies to */ + int nCol; /* Number of columns in table */ + int op; /* UPDATE, INSERT or DELETE */ + + sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0); + assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); + + rc = cbFindTable(p, zTab, &pTab); + assert( pTab || rc!=SQLITE_OK ); + if( pTab ){ + for(pIdx=pTab->pIdx; pIdx && rc==SQLITE_OK; pIdx=pIdx->pNext){ + if( op==SQLITE_UPDATE && pIdx->bPk ) continue; + if( op==SQLITE_UPDATE || op==SQLITE_DELETE ){ + rc = cbAddToHash(p, pIter, pIdx, sqlite3changeset_old, 0, &bConf); + } + if( op==SQLITE_UPDATE || op==SQLITE_INSERT ){ + rc = cbAddToHash(p, pIter, pIdx, + sqlite3changeset_new, sqlite3changeset_old, &bConf + ); + } + } + } + if( rc!=SQLITE_OK ) break; + } + + rc2 = sqlite3changeset_finalize(pIter); + if( rc==SQLITE_OK ) rc = rc2; + } + + if( rc==SQLITE_OK && bConf ){ + rc = SQLITE_CONSTRAINT; + } + p->iChangesetId++; + return rc; +} + +/* +** Zero an existing changebatch object. +*/ +void sqlite3changebatch_zero(sqlite3_changebatch *p){ + int i; + for(i=0; inHash; i++){ + BatchIndexEntry *pEntry; + BatchIndexEntry *pNext; + for(pEntry=p->apHash[i]; pEntry; pEntry=pNext){ + pNext = pEntry->pNext; + cbFree(pEntry); + } + } + cbFree(p->apHash); + p->nHash = 0; + p->apHash = 0; +} + +/* +** Delete a changebatch object. +*/ +void sqlite3changebatch_delete(sqlite3_changebatch *p){ + BatchTable *pTab; + BatchTable *pTabNext; + + sqlite3changebatch_zero(p); + for(pTab=p->pTab; pTab; pTab=pTabNext){ + pTabNext = pTab->pNext; + cbFreeTable(pTab); + } + cbFree(p); +} + +/* +** Return the db handle. +*/ +sqlite3 *sqlite3changebatch_db(sqlite3_changebatch *p){ + return p->db; +} + +#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ diff --cc manifest index 4359ecc0b2,cfdc624046..6cdd069a22 --- a/manifest +++ b/manifest @@@ -1,10 -1,10 +1,10 @@@ - C Merge\sthe\s"changebatch"\sfunctionality\sinto\sthis\sbranch. - D 2017-01-09T07:00:41.373 - F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e -C Add\sthe\sRFC-7396\sAppendix\sA\stest\scases\sfor\sjson_patch(). -D 2017-03-24T13:31:47.314 ++C Merge\sall\srecent\senhancements\sfrom\strunk. ++D 2017-03-24T15:09:47.005 + F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 - F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da - F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 - F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5 + F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a + F README.md 2b15fae33852f2f53996774c21fb41e1d94181c4401a0e43ac93e11f2cc901b9 + F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@@ -36,7 -36,7 +36,7 @@@ F contrib/sqlitecon.tcl 210a913ad63f9f9 F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a - F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1 -F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd ++F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd w ext/README.txt F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91 F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef @@@ -284,12 -294,10 +294,12 @@@ F ext/rtree/rtree_util.tcl 06aab2ed5b82 F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 +F ext/session/changebatch1.test 9ceaa8f7b2a505933e250fbe6cbc550e4ce1e59d +F ext/session/changebatchfault.test be49c793219bf387ad692a60856b921f0854ad6d F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a - F ext/session/session1.test e5125b216d1e8c91e0984b361b0b68529e7c5dfb + F ext/session/session1.test c8a50e0e8581dc1a00e832aa59bb61f180404d44 F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 - F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01 + F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26 @@@ -302,21 -310,22 +312,24 @@@ F ext/session/sessionD.test d4744c78334 F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26 F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60 - F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4 + F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73 + F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723 + F ext/session/sessionat.test b25d61d663ebc795506bf74079dc4ba0092fad25 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0 - F ext/session/sqlite3changebatch.c 96011bdf72ac12ebf707f4d0f0e719e333631605 + F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc -F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920 -F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53 -F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386 ++F ext/session/sqlite3changebatch.c d5553b79e012ee2cb06c0a96bdf9dfe19e66354390ea0036cc46c4953142d517 +F ext/session/sqlite3changebatch.h e72016998c9a22d439ddfd547b69e1ebac810c24 - F ext/session/sqlite3session.c 143d2a1547e760cd2653d1c7bf30acfb668de04f - F ext/session/sqlite3session.h 30b9ba3c5906d711b4e5b2e532d7a1f419942a29 ++F ext/session/sqlite3session.c 459b276e12065e34036f19cdc72528ac49f2d9977d0a142b9ef9b38122fe7ec0 ++F ext/session/sqlite3session.h ec4463a01e6e1c942f618f8944ceb96f05f5fec06f8de9af6f269fc216df1c68 +F ext/session/test_session.c badd5da3cb561564b093745f7d843430d1d76347 - F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 + F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 - F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e + F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 - F main.mk 87ee1e20124ca5cae5a5aa08608a0d8f63063eb8 -F main.mk 9abb506e717887d57f754bae139b85c1a06d6f2ac25b589f3e792e310567f278 ++F main.mk a8a58a3b44912e2ab0c6e52a94f8dd97282e4ce192b2f760f81adfa62ec51512 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@@ -335,20 -344,20 +348,20 @@@ F src/auth.c 930b376a9c56998557367e6f7f F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca - F src/btree.c 5e5bf5079aae45b91e71eb087f3eddd28deafafe - F src/btree.h 9306cfe42eed20cf2d0e407172704f5193af26cc - F src/btreeInt.h bade42398d4dcadd2263c6d17886e812e2471e87 - F src/build.c 58bd67d6648d6120592605768a7008fd52fb2656 -F src/btree.c ae0e0397e6ad58465bbf932239ee7539ca22f257c97b16c9d0960a1f5de743a3 -F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d -F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 -F src/build.c 43f903c9082040ced2b421543cb0300c2973647d ++F src/btree.c a6be01292ef0d290dbb768943542a112c5425702fd606099241e2bd7502d6e30 ++F src/btree.h d04766565d07aa84f1324f6092a912a34e98f8790d607842ae73a4e45c3047e1 ++F src/btreeInt.h b2cdfe83b930ae61c83ff9adc36f1b0aeda53758ab5a0755de5a0aec2be2f3a1 ++F src/build.c 3761b2cc63542368fdd39686180fb02574311ec9953195661d4926e1256fdf7a F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e - F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a - F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e + F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c + F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d - F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 - F src/expr.c f06f41e5e5daca10fb090e70a2502dcc0dbc992b + F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c + F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae - F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b + F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 F src/global.c 4a34512d82fc5aa13c802db06bcfff5e1d3de955 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@@ -377,31 -386,31 +390,31 @@@ F src/os.h 8e976e59eb4ca1c0fca6d35ee803 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820 - F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9 + F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a - F src/pager.c e5b8c9a975e0c208bc8886bf83b8780b6e578ac5 - F src/pager.h 0105583b49a9126b9d137f98ec57caefc64f51d4 - F src/parse.y bb387a078f2f7f78e5362479bfef4a05b9fd40b8 - F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e -F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b -F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa -F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 ++F src/pager.c 98a32b803fee30beaebe24ecbbf06bb2f8bc727957c0e410944b4597cbe8e81e ++F src/pager.h 5e7b4e5afdcbdf558c211f27786672b3d2536003d0fb6c4888addb500c826e15 ++F src/parse.y f48aeacb59e7f272b042872332af246a97847d234d17dfdacf719b8aa97f7236 + F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 - F src/pragma.c 0e7a7c6f1c6fd8ff50c0fff65b8bb80174bc49c5 - F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a + F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 + F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a - F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd + F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 - F src/resolve.c bb070cf5f23611c44ab7e4788803684e385fc3fb + F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac - F src/select.c 4437d9d5d56b6ffdedabf394c7fe3a07ff521ce9 - F src/shell.c 6095531aa900decdaa765e0f3993fba7153c92c1 - F src/sqlite.h.in 29bda4bee01248a5650567d7a22fac39bad1b542 + F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa + F src/shell.c ce39c4bbbaa02484cb45141034fd363c3bac80a6aa22b0bb3cecea1c6a4c0979 + F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae - F src/sqliteInt.h 0081f4d95b49a1accc29e5c96cf35296d0f68098 - F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 -F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4 ++F src/sqliteInt.h 33e415da02eea725392ed9a9bf00cac7a19fed0c1f75678e6b23a3aa0ba178e9 + F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 - F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 - F src/tclsqlite.c 205c66b9b81d97978a155caa3ef5be9c4de2b174 + F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 + F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79 F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee @@@ -415,10 -424,10 +428,10 @@@ F src/test_async.c 195ab49da082053fdb0f F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96 - F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83 + F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208 F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 - F src/test_config.c f3b4459a0c65933783030fb4a05073571f8fa897 - F src/test_delete.c 8499d4d323f2ec8e28301deb3d6ddd8eef8b8139 -F src/test_config.c edcba290248dc18736dd814c9b95863c6762e0b35753048d8cbe5bf65f7abfbb ++F src/test_config.c d3925a89099af6407929fe642adeb950b7e6150d738b4113b2a62ae3eb95a7cd + F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58 F src/test_fs.c e16cbe68d3b107e00a907c20a9a02629870eb69b @@@ -448,37 -457,38 +461,38 @@@ F src/test_tclvar.c df9fe1213c2634687a9 F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 - F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4 - F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01 + F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff + F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c - F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5 - F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c + F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1 + F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 - F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8 + F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c - F src/util.c a88b0466fddf445ce752226d4698ca3faada620a - F src/vacuum.c ebcf45799c7a82729a496ef5b65c5d3b2715ef8e - F src/vdbe.c 0254dc5bfb4d00b5ccc359332eeef26eb66dc5ee - F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b - F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e - F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 - F src/vdbeaux.c d1e423b8a659705cbad5a502a219fba22f306048 - F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 + F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 -F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 89a12451405a17c6e8d39b5826acb6999f1283e4e43d2e83a7ac7c9a7094a86a ++F src/vacuum.c 8aa1db0b7052269890ac03089ed030eefa88480897915f727703ca74d0676380 ++F src/vdbe.c 9a6b75f8265756bf49c776fa9f561b0c13a123064734e8237586e4c4c11897b6 + F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c + F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f + F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 -F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1 ++F src/vdbeaux.c 0a2d70e76ffe87869d4280f23477994f747fb0fa21305f4f9afcbdce22e4bafd + F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 - F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a + F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 -F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 +F src/wal.c 2858e71b30d521c80949fa10ed6b116367865594 +F src/wal.h 8659519a248ef0f33e575b20ab04211cebe1f430 - F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0 - F src/where.c 6bbf9284f4f15a6fa48663d033870cc0d7f5ee66 - F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d - F src/wherecode.c e04ac8f24c3ac8621df6c3be3ac8c7d4fa893745 - F src/whereexpr.c 87ecdf24beba4498e4380b31c4131febb0a6ceaa + F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 + F src/where.c e815093e5ee039b6b4eb19b646d22deb1a3a523f + F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 + F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 + F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd + F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@@ -587,13 -597,9 +602,13 @@@ F test/collate7.test 8ec29d98f3ee4ccebc F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334 F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 - F test/collateB.test 8ec2accd2d7166c1eff0d2a39bc90262c6f89632 + F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b +F test/concfault.test 500f17c3fcfe7705114422bcc6ddd3c740001a43 +F test/concurrent.test 634b6a88f1942f5d68cc89d4d5efa2b11ba7913c +F test/concurrent2.test 77d655c6af93e77803b5c926555a838bb21f922f +F test/concurrent3.test 0a5f7e3036d1eccf0782d7153ac21f5f222e9468 F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b @@@ -1464,10 -1478,10 +1487,10 @@@ F test/wordcount.c 06efb84b7c48a4973c2c F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 - F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3 + F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 +F tool/addopcodes.tcl f2e9aba2c2c718624fa14059198456d9e519b925 - F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x + F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@@ -1484,9 -1499,10 +1508,10 @@@ F tool/lempar.c db1bdb4821f2d8fbd76e577 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca + F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7 -F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 +F tool/mkkeywordhash.c f5ecfd09b56b8badc644554ed38c86056152b893 - F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d + F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@@ -1552,7 -1568,7 +1577,7 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 - P c8ca3e0a8d82dbb077551c2d952cb2043f78333b 391344d88a284f92c59b8d96a315b69292641de0 - R fb6607db49678e5588472158e22f722f - U dan - Z 69d374dd90bc72d9adab6847f15400aa -P 9d5350418b2f6113e0b50c57e8a872006f27753067baf08ffdfa7943c0c9a148 -R f5d3be53ea90768240f7c6616a0ecd20 ++P 50fb1eb368f14e4ddce2da875601c227f9f937fd c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 ++R cb23130cd73bf8b87b96abf4a0e40c76 + U drh -Z c6323f1875b7921e440a4d008ab9c650 ++Z e5649ef618566f41fb419552c48628f4 diff --cc manifest.uuid index aec8401384,40296ca7c1..e33520b19d --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - 50fb1eb368f14e4ddce2da875601c227f9f937fd -c5441d2df2526723f72610cc14dd243223663979e67ecdd76fe06fcd366f2b29 ++fd5676fe7f55b3d4fa15ca119af7c064c6f9d053affdfd5e748785e300affbeb diff --cc src/btree.c index b05d911865,52c0c47dd5..e73a4eb37f --- a/src/btree.c +++ b/src/btree.c @@@ -4431,8 -4101,12 +4496,13 @@@ int sqlite3BtreeSavepoint(Btree *p, in assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); sqlite3BtreeEnter(p); + btreePtrmapEnd(pBt, op, iSavepoint); - rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + if( op==SAVEPOINT_ROLLBACK ){ + rc = saveAllCursors(pBt, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + } if( rc==SQLITE_OK ){ if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ pBt->nPage = 0;