From: drh Date: Thu, 3 Jan 2008 23:44:53 +0000 (+0000) Subject: Change the sqlite3ExprCode() function so that callers can request that X-Git-Tag: version-3.6.10~1504 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=389a1adbd791c7814a7fecb72f57bd53d303c393;p=thirdparty%2Fsqlite.git Change the sqlite3ExprCode() function so that callers can request that the result of the expression be left on the stack or in a register. (CVS 4673) FossilOrigin-Name: 61bfb77c4267b99ac8a8ef49355bcbc395a1a37b --- diff --git a/manifest b/manifest index b28acd1ce3..dca696d48c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\scomment.\sTicket\s#2870.\s(CVS\s4672) -D 2008-01-03T18:56:26 +C Change\sthe\ssqlite3ExprCode()\sfunction\sso\sthat\scallers\scan\srequest\sthat\nthe\sresult\sof\sthe\sexpression\sbe\sleft\son\sthe\sstack\sor\sin\sa\sregister.\s(CVS\s4673) +D 2008-01-03T23:44:53 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -80,7 +80,7 @@ F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4 F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc F src/alter.c f95b19dab6e77978da5d75675f5cde7c6d3df120 F src/analyze.c addc8e75cc43eb7ad699cd3ffc0a9157b4bf9405 -F src/attach.c 4b214b411237531491e1186211e005e4de73630d +F src/attach.c 1c96631e56cdc51d3d70736bf61f1fe01c62cbea F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef @@ -92,11 +92,11 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 F src/delete.c b5f77d88cc35367cfafc2e4edcf9327d19428615 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 97c622402ef76303a211088936bdc55fb7be9104 +F src/expr.c e60ee4f48194469bf7b101fb7a14e56abea3daa4 F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 -F src/insert.c febae80da43fe28852f54d6ff8757ad03d1cda7b +F src/insert.c ecffad8ecc5dc69d6dc05d8dc136f872864af84e F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 @@ -131,12 +131,12 @@ F src/pragma.c ac8d91bb15dd475d239b9d7bd5dbd7d69a9428e7 F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3 F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da -F src/select.c 6aec65bf2d73bd45914ad27d9eb8c6cb18cf7b2b +F src/select.c 62b9cfb2c7c90570834816975ee1ceaf2e5a74e3 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 ccbd4283c7cc9cc790abf720a2157515f19fb919 +F src/sqliteInt.h 2cae3a7556208c68987752b6d8f9212a8a2327a7 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4 F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf @@ -164,7 +164,7 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730 F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48 F src/trigger.c 713b501b12ea41bf0297a2cf78f7d954c4a25d13 -F src/update.c b4aa2e8b6bda3b4d917c9427568fe5c85b4a0ea8 +F src/update.c a68e11e766376bf0fbec93d70c9389c4c502dd55 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0 @@ -177,7 +177,7 @@ F src/vdbeblob.c b90f7494c408d47ce6835000b01e40b371e27baf F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4 F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a -F src/where.c 10c0616d30112732cf4b13b8cd06d7ceefb6d985 +F src/where.c ce1e6c53fa443d8adb06358726d66c891429e769 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba @@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 4f3967073d2df9eae5a61b9770d5de2e1af47b4c -R 4f52a37c5fa32ca6d78b4ef42fbde779 -U danielk1977 -Z 0337ebe6152fe10004220ecc78a15376 +P e97e4578671d85b634072b8931cf55516bbd4ca8 +R d8d82fb96584ffb5e00eae859b1e26e3 +U drh +Z bf1918304aac944329f9dd57da302e51 diff --git a/manifest.uuid b/manifest.uuid index 5ab29b2f68..1ef8aef886 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e97e4578671d85b634072b8931cf55516bbd4ca8 \ No newline at end of file +61bfb77c4267b99ac8a8ef49355bcbc395a1a37b \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index fd3d7f2bf8..768d91ae2a 100644 --- a/src/attach.c +++ b/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.65 2008/01/03 00:01:24 drh Exp $ +** $Id: attach.c,v 1.66 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" @@ -326,9 +326,9 @@ static void codeAttach( } v = sqlite3GetVdbe(pParse); - sqlite3ExprCode(pParse, pFilename); - sqlite3ExprCode(pParse, pDbname); - sqlite3ExprCode(pParse, pKey); + sqlite3ExprCode(pParse, pFilename, 0); + sqlite3ExprCode(pParse, pDbname, 0); + sqlite3ExprCode(pParse, pKey, 0); assert( v || db->mallocFailed ); if( v ){ diff --git a/src/expr.c b/src/expr.c index c6f6f415d5..17e3165a14 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.328 2008/01/03 18:44:59 drh Exp $ +** $Id: expr.c,v 1.329 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" #include @@ -1784,7 +1784,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } /* Evaluate the expression and insert it into the temp table */ - sqlite3ExprCode(pParse, pE2); + sqlite3ExprCode(pParse, pE2, 0); sqlite3VdbeAddOp4(v, OP_MakeRecord, 1, 0, 0, &affinity, 1); sqlite3VdbeAddOp1(v, OP_IdxInsert, pExpr->iTable); } @@ -1927,7 +1927,12 @@ void sqlite3ExprCodeGetColumn( /* ** Generate code into the current Vdbe to evaluate the given -** expression and leave the result on the top of stack. +** expression and leaves the result in a register on on the stack. +** +** If the target register number is negative, allocate a new +** register to store the result. If the target register number +** is zero then push the result onto the stack. Return the target +** register number regardless. ** ** This code depends on the fact that certain token values (ex: TK_EQ) ** are the same as opcode values (ex: OP_Eq) that implement the corresponding @@ -1935,17 +1940,27 @@ void sqlite3ExprCodeGetColumn( ** the make process cause these values to align. Assert()s in the code ** below verify that the numbers are aligned correctly. */ -void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ +int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; int op; - int stackChng = 1; /* Amount of change to stack depth */ + int inReg = 0; + int stackChng = 0; + int subtarget = -1; + + assert( v!=0 || pParse->db->mallocFailed ); + if( v==0 ) return 0; + if( target<0 ){ + target = ++pParse->nMem; + }else if( target==0 ){ + stackChng = 1; + subtarget = 0; + } - if( v==0 ) return; if( pExpr==0 ){ - sqlite3VdbeAddOp0(v, OP_Null); - return; + op = TK_NULL; + }else{ + op = pExpr->op; } - op = pExpr->op; switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; @@ -1954,8 +1969,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp1(v, OP_MemLoad, pCol->iMem); break; }else if( pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp2(v, OP_Column, pAggInfo->sortingIdx, - pCol->iSorterColumn); + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, + pCol->iSorterColumn, target); + inReg = 1; break; } /* Otherwise, fall thru into the TK_COLUMN case */ @@ -1967,7 +1983,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, - pExpr->iColumn, pExpr->iTable, 0); + pExpr->iColumn, pExpr->iTable, target); + inReg = 1; } break; } @@ -2019,7 +2036,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ int aff, to_op; - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); aff = sqlite3AffinityType(&pExpr->token); to_op = aff - SQLITE_AFF_TEXT + OP_ToText; assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT ); @@ -2044,8 +2061,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); + sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0); stackChng = -1; break; @@ -2073,8 +2090,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( TK_LSHIFT==OP_ShiftLeft ); assert( TK_RSHIFT==OP_ShiftRight ); assert( TK_CONCAT==OP_Concat ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); + sqlite3ExprCode(pParse, pExpr->pRight, 0); sqlite3VdbeAddOp0(v, op); stackChng = -1; break; @@ -2097,7 +2114,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); assert( TK_NOT==OP_Not ); - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp0(v, op); stackChng = 0; break; @@ -2108,7 +2125,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); sqlite3VdbeAddOp1(v, OP_Integer, 1); - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); dest = sqlite3VdbeCurrentAddr(v) + 2; sqlite3VdbeAddOp2(v, op, 1, dest); sqlite3VdbeAddOp1(v, OP_AddImm, -1); @@ -2142,7 +2159,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); - nExpr = sqlite3ExprCodeExprList(pParse, pList); + nExpr = sqlite3ExprCodeExprList(pParse, pList, 0); #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. @@ -2210,7 +2227,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* Code the from " IN (...)". The temporary table ** pExpr->iTable contains the values that make up the (...) set. */ - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+4); /* addr + 0 */ sqlite3VdbeAddOp1(v, OP_Pop, 2); @@ -2236,20 +2253,20 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; - sqlite3ExprCode(pParse, pLeft); + sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp0(v, OP_Dup); - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0); sqlite3VdbeAddOp1(v, OP_Pull, 1); pLItem++; pRight = pLItem->pExpr; - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0); sqlite3VdbeAddOp0(v, OP_And); break; } case TK_UPLUS: { - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); stackChng = 0; break; } @@ -2269,10 +2286,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ nExpr = pEList->nExpr; expr_end_label = sqlite3VdbeMakeLabel(v); if( pExpr->pLeft ){ - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); } for(i=0; ipLeft ){ sqlite3VdbeAddOp2(v, OP_Dup, 1, 1); jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, @@ -2281,7 +2298,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ }else{ jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0); } - sqlite3ExprCode(pParse, aListelem[i+1].pExpr); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label); sqlite3VdbeJumpHere(v, jumpInst); } @@ -2289,7 +2306,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); } if( pExpr->pRight ){ - sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3ExprCode(pParse, pExpr->pRight, 0); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); } @@ -2301,7 +2318,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ if( !pParse->trigStack ){ sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); - return; + return 0; } if( pExpr->iColumn!=OE_Ignore ){ assert( pExpr->iColumn==OE_Rollback || @@ -2321,11 +2338,15 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } #endif } - + if( target && !inReg ){ + sqlite3VdbeAddOp2(v, OP_MemStore, target, 1); + stackChng = 0; + } if( pParse->ckOffset ){ pParse->ckOffset += stackChng; assert( pParse->ckOffset ); } + return target; } #ifndef SQLITE_OMIT_TRIGGER @@ -2346,7 +2367,7 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ int addr1, addr2; if( v==0 ) return; addr1 = sqlite3VdbeCurrentAddr(v); - sqlite3ExprCode(pParse, pExpr); + sqlite3ExprCode(pParse, pExpr, 0); addr2 = sqlite3VdbeCurrentAddr(v); if( addr2>addr1+1 || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){ @@ -2357,33 +2378,6 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ } #endif -/* -** Generate code to evaluate an expression and store the result in -** a designated register. If the target register number is negative, -** allocate a new register to store the result. Return the target -** register number regardless. -** -** The current implementation is a rough prototype for experimental -** purposes. There are many optimization opportunities here. -*/ -int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){ - Vdbe *v = pParse->pVdbe; - 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; - } - 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; -} - /* ** Generate code that pushes the value of every element of the given ** expression list onto the stack. @@ -2392,14 +2386,22 @@ int sqlite3ExprIntoReg(Parse *pParse, Expr *pExpr, int target){ */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ - ExprList *pList /* The expression list to be coded */ + ExprList *pList, /* The expression list to be coded */ + int target /* Where to write results */ ){ struct ExprList_item *pItem; - int i, n; + int i, n, incr = 1; if( pList==0 ) return 0; n = pList->nExpr; + if( target<0 ){ + target = pParse->nMem+1; + pParse->nMem += n; + }else if( target==0 ){ + incr = 0; + } for(pItem=pList->a, i=n; i>0; i--, pItem++){ - sqlite3ExprCode(pParse, pItem->pExpr); + sqlite3ExprCode(pParse, pItem->pExpr, target); + target += incr; } return n; } @@ -2453,8 +2455,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert( TK_GE==OP_Ge ); assert( TK_EQ==OP_Eq ); assert( TK_NE==OP_Ne ); - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); + sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } @@ -2462,7 +2464,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); assert( TK_NOTNULL==OP_NotNull ); - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp2(v, op, 1, dest); break; } @@ -2476,13 +2478,13 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ int addr; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; - sqlite3ExprCode(pParse, pLeft); + sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull); pRight = pExpr->pList->a[1].pExpr; - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull); sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); @@ -2491,7 +2493,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } default: { - sqlite3ExprCode(pParse, pExpr); + sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest); break; } @@ -2567,14 +2569,14 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - sqlite3ExprCode(pParse, pExpr->pLeft); - sqlite3ExprCode(pParse, pExpr->pRight); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); + sqlite3ExprCode(pParse, pExpr->pRight, 0); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } case TK_ISNULL: case TK_NOTNULL: { - sqlite3ExprCode(pParse, pExpr->pLeft); + sqlite3ExprCode(pParse, pExpr->pLeft, 0); sqlite3VdbeAddOp2(v, op, 1, dest); break; } @@ -2588,21 +2590,21 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ int addr; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; - sqlite3ExprCode(pParse, pLeft); + sqlite3ExprCode(pParse, pLeft, 0); sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); addr = sqlite3VdbeCurrentAddr(v); codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Goto, 0, dest); pRight = pExpr->pList->a[1].pExpr; - sqlite3ExprCode(pParse, pRight); + sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull); break; } default: { - sqlite3ExprCode(pParse, pExpr); + sqlite3ExprCode(pParse, pExpr, 0); sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest); break; } diff --git a/src/insert.c b/src/insert.c index 63dd967bcf..de74736b71 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.207 2008/01/03 18:03:09 drh Exp $ +** $Id: insert.c,v 1.208 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" @@ -660,7 +660,7 @@ void sqlite3Insert( sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); + sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, -1, 0); @@ -683,7 +683,7 @@ void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, j); }else{ @@ -727,7 +727,7 @@ void sqlite3Insert( sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1); }else{ VdbeOp *pOp; - sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); + sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); if( pOp && pOp->opcode==OP_Null ){ appendFlag = 1; @@ -780,13 +780,13 @@ void sqlite3Insert( } } if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); }else if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Column, srcTab, j); }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1); }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr); + sqlite3ExprCode(pParse, pList->a[j].pExpr, 0); } } @@ -1012,7 +1012,7 @@ void sqlite3GenerateConstraintChecks( break; } case OE_Replace: { - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0); break; } diff --git a/src/select.c b/src/select.c index 61ccbc4812..9fda68673a 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.382 2008/01/03 18:44:59 drh Exp $ +** $Id: select.c,v 1.383 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" @@ -387,7 +387,7 @@ static void pushOntoSorter( Select *pSelect /* The whole SELECT statement */ ){ Vdbe *v = pParse->pVdbe; - sqlite3ExprCodeExprList(pParse, pOrderBy); + sqlite3ExprCodeExprList(pParse, pOrderBy, 0); sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, 0); sqlite3VdbeAddOp2(v, OP_Pull, pOrderBy->nExpr + 1, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0); @@ -553,7 +553,7 @@ static int selectInnerLoop( ** values returned by the SELECT are not required. */ for(i=0; ia[i].pExpr, iMem+i+1); + sqlite3ExprCode(pParse, pEList->a[i].pExpr, iMem+i+1); } } nColumn = n; @@ -1750,7 +1750,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3ExprCode(pParse, p->pLimit); + sqlite3ExprCode(pParse, p->pLimit, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1); VdbeComment((v, "LIMIT counter")); @@ -1761,7 +1761,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->iOffset = iOffset = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3ExprCode(pParse, p->pOffset); + sqlite3ExprCode(pParse, p->pOffset, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0); VdbeComment((v, "OFFSET counter")); @@ -2978,7 +2978,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; - sqlite3ExprCodeExprList(pParse, pList); + sqlite3ExprCodeExprList(pParse, pList, 0); }else{ nArg = 0; } @@ -3007,8 +3007,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ } } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pExpr); - sqlite3VdbeAddOp2(v, OP_MemStore, pC->iMem, 1); + sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; } @@ -3518,7 +3517,7 @@ int sqlite3Select( ** in sorted order */ groupBySort = 1; - sqlite3ExprCodeExprList(pParse, pGroupBy); + sqlite3ExprCodeExprList(pParse, pGroupBy, 0); sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0); j = pGroupBy->nExpr+1; for(i=0; ia[j].pExpr); + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, 0); } sqlite3VdbeAddOp2(v, OP_MemStore, iBMem+j, jnExpr-1); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bbac412b3d..3e75f1f53a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.635 2008/01/03 18:44:59 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.636 2008/01/03 23:44:53 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1738,10 +1738,9 @@ void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCodeGetColumn(Vdbe*, Table*, int, int, int); -void sqlite3ExprCode(Parse*, Expr*); +int sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeAndCache(Parse*, Expr*); -int sqlite3ExprIntoReg(Parse*,Expr*,int); -int sqlite3ExprCodeExprList(Parse*, ExprList*); +int sqlite3ExprCodeExprList(Parse*, ExprList*, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); diff --git a/src/update.c b/src/update.c index ac48164465..3b0f1fd492 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.154 2008/01/03 18:03:09 drh Exp $ +** $Id: update.c,v 1.155 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" @@ -467,7 +467,7 @@ void sqlite3Update( ** on top of the stack.) */ if( chngRowid ){ - sqlite3ExprCode(pParse, pRowidExpr); + sqlite3ExprCode(pParse, pRowidExpr, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); } @@ -483,7 +483,7 @@ void sqlite3Update( sqlite3VdbeAddOp2(v, OP_Column, iCur, i); sqlite3ColumnDefault(v, pTab, i); }else{ - sqlite3ExprCode(pParse, pChanges->a[j].pExpr); + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, 0); } } diff --git a/src/where.c b/src/where.c index c5f64eed64..ad7901ead8 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.271 2008/01/03 18:39:42 danielk1977 Exp $ +** $Id: where.c,v 1.272 2008/01/03 23:44:53 drh Exp $ */ #include "sqliteInt.h" @@ -1731,7 +1731,7 @@ static void codeEqualityTerm( Expr *pX = pTerm->pExpr; Vdbe *v = pParse->pVdbe; if( pX->op==TK_EQ ){ - sqlite3ExprCode(pParse, pX->pRight); + sqlite3ExprCode(pParse, pX->pRight, 0); }else if( pX->op==TK_ISNULL ){ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); #ifndef SQLITE_OMIT_SUBQUERY @@ -2284,7 +2284,7 @@ WhereInfo *sqlite3WhereBegin( for(k=0; kpRight); + sqlite3ExprCode(pParse, wc.a[iTerm].pExpr->pRight, 0); break; } } @@ -2347,7 +2347,7 @@ WhereInfo *sqlite3WhereBegin( pX = pStart->pExpr; assert( pX!=0 ); assert( pStart->leftCursor==iCur ); - sqlite3ExprCode(pParse, pX->pRight); + sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_ForceInt, pX->op==TK_LE || pX->op==TK_GT, brk); sqlite3VdbeAddOp2(v, bRev ? OP_MoveLt : OP_MoveGe, iCur, brk); VdbeComment((v, "pk")); @@ -2360,7 +2360,7 @@ WhereInfo *sqlite3WhereBegin( pX = pEnd->pExpr; assert( pX!=0 ); assert( pEnd->leftCursor==iCur ); - sqlite3ExprCode(pParse, pX->pRight); + sqlite3ExprCode(pParse, pX->pRight, 0); pLevel->iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); if( pX->op==TK_LT || pX->op==TK_GT ){ @@ -2442,7 +2442,7 @@ WhereInfo *sqlite3WhereBegin( assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); - sqlite3ExprCode(pParse, pX->pRight); + sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq*2+1), nxt); topEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); @@ -2481,7 +2481,7 @@ WhereInfo *sqlite3WhereBegin( assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); - sqlite3ExprCode(pParse, pX->pRight); + sqlite3ExprCode(pParse, pX->pRight, 0); sqlite3VdbeAddOp2(v, OP_IsNull, -(nEq+1), nxt); btmEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm);