/ Check-in [c2c1d656]
Login

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

Overview
Comment:Initial implementation of the "sqlite_dbpage" virtual table. Currently it is read-only and has a place-holder xBestIndex.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dbpage
Files: files | file ages | folders
SHA3-256: c2c1d656e3f52465192c2a697a976cd1837ccc4e10708a2377cff8bf6eaa7d49
User & Date: drh 2017-10-11 13:48:11
Context
2017-10-11
15:02
Get writes working on the sqlite_dbpage virtual table. Add a few test cases. check-in: a8b264d8 user: drh tags: dbpage
13:48
Initial implementation of the "sqlite_dbpage" virtual table. Currently it is read-only and has a place-holder xBestIndex. check-in: c2c1d656 user: drh tags: dbpage
12:20
In the speed-check.sh test script, allow an additional test-name argument which becomes the comparison baseline, in place of "trunk". check-in: 0245adff user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   162    162   
   163    163   USE_AMALGAMATION = @USE_AMALGAMATION@
   164    164   
   165    165   # Object files for the SQLite library (non-amalgamation).
   166    166   #
   167    167   LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
   168    168            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   169         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
          169  +         callback.lo complete.lo ctime.lo \
          170  +         date.lo dbpage.lo dbstat.lo delete.lo \
   170    171            expr.lo fault.lo fkey.lo \
   171    172            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   172    173            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
   173    174            fts3_tokenize_vtab.lo \
   174    175            fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   175    176   	 fts5.lo \
   176    177            func.lo global.lo hash.lo \
................................................................................
   211    212     $(TOP)/src/btree.h \
   212    213     $(TOP)/src/btreeInt.h \
   213    214     $(TOP)/src/build.c \
   214    215     $(TOP)/src/callback.c \
   215    216     $(TOP)/src/complete.c \
   216    217     $(TOP)/src/ctime.c \
   217    218     $(TOP)/src/date.c \
          219  +  $(TOP)/src/dbpage.c \
   218    220     $(TOP)/src/dbstat.c \
   219    221     $(TOP)/src/delete.c \
   220    222     $(TOP)/src/expr.c \
   221    223     $(TOP)/src/fault.c \
   222    224     $(TOP)/src/fkey.c \
   223    225     $(TOP)/src/func.c \
   224    226     $(TOP)/src/global.c \
................................................................................
   445    447     $(TOP)/src/attach.c \
   446    448     $(TOP)/src/backup.c \
   447    449     $(TOP)/src/bitvec.c \
   448    450     $(TOP)/src/btree.c \
   449    451     $(TOP)/src/build.c \
   450    452     $(TOP)/src/ctime.c \
   451    453     $(TOP)/src/date.c \
          454  +  $(TOP)/src/dbpage.c \
   452    455     $(TOP)/src/dbstat.c \
   453    456     $(TOP)/src/expr.c \
   454    457     $(TOP)/src/func.c \
   455    458     $(TOP)/src/insert.c \
   456    459     $(TOP)/src/wal.c \
   457    460     $(TOP)/src/main.c \
   458    461     $(TOP)/src/mem5.c \
................................................................................
   748    751   
   749    752   ctime.lo:	$(TOP)/src/ctime.c $(HDR)
   750    753   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c
   751    754   
   752    755   date.lo:	$(TOP)/src/date.c $(HDR)
   753    756   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
   754    757   
          758  +dbpage.lo:	$(TOP)/src/dbpage.c $(HDR)
          759  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c
          760  +
   755    761   dbstat.lo:	$(TOP)/src/dbstat.c $(HDR)
   756    762   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
   757    763   
   758    764   delete.lo:	$(TOP)/src/delete.c $(HDR)
   759    765   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
   760    766   
   761    767   expr.lo:	$(TOP)/src/expr.c $(HDR)

