/ Check-in [ff70b6d2]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Move the 'busy-callback' logic to the pager layer. (CVS 1527)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ff70b6d2b60c143e3ada0606ceff97571998c7e3
User & Date: danielk1977 2004-06-04 06:22:01
Context
2004-06-04
10:38
Defer the exclusive db lock until the pager cache is flushed to disk. 41 tests now fail. (CVS 1528) check-in: d2f69e5e user: danielk1977 tags: trunk
06:22
Move the 'busy-callback' logic to the pager layer. (CVS 1527) check-in: ff70b6d2 user: danielk1977 tags: trunk
2004-06-03
16:08
Untested updates to support atomic multi-file transactions (CVS 1526) check-in: d57e5252 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
973
974
975
976
977
978
979
980

981
982
983
984
985
986
987
...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.156 2004/06/03 16:08:41 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
** a new database with a random name is created.  This randomly named
** database file will be deleted when sqlite3BtreeClose() is called.
*/
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 */

){
  Btree *pBt;
  int rc;

  /*
  ** The following asserts make sure that structures used by the btree are
  ** the right size.  This is to guard against size changes that result
................................................................................
  pBt = sqliteMalloc( sizeof(*pBt) );
  if( pBt==0 ){
    *ppBtree = 0;
    return SQLITE_NOMEM;
  }
  if( nCache<10 ) nCache = 10;
  rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
                        (flags & BTREE_OMIT_JOURNAL)==0);
  if( rc!=SQLITE_OK ){
    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
    sqliteFree(pBt);
    *ppBtree = 0;
    return rc;
  }
  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);







|







 







|
>







 







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $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
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
** a new database with a random name is created.  This randomly named
** database file will be deleted when sqlite3BtreeClose() is called.
*/
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 */
  void *pBusyHandler      /* Busy callback info passed to pager layer */
){
  Btree *pBt;
  int rc;

  /*
  ** The following asserts make sure that structures used by the btree are
  ** the right size.  This is to guard against size changes that result
................................................................................
  pBt = sqliteMalloc( sizeof(*pBt) );
  if( pBt==0 ){
    *ppBtree = 0;
    return SQLITE_NOMEM;
  }
  if( nCache<10 ) nCache = 10;
  rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
                        (flags & BTREE_OMIT_JOURNAL)==0, pBusyHandler);
  if( rc!=SQLITE_OK ){
    if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
    sqliteFree(pBt);
    *ppBtree = 0;
    return rc;
  }
  sqlite3pager_set_destructor(pBt->pPager, pageDestructor);

Changes to src/btree.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
26
27
28
29
30
31
32

33





34
35
36
37
38
39
40
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** 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 $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
................................................................................
/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;



int sqlite3BtreeOpen(const char *zFilename, Btree **, int nCache, int flags);






/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
*/
#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
#define BTREE_MEMORY        2  /* In-memory DB.  No argument */








|







 







>
|
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.53 2004/06/04 06:22:01 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
................................................................................
/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;


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.
*/
#define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
#define BTREE_MEMORY        2  /* In-memory DB.  No argument */

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
...
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
...
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** 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 $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
** given callback function with the given argument.
*/
void sqlite3_busy_handler(
  sqlite *db,
  int (*xBusy)(void*,const char*,int),
  void *pArg
){
  db->xBusyCallback = xBusy;
  db->pBusyArg = pArg;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
................................................................................
  if( omitJournal ){
    btree_flags |= BTREE_OMIT_JOURNAL;
  }
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);

}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
................................................................................
    rc = SQLITE_MISUSE;
    goto prepare_out;
  }

  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 ){}
      if( rc!=SQLITE_OK ){
        goto prepare_out;
      }
      if( zErrMsg ){
        sqliteFree(zErrMsg);
        zErrMsg = 0;
      }







|







 







|
|







 







|
>







 







|
<
<







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
...
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
...
844
845
846
847
848
849
850
851


852
853
854
855
856
857
858
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.204 2004/06/04 06:22:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
** given callback function with the given argument.
*/
void sqlite3_busy_handler(
  sqlite *db,
  int (*xBusy)(void*,const char*,int),
  void *pArg
){
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
................................................................................
  if( omitJournal ){
    btree_flags |= BTREE_OMIT_JOURNAL;
  }
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
      &db->busyHandler);
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
................................................................................
    rc = SQLITE_MISUSE;
    goto prepare_out;
  }

  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      int cnt = 1;
      rc = sqlite3Init(db, &zErrMsg);


      if( rc!=SQLITE_OK ){
        goto prepare_out;
      }
      if( zErrMsg ){
        sqliteFree(zErrMsg);
        zErrMsg = 0;
      }

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
209
210
211
212
213
214
215

