1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Initial implementation of variable page sizes and the temp_store pragma. (CVS 1843)

FossilOrigin-Name: 4cf6e9db757931aba2f300b7869305434d6f2d2b
This commit is contained in:
drh
2004-07-22 01:19:35 +00:00
parent 900dfba8ef
commit 90f5ecb39d
13 changed files with 387 additions and 216 deletions

View File

@@ -1,5 +1,5 @@
C Updates\scomments\sin\ssqlite.h.in\sthat\sdescribe\sthe\sdestructor\sparameter\nto\ssqlite3_bind_....\s(CVS\s1842) C Initial\simplementation\sof\svariable\spage\ssizes\sand\sthe\stemp_store\spragma.\s(CVS\s1843)
D 2004-07-21T15:21:36 D 2004-07-22T01:19:35
F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b F Makefile.in 4a5e570a9e2d35b09c31b3cf01b78cea764ade4b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -25,11 +25,11 @@ F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F sqlite3.def 7610bb4092dcfa7db8fe6d9a92d3e51adce23566 F sqlite3.def 7610bb4092dcfa7db8fe6d9a92d3e51adce23566
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c 5e37aaac0907edad5da8ba785b94f04fbb4003d7 F src/attach.c 9e3fcd504aa5760b3d95f4a0bceca075ca1c96a7
F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217 F src/auth.c 60db23b98bb94c8b0178180faaf49dc116674217
F src/btree.c 23d4cbe6f612a77738caa636c48dd38e1efdfd76 F src/btree.c 385dceb1ac0eb8bac6e60ad371c8c8ba809438d8
F src/btree.h 934d0ad30b5b419e9291a11da878be349df2277e F src/btree.h 02fd2c26b739f38e43493f52f381d9e7d688bb8e
F src/build.c a4b1e80b13c570c7c962f500fa58045450b5a0cd F src/build.c 3a1356286569266873d5d1c910e7797a3bfd5761
F src/date.c e1bb384a7856c18dce9cadb0afbe6934ba5ddb00 F src/date.c e1bb384a7856c18dce9cadb0afbe6934ba5ddb00
F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3 F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
@@ -39,7 +39,7 @@ F src/hash.c f0a2f22c2a7052d67053b5f4690ea3010bb3fb9f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18 F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
F src/main.c 4f3c3f0f9e9aa6d6595d6fcb0d3cdd4d31191554 F src/main.c 447db2fb6121360814afd725ee93c22d6eef8e7f
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345 F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21 F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21
@@ -51,21 +51,21 @@ F src/os_unix.c 02a08065f90ca2737514cdc19d60eb3c4b98fa6b
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 54181eb73cb4783c4241feca9eaa490768b39008 F src/os_win.c 54181eb73cb4783c4241feca9eaa490768b39008
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
F src/pager.c 53a310a7539c7550dc7cbad8e46c62926a40fb31 F src/pager.c 1354e8f80889a8c967f4bc4ee2723485624eb6e7
F src/pager.h 269b6cfc114dba0148203446e41dd19f9647dd53 F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
F src/parse.y 1c22ccb2b60237a7263873892a4d580ea5e53536 F src/parse.y 1c22ccb2b60237a7263873892a4d580ea5e53536
F src/pragma.c 8326df8c400f573eb43004dfb8e53e5102acb3e4 F src/pragma.c c8be18093f0492f9983406647808781ca0073d8b
F src/printf.c 36090f6d7b4946539de97c1850675ce55ef66c16 F src/printf.c 36090f6d7b4946539de97c1850675ce55ef66c16
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c aefda626660086addca4ce85c34aeef5d0f44c25 F src/select.c aefda626660086addca4ce85c34aeef5d0f44c25
F src/shell.c ebec5da57ea401f4886eefc790917b939d94d595 F src/shell.c ebec5da57ea401f4886eefc790917b939d94d595
F src/sqlite.h.in f43cde2bf8a92c09653358f30b2312424464ed37 F src/sqlite.h.in f43cde2bf8a92c09653358f30b2312424464ed37
F src/sqliteInt.h 788b13a74c421ab68068ab7fe50ec68ee22db1be F src/sqliteInt.h 17ed61c040c1e47e1dd660daef3adda9ea9cb4fb
F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49 F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49
F src/tclsqlite.c 62848128011e59291902c6e5c6f910c05956fcbb F src/tclsqlite.c 62848128011e59291902c6e5c6f910c05956fcbb
F src/test1.c 004885b49a7b5a594192f137c671135920f64c94 F src/test1.c 004885b49a7b5a594192f137c671135920f64c94
F src/test2.c dafd8bd314a554bf376c6d3a8c83fd69219f5a40 F src/test2.c f4c2f3928f1998fd8cb75a81e33a60e025ea85d4
F src/test3.c d0c56667e89f79ad0f060fdf010d1c34a4bc2988 F src/test3.c 8576bb977937265e2c1a4d3fab3793e1974153e8
F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2 F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1 F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
F src/tokenize.c 900374b6b37f04748bcd48c2d29a41c251542935 F src/tokenize.c 900374b6b37f04748bcd48c2d29a41c251542935
@@ -237,7 +237,7 @@ F www/tclsqlite.tcl 06a86cba4d7fc88e2bcd633b57702d3d16abebb5
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P df306ad9ee522b20f017be0be83d9e071d525f8e P 166eb60614d958674469d6661c694aa5955ada7b
R ae7b12b9273ae356dcc22ade3f89aa5e R 870b048870db5bdcb9c6b07388f49a9f
U drh U drh
Z 985db816d659e2b46dad451a399fdfd0 Z f55d5698fe1367622b023c25ee34d112

View File

