diff options
author | drh <drh@noemail.net> | 2004-04-23 17:04:44 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2004-04-23 17:04:44 +0000 |
commit | 1bdd9b57873f5f033963e4a44bb1409fc38f0c0e (patch) | |
tree | 1e2de2b5a294168ca66336c8e66ea8c82bdda487 /src | |
parent | 932ee8f4bb59938583bd577659df34ccc968ce98 (diff) | |
download | sqlite-1bdd9b57873f5f033963e4a44bb1409fc38f0c0e.tar.gz sqlite-1bdd9b57873f5f033963e4a44bb1409fc38f0c0e.zip |
Get the temp_store and default_temp_store pragmas working. Update the
documentation. Also fix a malloc problem that popped up during the regression
testing. (CVS 1302)
FossilOrigin-Name: 7ace576215367101904677bd69951755ee9cb1a1
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 3 | ||||
-rw-r--r-- | src/expr.c | 7 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/pragma.c | 55 | ||||
-rw-r--r-- | src/test4.c | 41 |
5 files changed, 84 insertions, 27 deletions
diff --git a/src/build.c b/src/build.c index 87c88346b..3d74322b3 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.175 2004/02/24 01:04:12 drh Exp $ +** $Id: build.c,v 1.176 2004/04/23 17:04:44 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -484,7 +484,6 @@ void sqliteStartTable( if( rc!=SQLITE_OK ){ sqliteErrorMsg(pParse, "unable to get a write lock on " "the temporary database file"); - pParse->nErr++; return; } } diff --git a/src/expr.c b/src/expr.c index eafc50ce8..f92dbc078 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.113 2004/03/17 23:32:08 drh Exp $ +** $Id: expr.c,v 1.114 2004/04/23 17:04:45 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -155,7 +155,8 @@ ExprList *sqliteExprListDup(ExprList *p){ if( pNew==0 ) return 0; pNew->nExpr = pNew->nAlloc = p->nExpr; pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) ); - for(i=0; pItem && i<p->nExpr; i++, pItem++){ + if( pItem==0 ) return 0; /* Leaks memory after a malloc failure */ + for(i=0; i<p->nExpr; i++, pItem++){ Expr *pNewExpr, *pOldExpr; pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr); if( pOldExpr->span.z!=0 && pNewExpr ){ @@ -278,6 +279,8 @@ ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ void sqliteExprListDelete(ExprList *pList){ int i; if( pList==0 ) return; + assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); + assert( pList->nExpr<=pList->nAlloc ); for(i=0; i<pList->nExpr; i++){ sqliteExprDelete(pList->a[i].pExpr); sqliteFree(pList->a[i].zName); diff --git a/src/main.c b/src/main.c index bf8b66673..27f237f7c 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.163 2004/03/17 18:44:47 drh Exp $ +** $Id: main.c,v 1.164 2004/04/23 17:04:45 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -300,6 +300,9 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){ if( size==0 ){ size = MAX_PAGES; } db->cache_size = size; db->safety_level = meta[4]; + if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){ + db->temp_store = meta[6]; + } if( db->safety_level==0 ) db->safety_level = 2; /* diff --git a/src/pragma.c b/src/pragma.c index d9cf6354a..a002c7dc2 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.18 2004/02/22 20:05:01 drh Exp $ +** $Id: pragma.c,v 1.19 2004/04/23 17:04:45 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -71,8 +71,8 @@ static int getSafetyLevel(char *z){ ** backed temporary databases, 2 for the Red-Black tree in memory database ** and 0 to use the compile-time default. */ -static int getTempStore(char *z){ - if( z[0]>='0' || z[0]<='2' ){ +static int getTempStore(const char *z){ + if( z[0]>='0' && z[0]<='2' ){ return z[0] - '0'; }else if( sqliteStrICmp(z, "file")==0 ){ return 1; @@ -84,6 +84,29 @@ static int getTempStore(char *z){ } /* +** 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 ){ + sqliteErrorMsg(pParse, "temporary storage cannot be changed " + "from within a transaction"); + return SQLITE_ERROR; + } + sqliteBtreeClose(db->aDb[1].pBt); + db->aDb[1].pBt = 0; + sqliteResetInternalSchema(db, 0); + } + db->temp_store = ts; + return SQLITE_OK; +} + +/* ** 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. ** Also, implement the pragma. @@ -498,12 +521,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0); sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc); }else{ - if (&db->aDb[1].pBt != 0) { - sqliteErrorMsg(pParse, "The temporary database already exists - " - "its location cannot now be changed"); - } else { - db->temp_store = getTempStore(zRight); - } + changeTempStorage(pParse, zRight); } }else @@ -511,8 +529,9 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ ** PRAGMA default_temp_store ** PRAGMA default_temp_store = "default"|"memory"|"file" ** - ** Return or set the value of the persistent temp_store flag (as - ** well as the value currently in force). + ** Return or set the value of the persistent temp_store flag. Any + ** change does not take effect until the next time the database is + ** opened. ** ** Note that it is possible for the library compile-time options to ** override this setting @@ -525,16 +544,10 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ if( pRight->z==pLeft->z ){ sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc); }else{ - if (&db->aDb[1].pBt != 0) { - sqliteErrorMsg(pParse, "The temporary database already exists - " - "its location cannot now be changed"); - } else { - sqliteBeginWriteOperation(pParse, 0, 0); - db->temp_store = getTempStore(zRight); - sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0); - sqliteVdbeAddOp(v, OP_SetCookie, 0, 5); - sqliteEndWriteOperation(pParse); - } + sqliteBeginWriteOperation(pParse, 0, 0); + sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0); + sqliteVdbeAddOp(v, OP_SetCookie, 0, 5); + sqliteEndWriteOperation(pParse); } }else diff --git a/src/test4.c b/src/test4.c index 3389f3eae..2966a6756 100644 --- a/src/test4.c +++ b/src/test4.c @@ -11,7 +11,7 @@ ************************************************************************* ** Code for testing the the SQLite library in a multithreaded environment. ** -** $Id: test4.c,v 1.2 2003/12/20 04:00:53 drh Exp $ +** $Id: test4.c,v 1.3 2004/04/23 17:04:45 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -564,6 +564,44 @@ static int tcl_thread_finalize( } /* +** Usage: thread_swap ID ID +** +** Interchange the sqlite* pointer between two threads. +*/ +static int tcl_thread_swap( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + const char **argv /* Text of each argument */ +){ + int i, j; + sqlite *temp; + if( argc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ID1 ID2", 0); + return TCL_ERROR; + } + i = parse_thread_id(interp, argv[1]); + if( i<0 ) return TCL_ERROR; + if( !threadset[i].busy ){ + Tcl_AppendResult(interp, "no such thread", 0); + return TCL_ERROR; + } + thread_wait(&threadset[i]); + j = parse_thread_id(interp, argv[2]); + if( j<0 ) return TCL_ERROR; + if( !threadset[j].busy ){ + Tcl_AppendResult(interp, "no such thread", 0); + return TCL_ERROR; + } + thread_wait(&threadset[j]); + temp = threadset[i].db; + threadset[i].db = threadset[j].db; + threadset[j].db = temp; + return TCL_OK; +} + +/* ** Register commands with the TCL interpreter. */ int Sqlitetest4_Init(Tcl_Interp *interp){ @@ -582,6 +620,7 @@ int Sqlitetest4_Init(Tcl_Interp *interp){ { "thread_compile", (Tcl_CmdProc*)tcl_thread_compile }, { "thread_step", (Tcl_CmdProc*)tcl_thread_step }, { "thread_finalize", (Tcl_CmdProc*)tcl_thread_finalize }, + { "thread_swap", (Tcl_CmdProc*)tcl_thread_swap }, }; int i; |