216
217
218
219
220
221
222
....
1076
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
....
1157
1158
1159
1160
1161
1162
1163

1164
1165
1166
1167
1168
1169
1170
....
1599
1600
1601
1602
1603
1604
1605


1606









1607
1608

1609
1610
1611
1612
1613
1614
1615
....
2000
2001
2002
2003
2004
2005
2006


2007









2008
2009

2010
2011
2012
2013
2014
2015
2016
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** 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 $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
  u8 *aInStmt;                /* One bit for each page in the database */
  PgHdr *pFirst, *pLast;      /* List of free pages */
  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
  PgHdr *pAll;                /* List of all pages */
  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 */

};

/*
** These are bits that can be set in Pager.errMask.
*/
#define PAGER_ERR_FULL     0x01  /* a write() failed */
#define PAGER_ERR_MEM      0x02  /* malloc() failed */
................................................................................
** automatically when it is closed.
*/
int sqlite3pager_open(
  Pager **ppPager,         /* Return the Pager structure here */
  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 */

){
  Pager *pPager;
  char *zFullPathname;
  int nameLen;
  OsFile fd;
  int rc, i;
  int tempFile;
................................................................................
  pPager->readOnly = readOnly;
  pPager->needSync = 0;
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->nExtra = nExtra;

  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  *ppPager = pPager;
  return SQLITE_OK;
}

