-C Fix\smixing\squote\sexcapes\sin\san\sawk\sscript.\s\sTicket\s#2877.\s(CVS\s4702)
-D 2008-01-10T00:08:43
+C Continuing\swork\stoward\sregisterizing\sthe\scode\sgenerator.\s(CVS\s4703)
+D 2008-01-10T03:46:36
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 4f760fb7e9b0bb3cf05534bb9d43ea9e726b7e74
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 27971029714d4b24081cf20b35e7c96d0e148311
+F src/expr.c 522ba17fa6253a98dc6451e600341277ea43d5c6
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
-F src/insert.c 8630ee92dac91944c9f7b75847fa4ef74292b220
+F src/insert.c b8406b40cc1cac732932ef587cbc0da006bfd68b
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c 7b88e17052dce3c89530cd6be014505b00d6ff4c
+F src/select.c 095296a572c296c9ce718768c6c984d33b239e5a
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 c2866ab4a8eb42e4daffe30d19afc82952ed67c1
+F src/sqliteInt.h 0606321d38df78adef2325e0b51cd3963731f290
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 1134c5ea7116bb2f342ccf09548d075c308c427b
-R 965fc5391bf9a2a36bfcbb9b6a1fc252
+P 05fbca91085cb1b271a05e62181596b4f6f1bb9e
+R 44353c14eaa458d109462754e477c6c2
U drh
-Z b84d4a6ab04978dba07488e081c74e60
+Z d88167e0b41893f49eaf4061856356de
-05fbca91085cb1b271a05e62181596b4f6f1bb9e
\ No newline at end of file
+173698c963473ab1b9db88b23a2de82e4097b96d
\ 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.340 2008/01/09 23:04:12 drh Exp $
+** $Id: expr.c,v 1.341 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
- iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
+ iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
- iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
+ iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
*/
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
int mem = ++pParse->nMem;
- sqlite3VdbeAddOp1(v, OP_SCopy, mem);
- testAddr = sqlite3VdbeAddOp0(v, OP_If);
+ sqlite3VdbeAddOp1(v, OP_If, mem);
+ testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
assert( testAddr>0 || pParse->db->mallocFailed );
- sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
}
switch( pExpr->op ){
** this code only executes once. Because for a non-constant
** expression we need to rerun this code each time.
*/
- if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){
- sqlite3VdbeChangeToNoop(v, testAddr-1, 3);
+ if( testAddr && !sqlite3ExprIsConstant(pE2) ){
+ sqlite3VdbeChangeToNoop(v, testAddr-1, 2);
testAddr = 0;
}
}
if( testAddr ){
- sqlite3VdbeJumpHere(v, testAddr);
+ sqlite3VdbeJumpHere(v, testAddr-1);
}
return;
nId = pExpr->token.n;
pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0);
assert( pDef!=0 );
- nExpr = sqlite3ExprCodeExprList(pParse, pList, 0);
+ if( pList ){
+ nExpr = pList->nExpr;
+ sqlite3ExprCodeExprList(pParse, pList, 0);
+ }else{
+ nExpr = 0;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Possibly overload the function if the first argument is
** a virtual table column.
/*
** Generate code that pushes the value of every element of the given
-** expression list onto the stack.
+** expression list onto the stack if target==0 or into a sequence of
+** registers beginning at target.
**
-** Return the number of elements pushed onto the stack.
+** Return the number of elements evaluated.
*/
int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
){
struct ExprList_item *pItem;
int i, n, incr = 1;
- if( pList==0 ) return 0;
+ assert( pList!=0 || pParse->db->mallocFailed );
+ if( pList==0 ){
+ return 0;
+ }
+ assert( target>=0 );
n = pList->nExpr;
- if( target<0 ){
- target = pParse->nMem+1;
- pParse->nMem += n;
- }else if( target==0 ){
+ if( target==0 ){
incr = 0;
}
for(pItem=pList->a, i=n; i>0; i--, pItem++){
}
return nErr;
}
+
+/*
+** Allocate or deallocate temporary use registers during code generation.
+*/
+int sqlite3GetTempReg(Parse *pParse){
+ if( pParse->nTempReg ){
+ return pParse->aTempReg[--pParse->nTempReg];
+ }else{
+ return ++pParse->nMem;
+ }
+}
+void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
+ if( pParse->nTempReg<sizeof(pParse->aTempReg)/sizeof(pParse->aTempReg[0]) ){
+ pParse->aTempReg[pParse->nTempReg++] = iReg;
+ }
+}
+
+/*
+** Allocate or deallocate a block of nReg consecutive registers
+*/
+int sqlite3GetTempRange(Parse *pParse, int nReg){
+ int i;
+ if( nReg<=pParse->nRangeReg ){
+ i = pParse->iRangeReg;
+ pParse->iRangeReg += nReg;
+ pParse->nRangeReg -= nReg;
+ }else{
+ i = pParse->nMem+1;
+ pParse->nMem += nReg;
+ }
+ return i;
+}
+void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
+ if( nReg>pParse->nRangeReg ){
+ pParse->nRangeReg = nReg;
+ pParse->iRangeReg = iReg;
+ }
+}
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.220 2008/01/09 23:04:12 drh Exp $
+** $Id: insert.c,v 1.221 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"
}
if( isUpdate ){
- sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1);
- sqlite3VdbeAddOp1(v, OP_SCopy, regRowid);
- j2 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
+ j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
}
j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
switch( onError ){
case OE_Replace: {
sqlite3GenerateRowIndexDelete(v, pTab, baseCur, 0);
if( isUpdate ){
- sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-hasTwoRowids);
- sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0);
+ sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-hasTwoRowids);
}
seenReplace = 1;
break;
sqlite3VdbeJumpHere(v, j3);
if( isUpdate ){
sqlite3VdbeJumpHere(v, j2);
- sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1);
- sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0);
+ sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-1);
}
}
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.395 2008/01/09 23:04:12 drh Exp $
+** $Id: select.c,v 1.396 2008/01/10 03:46:36 drh Exp $
*/
#include "sqliteInt.h"
Select *pSelect /* The whole SELECT statement */
){
Vdbe *v = pParse->pVdbe;
- sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
- sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor);
- sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1);
- sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2);
- sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor);
+ int nExpr = pOrderBy->nExpr;
+ int regBase = sqlite3GetTempRange(pParse, nExpr+2);
+ int regRecord = sqlite3GetTempReg(pParse);
+ sqlite3ExprCodeExprList(pParse, pOrderBy, regBase);
+ sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
+ sqlite3VdbeAddOp2(v, OP_Move, 0, regBase+nExpr+1);
+ sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nExpr + 2, regRecord);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
+ sqlite3ReleaseTempReg(pParse, regRecord);
+ sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
if( pSelect->iLimit>=0 ){
int addr1, addr2;
addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1);
ExprList *pList = pF->pExpr->pList;
if( pList ){
nArg = pList->nExpr;
- sqlite3ExprCodeExprList(pParse, pList, 0);
- regAgg = sqlite3StackToReg(pParse, nArg);
+ regAgg = sqlite3GetTempRange(pParse, nArg);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg);
}else{
nArg = 0;
regAgg = 0;
sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
(void*)pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, nArg);
+ sqlite3ReleaseTempRange(pParse, regAgg, nArg);
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
}
** then loop over the sorting index in order to get the output
** in sorted order
*/
+ int regBase;
+ int regRecord;
+ int nCol;
+ int nGroupBy;
+
groupBySort = 1;
- sqlite3ExprCodeExprList(pParse, pGroupBy, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0);
- j = pGroupBy->nExpr+1;
+ nGroupBy = pGroupBy->nExpr;
+ nCol = nGroupBy + 1;
+ j = nGroupBy+1;
+ for(i=0; i<sAggInfo.nColumn; i++){
+ if( sAggInfo.aCol[i].iSorterColumn>=j ){
+ nCol++;
+ j++;
+ }
+ }
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ sqlite3ExprCodeExprList(pParse, pGroupBy, regBase);
+ sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
+ j = nGroupBy+1;
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,0);
- j++;
+ if( pCol->iSorterColumn>=j ){
+ sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable,
+ j + regBase);
+ j++;
+ }
}
- sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0);
+ regRecord = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nCol, regRecord);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord);
+ sqlite3ReleaseTempReg(pParse, regRecord);
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
sqlite3WhereEnd(pWInfo);
sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd);
VdbeComment((v, "GROUP BY sort"));
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.645 2008/01/09 23:04:12 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.646 2008/01/10 03:46:36 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 parseError; /* True after a parsing error. Ticket #1794 */
+ u8 nTempReg; /* Number of temporary registers in aTempReg[] */
+ int aTempReg[8]; /* Holding area for temporary registers */
+ int nRangeReg; /* Size of the temporary register block */
+ int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
void sqlite3FinishCoding(Parse*);
+int sqlite3GetTempReg(Parse*);
+void sqlite3ReleaseTempReg(Parse*,int);
+int sqlite3GetTempRange(Parse*,int);
+void sqlite3ReleaseTempRange(Parse*,int,int);
Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
Expr *sqlite3RegisterExpr(Parse*,Token*);