/ Check-in [4cf6e9db]
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:Initial implementation of variable page sizes and the temp_store pragma. (CVS 1843)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4cf6e9db757931aba2f300b7869305434d6f2d2b
User & Date: drh 2004-07-22 01:19:35
Context
2004-07-22
02:40
Changes in support of using a codec. (CVS 1844) check-in: b77bec35 user: drh tags: trunk
01:19
Initial implementation of variable page sizes and the temp_store pragma. (CVS 1843) check-in: 4cf6e9db user: drh tags: trunk
2004-07-21
15:21
Updates comments in sqlite.h.in that describe the destructor parameter to sqlite3_bind_.... (CVS 1842) check-in: 166eb606 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/attach.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the ATTACH and DETACH commands.
    13     13   **
    14         -** $Id: attach.c,v 1.22 2004/07/19 00:56:24 drh Exp $
           14  +** $Id: attach.c,v 1.23 2004/07/22 01:19:35 drh Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   
    18     18   /*
    19     19   ** This routine is called by the parser to process an ATTACH statement:
    20     20   **
    21     21   **     ATTACH DATABASE filename AS dbname
................................................................................
    87     87     aNew->zName = zName;
    88     88     aNew->safety_level = 3;
    89     89     rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
    90     90     if( rc ){
    91     91       sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
    92     92     }
    93     93   #if SQLITE_HAS_CODEC
    94         -  {
    95         -    extern int sqliteCodecAttach(sqlite*, int, void*, int);
           94  +  assert( pKey!=0 );
           95  +  if( pKey->n>0 ){
           96  +    extern int sqlite3CodecAttach(sqlite*, int, void*, int);
    96     97       char *zKey = 0;
    97     98       int nKey;
    98         -    if( pKey && pKey->z && pKey->n ){
    99         -      sqlite3SetNString(&zKey, pKey->z, pKey->n, 0);
   100         -      sqlite3Dequote(zKey);
   101         -      nKey = strlen(zKey);
   102         -    }else{
   103         -      zKey = 0;
   104         -      nKey = 0;
   105         -    }
   106         -    sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
           99  +    sqlite3BtreeSetPageSize(aNew->pBt, -1, 4);
          100  +    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
          101  +    zKey = sqlite3NameFromToken(pKey);
          102  +    nKey = strlen(zKey);
   107    103     }
   108    104   #endif
   109    105     sqliteFree(zFile);
   110    106     db->flags &= ~SQLITE_Initialized;
   111    107     if( pParse->nErr==0 && rc==SQLITE_OK ){
   112    108       rc = sqlite3ReadSchema(pParse);
   113    109     }

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.177 2004/07/20 12:45:22 drh Exp $
           12  +** $Id: btree.c,v 1.178 2004/07/22 01:19:35 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
   207    207   #include "sqliteInt.h"
   208    208   #include "pager.h"
   209    209   #include "btree.h"
   210    210   #include "os.h"
   211    211   #include <assert.h>
   212    212   
   213    213   
   214         -/* Maximum page size.  The upper bound on this value is 65536 (a limit
   215         -** imposed by the 2-byte size of cell array pointers.)  The
   216         -** maximum page size determines the amount of stack space allocated
   217         -** by many of the routines in this module.  On embedded architectures
   218         -** or any machine where memory and especially stack memory is limited,
   219         -** one may wish to chose a smaller value for the maximum page size.
   220         -*/
   221         -#ifndef MX_PAGE_SIZE
   222         -# define MX_PAGE_SIZE 1024
   223         -#endif
   224         -
   225    214   /* The following value is the maximum cell size assuming a maximum page
   226    215   ** size give above.
   227    216   */
   228         -#define MX_CELL_SIZE  (MX_PAGE_SIZE-8)
          217  +#define MX_CELL_SIZE  (SQLITE_MAX_PAGE_SIZE-8)
   229    218   
   230    219   /* The maximum number of cells on a single page of the database.  This
   231    220   ** assumes a minimum cell size of 3 bytes.  Such small cells will be
   232    221   ** exceedingly rare, but they are possible.
   233    222   */
   234         -#define MX_CELL ((MX_PAGE_SIZE-8)/3)
          223  +#define MX_CELL ((SQLITE_MAX_PAGE_SIZE-8)/3)
   235    224   
   236    225   /* Forward declarations */
   237    226   typedef struct MemPage MemPage;
   238    227   
   239    228   /*
   240    229   ** This is a magic string that appears at the beginning of every
   241    230   ** SQLite database in order to identify the file as a real database.
................................................................................
   304    293     MemPage *pPage1;      /* First page of the database */
   305    294     u8 inTrans;           /* True if a transaction is in progress */
   306    295     u8 inStmt;            /* True if we are in a statement subtransaction */
   307    296     u8 readOnly;          /* True if the underlying file is readonly */
   308    297     u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
   309    298     u8 minEmbedFrac;      /* Minimum payload as % of total page size */
   310    299     u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
          300  +  u8 pageSizeFixed;     /* True if the page size can no longer be changed */
   311    301     u16 pageSize;         /* Total number of bytes on a page */
   312    302     u16 usableSize;       /* Number of usable bytes on each page */
   313    303     int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
   314    304     int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
   315    305     int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
   316    306     int minLeaf;          /* Minimum local payload in a LEAFDATA table */
   317    307   };
................................................................................
   528    518   #if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0
   529    519   static void _pageIntegrity(MemPage *pPage){
   530    520     int usableSize;
   531    521     u8 *data;
   532    522     int i, j, idx, c, pc, hdr, nFree;
   533    523     int cellOffset;
   534    524     int nCell, cellLimit;
   535         -  u8 used[MX_PAGE_SIZE];
          525  +  u8 used[SQLITE_MAX_PAGE_SIZE];
   536    526   
   537    527     usableSize = pPage->pBt->usableSize;
   538    528     assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
   539    529     hdr = pPage->hdrOffset;
   540    530     assert( hdr==(pPage->pgno==1 ? 100 : 0) );
   541    531     assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
   542    532     c = pPage->aData[hdr];
................................................................................
   612    602     int hdr;                   /* Offset to the page header */
   613    603     int size;                  /* Size of a cell */
   614    604     int usableSize;            /* Number of usable bytes on a page */
   615    605     int cellOffset;            /* Offset to the cell pointer array */
   616    606     int brk;                   /* Offset to the cell content area */
   617    607     int nCell;                 /* Number of cells on the page */
   618    608     unsigned char *data;               /* The page data */
   619         -  unsigned char temp[MX_PAGE_SIZE];  /* Temp holding area for cell content */
          609  +  unsigned char temp[SQLITE_MAX_PAGE_SIZE];  /* Temp area for cell content */
   620    610   
   621    611     assert( sqlite3pager_iswriteable(pPage->aData) );
   622    612     assert( pPage->pBt!=0 );
   623         -  assert( pPage->pBt->usableSize <= MX_PAGE_SIZE );
          613  +  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
   624    614     assert( pPage->nOverflow==0 );
   625    615     data = pPage->aData;
   626    616     hdr = pPage->hdrOffset;
   627    617     cellOffset = pPage->cellOffset;
   628    618     nCell = pPage->nCell;
   629    619     assert( nCell==get2byte(&data[hdr+3]) );
   630    620     usableSize = pPage->pBt->usableSize;
................................................................................
   853    843     /* Compute the total free space on the page */
   854    844     pc = get2byte(&data[hdr+1]);
   855    845     nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
   856    846     i = 0;
   857    847     while( pc>0 ){
   858    848       int next, size;
   859    849       if( pc>=usableSize ) return SQLITE_CORRUPT;
   860         -    if( i++>MX_PAGE_SIZE ) return SQLITE_CORRUPT;
          850  +    if( i++>SQLITE_MAX_PAGE_SIZE ) return SQLITE_CORRUPT;
   861    851       next = get2byte(&data[pc]);
   862    852       size = get2byte(&data[pc+2]);
   863    853       if( next>0 && next<=pc+size+3 ) return SQLITE_CORRUPT;
   864    854       nFree += size;
   865    855       pc = next;
   866    856     }
   867    857     pPage->nFree = nFree;
................................................................................
   994    984   ** zFilename is the name of the database file.  If zFilename is NULL
   995    985   ** a new database with a random name is created.  This randomly named
   996    986   ** database file will be deleted when sqlite3BtreeClose() is called.
   997    987   */
   998    988   int sqlite3BtreeOpen(
   999    989     const char *zFilename,  /* Name of the file containing the BTree database */
  1000    990     Btree **ppBtree,        /* Pointer to new Btree object written here */
  1001         -  int nCache,             /* Number of cache pages */
  1002         -  int flags,              /* Options */
  1003         -  void *pBusyHandler      /* Busy callback info passed to pager layer */
          991  +  int flags               /* Options */
  1004    992   ){
  1005    993     Btree *pBt;
  1006    994     int rc;
          995  +  int nReserve;
          996  +  unsigned char zDbHeader[100];
  1007    997   
  1008    998     /*
  1009    999     ** The following asserts make sure that structures used by the btree are
  1010   1000     ** the right size.  This is to guard against size changes that result
  1011   1001     ** when compiling on a different architecture.
  1012   1002     */
  1013   1003     assert( sizeof(i64)==8 );
................................................................................
  1019   1009     assert( sizeof(uptr)==sizeof(ptr) );
  1020   1010   
  1021   1011     pBt = sqliteMalloc( sizeof(*pBt) );
  1022   1012     if( pBt==0 ){
  1023   1013       *ppBtree = 0;
  1024   1014       return SQLITE_NOMEM;
  1025   1015     }
  1026         -  if( nCache<10 ) nCache = 10;
  1027         -  rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
  1028         -                        (flags & BTREE_OMIT_JOURNAL)==0, pBusyHandler);
         1016  +  rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE,
         1017  +                        (flags & BTREE_OMIT_JOURNAL)==0);
  1029   1018     if( rc!=SQLITE_OK ){
  1030   1019       if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
  1031   1020       sqliteFree(pBt);
  1032   1021       *ppBtree = 0;
  1033   1022       return rc;
  1034   1023     }
  1035   1024     sqlite3pager_set_destructor(pBt->pPager, pageDestructor);
  1036   1025     sqlite3pager_set_reiniter(pBt->pPager, pageReinit);
  1037   1026     pBt->pCursor = 0;
  1038   1027     pBt->pPage1 = 0;
  1039   1028     pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
  1040         -  pBt->pageSize = SQLITE_PAGE_SIZE;  /* FIX ME - read from header */
  1041         -  pBt->usableSize = pBt->pageSize;
  1042         -  pBt->maxEmbedFrac = 64;            /* FIX ME - read from header */
  1043         -  pBt->minEmbedFrac = 32;            /* FIX ME - read from header */
  1044         -  pBt->minLeafFrac = 32;             /* FIX ME - read from header */
  1045         -
         1029  +  sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
         1030  +  pBt->pageSize = get2byte(&zDbHeader[16]);
         1031  +  if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE ){
         1032  +    pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
         1033  +    pBt->maxEmbedFrac = 64;   /* 25% */
         1034  +    pBt->minEmbedFrac = 32;   /* 12.5% */
         1035  +    pBt->minLeafFrac = 32;    /* 12.5% */
         1036  +    nReserve = 0;
         1037  +  }else{
         1038  +    nReserve = zDbHeader[20];
         1039  +    pBt->maxEmbedFrac = zDbHeader[21];
         1040  +    pBt->minEmbedFrac = zDbHeader[22];
         1041  +    pBt->minLeafFrac = zDbHeader[23];
         1042  +    pBt->pageSizeFixed = 1;
         1043  +  }
         1044  +  pBt->usableSize = pBt->pageSize - nReserve;
         1045  +  sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
  1046   1046     *ppBtree = pBt;
  1047   1047     return SQLITE_OK;
  1048   1048   }
  1049   1049   
  1050   1050   /*
  1051   1051   ** Close an open database and invalidate all cursors.
  1052   1052   */
