aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/delete.c25
-rw-r--r--src/expr.c29
-rw-r--r--src/insert.c3
-rw-r--r--src/printf.c4
-rw-r--r--src/select.c11
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/trigger.c5
-rw-r--r--src/update.c6
-rw-r--r--src/vdbeaux.c15
-rw-r--r--src/where.c8
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;