@@ -1 +1 @@
166eb60614d958674469d6661c694aa5955ada7b 4cf6e9db757931aba2f300b7869305434d6f2d2b

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands. ** This file contains code used to implement the ATTACH and DETACH commands.
** **
** $Id: attach.c,v 1.22 2004/07/19 00:56:24 drh Exp $ ** $Id: attach.c,v 1.23 2004/07/22 01:19:35 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -91,19 +91,15 @@ void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey)
sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
} }
#if SQLITE_HAS_CODEC #if SQLITE_HAS_CODEC
{ assert( pKey!=0 );
extern int sqliteCodecAttach(sqlite*, int, void*, int); if( pKey->n>0 ){
extern int sqlite3CodecAttach(sqlite*, int, void*, int);
char *zKey = 0; char *zKey = 0;
int nKey; int nKey;
if( pKey && pKey->z && pKey->n ){ sqlite3BtreeSetPageSize(aNew->pBt, -1, 4);
sqlite3SetNString(&zKey, pKey->z, pKey->n, 0); sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
sqlite3Dequote(zKey); zKey = sqlite3NameFromToken(pKey);
nKey = strlen(zKey); nKey = strlen(zKey);
}else{
zKey = 0;
nKey = 0;
}
sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
} }
#endif #endif
sqliteFree(zFile); sqliteFree(zFile);

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** May you share freely, never taking more than you give.
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.177 2004/07/20 12:45:22 drh Exp $ ** $Id: btree.c,v 1.178 2004/07/22 01:19:35 drh Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** For a detailed discussion of BTrees, refer to
@@ -211,27 +211,16 @@
#include <assert.h> #include <assert.h>
/* Maximum page size. The upper bound on this value is 65536 (a limit
** imposed by the 2-byte size of cell array pointers.) The
** maximum page size determines the amount of stack space allocated
** by many of the routines in this module. On embedded architectures
** or any machine where memory and especially stack memory is limited,
** one may wish to chose a smaller value for the maximum page size.
*/
#ifndef MX_PAGE_SIZE
# define MX_PAGE_SIZE 1024
#endif
/* The following value is the maximum cell size assuming a maximum page /* The following value is the maximum cell size assuming a maximum page
** size give above. ** size give above.
*/ */
#define MX_CELL_SIZE (MX_PAGE_SIZE-8) #define MX_CELL_SIZE (SQLITE_MAX_PAGE_SIZE-8)
/* The maximum number of cells on a single page of the database. This /* The maximum number of cells on a single page of the database. This
** assumes a minimum cell size of 3 bytes. Such small cells will be ** assumes a minimum cell size of 3 bytes. Such small cells will be
** exceedingly rare, but they are possible. ** exceedingly rare, but they are possible.
*/ */
#define MX_CELL ((MX_PAGE_SIZE-8)/3) #define MX_CELL ((SQLITE_MAX_PAGE_SIZE-8)/3)
/* Forward declarations */ /* Forward declarations */
typedef struct MemPage MemPage; typedef struct MemPage MemPage;
@@ -308,6 +297,7 @@ struct Btree {
u8 maxEmbedFrac; /* Maximum payload as % of total page size */ u8 maxEmbedFrac; /* Maximum payload as % of total page size */
u8 minEmbedFrac; /* Minimum payload as % of total page size */ u8 minEmbedFrac; /* Minimum payload as % of total page size */
u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 minLeafFrac; /* Minimum leaf payload as % of total page size */
u8 pageSizeFixed; /* True if the page size can no longer be changed */
u16 pageSize; /* Total number of bytes on a page */ u16 pageSize; /* Total number of bytes on a page */
u16 usableSize; /* Number of usable bytes on each page */ u16 usableSize; /* Number of usable bytes on each page */
int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */
@@ -532,7 +522,7 @@ static void _pageIntegrity(MemPage *pPage){
int i, j, idx, c, pc, hdr, nFree; int i, j, idx, c, pc, hdr, nFree;
int cellOffset; int cellOffset;
int nCell, cellLimit; int nCell, cellLimit;
u8 used[MX_PAGE_SIZE]; u8 used[SQLITE_MAX_PAGE_SIZE];
usableSize = pPage->pBt->usableSize; usableSize = pPage->pBt->usableSize;
assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] ); assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
@@ -616,11 +606,11 @@ static void defragmentPage(MemPage *pPage){
int brk; /* Offset to the cell content area */ int brk; /* Offset to the cell content area */
int nCell; /* Number of cells on the page */ int nCell; /* Number of cells on the page */
unsigned char *data; /* The page data */ unsigned char *data; /* The page data */
unsigned char temp[MX_PAGE_SIZE]; /* Temp holding area for cell content */ unsigned char temp[SQLITE_MAX_PAGE_SIZE]; /* Temp area for cell content */
assert( sqlite3pager_iswriteable(pPage->aData) ); assert( sqlite3pager_iswriteable(pPage->aData) );
assert( pPage->pBt!=0 ); assert( pPage->pBt!=0 );
assert( pPage->pBt->usableSize <= MX_PAGE_SIZE ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
assert( pPage->nOverflow==0 ); assert( pPage->nOverflow==0 );
data = pPage->aData; data = pPage->aData;
hdr = pPage->hdrOffset; hdr = pPage->hdrOffset;
@@ -857,7 +847,7 @@ static int initPage(
while( pc>0 ){ while( pc>0 ){
int next, size; int next, size;
if( pc>=usableSize ) return SQLITE_CORRUPT; if( pc>=usableSize ) return SQLITE_CORRUPT;
if( i++>MX_PAGE_SIZE ) return SQLITE_CORRUPT; if( i++>SQLITE_MAX_PAGE_SIZE ) return SQLITE_CORRUPT;
next = get2byte(&data[pc]); next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]); size = get2byte(&data[pc+2]);
if( next>0 && next<=pc+size+3 ) return SQLITE_CORRUPT; if( next>0 && next<=pc+size+3 ) return SQLITE_CORRUPT;
@@ -998,12 +988,12 @@ static void pageReinit(void *pData, int pageSize){
int sqlite3BtreeOpen( int sqlite3BtreeOpen(
const char *zFilename, /* Name of the file containing the BTree database */ const char *zFilename, /* Name of the file containing the BTree database */
Btree **ppBtree, /* Pointer to new Btree object written here */ Btree **ppBtree, /* Pointer to new Btree object written here */
int nCache, /* Number of cache pages */ int flags /* Options */
int flags, /* Options */
void *pBusyHandler /* Busy callback info passed to pager layer */
){ ){
Btree *pBt; Btree *pBt;
int rc; int rc;
int nReserve;
unsigned char zDbHeader[100];
/* /*
** The following asserts make sure that structures used by the btree are ** The following asserts make sure that structures used by the btree are
@@ -1023,9 +1013,8 @@ int sqlite3BtreeOpen(
*ppBtree = 0; *ppBtree = 0;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
if( nCache<10 ) nCache = 10; rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE,
rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE, (flags & BTREE_OMIT_JOURNAL)==0);
(flags & BTREE_OMIT_JOURNAL)==0, pBusyHandler);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
if( pBt->pPager ) sqlite3pager_close(pBt->pPager); if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
sqliteFree(pBt); sqliteFree(pBt);
@@ -1037,12 +1026,23 @@ int sqlite3BtreeOpen(
pBt->pCursor = 0; pBt->pCursor = 0;
pBt->pPage1 = 0; pBt->pPage1 = 0;
pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager); pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
pBt->pageSize = SQLITE_PAGE_SIZE; /* FIX ME - read from header */ sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
pBt->usableSize = pBt->pageSize; pBt->pageSize = get2byte(&zDbHeader[16]);
pBt->maxEmbedFrac = 64; /* FIX ME - read from header */ if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE ){
pBt->minEmbedFrac = 32; /* FIX ME - read from header */ pBt->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
pBt->minLeafFrac = 32; /* FIX ME - read from header */ pBt->maxEmbedFrac = 64; /* 25% */
pBt->minEmbedFrac = 32; /* 12.5% */
pBt->minLeafFrac = 32; /* 12.5% */
nReserve = 0;
}else{
nReserve = zDbHeader[20];
pBt->maxEmbedFrac = zDbHeader[21];
pBt->minEmbedFrac = zDbHeader[22];
pBt->minLeafFrac = zDbHeader[23];
pBt->pageSizeFixed = 1;
}
pBt->usableSize = pBt->pageSize - nReserve;
sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize);
*ppBtree = pBt; *ppBtree = pBt;
return SQLITE_OK; return SQLITE_OK;
} }
@@ -1059,6 +1059,14 @@ int sqlite3BtreeClose(Btree *pBt){
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Change the busy handler callback function.
*/
int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){
sqlite3pager_set_busyhandler(pBt->pPager, pHandler);
return SQLITE_OK;
}
/* /*
** Change the limit on the number of pages allowed in the cache. ** Change the limit on the number of pages allowed in the cache.
** **
@@ -1092,6 +1100,31 @@ int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Change the default pages size and the number of reserved bytes per page.
*/
int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){
if( pBt->pageSizeFixed ){
return SQLITE_READONLY;
}
if( nReserve<0 ){
nReserve = pBt->pageSize - pBt->usableSize;
}
if( pageSize>512 && pageSize<SQLITE_MAX_PAGE_SIZE ){
pBt->pageSize = pageSize;
sqlite3pager_set_pagesize(pBt->pPager, pageSize);
}
pBt->usableSize = pBt->pageSize - nReserve;
return SQLITE_OK;
}
/*
** Return the currently defined page size
*/
int sqlite3BtreeGetPageSize(Btree *pBt){
return pBt->pageSize;
}
/* /*
** Get a reference to pPage1 of the database file. This will ** Get a reference to pPage1 of the database file. This will
** also acquire a readlock on that file. ** also acquire a readlock on that file.
@@ -1154,6 +1187,7 @@ static int lockBtree(Btree *pBt){
} }
assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE ); assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE );
pBt->pPage1 = pPage1; pBt->pPage1 = pPage1;
pBt->pageSizeFixed = 1;
return SQLITE_OK; return SQLITE_OK;
page1_init_failed: page1_init_failed:
@@ -2863,8 +2897,8 @@ static int balance_nonroot(MemPage *pPage){
int szNew[NB+2]; /* Combined size of cells place on i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */
u8 *apCell[(MX_CELL+2)*NB]; /* All cells from pages being balanced */ u8 *apCell[(MX_CELL+2)*NB]; /* All cells from pages being balanced */
int szCell[(MX_CELL+2)*NB]; /* Local size of all cells */ int szCell[(MX_CELL+2)*NB]; /* Local size of all cells */
u8 aCopy[NB][MX_PAGE_SIZE+sizeof(MemPage)]; /* Space for apCopy[] */ u8 aCopy[NB][SQLITE_MAX_PAGE_SIZE+sizeof(MemPage)]; /* Space for apCopy[] */
u8 aSpace[MX_PAGE_SIZE*5]; /* Space to copies of divider cells */ u8 aSpace[SQLITE_MAX_PAGE_SIZE*5]; /* Space to copies of divider cells */
/* /*
** Find the parent page. ** Find the parent page.
@@ -4042,7 +4076,7 @@ static int checkTreePage(
int maxLocal, usableSize; int maxLocal, usableSize;
char zMsg[100]; char zMsg[100];
char zContext[100]; char zContext[100];
char hit[MX_PAGE_SIZE]; char hit[SQLITE_MAX_PAGE_SIZE];
/* Check that the page exists /* Check that the page exists
*/ */

View File

@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description ** subsystem. See comments in the source code for a detailed description
** of what each interface routine does. ** of what each interface routine does.
** **
** @(#) $Id: btree.h,v 1.55 2004/06/26 08:38:25 danielk1977 Exp $ ** @(#) $Id: btree.h,v 1.56 2004/07/22 01:19:35 drh Exp $
*/ */
#ifndef _BTREE_H_ #ifndef _BTREE_H_
#define _BTREE_H_ #define _BTREE_H_
@@ -31,11 +31,9 @@ typedef struct BtCursor BtCursor;
int sqlite3BtreeOpen( int sqlite3BtreeOpen(
const char *zFilename, const char *zFilename, /* Name of database file to open */
Btree **, Btree **, /* Return open Btree* here */
int nCache, int flags /* Flags */
int flags,
void *pBusyHandler
); );
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
@@ -45,8 +43,11 @@ int sqlite3BtreeOpen(
#define BTREE_MEMORY 2 /* In-memory DB. No argument */ #define BTREE_MEMORY 2 /* In-memory DB. No argument */
int sqlite3BtreeClose(Btree*); int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetSafetyLevel(Btree*,int); int sqlite3BtreeSetSafetyLevel(Btree*,int);
int sqlite3BtreeSetPageSize(Btree*,int,int);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeBeginTrans(Btree*,int);
int sqlite3BtreeCommit(Btree*); int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*); int sqlite3BtreeRollback(Btree*);

View File

@@ -23,7 +23,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** PRAGMA
** **
** $Id: build.c,v 1.239 2004/07/20 12:45:22 drh Exp $ ** $Id: build.c,v 1.240 2004/07/22 01:19:35 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -447,9 +447,10 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){
*/ */
int findDb(sqlite3 *db, Token *pName){ int findDb(sqlite3 *db, Token *pName){
int i; int i;
for(i=0; i<db->nDb; i++){ Db *pDb;
if( pName->n==strlen(db->aDb[i].zName) && for(pDb=db->aDb, i=0; i<db->nDb; i++, pDb++){
0==sqlite3StrNICmp(db->aDb[i].zName, pName->z, pName->n) ){ if( pName->n==strlen(pDb->zName) &&
0==sqlite3StrNICmp(pDb->zName, pName->z, pName->n) ){
return i; return i;
} }
} }
@@ -474,7 +475,7 @@ int findDb(sqlite3 *db, Token *pName){
*/ */
int sqlite3TwoPartName( int sqlite3TwoPartName(
Parse *pParse, /* Parsing and code generating context */ Parse *pParse, /* Parsing and code generating context */
Token *pName1, /* The "xxx" in the name "xxx.yyy" */ Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */
Token *pName2, /* The "yyy" in the name "xxx.yyy" */ Token *pName2, /* The "yyy" in the name "xxx.yyy" */
Token **pUnqual /* Write the unqualified object name here */ Token **pUnqual /* Write the unqualified object name here */
){ ){

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** accessed by users of the library.
** **
** $Id: main.c,v 1.245 2004/07/19 17:25:25 drh Exp $ ** $Id: main.c,v 1.246 2004/07/22 01:19:35 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -821,6 +821,22 @@ void *sqlite3_commit_hook(
** the connection is closed.) If zFilename is NULL then the database ** the connection is closed.) If zFilename is NULL then the database
** is for temporary use only and is deleted as soon as the connection ** is for temporary use only and is deleted as soon as the connection
** is closed. ** is closed.
**
** A temporary database can be either a disk file (that is automatically
** deleted when the file is closed) or a set of red-black trees held in memory,
** depending on the values of the TEMP_STORE compile-time macro and the
** db->temp_store variable, according to the following chart:
**
** TEMP_STORE db->temp_store Location of temporary database
** ---------- -------------- ------------------------------
** 0 any file
** 1 1 file
** 1 2 memory
** 1 0 file
** 2 1 file
** 2 2 memory
** 2 0 memory
** 3 any memory
*/ */
int sqlite3BtreeFactory( int sqlite3BtreeFactory(
const sqlite *db, /* Main database when opening aux otherwise 0 */ const sqlite *db, /* Main database when opening aux otherwise 0 */
@@ -830,20 +846,41 @@ int sqlite3BtreeFactory(
Btree **ppBtree /* Pointer to new Btree object written here */ Btree **ppBtree /* Pointer to new Btree object written here */
){ ){
int btree_flags = 0; int btree_flags = 0;
int rc;
int useMem = 0;
assert( ppBtree != 0); assert( ppBtree != 0);
if( omitJournal ){ if( omitJournal ){
btree_flags |= BTREE_OMIT_JOURNAL; btree_flags |= BTREE_OMIT_JOURNAL;
} }
if( !zFilename || !strcmp(zFilename, ":memory:") ){ if( zFilename==0 ){
/* If zFilename is NULL or the magic string ":memory:" then the #ifndef TEMP_STORE
** new btree storest data in main memory, not a file. # define TEMP_STORE 2
*/ #endif
#if TEMP_STORE==0
useMem = 0;
#endif
#if TEMP_STORE==1
useMem = db->temp_store==2;
#endif
#if TEMP_STORE==2
useMem = db->temp_store!=1;
#endif
#if TEMP_STORE==3
useMem = 1;
#endif
}
if( (zFilename && strcmp(zFilename, ":memory:")==0)
|| (zFilename==0 && useMem) ){
btree_flags |= BTREE_MEMORY; btree_flags |= BTREE_MEMORY;
} }
return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags, rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags);
(void *)&db->busyHandler); if( rc==SQLITE_OK ){
sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
sqlite3BtreeSetCacheSize(*ppBtree, nCache);
}
return rc;
} }
/* /*

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while ** file simultaneously, or one process from reading the database while
** another is writing. ** another is writing.
** **
** @(#) $Id: pager.c,v 1.151 2004/07/20 12:45:22 drh Exp $ ** @(#) $Id: pager.c,v 1.152 2004/07/22 01:19:35 drh Exp $
*/ */
#include "os.h" /* Must be first to enable large file support */ #include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -130,7 +130,7 @@ struct PgHdr {
u8 alwaysRollback; /* Disable dont_rollback() for this page */ u8 alwaysRollback; /* Disable dont_rollback() for this page */
short int nRef; /* Number of users of this page */ short int nRef; /* Number of users of this page */
PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */
/* SQLITE_PAGE_SIZE bytes of page data follow this header */ /* pPager->pageSize bytes of page data follow this header */
/* Pager.nExtra bytes of local data follow the page data */ /* Pager.nExtra bytes of local data follow the page data */
}; };
@@ -166,7 +166,7 @@ struct PgHistory {
*/ */
#define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[SQLITE_PAGE_SIZE]) #define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize])
#define PGHDR_TO_HIST(P,PGR) \ #define PGHDR_TO_HIST(P,PGR) \
((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra])
@@ -262,7 +262,7 @@ struct Pager {
** **
** The sanity checking information for the new journal format consists ** The sanity checking information for the new journal format consists
** of a 32-bit checksum on each page of data. The checksum covers both ** of a 32-bit checksum on each page of data. The checksum covers both
** the page number and the SQLITE_PAGE_SIZE bytes of data for the page. ** the page number and the pPager->pageSize bytes of data for the page.
** This cksum is initialized to a 32-bit random value that appears in the ** This cksum is initialized to a 32-bit random value that appears in the
** journal file right after the header. The random initializer is important, ** journal file right after the header. The random initializer is important,
** because garbage data that appears at the end of a journal is likely ** because garbage data that appears at the end of a journal is likely
@@ -832,7 +832,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
PgHdr *pPg; /* An existing page in the cache */ PgHdr *pPg; /* An existing page in the cache */
Pgno pgno; /* The page number of a page in journal */ Pgno pgno; /* The page number of a page in journal */
u32 cksum; /* Checksum used for sanity checking */ u32 cksum; /* Checksum used for sanity checking */
u8 aData[SQLITE_PAGE_SIZE]; /* Store data here */ u8 aData[SQLITE_MAX_PAGE_SIZE]; /* Temp storage for a page */
rc = read32bits(jfd, &pgno); rc = read32bits(jfd, &pgno);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
@@ -873,8 +873,8 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){
assert( pPager->state>=PAGER_EXCLUSIVE || pPg ); assert( pPager->state>=PAGER_EXCLUSIVE || pPg );
TRACE2("PLAYBACK page %d\n", pgno); TRACE2("PLAYBACK page %d\n", pgno);
if( pPager->state>=PAGER_EXCLUSIVE ){ if( pPager->state>=PAGER_EXCLUSIVE ){
sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE); sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)pPager->pageSize);
rc = sqlite3OsWrite(&pPager->fd, aData, SQLITE_PAGE_SIZE); rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize);
} }
if( pPg ){ if( pPg ){
/* No page should ever be rolled back that is in use, except for page /* No page should ever be rolled back that is in use, except for page
@@ -995,23 +995,23 @@ static int pager_reload_cache(Pager *pPager){
PgHdr *pPg; PgHdr *pPg;
int rc = SQLITE_OK; int rc = SQLITE_OK;
for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
char zBuf[SQLITE_PAGE_SIZE]; char zBuf[SQLITE_MAX_PAGE_SIZE];
if( !pPg->dirty ) continue; if( !pPg->dirty ) continue;
if( (int)pPg->pgno <= pPager->origDbSize ){ if( (int)pPg->pgno <= pPager->origDbSize ){
sqlite3OsSeek(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1)); sqlite3OsSeek(&pPager->fd, pPager->pageSize*(off_t)(pPg->pgno-1));
rc = sqlite3OsRead(&pPager->fd, zBuf, SQLITE_PAGE_SIZE); rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize);
TRACE2("REFETCH page %d\n", pPg->pgno); TRACE2("REFETCH page %d\n", pPg->pgno);
CODEC(pPager, zBuf, pPg->pgno, 2); CODEC(pPager, zBuf, pPg->pgno, 2);
if( rc ) break; if( rc ) break;
}else{ }else{
memset(zBuf, 0, SQLITE_PAGE_SIZE); memset(zBuf, 0, pPager->pageSize);
} }
if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE) ){ if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), pPager->pageSize) ){
memcpy(PGHDR_TO_DATA(pPg), zBuf, SQLITE_PAGE_SIZE); memcpy(PGHDR_TO_DATA(pPg), zBuf, pPager->pageSize);
if( pPager->xReiniter ){ if( pPager->xReiniter ){
pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize); pPager->xReiniter(PGHDR_TO_DATA(pPg), pPager->pageSize);
}else{ }else{
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra); memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
} }
} }
pPg->needSync = 0; pPg->needSync = 0;
@@ -1138,7 +1138,7 @@ static int pager_playback(Pager *pPager){
*/ */
if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg ); assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)mxPg); rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)mxPg);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto end_playback; goto end_playback;
} }
@@ -1238,7 +1238,7 @@ static int pager_stmt_playback(Pager *pPager){
/* Truncate the database back to its original size. /* Truncate the database back to its original size.
*/ */
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)pPager->stmtSize); rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)pPager->stmtSize);
pPager->dbSize = pPager->stmtSize; pPager->dbSize = pPager->stmtSize;
/* Figure out how many records are in the statement journal. /* Figure out how many records are in the statement journal.
@@ -1396,14 +1396,16 @@ static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
** If zFilename is NULL then a randomly-named temporary file is created ** If zFilename is NULL then a randomly-named temporary file is created
** and used as the file to be cached. The file will be deleted ** and used as the file to be cached. The file will be deleted
** automatically when it is closed. ** automatically when it is closed.
**
** If zFilename is ":memory:" then all information is held in cache.
** It is never written to disk. This can be used to implement an
** in-memory database.
*/ */
int sqlite3pager_open( int sqlite3pager_open(
Pager **ppPager, /* Return the Pager structure here */ Pager **ppPager, /* Return the Pager structure here */
const char *zFilename, /* Name of the database file to open */ const char *zFilename, /* Name of the database file to open */
int mxPage, /* Max number of in-memory cache pages */
int nExtra, /* Extra bytes append to each in-memory page */ int nExtra, /* Extra bytes append to each in-memory page */
int useJournal, /* TRUE to use a rollback journal on this file */ int useJournal /* TRUE to use a rollback journal on this file */
void *pBusyHandler /* Busy callback */
){ ){
Pager *pPager; Pager *pPager;
char *zFullPathname = 0; char *zFullPathname = 0;
@@ -1477,11 +1479,11 @@ int sqlite3pager_open(
pPager->stmtInUse = 0; pPager->stmtInUse = 0;
pPager->nRef = 0; pPager->nRef = 0;
pPager->dbSize = memDb-1; pPager->dbSize = memDb-1;
pPager->pageSize = SQLITE_PAGE_SIZE; pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;
pPager->stmtSize = 0; pPager->stmtSize = 0;
pPager->stmtJSize = 0; pPager->stmtJSize = 0;
pPager->nPage = 0; pPager->nPage = 0;
pPager->mxPage = mxPage>5 ? mxPage : 10; pPager->mxPage = 100;
pPager->state = PAGER_UNLOCK; pPager->state = PAGER_UNLOCK;
pPager->errMask = 0; pPager->errMask = 0;
pPager->tempFile = tempFile; pPager->tempFile = tempFile;
@@ -1495,12 +1497,19 @@ int sqlite3pager_open(
pPager->pLast = 0; pPager->pLast = 0;
pPager->nExtra = nExtra; pPager->nExtra = nExtra;
pPager->sectorSize = PAGER_SECTOR_SIZE; pPager->sectorSize = PAGER_SECTOR_SIZE;
pPager->pBusyHandler = (BusyHandler *)pBusyHandler; pPager->pBusyHandler = 0;
memset(pPager->aHash, 0, sizeof(pPager->aHash)); memset(pPager->aHash, 0, sizeof(pPager->aHash));
*ppPager = pPager; *ppPager = pPager;
return SQLITE_OK; return SQLITE_OK;
} }
/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
pPager->pBusyHandler = pBusyHandler;
}
/* /*
** Set the destructor for this pager. If not NULL, the destructor is called ** Set the destructor for this pager. If not NULL, the destructor is called
** when the reference count on each page reaches zero. The destructor can ** when the reference count on each page reaches zero. The destructor can
@@ -1524,6 +1533,28 @@ void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){
pPager->xReiniter = xReinit; pPager->xReiniter = xReinit;
} }
/*
** Set the page size.
**
** The page size must only be changed when the cache is empty.
*/
void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){
assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
pPager->pageSize = pageSize;
}
/*
** Read the first N bytes from the beginning of the file into memory
** that pDest points to. No error checking is done.
*/
void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
memset(pDest, 0, N);
if( pPager->memDb==0 ){
sqlite3OsSeek(&pPager->fd, 0);
sqlite3OsRead(&pPager->fd, pDest, N);
}
}
/* /*
** Return the total number of pages in the disk file associated with ** Return the total number of pages in the disk file associated with
** pPager. ** pPager.
@@ -1538,8 +1569,8 @@ int sqlite3pager_pagecount(Pager *pPager){
pPager->errMask |= PAGER_ERR_DISK; pPager->errMask |= PAGER_ERR_DISK;
return 0; return 0;
} }
n /= SQLITE_PAGE_SIZE; n /= pPager->pageSize;
if( !pPager->memDb && n==PENDING_BYTE/SQLITE_PAGE_SIZE ){ if( !pPager->memDb && n==PENDING_BYTE/pPager->pageSize ){
n++; n++;
} }
if( pPager->state!=PAGER_UNLOCK ){ if( pPager->state!=PAGER_UNLOCK ){
@@ -1647,7 +1678,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
return rc; return rc;
} }
rc = sqlite3OsTruncate(&pPager->fd, SQLITE_PAGE_SIZE*(off_t)nPage); rc = sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(off_t)nPage);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
pPager->dbSize = nPage; pPager->dbSize = nPage;
} }
@@ -1914,10 +1945,10 @@ static int pager_write_pagelist(PgHdr *pList){
while( pList ){ while( pList ){
assert( pList->dirty ); assert( pList->dirty );
sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(off_t)SQLITE_PAGE_SIZE); sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(off_t)pPager->pageSize);
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
TRACE2("STORE page %d\n", pList->pgno); TRACE2("STORE page %d\n", pList->pgno);
rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), SQLITE_PAGE_SIZE); rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize);
CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
if( rc ) return rc; if( rc ) return rc;
pList->dirty = 0; pList->dirty = 0;
@@ -2066,7 +2097,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
pPager->nMiss++; pPager->nMiss++;
if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || pPager->memDb ){ if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || pPager->memDb ){
/* Create a new page */ /* Create a new page */
pPg = sqliteMallocRaw( sizeof(*pPg) + SQLITE_PAGE_SIZE pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize
+ sizeof(u32) + pPager->nExtra + sizeof(u32) + pPager->nExtra
+ pPager->memDb*sizeof(PgHistory) ); + pPager->memDb*sizeof(PgHistory) );
if( pPg==0 ){ if( pPg==0 ){
@@ -2178,7 +2209,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
pPg->pNextHash->pPrevHash = pPg; pPg->pNextHash->pPrevHash = pPg;
} }
if( pPager->nExtra>0 ){ if( pPager->nExtra>0 ){
memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra); memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
} }
if( pPager->dbSize<0 ) sqlite3pager_pagecount(pPager); if( pPager->dbSize<0 ) sqlite3pager_pagecount(pPager);
if( pPager->errMask!=0 ){ if( pPager->errMask!=0 ){
@@ -2187,22 +2218,22 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
return rc; return rc;
} }
if( pPager->dbSize<(int)pgno ){ if( pPager->dbSize<(int)pgno ){
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE); memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
}else{ }else{
int rc; int rc;
assert( pPager->memDb==0 ); assert( pPager->memDb==0 );
sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)SQLITE_PAGE_SIZE); sqlite3OsSeek(&pPager->fd, (pgno-1)*(off_t)pPager->pageSize);
rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE); rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize);
TRACE2("FETCH page %d\n", pPg->pgno); TRACE2("FETCH page %d\n", pPg->pgno);
CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
off_t fileSize; off_t fileSize;
if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK if( sqlite3OsFileSize(&pPager->fd,&fileSize)!=SQLITE_OK
|| fileSize>=pgno*SQLITE_PAGE_SIZE ){ || fileSize>=pgno*pPager->pageSize ){
sqlite3pager_unref(PGHDR_TO_DATA(pPg)); sqlite3pager_unref(PGHDR_TO_DATA(pPg));
return rc; return rc;
}else{ }else{
memset(PGHDR_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE); memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
} }
} }
} }
@@ -2486,16 +2517,16 @@ int sqlite3pager_write(void *pData){
pPg->inJournal = 1; pPg->inJournal = 1;
}else{ }else{
u32 cksum = pager_cksum(pPager, pPg->pgno, pData); u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
saved = *(u32*)PGHDR_TO_EXTRA(pPg); saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager);
store32bits(cksum, pPg, SQLITE_PAGE_SIZE); store32bits(cksum, pPg, pPager->pageSize);
szPg = SQLITE_PAGE_SIZE+8; szPg = pPager->pageSize+8;
store32bits(pPg->pgno, pPg, -4); store32bits(pPg->pgno, pPg, -4);
CODEC(pPager, pData, pPg->pgno, 7); CODEC(pPager, pData, pPg->pgno, 7);
rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
pPager->journalOff += szPg; pPager->journalOff += szPg;
TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync); TRACE3("JOURNAL page %d needSync=%d\n", pPg->pgno, pPg->needSync);
CODEC(pPager, pData, pPg->pgno, 0); CODEC(pPager, pData, pPg->pgno, 0);
*(u32*)PGHDR_TO_EXTRA(pPg) = saved; *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved;
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
sqlite3pager_rollback(pPager); sqlite3pager_rollback(pPager);
pPager->errMask |= PAGER_ERR_FULL; pPager->errMask |= PAGER_ERR_FULL;
@@ -2538,7 +2569,7 @@ int sqlite3pager_write(void *pData){
}else{ }else{
store32bits(pPg->pgno, pPg, -4); store32bits(pPg->pgno, pPg, -4);
CODEC(pPager, pData, pPg->pgno, 7); CODEC(pPager, pData, pPg->pgno, 7);
rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, SQLITE_PAGE_SIZE+4); rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, pPager->pageSize+4);
TRACE2("STMT-JOURNAL page %d\n", pPg->pgno); TRACE2("STMT-JOURNAL page %d\n", pPg->pgno);
CODEC(pPager, pData, pPg->pgno, 0); CODEC(pPager, pData, pPg->pgno, 0);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
@@ -2586,7 +2617,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3pager_write(pPage); rc = sqlite3pager_write(pPage);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
memcpy(pPage, pData, SQLITE_PAGE_SIZE); memcpy(pPage, pData, pPager->pageSize);
} }
sqlite3pager_unref(pPage); sqlite3pager_unref(pPage);
} }