................................................................................
  1054   1054     while( pBt->pCursor ){
  1055   1055       sqlite3BtreeCloseCursor(pBt->pCursor);
  1056   1056     }
  1057   1057     sqlite3pager_close(pBt->pPager);
  1058   1058     sqliteFree(pBt);
  1059   1059     return SQLITE_OK;
  1060   1060   }
         1061  +
         1062  +/*
         1063  +** Change the busy handler callback function.
         1064  +*/
         1065  +int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){
         1066  +  sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
         1067  +  return SQLITE_OK;
         1068  +}
  1061   1069   
  1062   1070   /*
  1063   1071   ** Change the limit on the number of pages allowed in the cache.
  1064   1072   **
  1065   1073   ** The maximum number of cache pages is set to the absolute
  1066   1074   ** value of mxPage.  If mxPage is negative, the pager will
  1067   1075   ** operate asynchronously - it will not stop to do fsync()s
................................................................................
  1087   1095   ** is a very low but non-zero probability of damage.  Level 3 reduces the
  1088   1096   ** probability of damage to near zero but with a write performance reduction.
  1089   1097   */
  1090   1098   int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
  1091   1099     sqlite3pager_set_safety_level(pBt->pPager, level);
  1092   1100     return SQLITE_OK;
  1093   1101   }
         1102  +
         1103  +/*
         1104  +** Change the default pages size and the number of reserved bytes per page.
         1105  +*/
         1106  +int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
         1107  +  if( pBt->pageSizeFixed ){
         1108  +    return SQLITE_READONLY;
         1109  +  }
         1110  +  if( nReserve<0 ){
         1111  +    nReserve = pBt->pageSize - pBt->usableSize;
         1112  +  }
         1113  +  if( pageSize>512 && pageSize<SQLITE_MAX_PAGE_SIZE ){
         1114  +    pBt->pageSize = pageSize;
         1115  +    sqlite3pager_set_pagesize(pBt->pPager, pageSize);
         1116  +  }
         1117  +  pBt->usableSize = pBt->pageSize - nReserve;
         1118  +  return SQLITE_OK;
         1119  +}
         1120  +
         1121  +/*
         1122  +** Return the currently defined page size
         1123  +*/
         1124  +int sqlite3BtreeGetPageSize(Btree *pBt){
         1125  +  return pBt->pageSize;
         1126  +}
  1094   1127   
  1095   1128   /*
  1096   1129   ** Get a reference to pPage1 of the database file.  This will
  1097   1130   ** also acquire a readlock on that file.
  1098   1131   **
  1099   1132   ** SQLITE_OK is returned on success.  If the file is not a
  1100   1133   ** well-formed database file, then SQLITE_CORRUPT is returned.
................................................................................
  1150   1183     pBt->maxLeaf = pBt->usableSize - 35;
  1151   1184     pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
  1152   1185     if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
  1153   1186       goto page1_init_failed;
  1154   1187     }
  1155   1188     assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE );
  1156   1189     pBt->pPage1 = pPage1;
         1190  +  pBt->pageSizeFixed = 1;
  1157   1191     return SQLITE_OK;
  1158   1192   
  1159   1193   page1_init_failed:
  1160   1194     releasePage(pPage1);
  1161   1195     pBt->pPage1 = 0;
  1162   1196     return rc;
  1163   1197   }
................................................................................
  2859   2893     Pgno pgnoNew[NB+2];          /* Page numbers for each page in apNew[] */
  2860   2894     int idxDiv[NB];              /* Indices of divider cells in pParent */
  2861   2895     u8 *apDiv[NB];               /* Divider cells in pParent */
  2862   2896     int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  2863   2897     int szNew[NB+2];             /* Combined size of cells place on i-th page */
  2864   2898     u8 *apCell[(MX_CELL+2)*NB];  /* All cells from pages being balanced */
  2865   2899     int szCell[(MX_CELL+2)*NB];  /* Local size of all cells */
  2866         -  u8 aCopy[NB][MX_PAGE_SIZE+sizeof(MemPage)];  /* Space for apCopy[] */
  2867         -  u8 aSpace[MX_PAGE_SIZE*5];   /* Space to copies of divider cells */
         2900  +  u8 aCopy[NB][SQLITE_MAX_PAGE_SIZE+sizeof(MemPage)];  /* Space for apCopy[] */
         2901  +  u8 aSpace[SQLITE_MAX_PAGE_SIZE*5];   /* Space to copies of divider cells */
  2868   2902   
  2869   2903     /* 
  2870   2904     ** Find the parent page.
  2871   2905     */
  2872   2906     assert( pPage->isInit );
  2873   2907     assert( sqlite3pager_iswriteable(pPage->aData) );
  2874   2908     pBt = pPage->pBt;
................................................................................
  4038   4072     int nCell;
  4039   4073     u8 *data;
  4040   4074     BtCursor cur;
  4041   4075     Btree *pBt;
  4042   4076     int maxLocal, usableSize;
  4043   4077     char zMsg[100];
  4044   4078     char zContext[100];
  4045         -  char hit[MX_PAGE_SIZE];
         4079  +  char hit[SQLITE_MAX_PAGE_SIZE];
  4046   4080   
  4047   4081     /* Check that the page exists
  4048   4082     */
  4049   4083     cur.pBt = pBt = pCheck->pBt;
  4050   4084     usableSize = pBt->usableSize;
  4051   4085     if( iPage==0 ) return 0;
  4052   4086     if( checkRef(pCheck, iPage, zParentContext) ) return 0;