Changes to Makefile.msc.

  1087   1087   ###############################################################################
  1088   1088   
  1089   1089   # <<mark>>
  1090   1090   # Object files for the SQLite library (non-amalgamation).
  1091   1091   #
  1092   1092   LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
  1093   1093            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
  1094         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
         1094  +         callback.lo complete.lo ctime.lo \
         1095  +         date.lo dbpage.lo dbstat.lo delete.lo \
  1095   1096            expr.lo fault.lo fkey.lo \
  1096   1097            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
  1097   1098            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
  1098   1099            fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
  1099   1100            fts5.lo \
  1100   1101            func.lo global.lo hash.lo \
  1101   1102            icu.lo insert.lo legacy.lo loadext.lo \
................................................................................
  1150   1151     $(TOP)\src\btmutex.c \
  1151   1152     $(TOP)\src\btree.c \
  1152   1153     $(TOP)\src\build.c \
  1153   1154     $(TOP)\src\callback.c \
  1154   1155     $(TOP)\src\complete.c \
  1155   1156     $(TOP)\src\ctime.c \
  1156   1157     $(TOP)\src\date.c \
         1158  +  $(TOP)\src\dbpage.c \
  1157   1159     $(TOP)\src\dbstat.c \
  1158   1160     $(TOP)\src\delete.c \
  1159   1161     $(TOP)\src\expr.c \
  1160   1162     $(TOP)\src\fault.c \
  1161   1163     $(TOP)\src\fkey.c \
  1162   1164     $(TOP)\src\func.c \
  1163   1165     $(TOP)\src\global.c \
................................................................................
  1743   1745   
  1744   1746   ctime.lo:	$(TOP)\src\ctime.c $(HDR)
  1745   1747   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\ctime.c
  1746   1748   
  1747   1749   date.lo:	$(TOP)\src\date.c $(HDR)
  1748   1750   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
  1749   1751   
  1750         -dbstat.lo:	$(TOP)\src\date.c $(HDR)
         1752  +dbpage.lo:	$(TOP)\src\dbpage.c $(HDR)
         1753  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbpage.c
         1754  +
         1755  +dbstat.lo:	$(TOP)\src\dbstat.c $(HDR)
  1751   1756   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
  1752   1757   
  1753   1758   delete.lo:	$(TOP)\src\delete.c $(HDR)
  1754   1759   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\delete.c
  1755   1760   
  1756   1761   expr.lo:	$(TOP)\src\expr.c $(HDR)
  1757   1762   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\expr.c

Changes to main.mk.

    51     51   THREADLIB += $(LIBS)
    52     52   
    53     53   # Object files for the SQLite library.
    54     54   #
    55     55   LIBOBJ+= vdbe.o parse.o \
    56     56            alter.o analyze.o attach.o auth.o \
    57     57            backup.o bitvec.o btmutex.o btree.o build.o \
    58         -         callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \
           58  +         callback.o complete.o ctime.o \
           59  +         date.o dbpage.o dbstat.o delete.o expr.o \
    59     60   	 fault.o fkey.o \
    60     61            fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
    61     62            fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
    62     63            fts3_tokenize_vtab.o \
    63     64   	 fts3_unicode.o fts3_unicode2.o \
    64     65            fts3_write.o fts5.o func.o global.o hash.o \
    65     66            icu.o insert.o json1.o legacy.o loadext.o \
................................................................................
    92     93     $(TOP)/src/btree.h \
    93     94     $(TOP)/src/btreeInt.h \
    94     95     $(TOP)/src/build.c \
    95     96     $(TOP)/src/callback.c \
    96     97     $(TOP)/src/complete.c \
    97     98     $(TOP)/src/ctime.c \
    98     99     $(TOP)/src/date.c \
          100  +  $(TOP)/src/dbpage.c \
    99    101     $(TOP)/src/dbstat.c \
   100    102     $(TOP)/src/delete.c \
   101    103     $(TOP)/src/expr.c \
   102    104     $(TOP)/src/fault.c \
   103    105     $(TOP)/src/fkey.c \
   104    106     $(TOP)/src/func.c \
   105    107     $(TOP)/src/global.c \
