aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2008-01-03 09:51:55 +0000
committerdanielk1977 <danielk1977@noemail.net>2008-01-03 09:51:55 +0000
commit1f4aa337cd87ccb96fdaa58233ad691aaca1ac23 (patch)
tree4d1d62f99b3d9723546d9d238873f8cd8dda7a29 /src
parent11641c11363ef866ba15f197acf5cd38f2f518a8 (diff)
downloadsqlite-1f4aa337cd87ccb96fdaa58233ad691aaca1ac23.tar.gz
sqlite-1f4aa337cd87ccb96fdaa58233ad691aaca1ac23.zip
Change the OP_Insert opcode to read the key and data to insert from memory cells, not the stack. (CVS 4666)
FossilOrigin-Name: 46501f490a5f5577ea31c758df749e02c7c65f39
Diffstat (limited to 'src')
-rw-r--r--src/analyze.c4
-rw-r--r--src/build.c4
-rw-r--r--src/delete.c18
-rw-r--r--src/insert.c17
-rw-r--r--src/select.c8
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/trigger.c8
-rw-r--r--src/update.c6
-rw-r--r--src/vdbe.c67
-rw-r--r--src/vdbe.h5
-rw-r--r--src/vdbeaux.c13
11 files changed, 91 insertions, 62 deletions
diff --git a/src/analyze.c b/src/analyze.c
index ffcc6d6cf..572fdb60f 100644
--- a/src/analyze.c
+++ b/src/analyze.c
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
-** @(#) $Id: analyze.c,v 1.28 2008/01/03 07:54:24 danielk1977 Exp $
+** @(#) $Id: analyze.c,v 1.29 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
@@ -212,7 +212,7 @@ static void analyzeOneTable(
}
}
sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
- sqlite3VdbeAddOp2(v, OP_Insert, iStatCur, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, iStatCur, OPFLAG_APPEND);
sqlite3VdbeJumpHere(v, addr);
}
}
diff --git a/src/build.c b/src/build.c
index 48ed5bd41..f6faeb747 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.454 2008/01/03 07:54:24 danielk1977 Exp $
+** $Id: build.c,v 1.455 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -883,7 +883,7 @@ void sqlite3StartTable(
sqlite3VdbeAddOp0(v, OP_NewRowid);
sqlite3VdbeAddOp0(v, OP_Dup);
sqlite3VdbeAddOp0(v, OP_Null);
- sqlite3VdbeAddOp2(v, OP_Insert, 0, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND);
sqlite3VdbeAddOp0(v, OP_Close);
sqlite3VdbeAddOp1(v, OP_Pull, 1);
}
diff --git a/src/delete.c b/src/delete.c
index 6214249b4..b97ce709b 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
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.141 2008/01/03 07:54:24 danielk1977 Exp $
+** $Id: delete.c,v 1.142 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -61,6 +61,20 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
}
/*
+** This function is a temporary measure required because OP_Insert now
+** reads the key and data to insert from memory cells.
+*/
+void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){
+ int iData = p->nMem++;
+ int iKey = p->nMem++;
+ Vdbe *v = sqlite3GetVdbe(p);
+ sqlite3VdbeAddOp2(v, OP_MemStore, iData, 1);
+ sqlite3VdbeAddOp2(v, OP_MemStore, iKey, 1);
+ sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
+ sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags);
+}
+
+/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
@@ -325,7 +339,7 @@ void sqlite3DeleteFrom(
}else{
sqlite3VdbeAddOp0(v, OP_Null);
}
- sqlite3VdbeAddOp1(v, OP_Insert, oldIdx);
+ sqlite3CodeInsert(pParse, oldIdx, 0);
/* Jump back and run the BEFORE triggers */
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
diff --git a/src/insert.c b/src/insert.c
index e8e0a0f4a..871cb70ab 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.203 2008/01/03 07:54:24 danielk1977 Exp $
+** $Id: insert.c,v 1.204 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -221,7 +221,7 @@ static void autoIncEnd(
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
- sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND);
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
}
}
@@ -511,7 +511,7 @@ void sqlite3Insert(
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
- sqlite3VdbeAddOp2(v, OP_Insert, srcTab, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND);
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
/* The following code runs first because the GOTO at the very top
@@ -701,7 +701,7 @@ void sqlite3Insert(
if( !isView ){
sqlite3TableAffinityStr(v, pTab);
}
- sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
+ sqlite3CodeInsert(pParse, newIdx, OPFLAG_APPEND);
/* Fire BEFORE or INSTEAD OF triggers */
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
@@ -1231,7 +1231,7 @@ void sqlite3CompleteInsertion(
if( newIdx>=0 ){
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
- sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
+ sqlite3CodeInsert(pParse, newIdx, 0);
}
#endif
if( pParse->nested ){
@@ -1243,7 +1243,7 @@ void sqlite3CompleteInsertion(
if( appendBias ){
pik_flags |= OPFLAG_APPEND;
}
- sqlite3VdbeAddOp2(v, OP_Insert, base, pik_flags);
+ sqlite3CodeInsert(pParse, base, pik_flags);
if( !pParse->nested ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
}
@@ -1563,9 +1563,8 @@ static int xferOptimization(
assert( pDest->autoInc==0 );
}
sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0);
- sqlite3VdbeAddOp4(v, OP_Insert, iDest, 0,
- OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
- pDest->zName, 0);
+ sqlite3CodeInsert(pParse,iDest,OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
+ sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
autoIncEnd(pParse, iDbDest, pDest, counterMem);
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
diff --git a/src/select.c b/src/select.c
index 38569fac7..bc2f0180d 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.379 2008/01/03 07:54:24 danielk1977 Exp $
+** $Id: select.c,v 1.380 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -613,7 +613,7 @@ static int selectInnerLoop(
}else{
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
- sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
}
break;
}
@@ -791,7 +791,7 @@ static void generateSortTail(
case SRT_EphemTab: {
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
- sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
+ sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -814,7 +814,7 @@ static void generateSortTail(
case SRT_Callback:
case SRT_Subroutine: {
int i;
- sqlite3VdbeAddOp2(v, OP_Insert, pseudoTab, 0);
+ sqlite3CodeInsert(pParse, pseudoTab, 0);
for(i=0; i<nColumn; i++){
sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i);
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 61b50c269..453793271 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.631 2008/01/03 00:01:25 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.632 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1918,6 +1918,7 @@ int sqlite3OpenTempDatabase(Parse *);
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
+void sqlite3CodeInsert(Parse *, int, u8);
/*
diff --git a/src/trigger.c b/src/trigger.c
index 96e9b2958..54129dd7d 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -237,10 +237,14 @@ void sqlite3FinishTrigger(
{ OP_String8, 0, 0, 0 }, /* 6: SQL */
{ OP_Concat, 0, 0, 0 },
{ OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */
+ { OP_MemStore, 0, 1, 0 }, /* 9: Store data */
+ { OP_MemStore, 0, 1, 0 }, /* 10: Store key */
{ OP_Insert, 0, 0, 0 },
};
int addr;
Vdbe *v;
+ int iKey = pParse->nMem++;
+ int iData = pParse->nMem++;
/* Make an entry in the sqlite_master table */
v = sqlite3GetVdbe(pParse);
@@ -254,6 +258,10 @@ void sqlite3FinishTrigger(
sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC);
sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC);
+ sqlite3VdbeChangeP1(v, addr+9, iData);
+ sqlite3VdbeChangeP2(v, addr+11, iData);
+ sqlite3VdbeChangeP1(v, addr+10, iKey);
+ sqlite3VdbeChangeP3(v, addr+11, iKey);
sqlite3ChangeCookie(db, v, iDb);
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
diff --git a/src/update.c b/src/update.c
index 3146a1d83..d7ae939e7 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.151 2008/01/03 08:08:40 danielk1977 Exp $
+** $Id: update.c,v 1.152 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -410,7 +410,7 @@ void sqlite3Update(
}else{
sqlite3VdbeAddOp2(v, OP_RowData, iCur, 0);
}
- sqlite3VdbeAddOp2(v, OP_Insert, oldIdx, 0);
+ sqlite3CodeInsert(pParse, oldIdx, 0);
/* Generate the NEW table
*/
@@ -441,7 +441,7 @@ void sqlite3Update(
sqlite3TableAffinityStr(v, pTab);
}
if( pParse->nErr ) goto update_cleanup;
- sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
+ sqlite3CodeInsert(pParse, newIdx, 0);
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
diff --git a/src/vdbe.c b/src/vdbe.c
index 8320a7657..c748b7082 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,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.667 2008/01/03 08:08:40 danielk1977 Exp $
+** $Id: vdbe.c,v 1.668 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -2043,12 +2043,9 @@ case OP_SetNumColumns: { /* no-push */
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
-** If the column contains fewer than P2 fields, then extract a NULL. Or
-** if the next instruction is OP_DfltValue then the P4 argument to the
-** OP_DfltValue instruction will be a P4_MEM. Use the P4 argument of
-** the OP_DfltValue instruction as the extracted value instead of NULL.
-** The OP_DfltValue P4 value will be a default value for a column
-** that has been added using the ALTER TABLE ADD COLUMN command.
+** If the column contains fewer than P2 fields, then extract a NULL. Or,
+** if the P4 argument is a P4_MEM use the value of the P4 argument as
+** the result.
*/
case OP_Column: {
u32 payloadSize; /* Number of bytes in the record */
@@ -3560,16 +3557,16 @@ case OP_NewRowid: {
break;
}
-/* Opcode: Insert P1 P2 P4
+/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1. A new entry is
** created if it doesn't already exist or the data for an existing
-** entry is overwritten. The data is the value on the top of the
-** stack. The key is the next value down on the stack. The key must
-** be an integer. The stack is popped twice by this instruction.
+** entry is overwritten. The data is the value stored register
+** number P2. The key is stored in register P3. The key must
+** be an integer.
**
-** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P2 is set,
+** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
+** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
@@ -3581,55 +3578,56 @@ case OP_NewRowid: {
** for indices is OP_IdxInsert.
*/
case OP_Insert: { /* no-push */
- Mem *pNos = &pTos[-1];
+ Mem *pData = &p->aMem[pOp->p2];
+ Mem *pKey = &p->aMem[pOp->p3];
+
int i = pOp->p1;
Cursor *pC;
- assert( pNos>=p->aStack );
assert( i>=0 && i<p->nCursor );
assert( p->apCsr[i]!=0 );
if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
i64 iKey; /* The integer ROWID or key for the record to be inserted */
- assert( pNos->flags & MEM_Int );
+ assert( pKey->flags & MEM_Int );
assert( pC->isTable );
- iKey = intToKey(pNos->u.i);
+ iKey = intToKey(pKey->u.i);
- if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->u.i;
- if( pC->nextRowidValid && pNos->u.i>=pC->nextRowid ){
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
+ if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
pC->nextRowidValid = 0;
}
- if( pTos->flags & MEM_Null ){
- pTos->z = 0;
- pTos->n = 0;
+ if( pData->flags & MEM_Null ){
+ pData->z = 0;
+ pData->n = 0;
}else{
- assert( pTos->flags & (MEM_Blob|MEM_Str) );
+ assert( pData->flags & (MEM_Blob|MEM_Str) );
}
if( pC->pseudoTable ){
sqlite3_free(pC->pData);
pC->iKey = iKey;
- pC->nData = pTos->n;
- if( pTos->flags & MEM_Dyn ){
- pC->pData = pTos->z;
- pTos->flags = MEM_Null;
+ pC->nData = pData->n;
+ if( pData->flags & MEM_Dyn ){
+ pC->pData = pData->z;
+ pData->flags = MEM_Null;
}else{
pC->pData = sqlite3_malloc( pC->nData+2 );
if( !pC->pData ) goto no_mem;
- memcpy(pC->pData, pTos->z, pC->nData);
+ memcpy(pC->pData, pData->z, pC->nData);
pC->pData[pC->nData] = 0;
pC->pData[pC->nData+1] = 0;
}
pC->nullRow = 0;
}else{
int nZero;
- if( pTos->flags & MEM_Zero ){
- nZero = pTos->u.i;
+ if( pData->flags & MEM_Zero ){
+ nZero = pData->u.i;
}else{
nZero = 0;
}
rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
- pTos->z, pTos->n, nZero,
- pOp->p2 & OPFLAG_APPEND);
+ pData->z, pData->n, nZero,
+ pOp->p5 & OPFLAG_APPEND);
}
pC->rowidIsValid = 0;
@@ -3640,13 +3638,12 @@ case OP_Insert: { /* no-push */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
const char *zDb = db->aDb[pC->iDb].zName;
const char *zTbl = pOp->p4.p;
- int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+ int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
assert( pC->isTable );
db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
assert( pC->iDb>=0 );
}
}
- popStack(&pTos, 2);
break;
}
diff --git a/src/vdbe.h b/src/vdbe.h
index 30538add2..bf221ca5f 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.120 2008/01/03 07:54:24 danielk1977 Exp $
+** $Id: vdbe.h,v 1.121 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -133,7 +133,8 @@ int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
-void sqlite3VdbeChangeP3(Vdbe*, int addr, int P2);
+void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
+void sqlite3VdbeChangeP5(Vdbe*, int addr, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index dd310c4f0..c7c98f545 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -438,8 +438,7 @@ void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
}
/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
+** Change the value of the P3 operand for a specific instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
@@ -449,6 +448,16 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
}
/*
+** Change the value of the P3 operand for a specific instruction.
+*/
+void sqlite3VdbeChangeP5(Vdbe *p, int addr, u8 val){
+ assert( p==0 || p->magic==VDBE_MAGIC_INIT );
+ if( p && addr>=0 && p->nOp>addr && p->aOp ){
+ p->aOp[addr].p5 = val;
+ }
+}
+
+/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/