-C Modify\sVFilter\sand\sVRename\sto\suse\sregisters\sinstead\sof\sthe\svdbe\sstack\sfor\sinputs.\s(CVS\s4670)
-D 2008-01-03T18:39:42
+C Update\sOP_Rowid,\sOP_Column\sand\srelated\sopcodes\sto\suse\sregisters.\s(CVS\s4671)
+D 2008-01-03T18:44:59
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
F src/delete.c b5f77d88cc35367cfafc2e4edcf9327d19428615
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 4e6bd195630aa99c0fe1a17d1e913873402cb40c
+F src/expr.c 97c622402ef76303a211088936bdc55fb7be9104
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c dae0e2ed8838746f89b0fd6e642e819a792168e3
+F src/select.c 6aec65bf2d73bd45914ad27d9eb8c6cb18cf7b2b
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
-F src/sqliteInt.h 44c2d9976f42bf088ada24a06bbfb174e720a74e
+F src/sqliteInt.h ccbd4283c7cc9cc790abf720a2157515f19fb919
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
-F src/vdbe.c 0fa40511ae71f0acac07782c323ed4cdac73b4b0
+F src/vdbe.c b49db80b9f38c333fd52c5c879f0ee04aaf18d27
F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
F src/vdbeInt.h 869d0f550354c1364dde1d3611d770bd1c767505
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 0b849805c3a0f562d50623f406279b400d335639
-R 13147325b139cd4d2f4693ae66738f7d
-U danielk1977
-Z fbbaf889648e9db07fda0b9d48b503d1
+P 253ed40aa36247fc846cc41c8612cd29899d9f8f
+R e098bb2688e6d77b10a1673326b22bcb
+U drh
+Z e08561688fc1cefafc1989e1679d8673
-253ed40aa36247fc846cc41c8612cd29899d9f8f
\ No newline at end of file
+4f3967073d2df9eae5a61b9770d5de2e1af47b4c
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.327 2008/01/03 18:03:09 drh Exp $
+** $Id: expr.c,v 1.328 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/*
** Generate code that will extract the iColumn-th column from
-** table pTab and push that column value on the stack. There
-** is an open cursor to pTab in iTable. If iColumn<0 then
-** code is generated that extracts the rowid.
+** table pTab and store the column value in register iMem, or on
+** the stack if iMem==0. There is an open cursor to pTab in
+** iTable. If iColumn<0 then code is generated that extracts the rowid.
*/
-void sqlite3ExprCodeGetColumn(Vdbe *v, Table *pTab, int iColumn, int iTable){
+void sqlite3ExprCodeGetColumn(
+ Vdbe *v, /* The VM being created */
+ Table *pTab, /* Description of the table we are reading from */
+ int iColumn, /* Index of the table column */
+ int iTable, /* The cursor pointing to the table */
+ int iReg /* Store results here */
+){
if( iColumn<0 ){
int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid;
- sqlite3VdbeAddOp1(v, op, iTable);
+ sqlite3VdbeAddOp2(v, op, iTable, iReg);
}else if( pTab==0 ){
- sqlite3VdbeAddOp2(v, OP_Column, iTable, iColumn);
+ sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg);
}else{
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- sqlite3VdbeAddOp2(v, op, iTable, iColumn);
+ sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
sqlite3ColumnDefault(v, pTab, iColumn);
#ifndef SQLITE_OMIT_FLOATING_POINT
if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp0(v, OP_RealAffinity);
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
}
assert( pParse->ckOffset>0 );
sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
}else{
- sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable);
+ sqlite3ExprCodeGetColumn(v, pExpr->pTab,
+ pExpr->iColumn, pExpr->iTable, 0);
}
break;
}
*/
int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){
Vdbe *v = pParse->pVdbe;
- if( v==0 ) return -1;
- sqlite3ExprCode(pParse, pExpr);
- if( target<0 ){
+ assert( v!=0 || pParse->db->mallocFailed );
+ assert( pExpr!=0 || pParse->db->mallocFailed );
+ if( v==0 || pExpr==0 ) return -1;
+ if( target<=0 ){
target = ++pParse->nMem;
}
- sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);
+ if( pExpr->op==TK_COLUMN && pExpr->iTable>=0 ){
+ sqlite3ExprCodeGetColumn(v, pExpr->pTab,
+ pExpr->iColumn, pExpr->iTable, target);
+ }else{
+ sqlite3ExprCode(pParse, pExpr);
+ sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);
+ }
return target;
}
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.381 2008/01/03 18:03:09 drh Exp $
+** $Id: select.c,v 1.382 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn<j ) continue;
- sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable);
+ sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn,pCol->iTable,0);
j++;
}
sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.634 2008/01/03 17:31:45 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.635 2008/01/03 18:44:59 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**);
void sqlite3WhereEnd(WhereInfo*);
-void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int);
+void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int);
void sqlite3ExprCode(Parse*, Expr*);
void sqlite3ExprCodeAndCache(Parse*, Expr*);
int sqlite3ExprIntoReg(Parse*,Expr*,int);
** 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.672 2008/01/03 18:39:42 danielk1977 Exp $
+** $Id: vdbe.c,v 1.673 2008/01/03 18:44:59 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
break;
}
-/* Opcode: RealAffinity * * *
+/* Opcode: RealAffinity P1 * *
**
-** If the top of the stack is an integer, convert it to a real value.
+** If register P1 holds an integer convert it to a real value.
**
** This opcode is used when extracting information from a column that
** has REAL affinity. Such column values may still be stored as
** to have only a real value.
*/
case OP_RealAffinity: { /* no-push */
- assert( pTos>=p->aStack );
- if( pTos->flags & MEM_Int ){
- sqlite3VdbeMemRealify(pTos);
+ assert( pOp->p1>=0 && pOp->p1<=p->nMem );
+ if( pOp->p1==0 ){
+ if( pTos->flags & MEM_Int ){
+ sqlite3VdbeMemRealify(pTos);
+ }
+ }else{
+ Mem *pX = &p->aMem[pOp->p1];
+ if( pX->flags & MEM_Int ){
+ sqlite3VdbeMemRealify(pX);
+ }
}
break;
}
break;
}
-/* Opcode: Rowid P1 * *
+/* Opcode: Rowid P1 P2 * * *
**
-** Push onto the stack an integer which is the key of the table entry that
-** P1 is currently point to.
+** Store in register P2 an integer which is the key of the table entry that
+** P1 is currently point to. If p2==0 then pust the integer.
*/
case OP_Rowid: {
int i = pOp->p1;
Cursor *pC;
i64 v;
+ Mem *pDest;
assert( i>=0 && i<p->nCursor );
pC = p->apCsr[i];
assert( pC!=0 );
rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
- pTos++;
+ if( pOp->p2>0 ){
+ assert( pOp->p2<=p->nMem );
+ pDest = &p->aMem[pOp->p2];
+ sqlite3VdbeMemRelease(pDest);
+ }else{
+ pDest = ++pTos;
+ }
if( pC->rowidIsValid ){
v = pC->lastRowid;
}else if( pC->pseudoTable ){
v = keyToInt(pC->iKey);
}else if( pC->nullRow || pC->pCursor==0 ){
- pTos->flags = MEM_Null;
+ pDest->flags = MEM_Null;
break;
}else{
assert( pC->pCursor!=0 );
sqlite3BtreeKeySize(pC->pCursor, &v);
v = keyToInt(v);
}
- pTos->u.i = v;
- pTos->flags = MEM_Int;
+ pDest->u.i = v;
+ pDest->flags = MEM_Int;
break;
}
break;
}
-/* Opcode: IdxRowid P1 * *
+/* Opcode: IdxRowid P1 P2 * * *
**
-** Push onto the stack an integer which is the last entry in the record at
+** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1. This integer should be
** the rowid of the table entry to which this index entry points.
**
int i = pOp->p1;
BtCursor *pCrsr;
Cursor *pC;
+ Mem *pDest;
assert( i>=0 && i<p->nCursor );
assert( p->apCsr[i]!=0 );
- pTos++;
- pTos->flags = MEM_Null;
+ if( pOp->p2>0 ){
+ assert( pOp->p2<=p->nMem );
+ pDest = &p->aMem[pOp->p2];
+ sqlite3VdbeMemRelease(pDest);
+ }else{
+ pDest = ++pTos;
+ }
+ pDest->flags = MEM_Null;
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
i64 rowid;
assert( pC->deferredMoveto==0 );
assert( pC->isTable==0 );
if( pC->nullRow ){
- pTos->flags = MEM_Null;
+ pDest->flags = MEM_Null;
}else{
rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- pTos->flags = MEM_Int;
- pTos->u.i = rowid;
+ pDest->flags = MEM_Int;
+ pDest->u.i = rowid;
}
}
break;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VRowid P1 * *
+/* Opcode: VRowid P1 P2 *
**
-** Push an integer onto the stack which is the rowid of
+** Store into register P2 the rowid of
** the virtual-table that the P1 cursor is pointing to.
+** If P2==0, push the value onto the stack.
*/
case OP_VRowid: {
const sqlite3_module *pModule;
rc = SQLITE_ERROR;
} else {
sqlite_int64 iRow;
+ Mem *pDest;
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- pTos++;
- pTos->flags = MEM_Int;
- pTos->u.i = iRow;
+ if( pOp->p2>0 ){
+ assert( pOp->p2<=p->nMem );
+ pDest = &p->aMem[pOp->p2];
+ sqlite3VdbeMemRelease(pDest);
+ }else{
+ pDest = ++pTos;
+ }
+ pDest->flags = MEM_Int;
+ pDest->u.i = iRow;
}
break;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 *
+/* Opcode: VColumn P1 P2 P3
**
-** Push onto the stack the value of the P2-th column of
-** the row of the virtual-table that the P1 cursor is pointing to.
+** Store the value of the P2-th column of
+** the row of the virtual-table that the
+** P1 cursor is pointing to into register P3.
+** Or if P3==0 push the value onto the stack.
*/
case OP_VColumn: {
const sqlite3_module *pModule;
sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0);
rc = SQLITE_ERROR;
} else {
+ Mem *pDest;
sqlite3_context sContext;
memset(&sContext, 0, sizeof(sContext));
sContext.s.flags = MEM_Null;
** dynamic allocation in sContext.s (a Mem struct) is released.
*/
sqlite3VdbeChangeEncoding(&sContext.s, encoding);
- pTos++;
- pTos->flags = 0;
- sqlite3VdbeMemMove(pTos, &sContext.s);
+ if( pOp->p3>0 ){
+ assert( pOp->p3<=p->nMem );
+ pDest = &p->aMem[pOp->p3];
+ }else{
+ pDest = ++pTos;
+ pDest->flags = 0;
+ }
+ sqlite3VdbeMemMove(pDest, &sContext.s);
if( sqlite3SafetyOn(db) ){
goto abort_due_to_misuse;
}
- if( sqlite3VdbeMemTooBig(pTos) ){
+ if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
}