................................................................................
   355    357   
   356    358   TESTSRC2 = \
   357    359     $(TOP)/src/attach.c \
   358    360     $(TOP)/src/backup.c \
   359    361     $(TOP)/src/btree.c \
   360    362     $(TOP)/src/build.c \
   361    363     $(TOP)/src/date.c \
          364  +  $(TOP)/src/dbpage.c \
   362    365     $(TOP)/src/dbstat.c \
   363    366     $(TOP)/src/expr.c \
   364    367     $(TOP)/src/func.c \
   365    368     $(TOP)/src/insert.c \
   366    369     $(TOP)/src/wal.c \
   367    370     $(TOP)/src/main.c \
   368    371     $(TOP)/src/mem5.c \

Added src/dbpage.c.

            1  +/*
            2  +** 2017-10-11
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains an implementation of the "sqlite_dbpage" virtual table.
           14  +**
           15  +** The sqlite_dbpage virtual table is used to read or write whole raw
           16  +** pages of the database file.  The pager interface is used so that 
           17  +** uncommitted changes and changes recorded in the WAL file are correctly
           18  +** retrieved.
           19  +*/
           20  +
           21  +#include "sqliteInt.h"   /* Requires access to internal data structures */
           22  +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
           23  +    && !defined(SQLITE_OMIT_VIRTUALTABLE)
           24  +
           25  +typedef struct DbpageTable DbpageTable;
           26  +typedef struct DbpageCursor DbpageCursor;
           27  +
           28  +struct DbpageCursor {
           29  +  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
           30  +  int pgno;                       /* Current page number */
           31  +};
           32  +
           33  +struct DbpageTable {
           34  +  sqlite3_vtab base;              /* Base class.  Must be first */
           35  +  sqlite3 *db;                    /* The database */
           36  +  Pager *pPager;                  /* Pager being read/written */
           37  +  int iDb;                        /* Index of database to analyze */
           38  +  int szPage;                     /* Size of each page in bytes */
           39  +  int nPage;                      /* Number of pages in the file */
           40  +};
           41  +
           42  +/*
           43  +** Connect to or create a dbpagevfs virtual table.
           44  +*/
           45  +static int dbpageConnect(
           46  +  sqlite3 *db,
           47  +  void *pAux,
           48  +  int argc, const char *const*argv,
           49  +  sqlite3_vtab **ppVtab,
           50  +  char **pzErr
           51  +){
           52  +  DbpageTable *pTab = 0;
           53  +  int rc = SQLITE_OK;
           54  +  int iDb;
           55  +
           56  +  if( argc>=4 ){
           57  +    Token nm;
           58  +    sqlite3TokenInit(&nm, (char*)argv[3]);
           59  +    iDb = sqlite3FindDb(db, &nm);
           60  +    if( iDb<0 ){
           61  +      *pzErr = sqlite3_mprintf("no such schema: %s", argv[3]);
           62  +      return SQLITE_ERROR;
           63  +    }
           64  +  }else{
           65  +    iDb = 0;
           66  +  }
           67  +  rc = sqlite3_declare_vtab(db, 
           68  +          "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB)");
           69  +  if( rc==SQLITE_OK ){
           70  +    pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
           71  +    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
           72  +  }
           73  +
           74  +  assert( rc==SQLITE_OK || pTab==0 );
           75  +  if( rc==SQLITE_OK ){
           76  +    Btree *pBt = db->aDb[iDb].pBt;
           77  +    memset(pTab, 0, sizeof(DbpageTable));
           78  +    pTab->db = db;
           79  +    pTab->iDb = iDb;
           80  +    pTab->pPager = pBt ? sqlite3BtreePager(pBt) : 0;
           81  +  }
           82  +
           83  +  *ppVtab = (sqlite3_vtab*)pTab;
           84  +  return rc;
           85  +}
           86  +
           87  +/*
           88  +** Disconnect from or destroy a dbpagevfs virtual table.
           89  +*/
           90  +static int dbpageDisconnect(sqlite3_vtab *pVtab){
           91  +  sqlite3_free(pVtab);
           92  +  return SQLITE_OK;
           93  +}
           94  +
           95  +/*
           96  +** idxNum:
           97  +**
           98  +**     0     full table scan
           99  +**     1     pgno=?1
          100  +*/
          101  +static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
          102  +  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
          103  +  return SQLITE_OK;
          104  +}
          105  +
          106  +/*
          107  +** Open a new dbpagevfs cursor.
          108  +*/
          109  +static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
          110  +  DbpageCursor *pCsr;
          111  +
          112  +  pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
          113  +  if( pCsr==0 ){
          114  +    return SQLITE_NOMEM_BKPT;
          115  +  }else{
          116  +    memset(pCsr, 0, sizeof(DbpageCursor));
          117  +    pCsr->base.pVtab = pVTab;
          118  +    pCsr->pgno = -1;
          119  +  }
          120  +
          121  +  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
          122  +  return SQLITE_OK;
          123  +}
          124  +
          125  +/*
          126  +** Close a dbpagevfs cursor.
          127  +*/
          128  +static int dbpageClose(sqlite3_vtab_cursor *pCursor){
          129  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          130  +  sqlite3_free(pCsr);
          131  +  return SQLITE_OK;
          132  +}
          133  +
          134  +/*
          135  +** Move a dbpagevfs cursor to the next entry in the file.
          136  +*/
          137  +static int dbpageNext(sqlite3_vtab_cursor *pCursor){
          138  +  int rc = SQLITE_OK;
          139  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          140  +  pCsr->pgno++;
          141  +  return rc;
          142  +}
          143  +
          144  +static int dbpageEof(sqlite3_vtab_cursor *pCursor){
          145  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          146  +  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
          147  +  return pCsr->pgno >= pTab->nPage;
          148  +}
          149  +
          150  +static int dbpageFilter(
          151  +  sqlite3_vtab_cursor *pCursor, 
          152  +  int idxNum, const char *idxStr,
          153  +  int argc, sqlite3_value **argv
          154  +){
          155  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          156  +  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
          157  +  int rc = SQLITE_OK;
          158  +  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
          159  +
          160  +  if( idxNum==1 ){
          161  +    pCsr->pgno = sqlite3_value_int(argv[0]);
          162  +  }else{
          163  +    pCsr->pgno = 0;
          164  +  }
          165  +  pTab->szPage = sqlite3BtreeGetPageSize(pBt);
          166  +  pTab->nPage = sqlite3BtreeLastPage(pBt);
          167  +  return rc;
          168  +}
          169  +
          170  +static int dbpageColumn(
          171  +  sqlite3_vtab_cursor *pCursor, 
          172  +  sqlite3_context *ctx, 
          173  +  int i
          174  +){
          175  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          176  +  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
          177  +  int rc = SQLITE_OK;
          178  +  switch( i ){
          179  +    case 0: {           /* pgno */
          180  +      sqlite3_result_int(ctx, pCsr->pgno);
          181  +      break;
          182  +    }
          183  +    case 1: {           /* data */
          184  +      DbPage *pDbPage = 0;
          185  +      rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
          186  +      if( rc==SQLITE_OK ){
          187  +        sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage,
          188  +                            SQLITE_TRANSIENT);
          189  +      }
          190  +      sqlite3PagerUnref(pDbPage);
          191  +      break;
          192  +    }
          193  +    default: {          /* schema */
          194  +      sqlite3 *db = sqlite3_context_db_handle(ctx);
          195  +      sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC);
          196  +      break;
          197  +    }
          198  +  }
          199  +  return SQLITE_OK;
          200  +}
          201  +
          202  +static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
          203  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          204  +  *pRowid = pCsr->pgno;
          205  +  return SQLITE_OK;
          206  +}
          207  +
          208  +/*
          209  +** Invoke this routine to register the "dbpage" virtual table module
          210  +*/
          211  +int sqlite3DbpageRegister(sqlite3 *db){
          212  +  static sqlite3_module dbpage_module = {
          213  +    0,                            /* iVersion */
          214  +    dbpageConnect,                /* xCreate */
          215  +    dbpageConnect,                /* xConnect */
          216  +    dbpageBestIndex,              /* xBestIndex */
          217  +    dbpageDisconnect,             /* xDisconnect */
          218  +    dbpageDisconnect,             /* xDestroy */
          219  +    dbpageOpen,                   /* xOpen - open a cursor */
          220  +    dbpageClose,                  /* xClose - close a cursor */
          221  +    dbpageFilter,                 /* xFilter - configure scan constraints */
          222  +    dbpageNext,                   /* xNext - advance a cursor */
          223  +    dbpageEof,                    /* xEof - check for end of scan */
          224  +    dbpageColumn,                 /* xColumn - read data */
          225  +    dbpageRowid,                  /* xRowid - read data */
          226  +    0,                            /* xUpdate */
          227  +    0,                            /* xBegin */
          228  +    0,                            /* xSync */
          229  +    0,                            /* xCommit */
          230  +    0,                            /* xRollback */
          231  +    0,                            /* xFindMethod */
          232  +    0,                            /* xRename */
          233  +    0,                            /* xSavepoint */
          234  +    0,                            /* xRelease */
          235  +    0,                            /* xRollbackTo */
          236  +  };
          237  +  return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
          238  +}
          239  +#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
          240  +int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
          241  +#endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/main.c.

  3049   3049   #endif
  3050   3050   
  3051   3051   #ifdef SQLITE_ENABLE_RTREE
  3052   3052     if( !db->mallocFailed && rc==SQLITE_OK){
  3053   3053       rc = sqlite3RtreeInit(db);
  3054   3054     }
  3055   3055   #endif
         3056  +
         3057  +#ifdef SQLITE_ENABLE_DBPAGE_VTAB
         3058  +  if( !db->mallocFailed && rc==SQLITE_OK){
         3059  +    rc = sqlite3DbpageRegister(db);
         3060  +  }
         3061  +#endif
  3056   3062   
  3057   3063   #ifdef SQLITE_ENABLE_DBSTAT_VTAB
  3058   3064     if( !db->mallocFailed && rc==SQLITE_OK){
  3059   3065       rc = sqlite3DbstatRegister(db);
  3060   3066     }
  3061   3067   #endif
  3062   3068   