/*
** Set the destructor for this pager.  If not NULL, the destructor is called
................................................................................
    return pager_errcode(pPager);
  }

  /* If this is the first page accessed, then get a SHARED lock
  ** on the database file.
  */
  if( pPager->nRef==0 && !pPager->memDb ){


    rc = sqlite3OsReadLock(&pPager->fd);









    if( rc!=SQLITE_OK ){
      return rc;

    }
    pPager->state = SQLITE_READLOCK;

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( pPager->useJournal && 
................................................................................
  assert( pPager->state!=SQLITE_UNLOCK );
  if( pPager->state==SQLITE_READLOCK ){
    assert( pPager->aInJournal==0 );
    if( pPager->memDb ){
      pPager->state = SQLITE_WRITELOCK;
      pPager->origDbSize = pPager->dbSize;
    }else{


      rc = sqlite3OsWriteLock(&pPager->fd);









      if( rc!=SQLITE_OK ){
        return rc;

      }
      pPager->nMaster = nMaster;
      pPager->state = SQLITE_WRITELOCK;
      pPager->dirtyFile = 0;
      TRACE1("TRANSACTION\n");
      if( pPager->useJournal && !pPager->tempFile ){
        rc = pager_open_journal(pPager);







|







 







>







 







|
>







 







>







 







>
>
|
>
>
>
>
>
>
>
>
>
|
|
>







 







>
>
|
>
>
>
>
>
>
>
>
>
|
|
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
....
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
....
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
....
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $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"
#include "pager.h"
#include <assert.h>
#include <string.h>

................................................................................
  u8 *aInStmt;                /* One bit for each page in the database */
  PgHdr *pFirst, *pLast;      /* List of free pages */
  PgHdr *pFirstSynced;        /* First free page with PgHdr.needSync==0 */
  PgHdr *pAll;                /* List of all pages */
  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 */
};

/*
** These are bits that can be set in Pager.errMask.
*/
#define PAGER_ERR_FULL     0x01  /* a write() failed */
#define PAGER_ERR_MEM      0x02  /* malloc() failed */
................................................................................
** automatically when it is closed.
*/
int sqlite3pager_open(
  Pager **ppPager,         /* Return the Pager structure here */
  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 */
  void  *pBusyHandler      /* Busy callback */
){
  Pager *pPager;
  char *zFullPathname;
  int nameLen;
  OsFile fd;
  int rc, i;
  int tempFile;
................................................................................
  pPager->readOnly = readOnly;
  pPager->needSync = 0;
  pPager->noSync = pPager->tempFile || !useJournal;
  pPager->pFirst = 0;
  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;
}

/*
** Set the destructor for this pager.  If not NULL, the destructor is called
................................................................................
    return pager_errcode(pPager);
  }

  /* If this is the first page accessed, then get a SHARED lock
  ** on the database file.
  */
  if( pPager->nRef==0 && !pPager->memDb ){
    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;

    /* If a journal file exists, and there is no RESERVED lock on the
    ** database file, then it either needs to be played back or deleted.
    */
    if( pPager->useJournal && 
................................................................................
  assert( pPager->state!=SQLITE_UNLOCK );
  if( pPager->state==SQLITE_READLOCK ){
    assert( pPager->aInJournal==0 );
    if( pPager->memDb ){
      pPager->state = SQLITE_WRITELOCK;
      pPager->origDbSize = pPager->dbSize;
    }else{
      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;
      pPager->dirtyFile = 0;
      TRACE1("TRANSACTION\n");
      if( pPager->useJournal && !pPager->tempFile ){
        rc = pager_open_journal(pPager);

Changes to src/pager.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** 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 $
*/

/*
** The size of a page.
**
** You can change this value to another (reasonable) value you want.
** It need not be a power of two, though the interface to the disk
................................................................................
typedef struct Pager Pager;

/*
** See source code comments for a detailed description of the following
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
                     int nPage, int nExtra, int useJournal);

void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
int sqlite3pager_ref(void*);
int sqlite3pager_unref(void*);







|







 







|
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** 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.31 2004/06/04 06:22:02 danielk1977 Exp $
*/

/*
** The size of a page.
**
** You can change this value to another (reasonable) value you want.
** It need not be a power of two, though the interface to the disk
................................................................................
typedef struct Pager Pager;

/*
** See source code comments for a detailed description of the following
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
                     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);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
int sqlite3pager_ref(void*);
int sqlite3pager_unref(void*);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
260
261
262
263
264
265
266

267
268
269
270
271
272
273
...
322
323
324
325
326
327
328














329
330
331
332
333
334
335
...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.267 2004/06/02 00:41:09 drh Exp $
*/
#include "config.h"
#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
typedef struct TriggerStack TriggerStack;
typedef struct FKey FKey;
typedef struct Db Db;
typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;



/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
................................................................................
** Possible values for the Db.textEnc field.
*/
#define TEXT_Utf8          1
#define TEXT_Utf16le       2
#define TEXT_Utf16be       3
#define TEXT_Utf16         (SQLITE_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le)















/*
** Each database is an instance of the following structure.
**
** The sqlite.temp_store determines where temporary database files
** are stored.  If 1, then a file is created to hold those tables.  If
** 2, then they are held in memory.  0 means use the default value in
** the TEMP_STORE macro.
................................................................................
  u8 file_format;               /* What file format version is this database? */
  u8 safety_level;              /* How aggressive at synching data to disk */
  u8 want_to_close;             /* Close after all VDBEs are deallocated */
  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
  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 */
  void *pCommitArg;             /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);/* Invoked at every commit. */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */







|







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.268 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite3.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
typedef struct TriggerStack TriggerStack;
typedef struct FKey FKey;
typedef struct Db Db;
typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct BusyHandler BusyHandler;


/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
................................................................................
** Possible values for the Db.textEnc field.
*/
#define TEXT_Utf8          1
#define TEXT_Utf16le       2
#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.
**
** The sqlite.temp_store determines where temporary database files
** are stored.  If 1, then a file is created to hold those tables.  If
** 2, then they are held in memory.  0 means use the default value in
** the TEMP_STORE macro.
................................................................................
  u8 file_format;               /* What file format version is this database? */
  u8 safety_level;              /* How aggressive at synching data to disk */
  u8 want_to_close;             /* Close after all VDBEs are deallocated */
  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
  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 */
  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 */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  i64 priorNewRowid;            /* Last randomly generated ROWID */

Changes to src/test2.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** 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 $
*/
#include "os.h"
#include "sqliteInt.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
  char zBuf[100];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME N-PAGE\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
  rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sprintf(zBuf,"0x%x",(int)pPager);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the pager.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test2.c,v 1.20 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "os.h"
#include "sqliteInt.h"
#include "pager.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
  char zBuf[100];
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME N-PAGE\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
  rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1, 0);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sprintf(zBuf,"0x%x",(int)pPager);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;

Changes to src/test3.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** 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 $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
  if( argc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME NCACHE FLAGS\"", 0);
    return TCL_ERROR;
  }
  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);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sprintf(zBuf,"%p", pBt);
  if( strncmp(zBuf,"0x",2) ){
    sprintf(zBuf, "0x%p", pBt);







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.43 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
................................................................................
  if( argc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME NCACHE FLAGS\"", 0);
    return TCL_ERROR;
  }
  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, 0);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  sprintf(zBuf,"%p", pBt);
  if( strncmp(zBuf,"0x",2) ){
    sprintf(zBuf, "0x%p", pBt);

Changes to src/test5.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
*************************************************************************
** Code for testing the utf.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library. Specifically, the code in this file
** 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 $
*/
#include "sqliteInt.h"
#include "os.h"         /* to get SQLITE_BIGENDIAN */
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    Tcl_ObjCmdProc *xProc;
  } aCmd[] = {
    { "sqlite_utf16to8",         (Tcl_ObjCmdProc*)sqlite_utf16to8    },
    { "sqlite_utf8to16le",       (Tcl_ObjCmdProc*)sqlite_utf8to16le  },
    { "sqlite_utf8to16be",       (Tcl_ObjCmdProc*)sqlite_utf8to16be  },
    { "sqlite_utf16to16le",      (Tcl_ObjCmdProc*)sqlite_utf16to16le },
    { "sqlite_utf16to16be",      (Tcl_ObjCmdProc*)sqlite_utf16to16be },
    { "binarize",                (Tcl_ObjCmdProc*)binarize }
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

  return TCL_OK;
}







|







 







|








11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
*************************************************************************
** Code for testing the utf.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library. Specifically, the code in this file
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
**
** $Id: test5.c,v 1.8 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"         /* to get SQLITE_BIGENDIAN */
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

................................................................................
    Tcl_ObjCmdProc *xProc;
  } aCmd[] = {
    { "sqlite_utf16to8",         (Tcl_ObjCmdProc*)sqlite_utf16to8    },
    { "sqlite_utf8to16le",       (Tcl_ObjCmdProc*)sqlite_utf8to16le  },
    { "sqlite_utf8to16be",       (Tcl_ObjCmdProc*)sqlite_utf8to16be  },
    { "sqlite_utf16to16le",      (Tcl_ObjCmdProc*)sqlite_utf16to16le },
    { "sqlite_utf16to16be",      (Tcl_ObjCmdProc*)sqlite_utf16to16be },
    { "binarize",                (Tcl_ObjCmdProc*)binarize },
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

  return TCL_OK;
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296

2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315

2316
2317
2318
2319
2320
2321
2322
2323
2324
....
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
....
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496

2497
2498
2499
2500
2501

2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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 $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** underway.  Starting a transaction also creates a rollback journal.  A
** transaction must be started before any changes can be made to the
** database.
**
** 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 ){
    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 ){

          p->pc = pc;
          p->rc = SQLITE_BUSY;
          p->pTos = pTos;
          return SQLITE_BUSY;
        }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
          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;
      }
    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 *
**
................................................................................
** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
  int busy = 0;
  int i = pOp->p1;
  int p2 = pOp->p2;
  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;
  
................................................................................
  }
  assert( i>=0 );
  if( expandCursorArraySize(p, i) ) goto no_mem;
  pCur = p->apCsr[i];
  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;
    }
    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;
      }
    }
  }while( busy );
  break;
}

