Skip to content

Commit

Permalink
Merge pull request #1652 from Expensify/tyler-new-sqlite
Browse files Browse the repository at this point in the history
Update SQLite to log correct db table/index on conflict.
  • Loading branch information
iwiznia authored Feb 21, 2024
2 parents 4e30a10 + 7af0e93 commit 4e8d6e5
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 33 deletions.
115 changes: 83 additions & 32 deletions libstuff/sqlite3.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
** 707f79c70c8b0fd889aede8806148457c691.
** 11a4178f0e6cd760303a5874b5a3529ccd78.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
Expand Down Expand Up @@ -462,7 +462,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.45.0"
#define SQLITE_VERSION_NUMBER 3045000
#define SQLITE_SOURCE_ID "2024-01-04 16:28:49 707f79c70c8b0fd889aede8806148457c691a008d0ce030084ba79f1e66ec53d"
#define SQLITE_SOURCE_ID "2024-02-16 11:05:35 11a4178f0e6cd760303a5874b5a3529ccd78a2398b59700e878c7e6b1251de91"

/*
** CAPI3REF: Run-Time Library Version Numbers
Expand Down Expand Up @@ -43450,7 +43450,7 @@ static int unixShmLock(
for(iMutex=ofst; iMutex<ofst+n; iMutex++){
if( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ){
rc = sqlite3_mutex_try(pShmNode->aMutex[iMutex]);
if( rc!=SQLITE_OK ) break;
if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes;
}else{
sqlite3_mutex_enter(pShmNode->aMutex[iMutex]);
}
Expand All @@ -43459,7 +43459,7 @@ static int unixShmLock(
sqlite3_mutex_enter(pShmNode->pShmMutex);
#endif

if( rc==SQLITE_OK ){
if( ALWAYS(rc==SQLITE_OK) ){
if( flags & SQLITE_SHM_UNLOCK ){
/* Case (a) - unlock. */
int bUnlock = 1;
Expand Down Expand Up @@ -43538,6 +43538,7 @@ static int unixShmLock(

/* Drop the mutexes acquired above. */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
leave_shmnode_mutexes:
for(iMutex--; iMutex>=ofst; iMutex--){
sqlite3_mutex_leave(pShmNode->aMutex[iMutex]);
}
Expand Down Expand Up @@ -68671,6 +68672,37 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
return rc;
}

/*
** The final argument passed to walTryBeginRead() is of type (int*). The
** caller should invoke walTryBeginRead as follows:
**
** int cnt = 0;
** do {
** rc = walTryBeginRead(..., &cnt);
** }while( rc==WAL_RETRY );
**
** The final value of "cnt" is of no use to the caller. It is used by
** the implementation of walTryBeginRead() as follows:
**
** + Each time walTryBeginRead() is called, it is incremented. Once
** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead()
** has many times been invoked and failed with WAL_RETRY - walTryBeginRead()
** returns SQLITE_PROTOCOL.
**
** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed
** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS
** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case
** the next invocation of walTryBeginRead() may omit an expected call to
** sqlite3OsSleep(). There has already been a delay when the previous call
** waited on a lock.
*/
#define WAL_RETRY_PROTOCOL_LIMIT 100
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
# define WAL_RETRY_BLOCKED_MASK 0x10000000
#else
# define WAL_RETRY_BLOCKED_MASK 0
#endif

/*
** Attempt to start a read transaction. This might fail due to a race or
** other transient condition. When that happens, it returns WAL_RETRY to
Expand Down Expand Up @@ -68721,7 +68753,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
** so it takes care to hold an exclusive lock on the corresponding
** WAL_READ_LOCK() while changing values.
*/
static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){
volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */
int rc = SQLITE_OK; /* Return code */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
Expand Down Expand Up @@ -68750,27 +68782,34 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
** The total delay time before giving up is less than 10 seconds.
*/
if( cnt>5 ){
(*pCnt)++;
if( *pCnt>5 ){
int nDelay = 1; /* Pause time in microseconds */
if( cnt>100 ){
int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK);
if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){
VVA_ONLY( pWal->lockError = 1; )
return SQLITE_PROTOCOL;
}
if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor
** to block for locks for approximately nDelay us. This affects three
** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if
** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the
** first attempted read fails, and (c) the shared lock taken on the DMS
** slot in os_unix.c. All three of these locks are attempted from within
** the call to walIndexReadHdr() below. */
** first attempted read fails, and (c) the shared lock taken on the
** read-mark.
**
** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error,
** then sleep for the minimum of 1us. The previous call already provided
** an extra delay while it was blocking on the lock.
*/
nBlockTmout = (nDelay+998) / 1000;
if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){
nDelay = 1;
if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1;
}
#endif
sqlite3OsSleep(pWal->pVfs, nDelay);
*pCnt &= ~WAL_RETRY_BLOCKED_MASK;
}

if( !useWal ){
Expand All @@ -68780,7 +68819,10 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
walDisableBlocking(pWal);
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
if( rc==SQLITE_BUSY_TIMEOUT ){
rc = SQLITE_BUSY;
*pCnt |= WAL_RETRY_BLOCKED_MASK;
}
#endif
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
Expand Down Expand Up @@ -68932,6 +68974,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
walDisableBlocking(pWal);
if( rc ){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
*pCnt |= WAL_RETRY_BLOCKED_MASK;
}
#else
assert( rc!=SQLITE_BUSY_TIMEOUT );
#endif
assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT);
return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc;

