diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/delete.c | 25 | ||||
-rw-r--r-- | src/expr.c | 29 | ||||
-rw-r--r-- | src/insert.c | 3 | ||||
-rw-r--r-- | src/printf.c | 4 | ||||
-rw-r--r-- | src/select.c | 11 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/trigger.c | 5 | ||||
-rw-r--r-- | src/update.c | 6 | ||||
-rw-r--r-- | src/vdbeaux.c | 15 | ||||
-rw-r--r-- | src/where.c | 8 |
10 files changed, 73 insertions, 36 deletions
diff --git a/src/delete.c b/src/delete.c index f741b5a3a..fefa45431 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.80 2004/09/06 17:24:13 drh Exp $ +** $Id: delete.c,v 1.81 2004/09/19 02:15:25 drh Exp $ */ #include "sqliteInt.h" @@ -50,6 +50,21 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ } /* +** Generate code that will open a table for reading. +*/ +void sqlite3OpenTableForReading( + Vdbe *v, /* Generate code into this VDBE */ + int iCur, /* The cursor number of the table */ + Table *pTab /* The table to be opened */ +){ + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); + VdbeComment((v, "# %s", pTab->zName)); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); +} + + +/* ** Process a DELETE FROM statement. */ void sqlite3DeleteFrom( @@ -166,9 +181,7 @@ void sqlite3DeleteFrom( int endOfLoop = sqlite3VdbeMakeLabel(v); int addr; if( !isView ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); + sqlite3OpenTableForReading(v, iCur, pTab); } sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2); addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); @@ -232,9 +245,7 @@ void sqlite3DeleteFrom( addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); + sqlite3OpenTableForReading(v, iCur, pTab); } sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); diff --git a/src/expr.c b/src/expr.c index 2e3e61100..c173be524 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.162 2004/09/19 00:50:21 drh Exp $ +** $Id: expr.c,v 1.163 2004/09/19 02:15:25 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -241,7 +241,8 @@ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); assert( pLeft!=0 ); if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){ - if( pLeft->dyn==0 && pRight->dyn==0 ){ + assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); + if( pLeft->z[pLeft->n]!=0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z); }else{ @@ -1241,6 +1242,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); + VdbeComment((v, "# %T", &pExpr->span)); }else{ sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0); } @@ -1370,6 +1372,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } case TK_SELECT: { sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); + VdbeComment((v, "# load subquery result")); break; } case TK_IN: { @@ -1469,20 +1472,20 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ if( !pParse->trigStack ){ sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); - pParse->nErr++; return; } - if( pExpr->iColumn == OE_Rollback || - pExpr->iColumn == OE_Abort || - pExpr->iColumn == OE_Fail ){ - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, - pExpr->token.z, pExpr->token.n); - sqlite3VdbeDequoteP3(v, -1); + if( pExpr->iColumn!=OE_Ignore ){ + assert( pExpr->iColumn==OE_Rollback || + pExpr->iColumn == OE_Abort || + pExpr->iColumn == OE_Fail ); + sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->iColumn, + pExpr->token.z, pExpr->token.n); + sqlite3VdbeDequoteP3(v, -1); } else { - assert( pExpr->iColumn == OE_Ignore ); - sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); - sqlite3VdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump, - "(IGNORE jump)", 0); + assert( pExpr->iColumn == OE_Ignore ); + sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); + sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->trigStack->ignoreJump); + VdbeComment((v, "# raise(IGNORE)")); } } break; diff --git a/src/insert.c b/src/insert.c index 245468f1c..06f7d5a4b 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.117 2004/09/17 17:23:15 drh Exp $ +** $Id: insert.c,v 1.118 2004/09/19 02:15:26 drh Exp $ */ #include "sqliteInt.h" @@ -1007,6 +1007,7 @@ void sqlite3OpenTableAndIndices( assert( v!=0 ); sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); sqlite3VdbeAddOp(v, op, base, pTab->tnum); + VdbeComment((v, "# %s", pTab->zName)); sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); diff --git a/src/printf.c b/src/printf.c index f4dc4eeae..474492157 100644 --- a/src/printf.c +++ b/src/printf.c @@ -586,7 +586,9 @@ static int vxprintf( break; case etTOKEN: { Token *pToken = va_arg(ap, Token*); - (*func)(arg, pToken->z, pToken->n); + if( pToken && pToken->z ){ + (*func)(arg, pToken->z, pToken->n); + } length = width = 0; break; } diff --git a/src/select.c b/src/select.c index c240c2f3b..265a40228 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.208 2004/09/08 15:09:41 drh Exp $ +** $Id: select.c,v 1.209 2004/09/19 02:15:26 drh Exp $ */ #include "sqliteInt.h" @@ -344,9 +344,11 @@ static void codeLimiter( sqlite3VdbeAddOp(v, OP_Pop, nPop, 0); } sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); + VdbeComment((v, "# skip OFFSET records")); } if( p->iLimit>=0 ){ sqlite3VdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak); + VdbeComment((v, "# exit when LIMIT reached")); } } @@ -415,6 +417,7 @@ static int selectInnerLoop( sqlite3VdbeAddOp(v, OP_Distinct, distinct, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue); + VdbeComment((v, "# skip indistinct records")); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0); if( pOrderBy==0 ){ @@ -1223,6 +1226,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p){ if( v==0 ) return; sqlite3VdbeAddOp(v, OP_Integer, -p->nLimit, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); + VdbeComment((v, "# LIMIT counter")); p->iLimit = iMem; } if( p->nOffset>0 ){ @@ -1231,6 +1235,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p){ if( v==0 ) return; sqlite3VdbeAddOp(v, OP_Integer, -p->nOffset, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); + VdbeComment((v, "# OFFSET counter")); p->iOffset = iMem; } } @@ -2107,9 +2112,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ base = pSrc->a[0].iCursor; computeLimitRegisters(pParse, p); if( pSrc->a[0].pSelect==0 ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, base, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol); + sqlite3OpenTableForReading(v, base, pTab); } cont = sqlite3VdbeMakeLabel(v); if( pIdx==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 04228b5b0..91cc0f177 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.321 2004/09/08 20:13:05 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.322 2004/09/19 02:15:26 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1263,6 +1263,7 @@ void sqlite3SelectDelete(Select*); void sqlite3SelectUnbind(Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); +void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**); diff --git a/src/trigger.c b/src/trigger.c index 3e601346a..90ab54e3f 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -760,7 +760,10 @@ int sqlite3CodeRowTrigger( fire_this = 0; } } - + + /* FIX ME: Can we not omit the sqliteMalloc() and make pTriggerStack + ** point to a stack variable? + */ if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){ int endTrigger; SrcList dummyTablist; diff --git a/src/update.c b/src/update.c index 60c049d68..5655bbe6e 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.88 2004/09/06 17:24:13 drh Exp $ +** $Id: update.c,v 1.89 2004/09/19 02:15:26 drh Exp $ */ #include "sqliteInt.h" @@ -253,9 +253,7 @@ void sqlite3Update( */ sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol); + sqlite3OpenTableForReading(v, iCur, pTab); } sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 64dddeb56..11e06462f 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -304,6 +304,21 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ } } +#ifndef NDEBUG +/* +** Replace the P3 field of the most recently coded instruction with +** comment text. +*/ +void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + assert( p->nOp>0 ); + assert( p->aOp[p->nOp-1].p3==0 ); + va_start(ap, zFormat); + sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC); + va_end(ap); +} +#endif + /* ** If the P3 operand to the specified instruction appears ** to be a quoted string token, then this procedure removes diff --git a/src/where.c b/src/where.c index ec77360d6..ce62b2b07 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.113 2004/09/06 17:24:13 drh Exp $ +** $Id: where.c,v 1.114 2004/09/19 02:15:26 drh Exp $ */ #include "sqliteInt.h" @@ -734,9 +734,7 @@ WhereInfo *sqlite3WhereBegin( pTab = pTabList->a[i].pTab; if( pTab->isTransient || pTab->pSelect ) continue; - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum); - sqlite3VdbeAddOp(v, OP_SetNumColumns, pTabList->a[i].iCursor, pTab->nCol); + sqlite3OpenTableForReading(v, pTabList->a[i].iCursor, pTab); sqlite3CodeVerifySchema(pParse, pTab->iDb); if( (pIx = pWInfo->a[i].pIdx)!=0 ){ sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0); @@ -763,6 +761,7 @@ WhereInfo *sqlite3WhereBegin( pLevel->iLeftJoin = pParse->nMem++; sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); + VdbeComment((v, "# init LEFT JOIN no-match flag")); } pIdx = pLevel->pIdx; @@ -1141,6 +1140,7 @@ WhereInfo *sqlite3WhereBegin( pLevel->top = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp(v, OP_Integer, 1, 0); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1); + VdbeComment((v, "# record LEFT JOIN hit")); for(pTerm=aExpr, j=0; j<nExpr; j++, pTerm++){ if( pTerm->p==0 ) continue; if( (pTerm->prereqAll & loopMask)!=pTerm->prereqAll ) continue; |