/* Opcode: OpenTemp P1 * P3
**
** Open a new cursor to a transient table.
** The transient cursor is always opened read/write even if 







|







 







<






|

|
<
|
<
>




|

<

<
|
<
<
<
<
<
<
<
<
<
>
|
<







 







<







 







<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|
|
|
<
>
|
<
|
|
|
|
|
|
|
<
|
|
|
|
<
|
|
|
|
|
|
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2277
2278
2279
2280
2281
2282
2283

2284
2285
2286
2287
2288
2289
2290
2291
2292

2293

2294
2295
2296
2297
2298
2299
2300

2301

2302









2303
2304

2305
2306
2307
2308
2309
2310
2311
....
2428
2429
2430
2431
2432
2433
2434

2435
2436
2437
2438
2439
2440
2441
....
2460
2461
2462
2463
2464
2465
2466

2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483
2484
2485

2486
2487

2488
2489
2490
2491
2492
2493
2494

2495
2496
2497
2498

2499
2500
2501
2502
2503
2504

2505
2506
2507
2508
2509
2510
2511
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.357 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** underway.  Starting a transaction also creates a rollback journal.  A
** transaction must be started before any changes can be made to the
** database.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {

  int i = pOp->p1;
  Btree *pBt;

  assert( i>=0 && i<db->nDb );
  pBt = db->aDb[i].pBt;

  if( pBt ){
    int nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+11;
    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{
          sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);

        }

    }









    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY && rc!=SQLITE_BUSY ){
      goto abort_due_to_error;

    }
  }
  break;
}

/* Opcode: ReadCookie P1 P2 *
**
................................................................................
** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {

  int i = pOp->p1;
  int p2 = pOp->p2;
  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;
  
................................................................................
  }
  assert( i>=0 );
  if( expandCursorArraySize(p, i) ) goto no_mem;
  pCur = p->apCsr[i];
  sqlite3VdbeCleanupCursor(pCur);
  pCur->nullRow = 1;
  if( pX==0 ) break;

  /* 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;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);
      pCur->intKey = (flags & BTREE_INTKEY)!=0;
      pCur->zeroData = (flags & BTREE_ZERODATA)!=0;

      break;
    }
    case SQLITE_EMPTY: {
      rc = SQLITE_OK;

      break;
    }
    default: {
      goto abort_due_to_error;
    }
  }

  break;
}

/* Opcode: OpenTemp P1 * P3
**
** Open a new cursor to a transient table.
** The transient cursor is always opened read/write even if