View File

@@ -13,42 +13,27 @@
** subsystem. The page cache subsystem reads and writes a file a page ** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback. ** at a time and provides a journal for rollback.
** **
** @(#) $Id: pager.h,v 1.36 2004/06/30 08:20:16 danielk1977 Exp $ ** @(#) $Id: pager.h,v 1.37 2004/07/22 01:19:35 drh Exp $
*/ */
/* /*
** The size of a page. ** The default size of a database page.
**
** You can change this value to another (reasonable) value you want.
** It need not be a power of two, though the interface to the disk
** will likely be faster if it is.
**
** Experiments show that a page size of 1024 gives the best speed
** for common usages. The speed differences for different sizes
** such as 512, 2048, 4096, an so forth, is minimal. Note, however,
** that changing the page size results in a completely imcompatible
** file format.
*/ */
#ifndef SQLITE_PAGE_SIZE #ifndef SQLITE_DEFAULT_PAGE_SIZE
#define SQLITE_PAGE_SIZE 1024 # define SQLITE_DEFAULT_PAGE_SIZE 1024
#endif #endif
/* /* Maximum page size. The upper bound on this value is 65536 (a limit
** Number of extra bytes of data allocated at the end of each page and ** imposed by the 2-byte size of cell array pointers.) The
** stored on disk but not used by the higher level btree layer. Changing ** maximum page size determines the amount of stack space allocated
** this value results in a completely incompatible file format. ** by many of the routines in pager.c and btree.c On embedded architectures
** or any machine where memory and especially stack memory is limited,
** one may wish to chose a smaller value for the maximum page size.
*/ */
#ifndef SQLITE_PAGE_RESERVE #ifndef SQLITE_MAX_PAGE_SIZE
#define SQLITE_PAGE_RESERVE 0 # define SQLITE_MAX_PAGE_SIZE 8192
#endif #endif
/*
** The total number of usable bytes stored on disk for each page.
** The usable bytes come at the beginning of the page and the reserve
** bytes come at the end.
*/
#define SQLITE_USABLE_SIZE (SQLITE_PAGE_SIZE-SQLITE_PAGE_RESERVE)
/* /*
** Maximum number of pages in one database. ** Maximum number of pages in one database.
*/ */
@@ -65,15 +50,18 @@ typedef unsigned int Pgno;
*/ */
typedef struct Pager Pager; typedef struct Pager Pager;
/* /*
** See source code comments for a detailed description of the following ** See source code comments for a detailed description of the following
** routines: ** routines:
*/ */
int sqlite3pager_open(Pager **ppPager, const char *zFilename, int sqlite3pager_open(Pager **ppPager, const char *zFilename,
int nPage, int nExtra, int useJournal, int nExtra, int useJournal);
void *pBusyHandler); void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
void sqlite3pager_set_pagesize(Pager*, int);
void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
void sqlite3pager_set_cachesize(Pager*, int); void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager); int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage); int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** This file contains code used to implement the PRAGMA command. ** This file contains code used to implement the PRAGMA command.
** **
** $Id: pragma.c,v 1.57 2004/06/30 09:49:24 danielk1977 Exp $ ** $Id: pragma.c,v 1.58 2004/07/22 01:19:35 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -71,6 +71,56 @@ static int getSafetyLevel(char *z){
return 1; return 1;
} }
/*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/
static int getTempStore(const char *z){
if( z[0]>='0' && z[0]<='2' ){
return z[0] - '0';
}else if( sqlite3StrICmp(z, "file")==0 ){
return 1;
}else if( sqlite3StrICmp(z, "memory")==0 ){
return 2;
}else{
return 0;
}
}
/*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading. This must be done when using the TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/
static int changeTempStorage(Parse *pParse, const char *zStorageType){
int ts = getTempStore(zStorageType);
sqlite *db = pParse->db;
if( db->temp_store==ts ) return SQLITE_OK;
if( db->aDb[1].pBt!=0 ){
if( db->flags & SQLITE_InTrans ){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
}
sqlite3BtreeClose(db->aDb[1].pBt);
db->aDb[1].pBt = 0;
sqlite3ResetInternalSchema(db, 0);
}
db->temp_store = ts;
return SQLITE_OK;
}
/*
** Generate code to return a single integer value.
*/
static void returnSingleInt(Vdbe *v, const char *zLabel, int value){
sqlite3VdbeAddOp(v, OP_Integer, value, 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, zLabel, P3_STATIC);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
}
/* /*
** Check to see if zRight and zLeft refer to a pragma that queries ** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags. Return 1 if so and 0 if not. ** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
@@ -99,10 +149,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
if( zRight==0 ){ if( zRight==0 ){
v = sqlite3GetVdbe(pParse); v = sqlite3GetVdbe(pParse);
if( v ){ if( v ){
sqlite3VdbeSetNumCols(v, 1); returnSingleInt(v, aPragma[i].zName, (db->flags&aPragma[i].mask)!=0);
sqlite3VdbeSetColName(v, 0, aPragma[i].zName, P3_STATIC);
sqlite3VdbeAddOp(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
} }
}else if( getBoolean(zRight) ){ }else if( getBoolean(zRight) ){
db->flags |= aPragma[i].mask; db->flags |= aPragma[i].mask;
@@ -125,6 +172,10 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
** The identifier might also be a string. The value is a string, and ** The identifier might also be a string. The value is a string, and
** identifier, or a number. If minusFlag is true, then the value is ** identifier, or a number. If minusFlag is true, then the value is
** a number that was preceded by a minus sign. ** a number that was preceded by a minus sign.
**
** If the left side is "database.id" then pId1 is the database name
** and pId2 is the id. If the left side is just "id" then pId1 is the
** id and pId2 is any empty string.
*/ */
void sqlite3Pragma( void sqlite3Pragma(
Parse *pParse, Parse *pParse,
@@ -139,6 +190,7 @@ void sqlite3Pragma(
Token *pId; /* Pointer to <id> token */ Token *pId; /* Pointer to <id> token */
int iDb; /* Database index for <database> */ int iDb; /* Database index for <database> */
sqlite *db = pParse->db; sqlite *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse); Vdbe *v = sqlite3GetVdbe(pParse);
if( v==0 ) return; if( v==0 ) return;
@@ -146,6 +198,7 @@ void sqlite3Pragma(
** index of the database this pragma is being applied to in db.aDb[]. */ ** index of the database this pragma is being applied to in db.aDb[]. */
iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
if( iDb<0 ) return; if( iDb<0 ) return;
pDb = &db->aDb[iDb];
zLeft = sqlite3NameFromToken(pId); zLeft = sqlite3NameFromToken(pId);
if( !zLeft ) return; if( !zLeft ) return;
@@ -156,14 +209,14 @@ void sqlite3Pragma(
zRight = sqlite3NameFromToken(pValue); zRight = sqlite3NameFromToken(pValue);
} }
zDb = ((iDb>0)?db->aDb[iDb].zName:0); zDb = ((iDb>0)?pDb->zName:0);
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
goto pragma_out; goto pragma_out;
} }
/* /*
** PRAGMA default_cache_size ** PRAGMA [database.]default_cache_size
** PRAGMA default_cache_size=N ** PRAGMA [database.]default_cache_size=N
** **
** The first form reports the current persistent setting for the ** The first form reports the current persistent setting for the
** page cache size. The value returned is the maximum number of ** page cache size. The value returned is the maximum number of
@@ -206,14 +259,33 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
sqlite3EndWriteOperation(pParse); sqlite3EndWriteOperation(pParse);
db->aDb[iDb].cache_size = size; pDb->cache_size = size;
sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
} }
}else }else
/* /*
** PRAGMA cache_size ** PRAGMA [database.]page_size
** PRAGMA cache_size=N ** PRAGMA [database.]page_size=N
**
** The first form reports the current setting for the
** database page size in bytes. The second form sets the
** database page size value. The value can only be set if
** the database has not yet been created.
*/
if( sqlite3StrICmp(zLeft,"page_size")==0 ){
Btree *pBt = pDb->pBt;
if( !zRight ){
int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0;
returnSingleInt(v, "page_size", size);
}else{
sqlite3BtreeSetPageSize(pBt, atoi(zRight), 0);
}
}else
/*
** PRAGMA [database.]cache_size
** PRAGMA [database.]cache_size=N
** **
** The first form reports the current local setting for the ** The first form reports the current local setting for the
** page cache size. The local setting can be different from ** page cache size. The local setting can be different from
@@ -226,28 +298,39 @@ void sqlite3Pragma(
** N should be a positive integer. ** N should be a positive integer.
*/ */
if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
static VdbeOpList getCacheSize[] = {
{ OP_Callback, 1, 0, 0},
};
if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( !zRight ){ if( !zRight ){
int size = db->aDb[iDb].cache_size; returnSingleInt(v, "cache_size", pDb->cache_size);
assert( size>0 );
sqlite3VdbeAddOp(v, OP_Integer, size, 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
}else{ }else{
int size = atoi(zRight); int size = atoi(zRight);
if( size<0 ) size = -size; if( size<0 ) size = -size;
db->aDb[iDb].cache_size = size; pDb->cache_size = size;
sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
} }
}else }else
/* /*
** PRAGMA synchronous ** PRAGMA temp_store
** PRAGMA synchronous=OFF|ON|NORMAL|FULL ** PRAGMA temp_store = "default"|"memory"|"file"
**
** Return or set the local value of the temp_store flag. Changing
** the local value does not make changes to the disk file and the default
** value will be restored the next time the database is opened.
**
** Note that it is possible for the library compile-time options to
** override this setting
*/
if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
if( !zRight ){
returnSingleInt(v, "temp_store", db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
}else
/*
** PRAGMA [database.]synchronous
** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
** **
** Return or set the local value of the synchronous flag. Changing ** Return or set the local value of the synchronous flag. Changing
** the local value does not make changes to the disk file and the ** the local value does not make changes to the disk file and the
@@ -255,22 +338,16 @@ void sqlite3Pragma(
** opened. ** opened.
*/ */
if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
static VdbeOpList getSync[] = {
{ OP_Callback, 1, 0, 0},
};
if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( !zRight ){ if( !zRight ){
sqlite3VdbeSetNumCols(v, 1); returnSingleInt(v, "synchronous", pDb->safety_level-1);
sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
}else{ }else{
if( !db->autoCommit ){ if( !db->autoCommit ){
sqlite3ErrorMsg(pParse, sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction"); "Safety level may not be changed inside a transaction");
}else{ }else{
db->aDb[iDb].safety_level = getSafetyLevel(zRight)+1; pDb->safety_level = getSafetyLevel(zRight)+1;
sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt,db->aDb[iDb].safety_level); sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level);
} }
} }
}else }else
@@ -286,7 +363,8 @@ void sqlite3Pragma(
#endif #endif
if( flagPragma(pParse, zLeft, zRight) ){ if( flagPragma(pParse, zLeft, zRight) ){
/* The flagPragma() call also generates any necessary code */ /* The flagPragma() subroutine also generates any necessary code
** there is nothing more to do here */
}else }else
/* /*

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.306 2004/07/20 12:45:22 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.307 2004/07/22 01:19:35 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -139,7 +139,23 @@ extern const int sqlite3one;
typedef struct sqlite sqlite; typedef struct sqlite sqlite;
/* /*
** Defer sourcing vdbe.h until after the "u8" typedef is defined. ** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
typedef struct BusyHandler BusyHandler;
struct BusyHandler {
int (*xFunc)(void *,int); /* The busy callback */
void *pArg; /* First arg to busy callback */
};
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler typedefs.
*/ */
#include "vdbe.h" #include "vdbe.h"
#include "btree.h" #include "btree.h"
@@ -262,7 +278,6 @@ typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass; typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq; typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo; typedef struct KeyInfo KeyInfo;
typedef struct BusyHandler BusyHandler;
/* /*
** Each database file to be accessed by the system is an instance ** Each database file to be accessed by the system is an instance
@@ -279,8 +294,8 @@ struct Db {
Hash idxHash; /* All (named) indices indexed by name */ Hash idxHash; /* All (named) indices indexed by name */
Hash trigHash; /* All triggers indexed by name */ Hash trigHash; /* All triggers indexed by name */
Hash aFKey; /* Foreign keys indexed by to-table */ Hash aFKey; /* Foreign keys indexed by to-table */
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u16 flags; /* Flags associated with this database */ u16 flags; /* Flags associated with this database */
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 safety_level; /* How aggressive at synching data to disk */ u8 safety_level; /* How aggressive at synching data to disk */
int cache_size; /* Number of pages to use in the cache */ int cache_size; /* Number of pages to use in the cache */
void *pAux; /* Auxiliary data. Usually NULL */ void *pAux; /* Auxiliary data. Usually NULL */
@@ -311,20 +326,6 @@ struct Db {
#define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) #define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
** handle is passed a pointer to sqlite.busyHandler. The busy-handler
** callback is currently invoked only from within pager.c.
*/
struct BusyHandler {
int (*xFunc)(void *,int); /* The busy callback */
void *pArg; /* First arg to busy callback */
};
/* /*
** Each database is an instance of the following structure. ** Each database is an instance of the following structure.
** **
@@ -357,6 +358,7 @@ struct sqlite {
Db aDbStatic[2]; /* Static space for the 2 default backends */ Db aDbStatic[2]; /* Static space for the 2 default backends */
int flags; /* Miscellanous flags. See below */ int flags; /* Miscellanous flags. See below */
u8 file_format; /* What file format version is this database? */ u8 file_format; /* What file format version is this database? */
u8 temp_store; /* 1: file 2: memory 0: default */
int nTable; /* Number of tables in the database */ int nTable; /* Number of tables in the database */
BusyHandler busyHandler; /* Busy callback */ BusyHandler busyHandler; /* Busy callback */
void *pCommitArg; /* Argument to xCommitCallback() */ void *pCommitArg; /* Argument to xCommitCallback() */
@@ -1331,7 +1333,7 @@ void sqlite3DeferForeignKey(Parse*, int);
void sqlite3Attach(Parse*, Token*, Token*, Token*); void sqlite3Attach(Parse*, Token*, Token*, Token*);
void sqlite3Detach(Parse*, Token*); void sqlite3Detach(Parse*, Token*);
int sqlite3BtreeFactory(const sqlite *db, const char *zFilename, int sqlite3BtreeFactory(const sqlite *db, const char *zFilename,
int mode, int nPg, Btree **ppBtree); int omitJournal, int nCache, Btree **ppBtree);
int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixSelect(DbFixer*, Select*);

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test2.c,v 1.23 2004/06/21 18:14:47 drh Exp $ ** $Id: test2.c,v 1.24 2004/07/22 01:19:35 drh Exp $
*/ */
#include "os.h" #include "os.h"
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -55,6 +55,11 @@ static char *errorName(int rc){
return zName; return zName;
} }
/*
** Page size and reserved size used for testing.
*/
static int test_pagesize = 1024;
/* /*
** Usage: pager_open FILENAME N-PAGE ** Usage: pager_open FILENAME N-PAGE
** **
@@ -76,11 +81,13 @@ static int pager_open(
return TCL_ERROR; return TCL_ERROR;
} }
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1, 0); rc = sqlite3pager_open(&pPager, argv[1], 0, 1);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0); Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR; return TCL_ERROR;
} }
sqlite3pager_set_cachesize(pPager, nPage);
sqlite3pager_set_pagesize(pPager, test_pagesize);
sprintf(zBuf,"0x%x",(int)pPager); sprintf(zBuf,"0x%x",(int)pPager);
Tcl_AppendResult(interp, zBuf, 0); Tcl_AppendResult(interp, zBuf, 0);
return TCL_OK; return TCL_OK;
@@ -468,8 +475,8 @@ static int page_write(
Tcl_AppendResult(interp, errorName(rc), 0); Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR; return TCL_ERROR;
} }
strncpy((char*)pPage, argv[2], SQLITE_USABLE_SIZE-1); strncpy((char*)pPage, argv[2], test_pagesize-1);
((char*)pPage)[SQLITE_USABLE_SIZE-1] = 0; ((char*)pPage)[test_pagesize-1] = 0;
return TCL_OK; return TCL_OK;
} }
@@ -526,7 +533,6 @@ static int fake_big_file(
*/ */
int Sqlitetest2_Init(Tcl_Interp *interp){ int Sqlitetest2_Init(Tcl_Interp *interp){
extern int sqlite3_io_error_pending; extern int sqlite3_io_error_pending;
char zBuf[100];
static struct { static struct {
char *zName; char *zName;
Tcl_CmdProc *xProc; Tcl_CmdProc *xProc;
@@ -554,11 +560,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){
} }
Tcl_LinkVar(interp, "sqlite_io_error_pending", Tcl_LinkVar(interp, "sqlite_io_error_pending",
(char*)&sqlite3_io_error_pending, TCL_LINK_INT); (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
sprintf(zBuf, "%d", SQLITE_PAGE_SIZE); Tcl_LinkVar(interp, "pager_pagesize",
Tcl_SetVar(interp, "SQLITE_PAGE_SIZE", zBuf, TCL_GLOBAL_ONLY); (char*)&test_pagesize, TCL_LINK_INT);
sprintf(zBuf, "%d", SQLITE_PAGE_RESERVE);
Tcl_SetVar(interp, "SQLITE_PAGE_RESERVE", zBuf, TCL_GLOBAL_ONLY);
sprintf(zBuf, "%d", SQLITE_USABLE_SIZE);
Tcl_SetVar(interp, "SQLITE_USABLE_SIZE", zBuf, TCL_GLOBAL_ONLY);
return TCL_OK; return TCL_OK;
} }

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test3.c,v 1.48 2004/06/30 04:02:12 drh Exp $ ** $Id: test3.c,v 1.49 2004/07/22 01:19:35 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "pager.h" #include "pager.h"
@@ -70,11 +70,12 @@ static int btree_open(
} }
if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR;
rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags, 0); rc = sqlite3BtreeOpen(argv[1], &pBt, flags);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0); Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR; return TCL_ERROR;
} }
sqlite3BtreeSetCacheSize(pBt, nCache);
sprintf(zBuf,"%p", pBt); sprintf(zBuf,"%p", pBt);
if( strncmp(zBuf,"0x",2) ){ if( strncmp(zBuf,"0x",2) ){
sprintf(zBuf, "0x%p", pBt); sprintf(zBuf, "0x%p", pBt);