From: drh Date: Wed, 9 Jan 2008 02:15:38 +0000 (+0000) Subject: Continued work toward converting to a register-based VM. (CVS 4698) X-Git-Tag: version-3.6.10~1479 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3c84ddff3efa925c8262481945ff704e5cef7486;p=thirdparty%2Fsqlite.git Continued work toward converting to a register-based VM. (CVS 4698) FossilOrigin-Name: 92deff07bba2089bbe011f44defb3a0ac1362d56 --- diff --git a/manifest b/manifest index 48bf47b5ee..5b6bc3fb02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Registerify\sthe\scomparison\sopcodes.\s(CVS\s4697) -D 2008-01-08T23:54:25 +C Continued\swork\stoward\sconverting\sto\sa\sregister-based\sVM.\s(CVS\s4698) +D 2008-01-09T02:15:39 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -92,11 +92,11 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 F src/delete.c 971f5f774d121cfb790630a878a54c939b5b1494 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 26b29dabea522d13b8da8cb41b35ed61aca6706c +F src/expr.c f1bee4f35fef3078fdbf9075f2b18e41202ccb09 F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 -F src/insert.c c79591d68740681bc28883206763595168ef15d4 +F src/insert.c 4443b9026fe9be6c64a689879c564dcd8b7cbcb3 F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 @@ -127,11 +127,11 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429 F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1 -F src/pragma.c ebf841efccc8d2df410fc10aa556a64256457ab4 -F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3 +F src/pragma.c 355d53bc64b70d2dfcd9a1c4a9c5c2ea87da2857 +F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da -F src/select.c d6bdf86c76c899991f7339291f124718028e8446 +F src/select.c 8570d4db93e115227393fd3cdf88be28d9ac585b F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f @@ -164,11 +164,11 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730 F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48 F src/trigger.c 1e77b3c21c129ad01f7f23a497ae1d224b4e5bc4 -F src/update.c 89ba318306daa20d901ed698018fe6e3d16b3586 +F src/update.c 93c7bca744988798c8898d024512954683e3e370 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736 F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0 -F src/vdbe.c 926b4630c583f355d5c7376ebc17d82f43a91866 +F src/vdbe.c cf1f4de3b96226da2b53fd01b843d5bb0d58f723 F src/vdbe.h c686e1b73011e74b764971b83c97069ece3c04cb F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346 F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c @@ -177,7 +177,7 @@ F src/vdbeblob.c b90f7494c408d47ce6835000b01e40b371e27baf F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c a94f3e9e85578ba457133ad3446fc6114a03ec5a F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a -F src/where.c 8f55e7257daf93d9c715df7cb312dede6f2d45d2 +F src/where.c 8c2bedcc61961a470c358b8c1466c7d8915bc722 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba @@ -605,7 +605,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c -R 22639e8ca20a12d23612d55375b01a67 +P 8862ce9ceefba4f5d1ffbd51d824c05f42a58c22 +R 0091ff2603f4efdcadacf8e9bc937331 U drh -Z 654c7ee149d8fd3c6129fb629505622c +Z 95c6f21519b46535c3e92448c74b125f diff --git a/manifest.uuid b/manifest.uuid index 4f8be3394d..a07fb92459 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8862ce9ceefba4f5d1ffbd51d824c05f42a58c22 \ No newline at end of file +92deff07bba2089bbe011f44defb3a0ac1362d56 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 5aa1b747f0..b332f4531a 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.338 2008/01/08 23:54:25 drh Exp $ +** $Id: expr.c,v 1.339 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -2121,10 +2121,14 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ }else{ codeInteger(v, (char*)p->z, p->n, 1, target); } - inReg = target; - break; + }else{ + int r1 = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); + sqlite3ExprCode(pParse, pExpr->pLeft, target); + sqlite3VdbeAddOp3(v, OP_Subtract, target, r1, target); } - /* Fall through into TK_NOT */ + inReg = target; + break; } case TK_BITNOT: case TK_NOT: { @@ -2245,7 +2249,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ j2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j1); if( eType==IN_INDEX_ROWID ){ - j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, 1); + j3 = sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, 1); j4 = sqlite3VdbeAddOp1(v, OP_NotExists, pExpr->iTable); j5 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, j3); @@ -2314,7 +2318,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp1(v, OP_Pop, 1); }else{ - jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0); + jumpInst = sqlite3VdbeAddOp3(v, OP_IfNot, 0, 0, 1); } sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label); @@ -2513,7 +2517,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } default: { sqlite3ExprCode(pParse, pExpr, 0); - sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest); + sqlite3VdbeAddOp3(v, OP_If, 0, dest, jumpIfNull!=0); break; } } @@ -2627,7 +2631,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ } default: { sqlite3ExprCode(pParse, pExpr, 0); - sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest); + sqlite3VdbeAddOp3(v, OP_IfNot, 0, dest, jumpIfNull!=0); break; } } diff --git a/src/insert.c b/src/insert.c index cf6c8ac3ad..ea1e7c5c56 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.218 2008/01/08 23:54:25 drh Exp $ +** $Id: insert.c,v 1.219 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" @@ -779,10 +779,10 @@ void sqlite3Insert( ** to generate a unique primary key value. */ if( !appendFlag ){ - sqlite3VdbeAddOp2(v, OP_IfMemNull, regRowid, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc); - sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); } }else if( IsVirtual(pTab) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); diff --git a/src/pragma.c b/src/pragma.c index b4b4059161..96fabbd5d1 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.162 2008/01/07 19:20:25 drh Exp $ +** $Id: pragma.c,v 1.163 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -298,13 +298,13 @@ void sqlite3Pragma( */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { - { OP_ReadCookie, 0, 0, 2}, /* 0 */ - { OP_AbsValue, 0, 0, 0}, - { OP_Copy, 0, 0, 0}, - { OP_Integer, 0, 0, 0}, - { OP_Ne, 0, 6, 0}, - { OP_Integer, 0, 0, 0}, /* 5 */ - { OP_Callback, 1, 0, 0}, + { OP_ReadCookie, 0, 1, 2}, /* 0 */ + { OP_IfPos, 1, 6, 0}, + { OP_Integer, 0, 2, 0}, + { OP_Subtract, 1, 2, 1}, + { OP_IfPos, 1, 6, 0}, + { OP_Integer, 0, 1, 0}, /* 5 */ + { OP_ResultRow, 1, 1, 0}, }; int addr; if( sqlite3ReadSchema(pParse) ) goto pragma_out; @@ -312,6 +312,7 @@ void sqlite3Pragma( if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC); + pParse->nMem += 2; addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); @@ -319,11 +320,11 @@ void sqlite3Pragma( int size = atoi(zRight); if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp2(v, OP_Integer, size, 0); + sqlite3VdbeAddOp1(v, OP_Integer, size); sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2); - addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3); - sqlite3VdbeAddOp2(v, OP_Negative, 0, 0); + addr = sqlite3VdbeAddOp2(v, OP_IfPos, 0, 0); + sqlite3VdbeAddOp1(v, OP_Integer, -size); + sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); @@ -493,10 +494,10 @@ void sqlite3Pragma( } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); - addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0); - sqlite3VdbeAddOp2(v, OP_Callback, 0, 0); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); + sqlite3VdbeAddOp0(v, OP_Callback); sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, addr); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); sqlite3VdbeJumpHere(v, addr); }else #endif @@ -863,7 +864,7 @@ void sqlite3Pragma( if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); - addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); @@ -899,7 +900,7 @@ void sqlite3Pragma( int loopTop; if( pTab->pIndex==0 ) continue; - addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); @@ -945,7 +946,7 @@ void sqlite3Pragma( { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; - addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); diff --git a/src/prepare.c b/src/prepare.c index 33e3fda89a..ba080fcf34 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.70 2008/01/03 07:09:48 danielk1977 Exp $ +** $Id: prepare.c,v 1.71 2008/01/09 02:15:39 drh Exp $ */ #include "sqliteInt.h" #include @@ -269,6 +269,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ size = meta[2]; if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } + if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); diff --git a/src/select.c b/src/select.c index 6f1d1dc93b..d8c4c9fe75 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.393 2008/01/08 23:54:25 drh Exp $ +** $Id: select.c,v 1.394 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" @@ -398,18 +398,18 @@ static void pushOntoSorter( ){ Vdbe *v = pParse->pVdbe; 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); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, 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); if( pSelect->iLimit>=0 ){ int addr1, addr2; - addr1 = sqlite3VdbeAddOp2(v, OP_IfMemZero, pSelect->iLimit+1, 0); + addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1); sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1); - addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + addr2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp2(v, OP_Last, pOrderBy->iECursor, 0); - sqlite3VdbeAddOp2(v, OP_Delete, pOrderBy->iECursor, 0); + sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor); + sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor); sqlite3VdbeJumpHere(v, addr2); pSelect->iLimit = -1; } @@ -427,9 +427,9 @@ static void codeOffset( if( p->iOffset>=0 && iContinue!=0 ){ int addr; sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1); - addr = sqlite3VdbeAddOp2(v, OP_IfMemNeg, p->iOffset, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset); if( nPop>0 ){ - sqlite3VdbeAddOp2(v, OP_Pop, nPop, 0); + sqlite3VdbeAddOp1(v, OP_Pop, nPop); } sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue); VdbeComment((v, "skip OFFSET records")); @@ -641,7 +641,7 @@ static int selectInnerLoop( int addr2; assert( nColumn==1 ); - addr2 = sqlite3VdbeAddOp2(v, OP_IfMemNull, iMem, 0); + addr2 = sqlite3VdbeAddOp2(v, OP_IsNull, iMem, 0); p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); if( pOrderBy ){ /* At first glance you would think we could optimize out the @@ -717,7 +717,7 @@ static int selectInnerLoop( */ if( p->iLimit>=0 && pOrderBy==0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); - sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, iBreak); + sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); } return 0; } @@ -852,7 +852,7 @@ static void generateSortTail( */ if( p->iLimit>=0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); - sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, brk); + sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, brk); } /* The bottom of the loop @@ -1768,10 +1768,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, 0); - sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp0(v, OP_MustBeInt); sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit); VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak); + sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0); } if( p->pOffset ){ @@ -1779,10 +1779,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset, 0); - sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp0(v, OP_MustBeInt); sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset); VdbeComment((v, "OFFSET counter")); - addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeJumpHere(v, addr1); @@ -1791,10 +1791,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ } } if( p->pLimit ){ - addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0); - sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); + addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); + sqlite3VdbeAddOp1(v, OP_Pop, 1); sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1); - addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + addr2 = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1); VdbeComment((v, "LIMIT+OFFSET")); @@ -1948,7 +1948,7 @@ static int multiSelect( p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit>=0 ){ - addr = sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeComment((v, "Jump ahead if LIMIT reached")); } rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff); @@ -3520,7 +3520,7 @@ int sqlite3Select( VdbeComment((v, "set abort flag")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); addrOutputRow = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfMemPos, iUseFlag, addrOutputRow+2); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeComment((v, "Groupby result generator entry point")); sqlite3VdbeAddOp2(v, OP_Return, 0, 0); finalizeAggFunctions(pParse, &sAggInfo); @@ -3626,7 +3626,7 @@ int sqlite3Select( } sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); VdbeComment((v, "output one row")); - sqlite3VdbeAddOp2(v, OP_IfMemPos, iAbortFlag, addrEnd); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset); VdbeComment((v, "reset accumulator")); diff --git a/src/update.c b/src/update.c index 89ececac93..824b06183a 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.164 2008/01/08 18:57:50 drh Exp $ +** $Id: update.c,v 1.165 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" @@ -468,7 +468,7 @@ void sqlite3Update( */ if( chngRowid ){ sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); - sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regNewRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); } /* Compute new data for this record. diff --git a/src/vdbe.c b/src/vdbe.c index f090e97fad..535770e14a 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.689 2008/01/08 23:54:25 drh Exp $ +** $Id: vdbe.c,v 1.690 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" #include @@ -913,7 +913,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ break; } -/* Opcode: String8 * * P4 +/* Opcode: String8 * P2 * P4 * ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. @@ -1023,7 +1023,7 @@ case OP_Blob: { /* out2-prerelease */ } #endif /* SQLITE_OMIT_BLOB_LITERAL */ -/* Opcode: Variable P1 * * +/* Opcode: Variable P1 P2 * * * ** ** The value of variable P1 is written into register P2 or pushed ** onto the stack if P2 is zero. A variable is @@ -1046,7 +1046,7 @@ case OP_Variable: { /* out2-prerelease */ break; } -/* Opcode: Pop P1 * * +/* Opcode: Pop P1 * * * * ** ** P1 elements are popped off of the top of stack and discarded. */ @@ -1308,50 +1308,34 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ break; } -/* Opcode: Add * * * +/* Opcode: Add P1 P2 P3 * * ** -** Pop the top two elements from the stack, add them together, -** and push the result back onto the stack. If either element -** is a string then it is converted to a double using the atof() -** function before the addition. +** Add the value in P1 to the value in P2 and store the result in P3. ** If either operand is NULL, the result is NULL. */ -/* Opcode: Multiply * * * +/* Opcode: Multiply P1 P2 P3 * * ** -** Pop the top two elements from the stack, multiply them together, -** and push the result back onto the stack. If either element -** is a string then it is converted to a double using the atof() -** function before the multiplication. +** +** Multiply the value in P1 by the value in P2 and store the result in P3. ** If either operand is NULL, the result is NULL. */ -/* Opcode: Subtract * * * +/* Opcode: Subtract P1 P2 P3 * * ** -** Pop the top two elements from the stack, subtract the -** first (what was on top of the stack) from the second (the -** next on stack) -** and push the result back onto the stack. If either element -** is a string then it is converted to a double using the atof() -** function before the subtraction. +** Subtract the value in P1 from the value in P2 and store the result +** in P3. ** If either operand is NULL, the result is NULL. */ /* Opcode: Divide * * * ** -** Pop the top two elements from the stack, divide the -** first (what was on top of the stack) from the second (the -** next on stack) -** and push the result back onto the stack. If either element -** is a string then it is converted to a double using the atof() -** function before the division. Division by zero returns NULL. +** Divide the value in P1 by the value in P2 and store the result +** in P3. If the value in P2 is zero, then the result is NULL. ** If either operand is NULL, the result is NULL. */ /* Opcode: Remainder * * * ** -** Pop the top two elements from the stack, divide the -** first (what was on top of the stack) from the second (the -** next on stack) -** and push the remainder after division onto the stack. If either element -** is a string then it is converted to a double using the atof() -** function before the division. Division by zero returns NULL. +** Compute the remainder after integer division of the value in +** register P1 by the value in register P2 and store the result in P3. +** If the value in register P2 is zero the result is NULL. ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ @@ -1648,35 +1632,32 @@ case OP_ForceInt: { /* no-push, jump, in1 */ /* Opcode: MustBeInt P1 P2 P3 ** -** Force the top of the stack to be an integer. If the top of the -** stack is not an integer and cannot be converted into an integer +** Force the value in register P1 to be an integer. If P1==0 then +** use the top of the stack. If the value in P1 +** is not an integer and cannot be converted into an integer ** without data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. ** -** If the top of the stack is not an integer and P2 is not zero and -** P1 is 1, then the stack is popped. In all other cases, the depth -** of the stack is unchanged. -** -** If P3 is not zero, then act on the value in register P3 instead -** of using the stack. +** If the P1==0 and the top of the stack is not an integer +** and P2 is not zero and P3 is 1, then the stack is popped. +** In all other cases, the depth of the stack is unchanged. */ -case OP_MustBeInt: { /* no-push, jump */ - Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]); - assert( pOp->p3 || pTos>=p->aStack ); - assert( pOp->p3>=0 && pOp->p3<=p->nMem ); - REGISTER_TRACE(pOp->p3, pMem); - applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding); - if( (pMem->flags & MEM_Int)==0 ){ +case OP_MustBeInt: { /* no-push, jump, in1 */ + nPop = 0; + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + if( (pIn1->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; - }else if( pMem==pTos ){ - if( pOp->p1 ) popStack(&pTos, 1); + }else{ + if( pOp->p3 && pOp->p1==0 ){ + popStack(&pTos, 1); + } pc = pOp->p2 - 1; } }else{ - Release(pMem); - pMem->flags = MEM_Int; + Release(pIn1); + pIn1->flags = MEM_Int; } break; } @@ -1989,53 +1970,19 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ break; } -/* Opcode: Negative * * * -** -** Treat the top of the stack as a numeric quantity. Replace it -** with its additive inverse. If the top of the stack is NULL -** its value is unchanged. -*/ -/* Opcode: AbsValue * * * -** -** Treat the top of the stack as a numeric quantity. Replace it -** with its absolute value. If the top of the stack is NULL -** its value is unchanged. -*/ -case OP_Negative: /* same as TK_UMINUS, no-push */ -case OP_AbsValue: { - assert( pTos>=p->aStack ); - if( (pTos->flags & (MEM_Real|MEM_Int|MEM_Null))==0 ){ - sqlite3VdbeMemNumerify(pTos); - } - if( pTos->flags & MEM_Real ){ - Release(pTos); - if( pOp->opcode==OP_Negative || pTos->r<0.0 ){ - pTos->r = -pTos->r; - } - pTos->flags = MEM_Real; - }else if( pTos->flags & MEM_Int ){ - Release(pTos); - if( pOp->opcode==OP_Negative || pTos->u.i<0 ){ - pTos->u.i = -pTos->u.i; - } - pTos->flags = MEM_Int; - } - break; -} - /* Opcode: Not * * * ** ** Interpret the top of the stack as a boolean value. Replace it ** with its complement. If the top of the stack is NULL its value ** is unchanged. */ -case OP_Not: { /* same as TK_NOT, no-push */ - assert( pTos>=p->aStack ); - if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ - sqlite3VdbeMemIntegerify(pTos); - assert( (pTos->flags & MEM_Dyn)==0 ); - pTos->u.i = !pTos->u.i; - pTos->flags = MEM_Int; +case OP_Not: { /* same as TK_NOT, no-push, in1 */ + nPop = 0; + if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ + sqlite3VdbeMemIntegerify(pIn1); + assert( (pIn1->flags & MEM_Dyn)==0 ); + pIn1->u.i = !pTos->u.i; + pIn1->flags = MEM_Int; break; } @@ -2045,13 +1992,13 @@ case OP_Not: { /* same as TK_NOT, no-push */ ** with its ones-complement. If the top of the stack is NULL its ** value is unchanged. */ -case OP_BitNot: { /* same as TK_BITNOT, no-push */ - assert( pTos>=p->aStack ); - if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ - sqlite3VdbeMemIntegerify(pTos); - assert( (pTos->flags & MEM_Dyn)==0 ); - pTos->u.i = ~pTos->u.i; - pTos->flags = MEM_Int; +case OP_BitNot: { /* same as TK_BITNOT, no-push, in1 */ + nPop = 0; + if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */ + sqlite3VdbeMemIntegerify(pIn1); + assert( (pIn1->flags & MEM_Dyn)==0 ); + pIn1->u.i = ~pTos->u.i; + pIn1->flags = MEM_Int; break; } @@ -2071,43 +2018,34 @@ case OP_Noop: { /* no-push */ break; } -/* Opcode: If P1 P2 * -** -** Pop a single boolean from the stack. If the boolean popped is -** true, then jump to p2. Otherwise continue to the next instruction. -** An integer is false if zero and true otherwise. A string is -** false if it has zero length and true otherwise. +/* Opcode: If P1 P2 P3 * * ** -** If the value popped of the stack is NULL, then take the jump if P1 -** is true and fall through if P1 is false. +** Jump to P2 if the value in register P1 is true. The value is +** is considered true if it is numeric and non-zero. If the value +** in P1 is NULL then take the jump if P3 is true. */ -/* Opcode: IfNot P1 P2 * +/* Opcode: IfNot P1 P2 P3 * * ** -** Pop a single boolean from the stack. If the boolean popped is -** false, then jump to p2. Otherwise continue to the next instruction. -** An integer is false if zero and true otherwise. A string is -** false if it has zero length and true otherwise. -** -** If the value popped of the stack is NULL, then take the jump if P1 -** is true and fall through if P1 is false. +** Jump to P2 if the value in register P1 is False. The value is +** is considered true if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if P3 is true. */ -case OP_If: /* no-push, jump */ -case OP_IfNot: { /* no-push, jump */ +case OP_If: /* no-push, jump, in1 */ +case OP_IfNot: { /* no-push, jump, in1 */ int c; - assert( pTos>=p->aStack ); - if( pTos->flags & MEM_Null ){ - c = pOp->p1; + if( pIn1->flags & MEM_Null ){ + c = pOp->p3; }else{ #ifdef SQLITE_OMIT_FLOATING_POINT - c = sqlite3VdbeIntValue(pTos); + c = sqlite3VdbeIntValue(pIn1); #else - c = sqlite3VdbeRealValue(pTos)!=0.0; + c = sqlite3VdbeRealValue(pIn1)!=0.0; #endif if( pOp->opcode==OP_IfNot ) c = !c; } - Release(pTos); - pTos--; - if( c ) pc = pOp->p2-1; + if( c ){ + pc = pOp->p2-1; + } break; } @@ -4758,71 +4696,46 @@ case OP_MemMax: { /* no-push */ } #endif /* SQLITE_OMIT_AUTOINCREMENT */ -/* Opcode: IfMemPos P1 P2 * +/* Opcode: IfPos P1 P2 * ** ** If the value of memory cell P1 is 1 or greater, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ -case OP_IfMemPos: { /* no-push, jump */ - int i = pOp->p1; - Mem *pMem; - assert( i>0 && i<=p->nMem ); - pMem = &p->aMem[i]; - assert( pMem->flags==MEM_Int ); - if( pMem->u.i>0 ){ +case OP_IfPos: { /* no-push, jump, in1 */ + assert( pIn1->flags==MEM_Int ); + if( pIn1->u.i>0 ){ pc = pOp->p2 - 1; } break; } -/* Opcode: IfMemNeg P1 P2 * +/* Opcode: IfNeg P1 P2 * ** ** If the value of memory cell P1 is less than zero, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ -case OP_IfMemNeg: { /* no-push, jump */ - int i = pOp->p1; - Mem *pMem; - assert( i>0 && i<=p->nMem ); - pMem = &p->aMem[i]; - assert( pMem->flags==MEM_Int ); - if( pMem->u.i<0 ){ +case OP_IfNeg: { /* no-push, jump, in1 */ + assert( pIn1->flags==MEM_Int ); + if( pIn1->u.i<0 ){ pc = pOp->p2 - 1; } break; } -/* Opcode: IfMemZero P1 P2 * +/* Opcode: IfZero P1 P2 * ** ** If the value of memory cell P1 is exactly 0, jump to P2. ** ** It is illegal to use this instruction on a memory cell that does ** not contain an integer. An assertion fault will result if you try. */ -case OP_IfMemZero: { /* no-push, jump */ - int i = pOp->p1; - Mem *pMem; - assert( i>0 && i<=p->nMem ); - pMem = &p->aMem[i]; - assert( pMem->flags==MEM_Int ); - if( pMem->u.i==0 ){ - pc = pOp->p2 - 1; - } - break; -} - -/* Opcode: IfMemNull P1 P2 * -** -** If the value of memory cell P1 is NULL, jump to P2. -*/ -case OP_IfMemNull: { /* no-push, jump */ - int i = pOp->p1; - assert( i>0 && i<=p->nMem ); - if( p->aMem[i].flags & MEM_Null ){ +case OP_IfZero: { /* no-push, jump, in1 */ + assert( pIn1->flags==MEM_Int ); + if( pIn1->u.i==0 ){ pc = pOp->p2 - 1; } break; diff --git a/src/where.c b/src/where.c index f5f86e9bd9..9f13fa1946 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.278 2008/01/08 23:54:26 drh Exp $ +** $Id: where.c,v 1.279 2008/01/09 02:15:42 drh Exp $ */ #include "sqliteInt.h" @@ -2329,7 +2329,7 @@ WhereInfo *sqlite3WhereBegin( assert( omitTable==0 ); codeEqualityTerm(pParse, pTerm, pLevel); nxt = pLevel->nxt; - sqlite3VdbeAddOp2(v, OP_MustBeInt, 1, nxt); + sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, nxt, 1); sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt); VdbeComment((v, "pk")); pLevel->op = OP_Noop; @@ -2766,10 +2766,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeResolveLabel(v, pLevel->brk); if( pLevel->iLeftJoin ){ int addr; - addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, pLevel->iLeftJoin, 0); - sqlite3VdbeAddOp2(v, OP_NullRow, pTabList->a[i].iCursor, 0); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); + sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); if( pLevel->iIdxCur>=0 ){ - sqlite3VdbeAddOp2(v, OP_NullRow, pLevel->iIdxCur, 0); + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top); sqlite3VdbeJumpHere(v, addr); @@ -2789,10 +2789,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pTab!=0 ); if( pTab->isEphem || pTab->pSelect ) continue; if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp2(v, OP_Close, pTabItem->iCursor, 0); + sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } if( pLevel->pIdx!=0 ){ - sqlite3VdbeAddOp2(v, OP_Close, pLevel->iIdxCur, 0); + sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); } /* If this scan uses an index, make code substitutions to read data