Expand Down Expand Up @@ -69136,7 +69185,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){
#endif

do{
rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
rc = walTryBeginRead(pWal, pChanged, 0, &cnt);
}while( rc==WAL_RETRY );
testcase( (rc&0xff)==SQLITE_BUSY );
testcase( (rc&0xff)==SQLITE_IOERR );
Expand Down Expand Up @@ -69594,7 +69643,7 @@ static int walUpgradeReadlock(Wal *pWal){
cnt = 0;
do{
int notUsed;
rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt);
rc = walTryBeginRead(pWal, &notUsed, 1, &cnt);
}while( rc==WAL_RETRY );
assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */
testcase( (rc&0xff)==SQLITE_IOERR );
Expand Down Expand Up @@ -78551,6 +78600,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
pCur->pPage = pCur->apPage[--pCur->iPage];
break;
}
setMempageRoot(pCur->pPage, pCur->pgnoRoot);
/*
***** End of in-lined moveToChild() call */
}
Expand Down Expand Up @@ -128639,7 +128689,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
if( iDb<0 ) return;
z = sqlite3NameFromToken(db, pObjName);
if( z==0 ) return;
zDb = db->aDb[iDb].zDbSName;
zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
Expand All @@ -128649,6 +128699,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
pIndex = sqlite3FindIndex(db, z, zDb);
sqlite3DbFree(db, z);
if( pIndex ){
iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema);
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3RefillIndex(pParse, pIndex, -1);
return;
Expand Down Expand Up @@ -211792,7 +211843,7 @@ static int nodeAcquire(
** increase its reference count and return it.
*/
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
if( pParent && pParent!=pNode->pParent ){
if( pParent && ALWAYS(pParent!=pNode->pParent) ){
RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
Expand Down Expand Up @@ -214527,7 +214578,7 @@ static int rtreeSqlInit(
}
sqlite3_free(zSql);
}
if( pRtree->nAux ){
if( pRtree->nAux && rc!=SQLITE_NOMEM ){
pRtree->zReadAuxSql = sqlite3_mprintf(
"SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1",
zDb, zPrefix);
Expand Down Expand Up @@ -215216,15 +215267,13 @@ static int rtreeCheckTable(
check.zTab = zTab;

/* Find the number of auxiliary columns */
if( check.rc==SQLITE_OK ){
pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
if( pStmt ){
nAux = sqlite3_column_count(pStmt) - 2;
sqlite3_finalize(pStmt);
}else
if( check.rc!=SQLITE_NOMEM ){
check.rc = SQLITE_OK;
}
pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
if( pStmt ){
nAux = sqlite3_column_count(pStmt) - 2;
sqlite3_finalize(pStmt);
}else
if( check.rc!=SQLITE_NOMEM ){
check.rc = SQLITE_OK;
}

/* Find number of dimensions in the rtree table. */
Expand Down Expand Up @@ -215279,6 +215328,7 @@ static int rtreeIntegrity(
if( rc==SQLITE_OK && *pzErr ){
*pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z",
pRtree->zDb, pRtree->zName, *pzErr);
if( (*pzErr)==0 ) rc = SQLITE_NOMEM;
}
return rc;
}
Expand Down Expand Up @@ -227957,9 +228007,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
** associated hash-tables. */
sessionDeleteTable(pSession, pSession->pTable);

/* Assert that all allocations have been freed and then free the
** session object itself. */
// assert( pSession->nMalloc==0 );
/* Free the session object. */
sqlite3_free(pSession);
}

Expand Down Expand Up @@ -251837,7 +251885,10 @@ static int fts5SpecialInsert(
}else if( 0==sqlite3_stricmp("flush", zCmd) ){
rc = sqlite3Fts5FlushToDisk(&pTab->p);
}else{
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
rc = sqlite3Fts5FlushToDisk(&pTab->p);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
}
Expand Down Expand Up @@ -253189,7 +253240,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2024-01-04 16:28:49 707f79c70c8b0fd889aede8806148457c691a008d0ce030084ba79f1e66ec53d", -1, SQLITE_TRANSIENT);
sqlite3_result_text(pCtx, "fts5: 2024-02-16 11:05:35 11a4178f0e6cd760303a5874b5a3529ccd78a2398b59700e878c7e6b1251de91", -1, SQLITE_TRANSIENT);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion libstuff/sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ extern "C" {
*/
#define SQLITE_VERSION "3.45.0"
#define SQLITE_VERSION_NUMBER 3045000
#define SQLITE_SOURCE_ID "2024-01-04 16:28:49 707f79c70c8b0fd889aede8806148457c691a008d0ce030084ba79f1e66ec53d"
#define SQLITE_SOURCE_ID "2024-02-16 11:05:35 11a4178f0e6cd760303a5874b5a3529ccd78a2398b59700e878c7e6b1251de91"

/*
** CAPI3REF: Run-Time Library Version Numbers
Expand Down

0 comments on commit 4e8d6e5

Please sign in to comment.