Changes to src/btree.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite B-Tree file
    13     13   ** subsystem.  See comments in the source code for a detailed description
    14     14   ** of what each interface routine does.
    15     15   **
    16         -** @(#) $Id: btree.h,v 1.55 2004/06/26 08:38:25 danielk1977 Exp $
           16  +** @(#) $Id: btree.h,v 1.56 2004/07/22 01:19:35 drh Exp $
    17     17   */
    18     18   #ifndef _BTREE_H_
    19     19   #define _BTREE_H_
    20     20   
    21     21   /* TODO: This definition is just included so other modules compile. It
    22     22   ** needs to be revisited.
    23     23   */
................................................................................
    27     27   ** Forward declarations of structure
    28     28   */
    29     29   typedef struct Btree Btree;
    30     30   typedef struct BtCursor BtCursor;
    31     31   
    32     32   
    33     33   int sqlite3BtreeOpen(
    34         -  const char *zFilename, 
    35         -  Btree **, 
    36         -  int nCache, 
    37         -  int flags,
    38         -  void *pBusyHandler
           34  +  const char *zFilename,   /* Name of database file to open */
           35  +  Btree **,                /* Return open Btree* here */
           36  +  int flags                /* Flags */
    39     37   );
    40     38   
    41     39   /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
    42     40   ** following values.
    43     41   */
    44     42   #define BTREE_OMIT_JOURNAL  1  /* Do not use journal.  No argument */
    45     43   #define BTREE_MEMORY        2  /* In-memory DB.  No argument */
    46     44   
    47     45   int sqlite3BtreeClose(Btree*);
           46  +int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
    48     47   int sqlite3BtreeSetCacheSize(Btree*,int);
    49     48   int sqlite3BtreeSetSafetyLevel(Btree*,int);
           49  +int sqlite3BtreeSetPageSize(Btree*,int,int);
           50  +int sqlite3BtreeGetPageSize(Btree*);
    50     51   int sqlite3BtreeBeginTrans(Btree*,int);
    51     52   int sqlite3BtreeCommit(Btree*);
    52     53   int sqlite3BtreeRollback(Btree*);
    53     54   int sqlite3BtreeBeginStmt(Btree*);
    54     55   int sqlite3BtreeCommitStmt(Btree*);
    55     56   int sqlite3BtreeRollbackStmt(Btree*);
    56     57   int sqlite3BtreeCreateTable(Btree*, int*, int flags);

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.239 2004/07/20 12:45:22 drh Exp $
           26  +** $Id: build.c,v 1.240 2004/07/22 01:19:35 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
   443    443   ** The token *pName contains the name of a database (either "main" or
   444    444   ** "temp" or the name of an attached db). This routine returns the
   445    445   ** index of the named database in db->aDb[], or -1 if the named db 
   446    446   ** does not exist.
   447    447   */
   448    448   int findDb(sqlite3 *db, Token *pName){
   449    449     int i;
   450         -  for(i=0; i<db->nDb; i++){
   451         -    if( pName->n==strlen(db->aDb[i].zName) && 
   452         -        0==sqlite3StrNICmp(db->aDb[i].zName, pName->z, pName->n) ){
          450  +  Db *pDb;
          451  +  for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){
          452  +    if( pName->n==strlen(pDb->zName) && 
          453  +        0==sqlite3StrNICmp(pDb->zName, pName->z, pName->n) ){
   453    454         return i;
   454    455       }
   455    456     }
   456    457     return -1;
   457    458   }
   458    459   
   459    460   /* The table or view or trigger name is passed to this routine via tokens
................................................................................
   470    471   **
   471    472   ** This routine sets the *ppUnqual pointer to point at the token (pName1 or
   472    473   ** pName2) that stores the unqualified table name.  The index of the
   473    474   ** database "xxx" is returned.
   474    475   */
   475    476   int sqlite3TwoPartName(
   476    477     Parse *pParse,      /* Parsing and code generating context */
   477         -  Token *pName1,      /* The "xxx" in the name "xxx.yyy" */
          478  +  Token *pName1,      /* The "xxx" in the name "xxx.yyy" or "xxx" */
   478    479     Token *pName2,      /* The "yyy" in the name "xxx.yyy" */
   479    480     Token **pUnqual     /* Write the unqualified object name here */
   480    481   ){
   481    482     int iDb;                    /* Database holding the object */
   482    483     sqlite3 *db = pParse->db;
   483    484   
   484    485     if( pName2 && pName2->n>0 ){

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.245 2004/07/19 17:25:25 drh Exp $
           17  +** $Id: main.c,v 1.246 2004/07/22 01:19:35 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
   817    817   ** This routine is called to create a connection to a database BTree
   818    818   ** driver.  If zFilename is the name of a file, then that file is
   819    819   ** opened and used.  If zFilename is the magic name ":memory:" then
   820    820   ** the database is stored in memory (and is thus forgotten as soon as
   821    821   ** the connection is closed.)  If zFilename is NULL then the database
   822    822   ** is for temporary use only and is deleted as soon as the connection
   823    823   ** is closed.
          824  +**
          825  +** A temporary database can be either a disk file (that is automatically
          826  +** deleted when the file is closed) or a set of red-black trees held in memory,
          827  +** depending on the values of the TEMP_STORE compile-time macro and the
          828  +** db->temp_store variable, according to the following chart:
          829  +**
          830  +**       TEMP_STORE     db->temp_store     Location of temporary database
          831  +**       ----------     --------------     ------------------------------
          832  +**           0               any             file
          833  +**           1                1              file
          834  +**           1                2              memory
          835  +**           1                0              file
          836  +**           2                1              file
          837  +**           2                2              memory
          838  +**           2                0              memory
          839  +**           3               any             memory
   824    840   */
   825    841   int sqlite3BtreeFactory(
   826    842     const sqlite *db,	    /* Main database when opening aux otherwise 0 */
   827    843     const char *zFilename,    /* Name of the file containing the BTree database */
   828    844     int omitJournal,          /* if TRUE then do not journal this file */
   829    845     int nCache,               /* How many pages in the page cache */
   830    846     Btree **ppBtree           /* Pointer to new Btree object written here */
   831    847   ){
   832    848     int btree_flags = 0;
          849  +  int rc;
          850  +  int useMem = 0;
   833    851     
   834    852     assert( ppBtree != 0);
   835    853     if( omitJournal ){
   836    854       btree_flags |= BTREE_OMIT_JOURNAL;
   837    855     }
   838         -  if( !zFilename || !strcmp(zFilename, ":memory:") ){
   839         -    /* If zFilename is NULL or the magic string ":memory:" then the
   840         -    ** new btree storest data in main memory, not a file.
   841         -    */
          856  +  if( zFilename==0 ){
          857  +#ifndef TEMP_STORE
          858  +# define TEMP_STORE 2
          859  +#endif
          860  +#if TEMP_STORE==0
          861  +    useMem = 0;
          862  +#endif
          863  +#if TEMP_STORE==1
          864  +    useMem = db->temp_store==2;
          865  +#endif
          866  +#if TEMP_STORE==2
          867  +    useMem = db->temp_store!=1;
          868  +#endif
          869  +#if TEMP_STORE==3
          870  +    useMem = 1;
          871  +#endif
          872  +  }
          873  +  if( (zFilename && strcmp(zFilename, ":memory:")==0)
          874  +         || (zFilename==0 && useMem) ){
   842    875       btree_flags |= BTREE_MEMORY;
   843    876     }
   844    877   
   845         -  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
   846         -      (void *)&db->busyHandler);
          878  +  rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
          879  +  if( rc==SQLITE_OK ){
          880  +    sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
          881  +    sqlite3BtreeSetCacheSize(*ppBtree, nCache);
          882  +  }
          883  +  return rc;
   847    884   }
   848    885   
   849    886   /*
   850    887   ** Return UTF-8 encoded English language explanation of the most recent
   851    888   ** error.
   852    889   */
   853    890   const char *sqlite3_errmsg(sqlite3 *db){

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.151 2004/07/20 12:45:22 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.152 2004/07/22 01:19:35 drh Exp $
    22     22   */
    23     23   #include "os.h"         /* Must be first to enable large file support */
    24     24   #include "sqliteInt.h"
    25     25   #include "pager.h"
    26     26   #include <assert.h>
    27     27   #include <string.h>
    28     28   
................................................................................
   126    126     u8 inJournal;                  /* TRUE if has been written to journal */
   127    127     u8 inStmt;                     /* TRUE if in the statement subjournal */
   128    128     u8 dirty;                      /* TRUE if we need to write back changes */
   129    129     u8 needSync;                   /* Sync journal before writing this page */
   130    130     u8 alwaysRollback;             /* Disable dont_rollback() for this page */
   131    131     short int nRef;                /* Number of users of this page */
   132    132     PgHdr *pDirty;                 /* Dirty pages sorted by PgHdr.pgno */
   133         -  /* SQLITE_PAGE_SIZE bytes of page data follow this header */
          133  +  /* pPager->pageSize bytes of page data follow this header */
   134    134     /* Pager.nExtra bytes of local data follow the page data */
   135    135   };
   136    136   
   137    137   /*
   138    138   ** For an in-memory only database, some extra information is recorded about
   139    139   ** each page so that changes can be rolled back.  (Journal files are not
   140    140   ** used for in-memory databases.)  The following information is added to
................................................................................
   162    162   
   163    163   /*
   164    164   ** Convert a pointer to a PgHdr into a pointer to its data
   165    165   ** and back again.
   166    166   */
   167    167   #define PGHDR_TO_DATA(P)  ((void*)(&(P)[1]))
   168    168   #define DATA_TO_PGHDR(D)  (&((PgHdr*)(D))[-1])
   169         -#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE])
          169  +#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize])
   170    170   #define PGHDR_TO_HIST(P,PGR)  \
   171    171               ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra])
   172    172   
   173    173   /*
   174    174   ** How big to make the hash table used for locating in-memory pages
   175    175   ** by page number.
   176    176   */
................................................................................
   258    258   ** file after power is restored.  If an attempt is then made
   259    259   ** to roll the journal back, the database could be corrupted.  The additional
   260    260   ** sanity checking data is an attempt to discover the garbage in the
   261    261   ** journal and ignore it.
   262    262   **
   263    263   ** The sanity checking information for the new journal format consists
   264    264   ** of a 32-bit checksum on each page of data.  The checksum covers both
   265         -** the page number and the SQLITE_PAGE_SIZE bytes of data for the page.
          265  +** the page number and the pPager->pageSize bytes of data for the page.
   266    266   ** This cksum is initialized to a 32-bit random value that appears in the
   267    267   ** journal file right after the header.  The random initializer is important,
   268    268   ** because garbage data that appears at the end of a journal is likely
   269    269   ** data that was once in other files that have now been deleted.  If the
   270    270   ** garbage data came from an obsolete journal file, the checksums might
   271    271   ** be correct.  But by initializing the checksum to random value which
   272    272   ** is different for every journal, we minimize that risk.
................................................................................
   828    828   ** need to survive power failures.
   829    829   */
   830    830   static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
   831    831     int rc;
   832    832     PgHdr *pPg;                   /* An existing page in the cache */
   833    833     Pgno pgno;                    /* The page number of a page in journal */
   834    834     u32 cksum;                    /* Checksum used for sanity checking */
   835         -  u8 aData[SQLITE_PAGE_SIZE];   /* Store data here */
          835  +  u8 aData[SQLITE_MAX_PAGE_SIZE];  /* Temp storage for a page */
   836    836   
   837    837     rc = read32bits(jfd, &pgno);
   838    838     if( rc!=SQLITE_OK ) return rc;
   839    839     rc = sqlite3OsRead(jfd, &aData, pPager->pageSize);
   840    840     if( rc!=SQLITE_OK ) return rc;
   841    841     pPager->journalOff += pPager->pageSize + 4;
   842    842   
................................................................................
   869    869     ** If in EXCLUSIVE state, then we update the pager cache if it exists
   870    870     ** and the main file. The page is then marked not dirty.
   871    871     */
   872    872     pPg = pager_lookup(pPager, pgno);
   873    873     assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
   874    874     TRACE2("PLAYBACK page %d\n", pgno);
   875    875     if( pPager->state>=PAGER_EXCLUSIVE ){
   876         -    sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
   877         -    rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE);
          876  +    sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)pPager->pageSize);
          877  +    rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
   878    878     }
   879    879     if( pPg ){
   880    880       /* No page should ever be rolled back that is in use, except for page
   881    881       ** 1 which is held in use in order to keep the lock on the database
   882    882       ** active.
   883    883       */
   884    884       void *pData;
................................................................................
   991    991   ** cache content and the easiest way to do that is to reread the old content
   992    992   ** back from the disk.
   993    993   */
   994    994   static int pager_reload_cache(Pager *pPager){
   995    995     PgHdr *pPg;
   996    996     int rc = SQLITE_OK;
   997    997     for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
   998         -    char zBuf[SQLITE_PAGE_SIZE];
          998  +    char zBuf[SQLITE_MAX_PAGE_SIZE];
   999    999       if( !pPg->dirty ) continue;
  1000   1000       if( (int)pPg->pgno <= pPager->origDbSize ){
  1001         -      sqlite3OsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
  1002         -      rc = sqlite3OsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE);
         1001  +      sqlite3OsSeek(&pPager->fd, pPager->pageSize*(off_t)(pPg->pgno-1));
         1002  +      rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
  1003   1003         TRACE2("REFETCH page %d\n", pPg->pgno);
  1004   1004         CODEC(pPager, zBuf, pPg->pgno, 2);
  1005   1005         if( rc ) break;
  1006   1006       }else{
  1007         -      memset(zBuf, 0, SQLITE_PAGE_SIZE);
         1007  +      memset(zBuf, 0, pPager->pageSize);
  1008   1008       }
  1009         -    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE) ){
  1010         -      memcpy(PGHDR_TO_DATA(pPg), zBuf, SQLITE_PAGE_SIZE);
         1009  +    if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
         1010  +      memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
  1011   1011         if( pPager->xReiniter ){
  1012   1012           pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
  1013   1013         }else{
  1014         -        memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
         1014  +        memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
  1015   1015         }
  1016   1016       }
  1017   1017       pPg->needSync = 0;
  1018   1018       pPg->dirty = 0;
  1019   1019     }
  1020   1020     return rc;
  1021   1021   }
