@@ -5779,6 +5779,8 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
57795779SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
57805780
57815781
5782+ SQLITE_API void libsql_stmt_interrupt(sqlite3_stmt *stmt);
5783+
57825784/*
57835785** CAPI3REF: Create Or Redefine SQL Functions
57845786** KEYWORDS: {function creation routines}
@@ -10953,15 +10955,6 @@ SQLITE_API void *libsql_close_hook(sqlite3 *db, void (*xClose)(void *pCtx, sqlit
1095310955*/
1095410956SQLITE_API int libsql_wal_disable_checkpoint(sqlite3 *db);
1095510957
10956- /*
10957- ** CAPI3REF: Get the checkpoint sequence counter of the WAL file
10958- ** METHOD: sqlite3
10959- **
10960- ** ^The [libsql_wal_checkpoint_seq_count(D,P)] interface returns the checkpoint sequence counter
10961- ** of the WAL file for [database connection] D into *P.
10962- */
10963- SQLITE_API int libsql_wal_checkpoint_seq_count(sqlite3 *db, unsigned int *pnCkpt);
10964-
1096510958/*
1096610959** CAPI3REF: Get the number of frames in the WAL file
1096710960** METHOD: sqlite3
@@ -14045,9 +14038,6 @@ typedef struct libsql_wal_methods {
1404514038 ** response to a ROLLBACK TO command. */
1404614039 int (*xSavepointUndo)(wal_impl* pWal, unsigned int *aWalData);
1404714040
14048- /* Return the current checkpoint generation in the WAL file. */
14049- int (*xCheckpointSeqCount)(wal_impl* pWal, unsigned int *pnCkpt);
14050-
1405114041 /* Return the number of frames in the WAL */
1405214042 int (*xFrameCount)(wal_impl* pWal, int, unsigned int *);
1405314043
@@ -24207,6 +24197,7 @@ struct Vdbe {
2420724197 int nScan; /* Entries in aScan[] */
2420824198 ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */
2420924199#endif
24200+ u8 isInterrupted; /* True if the statement has been interrupted */
2421024201};
2421124202
2421224203void libsql_inc_row_read(Vdbe *p, int count);
@@ -57366,9 +57357,6 @@ typedef struct libsql_wal_methods {
5736657357 ** response to a ROLLBACK TO command. */
5736757358 int (*xSavepointUndo)(wal_impl* pWal, unsigned int *aWalData);
5736857359
57369- /* Return the current checkpoint generation in the WAL file. */
57370- int (*xCheckpointSeqCount)(wal_impl* pWal, unsigned int *pnCkpt);
57371-
5737257360 /* Return the number of frames in the WAL */
5737357361 int (*xFrameCount)(wal_impl* pWal, int, unsigned int *);
5737457362
@@ -65297,18 +65285,6 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
6529765285 return rc;
6529865286}
6529965287
65300- /**
65301- ** Return the current checkpoint generation in the WAL file.
65302- **/
65303- SQLITE_PRIVATE int sqlite3PagerWalCheckpointSeqCount(Pager *pPager, unsigned int *pnCkpt){
65304- if( pagerUseWal(pPager) ){
65305- return pPager->wal->methods.xCheckpointSeqCount(pPager->wal->pData, pnCkpt);
65306- } else {
65307- *pnCkpt = 0;
65308- return SQLITE_OK;
65309- }
65310- }
65311-
6531265288/**
6531365289** Return the number of frames in the WAL file.
6531465290**
@@ -67671,9 +67647,11 @@ static int walCheckpoint(
6767167647 if (xCb) {
6767267648 rc = (xCb)(pCbData, mxSafeFrame, NULL, 0, 0, 0);
6767367649 }
67674- i64 szDb = pWal->hdr.nPage*(i64)szPage;
67675- testcase( IS_BIG_INT(szDb) );
67676- rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
67650+ if( rc==SQLITE_OK ){
67651+ i64 szDb = pWal->hdr.nPage*(i64)szPage;
67652+ testcase( IS_BIG_INT(szDb) );
67653+ rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
67654+ }
6767767655 if( rc==SQLITE_OK ){
6767867656 rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
6767967657 }
@@ -69561,11 +69539,6 @@ static int walFrames(
6956169539 return rc;
6956269540}
6956369541
69564- SQLITE_PRIVATE int sqlite3WalCheckpointSeqCount(Wal *pWal, unsigned int *pnCkpt){
69565- *pnCkpt = pWal->nCkpt;
69566- return SQLITE_OK;
69567- }
69568-
6956969542SQLITE_PRIVATE int sqlite3WalFrameCount(Wal *pWal, int locked, unsigned int *pnFrames){
6957069543 int rc = SQLITE_OK;
6957169544 if( locked==0 ) {
@@ -69671,13 +69644,21 @@ static int sqlite3WalCheckpoint(
6967169644 */
6967269645 if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
6967369646 rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
69647+ #ifndef LIBSQL_DISABLE_CHECKPOINT_DOWNGRADE
6967469648 if( rc==SQLITE_OK ){
6967569649 pWal->writeLock = 1;
6967669650 }else if( rc==SQLITE_BUSY ){
6967769651 eMode2 = SQLITE_CHECKPOINT_PASSIVE;
6967869652 xBusy2 = 0;
6967969653 rc = SQLITE_OK;
6968069654 }
69655+ #else
69656+ // checkpoint downgrade can be undesirable behaviour especially in case of custom VWal implementation
69657+ // LIBSQL_DISABLE_CHECKPOINT_DOWNGRADE compile time option disables downgrade of checkpoint mode
69658+ if( rc==SQLITE_OK ){
69659+ pWal->writeLock = 1;
69660+ }
69661+ #endif
6968169662 }
6968269663 }
6968369664
@@ -70085,7 +70066,6 @@ static int sqlite3WalOpen(
7008570066 out->methods.xUndo = (int (*)(wal_impl *, int (*)(void *, unsigned int), void *))sqlite3WalUndo;
7008670067 out->methods.xSavepoint = (void (*)(wal_impl *, unsigned int *))sqlite3WalSavepoint;
7008770068 out->methods.xSavepointUndo = (int (*)(wal_impl *, unsigned int *))sqlite3WalSavepointUndo;
70088- out->methods.xCheckpointSeqCount = (int (*)(wal_impl *, unsigned int *))sqlite3WalCheckpointSeqCount;
7008970069 out->methods.xFrameCount = (int (*)(wal_impl *, int, unsigned int *))sqlite3WalFrameCount;
7009070070 out->methods.xFrames = (int (*)(wal_impl *, int, libsql_pghdr *, unsigned int, int, int, int *))sqlite3WalFrames;
7009170071 out->methods.xCheckpoint = (int (*)(wal_impl *, sqlite3 *, int, int (*)(void *), void *, int, int, unsigned char *, int *, int *, int (*)(void*, int, const unsigned char*, int, int, int), void*))sqlite3WalCheckpoint;
@@ -89506,6 +89486,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
8950689486#ifdef SQLITE_DEBUG
8950789487 p->nWrite = 0;
8950889488#endif
89489+ p->isInterrupted = 0;
8950989490
8951089491 /* Save profiling information from this VDBE run.
8951189492 */
@@ -92310,6 +92291,18 @@ static int sqlite3Step(Vdbe *p){
9231092291 return (rc&db->errMask);
9231192292}
9231292293
92294+ /*
92295+ ** Interrupt the statement.
92296+ */
92297+ void libsql_stmt_interrupt(sqlite3_stmt *pStmt){
92298+ Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
92299+ if( vdbeSafetyNotNull(v) ){
92300+ (void)SQLITE_MISUSE_BKPT;
92301+ return;
92302+ }
92303+ v->isInterrupted = 1;
92304+ }
92305+
9231392306/*
9231492307** This is the top-level implementation of sqlite3_step(). Call
9231592308** sqlite3Step() to do most of the work. If a schema error occurs,
@@ -92325,6 +92318,12 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
9232592318 return SQLITE_MISUSE_BKPT;
9232692319 }
9232792320 db = v->db;
92321+ if( v->isInterrupted ){
92322+ rc = SQLITE_INTERRUPT;
92323+ v->rc = rc;
92324+ db->errCode = rc;
92325+ return rc;
92326+ }
9232892327 sqlite3_mutex_enter(db->mutex);
9232992328 while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
9233092329 && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
@@ -183240,30 +183239,6 @@ int libsql_wal_disable_checkpoint(sqlite3 *db) {
183240183239 return SQLITE_OK;
183241183240}
183242183241
183243- /*
183244- ** Return the checkpoint sequence counter of the given database.
183245- */
183246- int libsql_wal_checkpoint_seq_count(sqlite3 *db, unsigned int *pnCkpt) {
183247- int rc = SQLITE_OK;
183248- Pager *pPager;
183249-
183250- #ifdef SQLITE_OMIT_WAL
183251- *pnFrame = 0;
183252- return SQLITE_OK;
183253- #else
183254- #ifdef SQLITE_ENABLE_API_ARMOR
183255- if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
183256- #endif
183257-
183258- sqlite3_mutex_enter(db->mutex);
183259- pPager = sqlite3BtreePager(db->aDb[0].pBt);
183260- rc = sqlite3PagerWalCheckpointSeqCount(pPager, pnCkpt);
183261- sqlite3Error(db, rc);
183262- sqlite3_mutex_leave(db->mutex);
183263- return rc;
183264- #endif
183265- }
183266-
183267183242/*
183268183243** Return the number of frames in the WAL of the given database.
183269183244*/
0 commit comments