Changes to src/sqliteInt.h.

  4396   4396   ** Threading interface
  4397   4397   */
  4398   4398   #if SQLITE_MAX_WORKER_THREADS>0
  4399   4399   int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
  4400   4400   int sqlite3ThreadJoin(SQLiteThread*, void**);
  4401   4401   #endif
  4402   4402   
         4403  +#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
         4404  +int sqlite3DbpageRegister(sqlite3*);
         4405  +#endif
  4403   4406   #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
  4404   4407   int sqlite3DbstatRegister(sqlite3*);
  4405   4408   #endif
  4406   4409   
  4407   4410   int sqlite3ExprVectorSize(Expr *pExpr);
  4408   4411   int sqlite3ExprIsVector(Expr *pExpr);
  4409   4412   Expr *sqlite3VectorFieldSubexpr(Expr*, int);

Changes to tool/mksqlite3c.tcl.

   390    390      fts3_unicode2.c
   391    391   
   392    392      rtree.c
   393    393      icu.c
   394    394      fts3_icu.c
   395    395      sqlite3rbu.c
   396    396      dbstat.c
          397  +   dbpage.c
   397    398      sqlite3session.c
   398    399      json1.c
   399    400      fts5.c
   400    401      stmt.c
   401    402   } {
   402    403     copy_file tsrc/$file
   403    404   }