Move the 'busy-callback' logic to the pager layer. (CVS 1527)

FossilOrigin-Name: ff70b6d2b60c143e3ada0606ceff97571998c7e3
This commit is contained in:
danielk1977 2004-06-04 06:22:00 +00:00
parent 13adf8a071
commit 24162fe668
12 changed files with 140 additions and 111 deletions

View File

@ -1,5 +1,5 @@
C Untested\supdates\sto\ssupport\satomic\smulti-file\stransactions\s(CVS\s1526)
D 2004-06-03T16:08:41
C Move\sthe\s'busy-callback'\slogic\sto\sthe\spager\slayer.\s(CVS\s1527)
D 2004-06-04T06:22:01
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -25,8 +25,8 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5
F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
F src/btree.c 3cf513520d5b6fe54cc4c5fb44ce5c6231f1a535
F src/btree.h 7b682341772eb1199de3f9c29ce5e34f96836d17
F src/btree.c 39dfc3954a7af77be42ef7fb19ab22c1fa644a83
F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa
F src/build.c e12e602f06e37a0fbcb49af17cba68ad85e101b6
F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
@ -37,7 +37,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
F src/main.c d2a7632f459e9c270bb6e313e10916fc840f4a6e
F src/main.c 4e8e5c96e5a9460e71b97c83cb30cb3ad44db259
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
F src/os.h cc2fd62b2e8e11103701913871908ff77532af58
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
@ -47,8 +47,8 @@ F src/os_unix.c 3175540f8d1c820dab7a470c50875c221c3a98cd
F src/os_unix.h 7999f2246c6347707e98f7078871ea8ca605df3f
F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
F src/pager.c 1619b6a0338cefa3b4d8be54afbbe1c46e85e64e
F src/pager.h ade5bee4a0771adf82180fd702f170cb0031d811
F src/pager.c 00fabe423729e8d8a4c5e8f9602341b69a5a21b5
F src/pager.h 0c7b5ac45c69e690c45d160d03bdc8fbd2d4657b
F src/parse.y 27c1ce09f9d309be91f9e537df2fb00892990af4
F src/pragma.c 1b58d852b84b36a8b84e2245dd29b63c377414ec
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
@ -56,21 +56,21 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 0297717eb7331604687c2e29c147d3a311359df1
F src/shell.c a9e2ad8f6c1d39b04bad61a0ec655e9a3a360b50
F src/sqlite.h.in 8236db65bc6d8f5f47dc5a5e86c4a9bce42f2adf
F src/sqliteInt.h 1aa9f7d5f88d13442d39c1bc9216c73e9b6c5191
F src/sqliteInt.h 99f2b4ff4ed28123890a0c71359fec3d2c5901c9
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5
F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
F src/test3.c b3f331bda440ae21b6cab5171f28ddb402001f26
F src/test2.c ae18537d8a85e5028c955837797f9da461b908b8
F src/test3.c beafd0ccf7b9ae784744be1b1e66ffe8f64c25da
F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
F src/test5.c e731274b902eaad09b195cfbac06768dfefba93e
F src/test5.c 44178ce85c3afd2004ab4eeb5cfd7487116ce366
F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b
F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88
F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
F src/utf.c c8be20ecdcb10659e23c43e35d835460e964d248
F src/util.c d3d2f62ec94160db3cb2b092267405ba99122152
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
F src/vdbe.c 2cf1376f23e2f8ddd1a55143ea9e0e289095504d
F src/vdbe.c e1e62347215a8dbe0ec72c155e4a042e81c6aa71
F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
F src/vdbeInt.h 9f5df0a21474be02fe870cbb0a414d09b66eb31a
F src/vdbeapi.c 77d2e681a992ef189032cd9c1b7bf922f01ebe3e
@ -214,7 +214,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 51348b82c4d5801091537b80059d770410774905
R 0e06f4b108dd74f5024eb81017752495
P d57e5252c8baaf615c2cd218a33356ea5d95a5e2
R 2d675c6973e7ef6b1853da4802084a3d
U danielk1977
Z 4a23c8e1ebb05080684ee0992bb72463
Z bb8854c6d118151a9229d93a5653a12b