................................................................................
  1134   1134       }
  1135   1135   
  1136   1136       /* If this is the first header read from the journal, truncate the
  1137   1137       ** database file back to it's original size.
  1138   1138       */
  1139   1139       if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
  1140   1140         assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
  1141         -      rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg);
         1141  +      rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)mxPg);
  1142   1142         if( rc!=SQLITE_OK ){
  1143   1143           goto end_playback;
  1144   1144         }
  1145   1145         pPager->dbSize = mxPg;
  1146   1146       }
  1147   1147   
  1148   1148       /* rc = sqlite3OsSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */
................................................................................
  1234   1234     if( !hdrOff ){
  1235   1235       hdrOff = szJ;
  1236   1236     }
  1237   1237     
  1238   1238   
  1239   1239     /* Truncate the database back to its original size.
  1240   1240     */
  1241         -  rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->stmtSize);
         1241  +  rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)pPager->stmtSize);
  1242   1242     pPager->dbSize = pPager->stmtSize;
  1243   1243   
  1244   1244     /* Figure out how many records are in the statement journal.
  1245   1245     */
  1246   1246     assert( pPager->stmtInUse && pPager->journalOpen );
  1247   1247     sqlite3OsSeek(&pPager->stfd, 0);
  1248   1248     nRec = pPager->stmtNRec;
