diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 11 | ||||
-rw-r--r-- | src/select.c | 14 | ||||
-rw-r--r-- | src/sqlite.h.in | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 5 | ||||
-rw-r--r-- | src/test1.c | 20 | ||||
-rw-r--r-- | src/tokenize.c | 8 | ||||
-rw-r--r-- | src/util.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 40 | ||||
-rw-r--r-- | src/vdbe.h | 9 |
9 files changed, 75 insertions, 40 deletions
diff --git a/src/main.c b/src/main.c index 2be750bec..7b5c76e5e 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.110 2003/01/28 23:13:12 drh Exp $ +** $Id: main.c,v 1.111 2003/01/29 14:06:08 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -622,8 +622,7 @@ static int sqliteMain( sqliteSetString(pzErrMsg, "obsolete database file format", 0); return SQLITE_ERROR; } - if( db->recursionDepth==0 ){ db->nChange = 0; } - db->recursionDepth++; + if( db->pVdbe==0 ){ db->nChange = 0; } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.pBe = db->pBe; @@ -642,6 +641,7 @@ static int sqliteMain( db->flags &= ~SQLITE_InTrans; sqliteResetInternalSchema(db); } + if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), 0); } @@ -649,11 +649,10 @@ static int sqliteMain( if( sParse.rc==SQLITE_SCHEMA ){ sqliteResetInternalSchema(db); } - db->recursionDepth--; if( sParse.useCallback==0 ){ assert( ppVm ); - *ppVm = sParse.pVdbe; - *pzTail = &sParse.sLastToken.z[sParse.sLastToken.n]; + *ppVm = (sqlite_vm*)sParse.pVdbe; + *pzTail = sParse.zTail; } if( sqliteSafetyOff(db) ) goto exec_misuse; return sParse.rc; diff --git a/src/select.c b/src/select.c index 29b1f9e3a..4998a5352 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.123 2003/01/19 03:59:47 drh Exp $ +** $Id: select.c,v 1.124 2003/01/29 14:06:09 drh Exp $ */ #include "sqliteInt.h" @@ -697,7 +697,9 @@ static void generateColumnTypes( ){ Vdbe *v = pParse->pVdbe; int i; - if( (pParse->db->flags & SQLITE_ReportTypes)==0 ) return; + if( pParse->useCallback && (pParse->db->flags & SQLITE_ReportTypes)==0 ){ + return; + } for(i=0; i<pEList->nExpr; i++){ Expr *p = pEList->a[i].pExpr; char *zType = 0; @@ -1456,7 +1458,9 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ /* Issue a null callback if that is what the user wants. */ - if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){ + if( eDest==SRT_Callback && + (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0) + ){ sqliteVdbeAddOp(v, OP_NullCallback, p->pEList->nExpr, 0); } return 0; @@ -2306,7 +2310,9 @@ int sqliteSelect( /* Issue a null callback if that is what the user wants. */ - if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){ + if( eDest==SRT_Callback && + (pParse->useCallback==0 || (pParse->db->flags & SQLITE_NullCallback)!=0) + ){ sqliteVdbeAddOp(v, OP_NullCallback, pEList->nExpr, 0); } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1b1c52892..159045333 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.40 2003/01/28 23:13:12 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.41 2003/01/29 14:06:09 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -588,6 +588,8 @@ typedef struct sqlite_vm sqlite_vm; ** ** *ppVm is left pointing to a "virtual machine" that can be used to execute ** the compiled statement. Or if there is an error, *ppVm may be set to NULL. +** If the input text contained no SQL (if the input is and empty string or +** a comment) then *ppVm is set to NULL. ** ** If any errors are detected during compilation, an error message is written ** into space obtained from malloc() and *pzErrMsg is made to point to that diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 734eadd18..19cf9993e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.157 2003/01/28 23:13:12 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.158 2003/01/29 14:06:09 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -224,7 +224,7 @@ struct sqlite { int onError; /* Default conflict algorithm */ int magic; /* Magic number for detect library misuse */ int nChange; /* Number of rows changed */ - int recursionDepth; /* Number of nested calls to sqlite_exec() */ + struct Vdbe *pVdbe; /* List of active virtual machines */ #ifndef SQLITE_OMIT_TRACE void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ @@ -737,6 +737,7 @@ struct Parse { Token sErrToken; /* The token at which the error occurred */ Token sFirstToken; /* The first token parsed */ Token sLastToken; /* The last token parsed */ + const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ Vdbe *pVdbe; /* An engine for executing database bytecode */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ diff --git a/src/test1.c b/src/test1.c index 434662a21..09d6c1953 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.17 2003/01/28 23:13:12 drh Exp $ +** $Id: test1.c,v 1.18 2003/01/29 14:06:09 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -733,8 +733,10 @@ static int test_compile( sqlite_freemem(zErr); return TCL_ERROR; } - sprintf(zBuf, "%p", vm); - Tcl_AppendResult(interp, zBuf, 0); + if( vm ){ + sprintf(zBuf, "%p", vm); + Tcl_AppendResult(interp, zBuf, 0); + } Tcl_SetVar(interp, argv[3], zTail, 0); return TCL_OK; } @@ -765,7 +767,7 @@ static int test_step( } if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; rc = sqlite_step(vm, &N, &azValue, &azColName); - if( rc==SQLITE_DONE || SQLITE_ROW ){ + if( rc==SQLITE_DONE || rc==SQLITE_ROW ){ sprintf(zBuf, "%d", N); Tcl_SetVar(interp, argv[2], zBuf, 0); Tcl_SetVar(interp, argv[3], "", 0); @@ -777,15 +779,15 @@ static int test_step( } Tcl_SetVar(interp, argv[4], "", 0); for(i=0; i<N*2; i++){ - Tcl_SetVar(interp, argv[4], azValue[i] ? azValue[i] : "", + Tcl_SetVar(interp, argv[4], azColName[i] ? azColName[i] : "", TCL_APPEND_VALUE | TCL_LIST_ELEMENT); } } switch( rc ){ case SQLITE_DONE: zRc = "SQLITE_DONE"; break; - case SQLITE_BUSY: zRc = "SQLITE_DONE"; break; - case SQLITE_ROW: zRc = "SQLITE_DONE"; break; - case SQLITE_ERROR: zRc = "SQLITE_DONE"; break; + case SQLITE_BUSY: zRc = "SQLITE_BUSY"; break; + case SQLITE_ROW: zRc = "SQLITE_ROW"; break; + case SQLITE_ERROR: zRc = "SQLITE_ERROR"; break; case SQLITE_MISUSE: zRc = "SQLITE_MISUSE"; break; default: zRc = "unknown"; break; } @@ -809,7 +811,7 @@ static int test_finalize( char *zErrMsg = 0; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " VM NVAR VALUEVAR COLNAMEVAR", 0); + " VM\"", 0); return TCL_ERROR; } if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; diff --git a/src/tokenize.c b/src/tokenize.c index df27fa732..7dd49b21a 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.54 2003/01/28 23:13:12 drh Exp $ +** $Id: tokenize.c,v 1.55 2003/01/29 14:06:09 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -422,6 +422,7 @@ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ return 1; } pParse->sLastToken.dyn = 0; + pParse->zTail = zSql; while( sqlite_malloc_failed==0 && zSql[i]!=0 ){ assert( i>=0 ); @@ -445,6 +446,10 @@ int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ nErr++; goto abort_parse; } + case TK_SEMI: { + pParse->zTail = &zSql[i]; + /* Fall thru into the default case */ + } default: { sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse); lastTokenParsed = tokenType; @@ -459,6 +464,7 @@ abort_parse: if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){ if( lastTokenParsed!=TK_SEMI ){ sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse); + pParse->zTail = &zSql[i]; } sqliteParser(pEngine, 0, pParse->sLastToken, pParse); } diff --git a/src/util.c b/src/util.c index f71950cef..26e7afcb2 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.56 2003/01/14 00:44:09 drh Exp $ +** $Id: util.c,v 1.57 2003/01/29 14:06:09 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> @@ -1196,7 +1196,7 @@ int sqliteSafetyOff(sqlite *db){ ** at the wrong time or in the wrong sequence. */ int sqliteSafetyCheck(sqlite *db){ - if( db->recursionDepth ){ + if( db->pVdbe!=0 ){ db->magic = SQLITE_MAGIC_ERROR; return 1; } diff --git a/src/vdbe.c b/src/vdbe.c index 0839b303b..c0ec8ac3f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -36,7 +36,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.200 2003/01/28 23:13:12 drh Exp $ +** $Id: vdbe.c,v 1.201 2003/01/29 14:06:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -242,6 +242,7 @@ struct Keylist { */ struct Vdbe { sqlite *db; /* The whole database */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Btree *pBt; /* Opaque context structure used by DB backend */ FILE *trace; /* Write an execution trace here, if not NULL */ int nOp; /* Number of instructions in the program */ @@ -316,6 +317,12 @@ Vdbe *sqliteVdbeCreate(sqlite *db){ if( p==0 ) return 0; p->pBt = db->pBe; p->db = db; + if( db->pVdbe ){ + db->pVdbe->pPrev = p; + } + p->pNext = db->pVdbe; + p->pPrev = 0; + db->pVdbe = p; p->magic = VDBE_MAGIC_INIT; return p; } @@ -763,17 +770,22 @@ int sqlite_step( const char ***pazColName /* OUT: Column names and datatypes */ ){ Vdbe *p = (Vdbe*)pVm; + sqlite *db; int rc; if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } + db = p->db; + if( sqliteSafetyOn(db) ){ + return SQLITE_MISUSE; + } if( p->explain ){ rc = sqliteVdbeList(p); }else{ rc = sqliteVdbeExec(p); } - if( rc!=SQLITE_DONE ){ + if( rc==SQLITE_DONE || rc==SQLITE_ROW ){ *pazColName = (const char**)p->azColName; *pN = p->nResColumn; }else{ @@ -785,6 +797,9 @@ int sqlite_step( }else{ *pazValue = 0; } + if( sqliteSafetyOff(db) ){ + return SQLITE_MISUSE; + } return rc; } @@ -1191,6 +1206,16 @@ void sqliteVdbeDelete(Vdbe *p){ int i; if( p==0 ) return; Cleanup(p); + if( p->pPrev ){ + p->pPrev->pNext = p->pNext; + }else{ + assert( p->db->pVdbe==p ); + p->db->pVdbe = p->pNext; + } + if( p->pNext ){ + p->pNext->pPrev = p->pPrev; + } + p->pPrev = p->pNext = 0; if( p->nOpAlloc==0 ){ p->aOp = 0; p->nOp = 0; @@ -1255,7 +1280,7 @@ int sqliteVdbeList( p->pc = i+1; p->azResColumn = p->zStack; p->nResColumn = 5; - return SQLITE_CALLBACK; + return SQLITE_ROW; } if( sqliteSafetyOff(db) ){ p->rc = SQLITE_MISUSE; @@ -1453,7 +1478,7 @@ __inline__ unsigned long long int hwtime(void){ ** ** The behavior of sqliteVdbeExec() is influenced by the parameters to ** this routine. If xCallback is NULL, then sqliteVdbeExec() will return -** with SQLITE_CALLBACK whenever there is a row of the result set ready +** with SQLITE_ROW whenever there is a row of the result set ready ** to be delivered. p->azResColumn will point to the row and ** p->nResColumn gives the number of columns in the row. If xCallback ** is not NULL, then the xCallback() routine is invoked to process each @@ -1523,7 +1548,7 @@ void sqliteVdbeMakeReady( ** ** Whenever a row or result data is available, this routine will either ** invoke the result callback (if there is one) or return with -** SQLITE_CALLBACK. +** SQLITE_ROW. ** ** If an attempt is made to open a locked database, then this routine ** will either invoke the busy callback (if there is one) or it will @@ -1887,7 +1912,7 @@ case OP_Callback: { p->nResColumn = pOp->p1; p->popStack = pOp->p1; p->pc = pc + 1; - return SQLITE_CALLBACK; + return SQLITE_ROW; } if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; if( p->xCallback(p->pCbArg, pOp->p1, &zStack[i], p->azColName)!=0 ){ @@ -1926,6 +1951,7 @@ case OP_NullCallback: { p->nCallback++; if( sqlite_malloc_failed ) goto no_mem; } + p->nResColumn = pOp->p1; break; } @@ -4843,7 +4869,7 @@ case OP_SortCallback: { p->azResColumn = (char**)zStack[i]; p->nResColumn = pOp->p1; p->popStack = 1; - return SQLITE_CALLBACK; + return SQLITE_ROW; }else{ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; if( p->xCallback(p->pCbArg, pOp->p1, (char**)zStack[i], p->azColName)!=0 ){ diff --git a/src/vdbe.h b/src/vdbe.h index 535b1e7d6..6a8e191f5 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.62 2003/01/28 23:13:13 drh Exp $ +** $Id: vdbe.h,v 1.63 2003/01/29 14:06:10 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -63,13 +63,6 @@ typedef struct VdbeOp VdbeOp; #define ADDR(X) (-1-(X)) /* -** The sqliteVdbeExec() routine can return any of the normal SQLite return -** codes defined in sqlite.h. But it can also return the following -** additional values: -*/ -#define SQLITE_CALLBACK 100 /* sqliteVdbeExec() hit an OP_Callback */ - -/* ** The makefile scans the vdbe.c source file and creates the "opcodes.h" ** header file that defines a number for each opcode used by the VDBE. */ |