aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2004-04-23 17:04:44 +0000
committerdrh <drh@noemail.net>2004-04-23 17:04:44 +0000
commit1bdd9b57873f5f033963e4a44bb1409fc38f0c0e (patch)
tree1e2de2b5a294168ca66336c8e66ea8c82bdda487 /src
parent932ee8f4bb59938583bd577659df34ccc968ce98 (diff)
downloadsqlite-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.c3
-rw-r--r--src/expr.c7
-rw-r--r--src/main.c5
-rw-r--r--src/pragma.c55
-rw-r--r--src/test4.c41
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;