................................................................................
  1392   1392   ** The file to be cached need not exist.  The file is not locked until
  1393   1393   ** the first call to sqlite3pager_get() and is only held open until the
  1394   1394   ** last page is released using sqlite3pager_unref().
  1395   1395   **
  1396   1396   ** If zFilename is NULL then a randomly-named temporary file is created
  1397   1397   ** and used as the file to be cached.  The file will be deleted
  1398   1398   ** automatically when it is closed.
         1399  +**
         1400  +** If zFilename is ":memory:" then all information is held in cache.
         1401  +** It is never written to disk.  This can be used to implement an
         1402  +** in-memory database.
  1399   1403   */
  1400   1404   int sqlite3pager_open(
  1401   1405     Pager **ppPager,         /* Return the Pager structure here */
  1402   1406     const char *zFilename,   /* Name of the database file to open */
  1403         -  int mxPage,              /* Max number of in-memory cache pages */
  1404   1407     int nExtra,              /* Extra bytes append to each in-memory page */
  1405         -  int useJournal,          /* TRUE to use a rollback journal on this file */
  1406         -  void  *pBusyHandler      /* Busy callback */
         1408  +  int useJournal           /* TRUE to use a rollback journal on this file */
  1407   1409   ){
  1408   1410     Pager *pPager;
  1409   1411     char *zFullPathname = 0;
  1410   1412     int nameLen;
  1411   1413     OsFile fd;
  1412   1414     int rc = SQLITE_OK;
  1413   1415     int i;
................................................................................
  1473   1475   #endif
  1474   1476     pPager->journalOpen = 0;
  1475   1477     pPager->useJournal = useJournal && !memDb;
  1476   1478     pPager->stmtOpen = 0;
  1477   1479     pPager->stmtInUse = 0;
  1478   1480     pPager->nRef = 0;
  1479   1481     pPager->dbSize = memDb-1;
  1480         -  pPager->pageSize = SQLITE_PAGE_SIZE;
         1482  +  pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
  1481   1483     pPager->stmtSize = 0;
  1482   1484     pPager->stmtJSize = 0;
  1483   1485     pPager->nPage = 0;
  1484         -  pPager->mxPage = mxPage>5 ? mxPage : 10;
         1486  +  pPager->mxPage = 100;
  1485   1487     pPager->state = PAGER_UNLOCK;
  1486   1488     pPager->errMask = 0;
  1487   1489     pPager->tempFile = tempFile;
  1488   1490     pPager->memDb = memDb;
  1489   1491     pPager->readOnly = readOnly;
  1490   1492     pPager->needSync = 0;
  1491   1493     pPager->noSync = pPager->tempFile || !useJournal;
  1492   1494     pPager->fullSync = (pPager->noSync?0:1);
  1493   1495     pPager->pFirst = 0;
  1494   1496     pPager->pFirstSynced = 0;
  1495   1497     pPager->pLast = 0;
  1496   1498     pPager->nExtra = nExtra;
  1497   1499     pPager->sectorSize = PAGER_SECTOR_SIZE;
  1498         -  pPager->pBusyHandler = (BusyHandler *)pBusyHandler;
         1500  +  pPager->pBusyHandler = 0;
  1499   1501     memset(pPager->aHash, 0, sizeof(pPager->aHash));
  1500   1502     *ppPager = pPager;
  1501   1503     return SQLITE_OK;
  1502   1504   }
         1505  +
         1506  +/*
         1507  +** Set the busy handler function.
         1508  +*/
         1509  +void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
         1510  +  pPager->pBusyHandler = pBusyHandler;
         1511  +}
  1503   1512   
  1504   1513   /*
  1505   1514   ** Set the destructor for this pager.  If not NULL, the destructor is called
  1506   1515   ** when the reference count on each page reaches zero.  The destructor can
  1507   1516   ** be used to clean up information in the extra segment appended to each page.
  1508   1517   **
  1509   1518   ** The destructor is not called as a result sqlite3pager_close().  
................................................................................
  1519   1528   ** value as a result of a rollback.  The callback gives higher-level code
  1520   1529   ** an opportunity to restore the EXTRA section to agree with the restored
  1521   1530   ** page data.
  1522   1531   */
  1523   1532   void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
  1524   1533     pPager->xReiniter = xReinit;
  1525   1534   }
         1535  +
         1536  +/*
         1537  +** Set the page size.
         1538  +**
         1539  +** The page size must only be changed when the cache is empty.
         1540  +*/
         1541  +void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
         1542  +  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
         1543  +  pPager->pageSize = pageSize;
         1544  +}
         1545  +
         1546  +/*
         1547  +** Read the first N bytes from the beginning of the file into memory
         1548  +** that pDest points to.  No error checking is done.
         1549  +*/
         1550  +void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
         1551  +  memset(pDest, 0, N);
         1552  +  if( pPager->memDb==0 ){
         1553  +    sqlite3OsSeek(&pPager->fd, 0);
         1554  +    sqlite3OsRead(&pPager->fd, pDest, N);
         1555  +  }
         1556  +}
  1526   1557   
  1527   1558   /*
  1528   1559   ** Return the total number of pages in the disk file associated with
  1529   1560   ** pPager.
  1530   1561   */
  1531   1562   int sqlite3pager_pagecount(Pager *pPager){
  1532   1563     off_t n;
................................................................................
  1534   1565     if( pPager->dbSize>=0 ){
  1535   1566       return pPager->dbSize;
  1536   1567     }
  1537   1568     if( sqlite3OsFileSize(&pPager->fd, &n)!=SQLITE_OK ){
  1538   1569       pPager->errMask |= PAGER_ERR_DISK;
  1539   1570       return 0;
  1540   1571     }
  1541         -  n /= SQLITE_PAGE_SIZE;
  1542         -  if( !pPager->memDb && n==PENDING_BYTE/SQLITE_PAGE_SIZE ){
         1572  +  n /= pPager->pageSize;
         1573  +  if( !pPager->memDb && n==PENDING_BYTE/pPager->pageSize ){
  1543   1574       n++;
  1544   1575     }
  1545   1576     if( pPager->state!=PAGER_UNLOCK ){
  1546   1577       pPager->dbSize = n;
  1547   1578     }
  1548   1579     return n;
  1549   1580   }
................................................................................
  1643   1674       memoryTruncate(pPager);
  1644   1675       return SQLITE_OK;
  1645   1676     }
  1646   1677     rc = syncJournal(pPager);
  1647   1678     if( rc!=SQLITE_OK ){
  1648   1679       return rc;
  1649   1680     }
  1650         -  rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)nPage);
         1681  +  rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)nPage);
  1651   1682     if( rc==SQLITE_OK ){
  1652   1683       pPager->dbSize = nPage;
  1653   1684     }
  1654   1685     return rc;
  1655   1686   }
  1656   1687   
  1657   1688   /*
................................................................................
  1910   1941     if( rc!=SQLITE_OK ){
  1911   1942       return rc;
  1912   1943     }
  1913   1944     pPager->state = PAGER_EXCLUSIVE;
  1914   1945   
  1915   1946     while( pList ){
  1916   1947       assert( pList->dirty );
  1917         -    sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_PAGE_SIZE);
         1948  +    sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(off_t)pPager->pageSize);
  1918   1949       CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
  1919   1950       TRACE2("STORE page %d\n", pList->pgno);
  1920         -    rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_PAGE_SIZE);
         1951  +    rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
  1921   1952       CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
  1922   1953       if( rc ) return rc;
  1923   1954       pList->dirty = 0;
  1924   1955       pList = pList->pDirty;
  1925   1956     }
  1926   1957     return SQLITE_OK;
  1927   1958   }
................................................................................
  2062   2093     }
  2063   2094     if( pPg==0 ){
  2064   2095       /* The requested page is not in the page cache. */
  2065   2096       int h;
  2066   2097       pPager->nMiss++;
  2067   2098       if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || pPager->memDb ){
  2068   2099         /* Create a new page */
  2069         -      pPg = sqliteMallocRaw( sizeof(*pPg) + SQLITE_PAGE_SIZE 
         2100  +      pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize 
  2070   2101                                 + sizeof(u32) + pPager->nExtra
  2071   2102                                 + pPager->memDb*sizeof(PgHistory) );
  2072   2103         if( pPg==0 ){
  2073   2104           if( !pPager->memDb ){
  2074   2105             pager_unwritelock(pPager);
  2075   2106           }
  2076   2107           pPager->errMask |= PAGER_ERR_MEM;
................................................................................
  2174   2205       pPg->pNextHash = pPager->aHash[h];
  2175   2206       pPager->aHash[h] = pPg;
  2176   2207       if( pPg->pNextHash ){
  2177   2208         assert( pPg->pNextHash->pPrevHash==0 );
  2178   2209         pPg->pNextHash->pPrevHash = pPg;
  2179   2210       }
  2180   2211       if( pPager->nExtra>0 ){
  2181         -      memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
         2212  +      memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
  2182   2213       }
  2183   2214       if( pPager->dbSize<0 ) sqlite3pager_pagecount(pPager);
  2184   2215       if( pPager->errMask!=0 ){
  2185   2216         sqlite3pager_unref(PGHDR_TO_DATA(pPg));
  2186   2217         rc = pager_errcode(pPager);
  2187   2218         return rc;
  2188   2219       }
  2189   2220       if( pPager->dbSize<(int)pgno ){
  2190         -      memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
         2221  +      memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
  2191   2222       }else{
  2192   2223         int rc;
  2193   2224         assert( pPager->memDb==0 );
  2194         -      sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE);
  2195         -      rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
         2225  +      sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)pPager->pageSize);
         2226  +      rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);
  2196   2227         TRACE2("FETCH page %d\n", pPg->pgno);
  2197   2228         CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
  2198   2229         if( rc!=SQLITE_OK ){
  2199   2230           off_t fileSize;
  2200   2231           if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
  2201         -               || fileSize>=pgno*SQLITE_PAGE_SIZE ){
         2232  +               || fileSize>=pgno*pPager->pageSize ){
  2202   2233             sqlite3pager_unref(PGHDR_TO_DATA(pPg));
  2203   2234             return rc;
  2204   2235           }else{
  2205         -          memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
         2236  +          memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
  2206   2237           }
  2207   2238         }
  2208   2239       }
  2209   2240     }else{
  2210   2241       /* The requested page is in the page cache. */
  2211   2242       pPager->nHit++;
  2212   2243       page_ref(pPg);
................................................................................
  2482   2513           pHist->pOrig = sqliteMallocRaw( pPager->pageSize );
  2483   2514           if( pHist->pOrig ){
  2484   2515             memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize);
  2485   2516           }
  2486   2517           pPg->inJournal = 1;
  2487   2518         }else{
  2488   2519           u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
  2489         -        saved = *(u32*)PGHDR_TO_EXTRA(pPg);
  2490         -        store32bits(cksum, pPg, SQLITE_PAGE_SIZE);
  2491         -        szPg = SQLITE_PAGE_SIZE+8;
         2520  +        saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
         2521  +        store32bits(cksum, pPg, pPager->pageSize);
         2522  +        szPg = pPager->pageSize+8;
  2492   2523           store32bits(pPg->pgno, pPg, -4);
  2493   2524           CODEC(pPager, pData, pPg->pgno, 7);
  2494   2525           rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
  2495   2526           pPager->journalOff += szPg;
  2496   2527           TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync);
  2497   2528           CODEC(pPager, pData, pPg->pgno, 0);
  2498         -        *(u32*)PGHDR_TO_EXTRA(pPg) = saved;
         2529  +        *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
  2499   2530           if( rc!=SQLITE_OK ){
  2500   2531             sqlite3pager_rollback(pPager);
  2501   2532             pPager->errMask |= PAGER_ERR_FULL;
  2502   2533             return rc;
  2503   2534           }
  2504   2535           pPager->nRec++;
  2505   2536           assert( pPager->aInJournal!=0 );
................................................................................
  2534   2565         if( pHist->pStmt ){
  2535   2566           memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
  2536   2567         }
  2537   2568         TRACE2("STMT-JOURNAL page %d\n", pPg->pgno);
  2538   2569       }else{
  2539   2570         store32bits(pPg->pgno, pPg, -4);
  2540   2571         CODEC(pPager, pData, pPg->pgno, 7);
  2541         -      rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, SQLITE_PAGE_SIZE+4);
         2572  +      rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, pPager->pageSize+4);
  2542   2573         TRACE2("STMT-JOURNAL page %d\n", pPg->pgno);
  2543   2574         CODEC(pPager, pData, pPg->pgno, 0);
  2544   2575         if( rc!=SQLITE_OK ){
  2545   2576           sqlite3pager_rollback(pPager);
  2546   2577           pPager->errMask |= PAGER_ERR_FULL;
  2547   2578           return rc;
  2548   2579         }
