diff options
author | danielk1977 <danielk1977@noemail.net> | 2008-01-03 09:51:55 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2008-01-03 09:51:55 +0000 |
commit | 1f4aa337cd87ccb96fdaa58233ad691aaca1ac23 (patch) | |
tree | 4d1d62f99b3d9723546d9d238873f8cd8dda7a29 /src | |
parent | 11641c11363ef866ba15f197acf5cd38f2f518a8 (diff) | |
download | sqlite-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.c | 4 | ||||
-rw-r--r-- | src/build.c | 4 | ||||
-rw-r--r-- | src/delete.c | 18 | ||||
-rw-r--r-- | src/insert.c | 17 | ||||
-rw-r--r-- | src/select.c | 8 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/trigger.c | 8 | ||||
-rw-r--r-- | src/update.c | 6 | ||||
-rw-r--r-- | src/vdbe.c | 67 | ||||
-rw-r--r-- | src/vdbe.h | 5 | ||||
-rw-r--r-- | src/vdbeaux.c | 13 |
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. */ |