View File

@ -1 +1 @@
d57e5252c8baaf615c2cd218a33356ea5d95a5e2
ff70b6d2b60c143e3ada0606ceff97571998c7e3

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.156 2004/06/03 16:08:41 danielk1977 Exp $
** $Id: btree.c,v 1.157 2004/06/04 06:22:01 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@ -977,7 +977,8 @@ int sqlite3BtreeOpen(
const char *zFilename, /* Name of the file containing the BTree database */
Btree **ppBtree, /* Pointer to new Btree object written here */
int nCache, /* Number of cache pages */
int flags /* Options */
int flags, /* Options */
void *pBusyHandler /* Busy callback info passed to pager layer */
){
Btree *pBt;
int rc;
@ -1002,7 +1003,7 @@ int sqlite3BtreeOpen(
}
if( nCache<10 ) nCache = 10;
rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
(flags & BTREE_OMIT_JOURNAL)==0);
(flags & BTREE_OMIT_JOURNAL)==0, pBusyHandler);
if( rc!=SQLITE_OK ){
if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
sqliteFree(pBt);

View File

@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.52 2004/06/03 16:08:41 danielk1977 Exp $
** @(#) $Id: btree.h,v 1.53 2004/06/04 06:22:01 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
@ -30,7 +30,13 @@ typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
int sqlite3BtreeOpen(const char *zFilename, Btree **, int nCache, int flags);
int sqlite3BtreeOpen(
const char *zFilename,
Btree **,
int nCache,
int flags,
void *pBusyHandler
);
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.203 2004/06/02 00:41:09 drh Exp $
** $Id: main.c,v 1.204 2004/06/04 06:22:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -570,8 +570,8 @@ void sqlite3_busy_handler(
int (*xBusy)(void*,const char*,int),
void *pArg
){
db->xBusyCallback = xBusy;
db->pBusyArg = pArg;
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@ -762,7 +762,8 @@ int sqlite3BtreeFactory(
btree_flags |= BTREE_MEMORY;
}
return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
&db->busyHandler);
}
/*
@ -847,9 +848,7 @@ int sqlite3_prepare(
if( !db->init.busy ){
if( (db->flags & SQLITE_Initialized)==0 ){
int cnt = 1;
while( (rc = sqlite3Init(db, &zErrMsg))==SQLITE_BUSY
&& db->xBusyCallback
&& db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
rc = sqlite3Init(db, &zErrMsg);
if( rc!=SQLITE_OK ){
goto prepare_out;
}

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.110 2004/06/03 16:08:42 danielk1977 Exp $
** @(#) $Id: pager.c,v 1.111 2004/06/04 06:22:01 danielk1977 Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
@ -213,6 +213,7 @@ struct Pager {
PgHdr *pStmt; /* List of pages in the statement subjournal */
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
int nMaster; /* Number of bytes to reserve for master j.p */
BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */
};
/*
@ -1080,7 +1081,8 @@ int sqlite3pager_open(
const char *zFilename, /* Name of the database file to open */
int mxPage, /* Max number of in-memory cache pages */
int nExtra, /* Extra bytes append to each in-memory page */
int useJournal /* TRUE to use a rollback journal on this file */
int useJournal, /* TRUE to use a rollback journal on this file */
void *pBusyHandler /* Busy callback */
){
Pager *pPager;
char *zFullPathname;
@ -1161,6 +1163,7 @@ int sqlite3pager_open(
pPager->pFirstSynced = 0;
pPager->pLast = 0;
pPager->nExtra = nExtra;
pPager->pBusyHandler = (BusyHandler *)pBusyHandler;
memset(pPager->aHash, 0, sizeof(pPager->aHash));
*ppPager = pPager;
return SQLITE_OK;
@ -1603,9 +1606,21 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
** on the database file.
*/
if( pPager->nRef==0 && !pPager->memDb ){
rc = sqlite3OsReadLock(&pPager->fd);
if( rc!=SQLITE_OK ){
return rc;
int busy = 1;
while( busy ){
rc = sqlite3OsReadLock(&pPager->fd);
if( rc==SQLITE_BUSY &&
pPager->pBusyHandler &&
pPager->pBusyHandler->xFunc &&
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, "", busy++)
){
rc = SQLITE_OK;
}else{
busy = 0;
}
if( rc!=SQLITE_OK ){
return rc;
}
}
pPager->state = SQLITE_READLOCK;
@ -2004,9 +2019,21 @@ int sqlite3pager_begin(void *pData, int nMaster){
pPager->state = SQLITE_WRITELOCK;
pPager->origDbSize = pPager->dbSize;
}else{
rc = sqlite3OsWriteLock(&pPager->fd);
if( rc!=SQLITE_OK ){
return rc;
int busy = 1;
while( busy ){
rc = sqlite3OsWriteLock(&pPager->fd);
if( rc==SQLITE_BUSY &&
pPager->pBusyHandler &&
pPager->pBusyHandler->xFunc &&
pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, "", busy++)
){
rc = SQLITE_OK;
}else{
busy = 0;
}
if( rc!=SQLITE_OK ){
return rc;
}
}
pPager->nMaster = nMaster;
pPager->state = SQLITE_WRITELOCK;

View File

@ -13,7 +13,7 @@
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.30 2004/06/03 16:08:42 danielk1977 Exp $
** @(#) $Id: pager.h,v 1.31 2004/06/04 06:22:02 danielk1977 Exp $
*/
/*
@ -70,7 +70,8 @@ typedef struct Pager Pager;
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
int nPage, int nExtra, int useJournal);
int nPage, int nExtra, int useJournal,
void *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.267 2004/06/02 00:41:09 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.268 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite3.h"
@ -264,6 +264,7 @@ typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct BusyHandler BusyHandler;
/*
@ -326,6 +327,20 @@ struct Db {
#define TEXT_Utf16be 3
#define TEXT_Utf16 (SQLITE_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le)
/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
struct BusyHandler {
int (*xFunc)(void *,const char*,int); /* The busy callback */
void *pArg; /* First arg to busy callback */
};
/*
** Each database is an instance of the following structure.
**
@ -369,8 +384,7 @@ struct sqlite {
int next_cookie; /* Next value of aDb[0].schema_cookie */
int cache_size; /* Number of pages to use in the cache */
int nTable; /* Number of tables in the database */
void *pBusyArg; /* 1st Argument to the busy callback */
int (*xBusyCallback)(void *,const char*,int); /* The busy callback */
BusyHandler busyHandler; /* Busy callback */
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*);/* Invoked at every commit. */
Hash aFunc; /* All functions that can be in SQL exprs */

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.19 2004/05/10 10:34:53 danielk1977 Exp $
** $Id: test2.c,v 1.20 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "os.h"
#include "sqliteInt.h"
@ -76,7 +76,7 @@ static int pager_open(
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1);
rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.42 2004/06/03 16:08:42 danielk1977 Exp $
** $Id: test3.c,v 1.43 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
@ -70,7 +70,7 @@ static int btree_open(
}
if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR;
rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags);
rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;

View File

@ -15,7 +15,7 @@
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
**
** $Id: test5.c,v 1.7 2004/06/02 00:41:10 drh Exp $
** $Id: test5.c,v 1.8 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h" /* to get SQLITE_BIGENDIAN */
@ -248,7 +248,7 @@ int Sqlitetest5_Init(Tcl_Interp *interp){
{ "sqlite_utf8to16be", (Tcl_ObjCmdProc*)sqlite_utf8to16be },
{ "sqlite_utf16to16le", (Tcl_ObjCmdProc*)sqlite_utf16to16le },
{ "sqlite_utf16to16be", (Tcl_ObjCmdProc*)sqlite_utf16to16be },
{ "binarize", (Tcl_ObjCmdProc*)binarize }
{ "binarize", (Tcl_ObjCmdProc*)binarize },
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){

View File

@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.356 2004/06/03 16:08:42 danielk1977 Exp $
** $Id: vdbe.c,v 1.357 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -2281,40 +2281,27 @@ case OP_AutoCommit: {
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
int busy = 1;
int i = pOp->p1;
Btree *pBt;
assert( i>=0 && i<db->nDb );
pBt = db->aDb[i].pBt;
while( pBt && busy ){
if( pBt ){
int nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+11;
rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt, pOp->p2, nMaster);
switch( rc ){
case SQLITE_BUSY: {
if( db->xBusyCallback==0 ){
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, nMaster);
if( rc==SQLITE_BUSY ){
if( db->busyHandler.xFunc==0 ){
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = pTos;
return SQLITE_BUSY;
}else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
}else{
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
busy = 0;
}
break;
}
case SQLITE_READONLY: {
rc = SQLITE_OK;
/* Fall thru into the next case */
}
case SQLITE_OK: {
busy = 0;
break;
}
default: {
goto abort_due_to_error;
}
}
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY && rc!=SQLITE_BUSY ){
goto abort_due_to_error;
}
}
break;
@ -2445,7 +2432,6 @@ case OP_VerifyCookie: {
*/
case OP_OpenRead:
case OP_OpenWrite: {
int busy = 0;
int i = pOp->p1;
int p2 = pOp->p2;
int wrFlag;
@ -2478,49 +2464,44 @@ case OP_OpenWrite: {
sqlite3VdbeCleanupCursor(pCur);
pCur->nullRow = 1;
if( pX==0 ) break;
do{
/* We always provide a key comparison function. If the table being
** opened is of type INTKEY, the comparision function will be ignored. */
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
sqlite3VdbeRecordCompare, pOp->p3,
&pCur->pCursor);
pCur->pKeyInfo = (KeyInfo*)pOp->p3;
if( pCur->pKeyInfo ){
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
pCur->pKeyInfo->enc = p->db->enc;
}else{
pCur->pIncrKey = &pCur->bogusIncrKey;
/* We always provide a key comparison function. If the table being
** opened is of type INTKEY, the comparision function will be ignored. */
rc = sqlite3BtreeCursor(pX, p2, wrFlag,
sqlite3VdbeRecordCompare, pOp->p3,
&pCur->pCursor);
pCur->pKeyInfo = (KeyInfo*)pOp->p3;
if( pCur->pKeyInfo ){
pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
pCur->pKeyInfo->enc = p->db->enc;
}else{
pCur->pIncrKey = &pCur->bogusIncrKey;
}
switch( rc ){
case SQLITE_BUSY: {
if( db->busyHandler.xFunc ){
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
return SQLITE_BUSY;
}else{
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
}
break;
}
switch( rc ){
case SQLITE_BUSY: {
if( db->xBusyCallback==0 ){
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
return SQLITE_BUSY;
}else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
busy = 0;
}
break;
}
case SQLITE_OK: {
int flags = sqlite3BtreeFlags(pCur->pCursor);
pCur->intKey = (flags & BTREE_INTKEY)!=0;
pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
busy = 0;
break;
}
case SQLITE_EMPTY: {
rc = SQLITE_OK;
busy = 0;
break;
}
default: {
goto abort_due_to_error;
}
case SQLITE_OK: {
int flags = sqlite3BtreeFlags(pCur->pCursor);
pCur->intKey = (flags & BTREE_INTKEY)!=0;
pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
break;
}
}while( busy );
case SQLITE_EMPTY: {
rc = SQLITE_OK;
break;
}
default: {
goto abort_due_to_error;
}
}
break;
}