................................................................................
  2582   2613     void *pPage;
  2583   2614     int rc;
  2584   2615   
  2585   2616     rc = sqlite3pager_get(pPager, pgno, &pPage);
  2586   2617     if( rc==SQLITE_OK ){
  2587   2618       rc = sqlite3pager_write(pPage);
  2588   2619       if( rc==SQLITE_OK ){
  2589         -      memcpy(pPage, pData, SQLITE_PAGE_SIZE);
         2620  +      memcpy(pPage, pData, pPager->pageSize);
  2590   2621       }
  2591   2622       sqlite3pager_unref(pPage);
  2592   2623     }
  2593   2624     return rc;
  2594   2625   }
  2595   2626   
  2596   2627   /*

Changes to src/pager.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite page cache
    13     13   ** subsystem.  The page cache subsystem reads and writes a file a page
    14     14   ** at a time and provides a journal for rollback.
    15     15   **
    16         -** @(#) $Id: pager.h,v 1.36 2004/06/30 08:20:16 danielk1977 Exp $
           16  +** @(#) $Id: pager.h,v 1.37 2004/07/22 01:19:35 drh Exp $
    17     17   */
    18     18   
    19     19   /*
    20         -** The size of a page.
    21         -**
    22         -** You can change this value to another (reasonable) value you want.
    23         -** It need not be a power of two, though the interface to the disk
    24         -** will likely be faster if it is.
    25         -**
    26         -** Experiments show that a page size of 1024 gives the best speed
    27         -** for common usages.  The speed differences for different sizes
    28         -** such as 512, 2048, 4096, an so forth, is minimal.  Note, however,
    29         -** that changing the page size results in a completely imcompatible
    30         -** file format.
           20  +** The default size of a database page.
    31     21   */
    32         -#ifndef SQLITE_PAGE_SIZE
    33         -#define SQLITE_PAGE_SIZE 1024
           22  +#ifndef SQLITE_DEFAULT_PAGE_SIZE
           23  +# define SQLITE_DEFAULT_PAGE_SIZE 1024
    34     24   #endif
    35     25   
    36         -/*
    37         -** Number of extra bytes of data allocated at the end of each page and
    38         -** stored on disk but not used by the higher level btree layer.  Changing
    39         -** this value results in a completely incompatible file format.
           26  +/* Maximum page size.  The upper bound on this value is 65536 (a limit
           27  +** imposed by the 2-byte size of cell array pointers.)  The
           28  +** maximum page size determines the amount of stack space allocated
           29  +** by many of the routines in pager.c and btree.c  On embedded architectures
           30  +** or any machine where memory and especially stack memory is limited,
           31  +** one may wish to chose a smaller value for the maximum page size.
    40     32   */
    41         -#ifndef SQLITE_PAGE_RESERVE
    42         -#define SQLITE_PAGE_RESERVE 0
           33  +#ifndef SQLITE_MAX_PAGE_SIZE
           34  +# define SQLITE_MAX_PAGE_SIZE 8192
    43     35   #endif
    44     36   
    45         -/*
    46         -** The total number of usable bytes stored on disk for each page.
    47         -** The usable bytes come at the beginning of the page and the reserve
    48         -** bytes come at the end.
    49         -*/
    50         -#define SQLITE_USABLE_SIZE (SQLITE_PAGE_SIZE-SQLITE_PAGE_RESERVE)
    51         -
    52     37   /*
    53     38   ** Maximum number of pages in one database.
    54     39   */
    55     40   #define SQLITE_MAX_PAGE 1073741823
    56     41   
    57     42   /*
    58     43   ** The type used to represent a page number.  The first page in a file
................................................................................
    60     45   */
    61     46   typedef unsigned int Pgno;
    62     47   
    63     48   /*
    64     49   ** Each open file is managed by a separate instance of the "Pager" structure.
    65     50   */
    66     51   typedef struct Pager Pager;
           52  +
    67     53   
    68     54   /*
    69     55   ** See source code comments for a detailed description of the following
    70     56   ** routines:
    71     57   */
    72     58   int sqlite3pager_open(Pager **ppPager, const char *zFilename,
    73         -                     int nPage, int nExtra, int useJournal,
    74         -                     void *pBusyHandler);
           59  +                     int nExtra, int useJournal);
           60  +void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
    75     61   void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
    76     62   void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
           63  +void sqlite3pager_set_pagesize(Pager*, int);
           64  +void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
    77     65   void sqlite3pager_set_cachesize(Pager*, int);
    78     66   int sqlite3pager_close(Pager *pPager);
    79     67   int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
    80     68   void *sqlite3pager_lookup(Pager *pPager, Pgno pgno);
    81     69   int sqlite3pager_ref(void*);
    82     70   int sqlite3pager_unref(void*);
    83     71   Pgno sqlite3pager_pagenumber(void*);

Changes to src/pragma.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used to implement the PRAGMA command.
    13     13   **
    14         -** $Id: pragma.c,v 1.57 2004/06/30 09:49:24 danielk1977 Exp $
           14  +** $Id: pragma.c,v 1.58 2004/07/22 01:19:35 drh Exp $
    15     15   */
    16     16   #include "sqliteInt.h"
    17     17   #include <ctype.h>
    18     18   
    19     19   #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
    20     20   # include "pager.h"
    21     21   # include "btree.h"
................................................................................
    66     66       return atoi(z);
    67     67     }
    68     68     for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
    69     69       if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
    70     70     }
    71     71     return 1;
    72     72   }
           73  +
           74  +/*
           75  +** Interpret the given string as a temp db location. Return 1 for file
           76  +** backed temporary databases, 2 for the Red-Black tree in memory database
           77  +** and 0 to use the compile-time default.
           78  +*/
           79  +static int getTempStore(const char *z){
           80  +  if( z[0]>='0' && z[0]<='2' ){
           81  +    return z[0] - '0';
           82  +  }else if( sqlite3StrICmp(z, "file")==0 ){
           83  +    return 1;
           84  +  }else if( sqlite3StrICmp(z, "memory")==0 ){
           85  +    return 2;
           86  +  }else{
           87  +    return 0;
           88  +  }
           89  +}
           90  +
           91  +/*
           92  +** If the TEMP database is open, close it and mark the database schema
           93  +** as needing reloading.  This must be done when using the TEMP_STORE
           94  +** or DEFAULT_TEMP_STORE pragmas.
           95  +*/
           96  +static int changeTempStorage(Parse *pParse, const char *zStorageType){
           97  +  int ts = getTempStore(zStorageType);
           98  +  sqlite *db = pParse->db;
           99  +  if( db->temp_store==ts ) return SQLITE_OK;
          100  +  if( db->aDb[1].pBt!=0 ){
          101  +    if( db->flags & SQLITE_InTrans ){
          102  +      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
          103  +        "from within a transaction");
          104  +      return SQLITE_ERROR;
          105  +    }
          106  +    sqlite3BtreeClose(db->aDb[1].pBt);
          107  +    db->aDb[1].pBt = 0;
          108  +    sqlite3ResetInternalSchema(db, 0);
          109  +  }
          110  +  db->temp_store = ts;
          111  +  return SQLITE_OK;
          112  +}
          113  +
          114  +/*
          115  +** Generate code to return a single integer value.
          116  +*/
          117  +static void returnSingleInt(Vdbe *v, const char *zLabel, int value){
          118  +  sqlite3VdbeAddOp(v, OP_Integer, value, 0);
          119  +  sqlite3VdbeSetNumCols(v, 1);
          120  +  sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
          121  +  sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
          122  +}
    73    123   
    74    124   /*
    75    125   ** Check to see if zRight and zLeft refer to a pragma that queries
    76    126   ** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
    77    127   ** Also, implement the pragma.
    78    128   */
    79    129   static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
................................................................................
    95    145     for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
    96    146       if( sqlite3StrICmp(zLeft, aPragma[i].zName)==0 ){
    97    147         sqlite *db = pParse->db;
    98    148         Vdbe *v;
    99    149         if( zRight==0 ){
   100    150           v = sqlite3GetVdbe(pParse);
   101    151           if( v ){
   102         -          sqlite3VdbeSetNumCols(v, 1);
   103         -          sqlite3VdbeSetColName(v, 0, aPragma[i].zName, P3_STATIC);
   104         -          sqlite3VdbeAddOp(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0);
   105         -          sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
          152  +          returnSingleInt(v, aPragma[i].zName, (db->flags&aPragma[i].mask)!=0);
   106    153           }
   107    154         }else if( getBoolean(zRight) ){
   108    155           db->flags |= aPragma[i].mask;
   109    156         }else{
   110    157           db->flags &= ~aPragma[i].mask;
   111    158         }
   112    159         return 1;
................................................................................
   121    168   ** Pragmas are of this form:
   122    169   **
   123    170   **      PRAGMA [database.]id [= value]
   124    171   **
   125    172   ** The identifier might also be a string.  The value is a string, and
   126    173   ** identifier, or a number.  If minusFlag is true, then the value is
   127    174   ** a number that was preceded by a minus sign.
          175  +**
          176  +** If the left side is "database.id" then pId1 is the database name
          177  +** and pId2 is the id.  If the left side is just "id" then pId1 is the
          178  +** id and pId2 is any empty string.
   128    179   */
   129    180   void sqlite3Pragma(
   130    181     Parse *pParse, 
   131    182     Token *pId1,        /* First part of [database.]id field */
   132    183     Token *pId2,        /* Second part of [database.]id field, or NULL */
   133    184     Token *pValue,      /* Token for <value>, or NULL */
   134    185     int minusFlag       /* True if a '-' sign preceded <value> */
................................................................................
   135    186   ){
   136    187     char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
   137    188     char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
   138    189     const char *zDb = 0;   /* The database name */
   139    190     Token *pId;            /* Pointer to <id> token */
   140    191     int iDb;               /* Database index for <database> */
   141    192     sqlite *db = pParse->db;
          193  +  Db *pDb;
   142    194     Vdbe *v = sqlite3GetVdbe(pParse);
   143    195     if( v==0 ) return;
   144    196   
   145    197     /* Interpret the [database.] part of the pragma statement. iDb is the
   146    198     ** index of the database this pragma is being applied to in db.aDb[]. */
   147    199     iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
   148    200     if( iDb<0 ) return;
          201  +  pDb = &db->aDb[iDb];
   149    202   
   150    203     zLeft = sqlite3NameFromToken(pId);
   151    204     if( !zLeft ) return;
   152    205     if( minusFlag ){
   153    206       zRight = 0;
   154    207       sqlite3SetNString(&zRight, "-", 1, pValue->z, pValue->n, 0);
   155    208     }else{
   156    209       zRight = sqlite3NameFromToken(pValue);
   157    210     }
   158    211   
   159         -  zDb = ((iDb>0)?db->aDb[iDb].zName:0);
          212  +  zDb = ((iDb>0)?pDb->zName:0);
   160    213     if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
   161    214       goto pragma_out;
   162    215     }
   163    216    
   164    217     /*
   165         -  **  PRAGMA default_cache_size
   166         -  **  PRAGMA default_cache_size=N
          218  +  **  PRAGMA [database.]default_cache_size
          219  +  **  PRAGMA [database.]default_cache_size=N
   167    220     **
   168    221     ** The first form reports the current persistent setting for the
   169    222     ** page cache size.  The value returned is the maximum number of
   170    223     ** pages in the page cache.  The second form sets both the current
   171    224     ** page cache size value and the persistent page cache size value
   172    225     ** stored in the database file.
   173    226     **
................................................................................
   202    255         sqlite3VdbeAddOp(v, OP_Integer, size, 0);
   203    256         sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
   204    257         addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
   205    258         sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
   206    259         sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
   207    260         sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
   208    261         sqlite3EndWriteOperation(pParse);
   209         -      db->aDb[iDb].cache_size = size;
   210         -      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
          262  +      pDb->cache_size = size;
          263  +      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
          264  +    }
          265  +  }else
          266  +
          267  +  /*
          268  +  **  PRAGMA [database.]page_size
          269  +  **  PRAGMA [database.]page_size=N
          270  +  **
          271  +  ** The first form reports the current setting for the
          272  +  ** database page size in bytes.  The second form sets the
          273  +  ** database page size value.  The value can only be set if
          274  +  ** the database has not yet been created.
          275  +  */
          276  +  if( sqlite3StrICmp(zLeft,"page_size")==0 ){
          277  +    Btree *pBt = pDb->pBt;
          278  +    if( !zRight ){
          279  +      int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
          280  +      returnSingleInt(v, "page_size", size);
          281  +    }else{
          282  +      sqlite3BtreeSetPageSize(pBt, atoi(zRight), 0);
   211    283       }
   212    284     }else
   213    285   
   214    286     /*
   215         -  **  PRAGMA cache_size
   216         -  **  PRAGMA cache_size=N
          287  +  **  PRAGMA [database.]cache_size
          288  +  **  PRAGMA [database.]cache_size=N
   217    289     **
   218    290     ** The first form reports the current local setting for the
   219    291     ** page cache size.  The local setting can be different from
   220    292     ** the persistent cache size value that is stored in the database
   221    293     ** file itself.  The value returned is the maximum number of
   222    294     ** pages in the page cache.  The second form sets the local
   223    295     ** page cache size value.  It does not change the persistent
   224    296     ** cache size stored on the disk so the cache size will revert
   225    297     ** to its default value when the database is closed and reopened.
   226    298     ** N should be a positive integer.
   227    299     */
   228    300     if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
   229         -    static VdbeOpList getCacheSize[] = {
   230         -      { OP_Callback,    1, 0,        0},
   231         -    };
   232    301       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   233    302       if( !zRight ){
   234         -      int size = db->aDb[iDb].cache_size;
   235         -      assert( size>0 );
   236         -      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
   237         -      sqlite3VdbeSetNumCols(v, 1);
   238         -      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
   239         -      sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
          303  +      returnSingleInt(v, "cache_size", pDb->cache_size);
   240    304       }else{
   241    305         int size = atoi(zRight);
   242    306         if( size<0 ) size = -size;
   243         -      db->aDb[iDb].cache_size = size;
   244         -      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
          307  +      pDb->cache_size = size;
          308  +      sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
          309  +    }
          310  +  }else
          311  +
          312  +  /*
          313  +  **   PRAGMA temp_store
          314  +  **   PRAGMA temp_store = "default"|"memory"|"file"
          315  +  **
          316  +  ** Return or set the local value of the temp_store flag.  Changing
          317  +  ** the local value does not make changes to the disk file and the default
          318  +  ** value will be restored the next time the database is opened.
          319  +  **
          320  +  ** Note that it is possible for the library compile-time options to
          321  +  ** override this setting
          322  +  */
          323  +  if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
          324  +    if( !zRight ){
          325  +      returnSingleInt(v, "temp_store", db->temp_store);
          326  +    }else{
          327  +      changeTempStorage(pParse, zRight);
   245    328       }
   246    329     }else
   247    330   
   248    331     /*
   249         -  **   PRAGMA synchronous
   250         -  **   PRAGMA synchronous=OFF|ON|NORMAL|FULL
          332  +  **   PRAGMA [database.]synchronous
          333  +  **   PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
   251    334     **
   252    335     ** Return or set the local value of the synchronous flag.  Changing
   253    336     ** the local value does not make changes to the disk file and the
   254    337     ** default value will be restored the next time the database is
   255    338     ** opened.
   256    339     */
   257    340     if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
   258         -    static VdbeOpList getSync[] = {
   259         -      { OP_Callback,    1, 0,        0},
   260         -    };
   261    341       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   262    342       if( !zRight ){
   263         -      sqlite3VdbeSetNumCols(v, 1);
   264         -      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
   265         -      sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
   266         -      sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
          343  +      returnSingleInt(v, "synchronous", pDb->safety_level-1);
   267    344       }else{
   268    345         if( !db->autoCommit ){
   269    346           sqlite3ErrorMsg(pParse, 
   270    347               "Safety level may not be changed inside a transaction");
   271    348         }else{
   272         -        db->aDb[iDb].safety_level = getSafetyLevel(zRight)+1;
   273         -        sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt,db->aDb[iDb].safety_level);
          349  +        pDb->safety_level = getSafetyLevel(zRight)+1;
          350  +        sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
   274    351         }
   275    352       }
   276    353     }else
   277    354   
   278    355   #if 0  /* Used once during development.  No longer needed */
   279    356     if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){
   280    357       if( getBoolean(zRight) ){
................................................................................
   282    359       }else{
   283    360         sqlite3_always_code_trigger_setup = 0;
   284    361       }
   285    362     }else
   286    363   #endif
   287    364   
   288    365     if( flagPragma(pParse, zLeft, zRight) ){
   289         -    /* The flagPragma() call also generates any necessary code */
          366  +    /* The flagPragma() subroutine also generates any necessary code
          367  +    ** there is nothing more to do here */
   290    368     }else
   291    369   
   292    370     /*
   293    371     **   PRAGMA table_info(<table>)
   294    372     **
   295    373     ** Return a single row for each column of the named table. The columns of
   296    374     ** the returned data set are:

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.306 2004/07/20 12:45:22 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.307 2004/07/22 01:19:35 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   #include "config.h"
    20     20   #include "sqlite3.h"
    21     21   #include "hash.h"
................................................................................
   135    135   extern const int sqlite3one;
   136    136   #define SQLITE_BIGENDIAN    (*(char *)(&sqlite3one)==0)
   137    137   #define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
   138    138   
   139    139   typedef struct sqlite sqlite;
   140    140   
   141    141   /*
   142         -** Defer sourcing vdbe.h until after the "u8" typedef is defined.
          142  +** An instance of the following structure is used to store the busy-handler
          143  +** callback for a given sqlite handle. 
          144  +**
          145  +** The sqlite.busyHandler member of the sqlite struct contains the busy
          146  +** callback for the database handle. Each pager opened via the sqlite
          147  +** handle is passed a pointer to sqlite.busyHandler. The busy-handler
          148  +** callback is currently invoked only from within pager.c.
          149  +*/
          150  +typedef struct BusyHandler BusyHandler;
          151  +struct BusyHandler {
          152  +  int (*xFunc)(void *,int);  /* The busy callback */
          153  +  void *pArg;                /* First arg to busy callback */
          154  +};
          155  +
          156  +/*
          157  +** Defer sourcing vdbe.h and btree.h until after the "u8" and 
          158  +** "BusyHandler typedefs.
   143    159   */
   144    160   #include "vdbe.h"
   145    161   #include "btree.h"
   146    162   
   147    163   /*
   148    164   ** This macro casts a pointer to an integer.  Useful for doing
   149    165   ** pointer arithmetic.
................................................................................
   258    274   typedef struct TriggerStack TriggerStack;
   259    275   typedef struct FKey FKey;
   260    276   typedef struct Db Db;
   261    277   typedef struct AuthContext AuthContext;
   262    278   typedef struct KeyClass KeyClass;
   263    279   typedef struct CollSeq CollSeq;
   264    280   typedef struct KeyInfo KeyInfo;
   265         -typedef struct BusyHandler BusyHandler;
   266    281   
   267    282   /*
   268    283   ** Each database file to be accessed by the system is an instance
   269    284   ** of the following structure.  There are normally two of these structures
   270    285   ** in the sqlite.aDb[] array.  aDb[0] is the main database file and
   271    286   ** aDb[1] is the database file used to hold temporary tables.  Additional
   272    287   ** databases may be attached.
................................................................................
   275    290     char *zName;         /* Name of this database */
   276    291     Btree *pBt;          /* The B*Tree structure for this database file */
   277    292     int schema_cookie;   /* Database schema version number for this file */
   278    293     Hash tblHash;        /* All tables indexed by name */
   279    294     Hash idxHash;        /* All (named) indices indexed by name */
   280    295     Hash trigHash;       /* All triggers indexed by name */
   281    296     Hash aFKey;          /* Foreign keys indexed by to-table */
   282         -  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   283    297     u16 flags;           /* Flags associated with this database */
          298  +  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   284    299     u8 safety_level;     /* How aggressive at synching data to disk */
   285    300     int cache_size;      /* Number of pages to use in the cache */
   286    301     void *pAux;          /* Auxiliary data.  Usually NULL */
   287    302     void (*xFreeAux)(void*);  /* Routine to free pAux */
   288    303   };
   289    304   
   290    305   /*
................................................................................
   307    322   ** changes and so the view will need to be reset.
   308    323   */
   309    324   #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
   310    325   #define DB_UnresetViews    0x0002  /* Some views have defined column names */
   311    326   
   312    327   #define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
   313    328   
   314         -/*
   315         -** An instance of the following structure is used to store the busy-handler
   316         -** callback for a given sqlite handle. 
   317         -**
   318         -** The sqlite.busyHandler member of the sqlite struct contains the busy
   319         -** callback for the database handle. Each pager opened via the sqlite
   320         -** handle is passed a pointer to sqlite.busyHandler. The busy-handler
   321         -** callback is currently invoked only from within pager.c.
   322         -*/
   323         -struct BusyHandler {
   324         -  int (*xFunc)(void *,int);  /* The busy callback */
   325         -  void *pArg;                /* First arg to busy callback */
   326         -};
   327         -
   328    329   /*
   329    330   ** Each database is an instance of the following structure.
   330    331   **
   331    332   ** The sqlite.lastRowid records the last insert rowid generated by an
   332    333   ** insert statement.  Inserts on views do not affect its value.  Each
   333    334   ** trigger has its own context, so that lastRowid can be updated inside
   334    335   ** triggers as usual.  The previous value will be restored once the trigger
................................................................................
   353    354   */
   354    355   struct sqlite {
   355    356     int nDb;                      /* Number of backends currently in use */
   356    357     Db *aDb;                      /* All backends */
   357    358     Db aDbStatic[2];              /* Static space for the 2 default backends */
   358    359     int flags;                    /* Miscellanous flags. See below */
   359    360     u8 file_format;               /* What file format version is this database? */
          361  +  u8 temp_store;                /* 1: file 2: memory 0: default */
   360    362     int nTable;                   /* Number of tables in the database */
   361    363     BusyHandler busyHandler;      /* Busy callback */
   362    364     void *pCommitArg;             /* Argument to xCommitCallback() */   
   363    365     int (*xCommitCallback)(void*);/* Invoked at every commit. */
   364    366     Hash aFunc;                   /* All functions that can be in SQL exprs */
   365    367     Hash aCollSeq;                /* All collating sequences */
   366    368     CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
................................................................................
  1327   1329   # define sqlite3AuthCheck(a,b,c,d,e)    SQLITE_OK
  1328   1330   # define sqlite3AuthContextPush(a,b,c)
  1329   1331   # define sqlite3AuthContextPop(a)  ((void)(a))
  1330   1332   #endif
  1331   1333   void sqlite3Attach(Parse*, Token*, Token*, Token*);
  1332   1334   void sqlite3Detach(Parse*, Token*);
  1333   1335   int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
  1334         -                       int mode, int nPg, Btree **ppBtree);
         1336  +                       int omitJournal, int nCache, Btree **ppBtree);
  1335   1337   int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
  1336   1338   int sqlite3FixSrcList(DbFixer*, SrcList*);
  1337   1339   int sqlite3FixSelect(DbFixer*, Select*);
  1338   1340   int sqlite3FixExpr(DbFixer*, Expr*);
  1339   1341   int sqlite3FixExprList(DbFixer*, ExprList*);
  1340   1342   int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
  1341   1343   double sqlite3AtoF(const char *z, const char **);

Changes to src/test2.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the pager.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test2.c,v 1.23 2004/06/21 18:14:47 drh Exp $
           16  +** $Id: test2.c,v 1.24 2004/07/22 01:19:35 drh Exp $
    17     17   */
    18     18   #include "os.h"
    19     19   #include "sqliteInt.h"
    20     20   #include "pager.h"
    21     21   #include "tcl.h"
    22     22   #include <stdlib.h>
    23     23   #include <string.h>
................................................................................
    51     51       case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    52     52       case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    53     53       default:                zName = "SQLITE_Unknown";     break;
    54     54     }
    55     55     return zName;
    56     56   }
    57     57   
           58  +/*
           59  +** Page size and reserved size used for testing.
           60  +*/
           61  +static int test_pagesize = 1024;
           62  +
    58     63   /*
    59     64   ** Usage:   pager_open FILENAME N-PAGE
    60     65   **
    61     66   ** Open a new pager
    62     67   */
    63     68   static int pager_open(
    64     69     void *NotUsed,
................................................................................
    72     77     char zBuf[100];
    73     78     if( argc!=3 ){
    74     79       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    75     80          " FILENAME N-PAGE\"", 0);
    76     81       return TCL_ERROR;
    77     82     }
    78     83     if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
    79         -  rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1, 0);
           84  +  rc = sqlite3pager_open(&pPager, argv[1], 0, 1);
    80     85     if( rc!=SQLITE_OK ){
    81     86       Tcl_AppendResult(interp, errorName(rc), 0);
    82     87       return TCL_ERROR;
    83     88     }
           89  +  sqlite3pager_set_cachesize(pPager, nPage);
           90  +  sqlite3pager_set_pagesize(pPager, test_pagesize);
    84     91     sprintf(zBuf,"0x%x",(int)pPager);
    85     92     Tcl_AppendResult(interp, zBuf, 0);
    86     93     return TCL_OK;
    87     94   }
    88     95   
    89     96   /*
    90     97   ** Usage:   pager_close ID
................................................................................
   464    471     }
   465    472     if( Tcl_GetInt(interp, argv[1], (int*)&pPage) ) return TCL_ERROR;
   466    473     rc = sqlite3pager_write(pPage);
   467    474     if( rc!=SQLITE_OK ){
   468    475       Tcl_AppendResult(interp, errorName(rc), 0);
   469    476       return TCL_ERROR;
   470    477     }
   471         -  strncpy((char*)pPage, argv[2], SQLITE_USABLE_SIZE-1);
   472         -  ((char*)pPage)[SQLITE_USABLE_SIZE-1] = 0;
          478  +  strncpy((char*)pPage, argv[2], test_pagesize-1);
          479  +  ((char*)pPage)[test_pagesize-1] = 0;
   473    480     return TCL_OK;
   474    481   }
   475    482   
   476    483   /*
   477    484   ** Usage:   fake_big_file  N  FILENAME
   478    485   **
   479    486   ** Write a few bytes at the N megabyte point of FILENAME.  This will
................................................................................
   522    529   }
   523    530   
   524    531   /*
   525    532   ** Register commands with the TCL interpreter.
   526    533   */
   527    534   int Sqlitetest2_Init(Tcl_Interp *interp){
   528    535     extern int sqlite3_io_error_pending;
   529         -  char zBuf[100];
   530    536     static struct {
   531    537       char *zName;
   532    538       Tcl_CmdProc *xProc;
   533    539     } aCmd[] = {
   534    540       { "pager_open",              (Tcl_CmdProc*)pager_open          },
   535    541       { "pager_close",             (Tcl_CmdProc*)pager_close         },
   536    542       { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
................................................................................
   550    556     };
   551    557     int i;
   552    558     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
   553    559       Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
   554    560     }
   555    561     Tcl_LinkVar(interp, "sqlite_io_error_pending",
   556    562        (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
   557         -  sprintf(zBuf, "%d", SQLITE_PAGE_SIZE);
   558         -  Tcl_SetVar(interp, "SQLITE_PAGE_SIZE", zBuf, TCL_GLOBAL_ONLY); 
   559         -  sprintf(zBuf, "%d", SQLITE_PAGE_RESERVE);
   560         -  Tcl_SetVar(interp, "SQLITE_PAGE_RESERVE", zBuf, TCL_GLOBAL_ONLY); 
   561         -  sprintf(zBuf, "%d", SQLITE_USABLE_SIZE);
   562         -  Tcl_SetVar(interp, "SQLITE_USABLE_SIZE", zBuf, TCL_GLOBAL_ONLY); 
          563  +  Tcl_LinkVar(interp, "pager_pagesize",
          564  +     (char*)&test_pagesize, TCL_LINK_INT);
   563    565     return TCL_OK;
   564    566   }

Changes to src/test3.c.

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