-C Finish\sregisterizing\sthe\score\slogic\sof\sINSERT\sand\sUPDATE.\s(CVS\s4696)
-D 2008-01-08T18:57:50
+C Registerify\sthe\scomparison\sopcodes.\s(CVS\s4697)
+D 2008-01-08T23:54:25
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
F src/alter.c 5a54f58d9481ac14c4e58b702f3f8758dee84d04
-F src/analyze.c 96e12e03c101cffaab50be7829d7194184864f42
+F src/analyze.c 6327934f5a4ec38b71f085482df4a05db0a99126
F src/attach.c 1c96631e56cdc51d3d70736bf61f1fe01c62cbea
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
-F src/delete.c d78e46b259a94a5f98a1bceee206c5fd21276ae7
+F src/delete.c 971f5f774d121cfb790630a878a54c939b5b1494
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c 6f2a852227ba2abd5ad0916f539c1f2159da28b4
+F src/expr.c 26b29dabea522d13b8da8cb41b35ed61aca6706c
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
-F src/insert.c e46f25f5262b243b60419f6ca5cc4811bf96eec6
+F src/insert.c c79591d68740681bc28883206763595168ef15d4
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
-F src/select.c 1162f736dbe227a1978f2d2c0e3fc111288f9653
+F src/select.c d6bdf86c76c899991f7339291f124718028e8446
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 fd911a263a5b50015afe01be5501bf5b6be913d0
+F src/sqliteInt.h 884eb3db36efe571ce371309592ad44fefb91c9a
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
-F src/trigger.c 33071215111825634b85567bfc36c14094eebe54
+F src/trigger.c 1e77b3c21c129ad01f7f23a497ae1d224b4e5bc4
F src/update.c 89ba318306daa20d901ed698018fe6e3d16b3586
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
-F src/vdbe.c e71595acce83c585c31ac0551cee1c8cf9540fd2
-F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
+F src/vdbe.c 926b4630c583f355d5c7376ebc17d82f43a91866
+F src/vdbe.h c686e1b73011e74b764971b83c97069ece3c04cb
F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
-F src/vdbeaux.c b6241be0277795ecd902743366434704f03b7636
+F src/vdbeaux.c 2f716ebde79aa5bd83231c61269000413d8710f0
F src/vdbeblob.c b90f7494c408d47ce6835000b01e40b371e27baf
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
F src/vdbemem.c a94f3e9e85578ba457133ad3446fc6114a03ec5a
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
-F src/where.c 306fafa709ced14b1c816d38b96a8f4446ec1eeb
+F src/where.c 8f55e7257daf93d9c715df7cb312dede6f2d45d2
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 87b4ac4b73fb84411ced9e9a859dd0e2d211c4b3
-R ea42342909fb8c895292e16f7eae74b2
+P 5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c
+R 22639e8ca20a12d23612d55375b01a67
U drh
-Z c9e18a2ce9ff1c41852f6d73afcc5930
+Z 654c7ee149d8fd3c6129fb629505622c
-5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c
\ No newline at end of file
+8862ce9ceefba4f5d1ffbd51d824c05f42a58c22
\ No newline at end of file
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
-** @(#) $Id: analyze.c,v 1.34 2008/01/05 16:29:28 drh Exp $
+** @(#) $Id: analyze.c,v 1.35 2008/01/08 23:54:25 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
sqlite3VdbeAddOp1(v, OP_SCopy, iMem+nCol+i+1);
- sqlite3VdbeAddOp1(v, OP_Ne, 0x100); /* FIX ME: use collating sequence */
+ sqlite3VdbeAddOp0(v, OP_Ne ); /* Use Collating sequence */
+ sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
for(i=0; i<nCol; i++){
** 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.153 2008/01/08 02:57:56 drh Exp $
+** $Id: delete.c,v 1.154 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
sqlite3VdbeAddOp2(v, OP_Move, 0, iData);
sqlite3VdbeAddOp2(v, OP_Move, 0, iKey);
sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
- sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags);
+ sqlite3VdbeChangeP5(v, flags);
}
/*
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.337 2008/01/08 02:57:56 drh Exp $
+** $Id: expr.c,v 1.338 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
}
/*
-** Return the P1 value that should be used for a binary comparison
+** Return the P5 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
-** If jumpIfNull is true, then set the low byte of the returned
-** P1 value to tell the opcode to jump if either expression
-** evaluates to NULL.
*/
-static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
- char aff = sqlite3ExprAffinity(pExpr2);
- return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
+static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
+ u8 aff = (char)sqlite3ExprAffinity(pExpr2);
+ aff = sqlite3CompareAffinity(pExpr1, aff) | jumpIfNull;
+ return aff;
}
/*
Expr *pLeft, /* The left operand */
Expr *pRight, /* The right operand */
int opcode, /* The comparison opcode */
+ int in1, int in2, /* Register holding operands */
int dest, /* Jump here if true. */
int jumpIfNull /* If true, jump if either operand is NULL */
){
- int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
- CollSeq *p3 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
- return sqlite3VdbeAddOp4(pParse->pVdbe, opcode, p1, dest, 0,
- (void*)p3, P4_COLLSEQ);
+ int p5;
+ int addr;
+ CollSeq *p4;
+
+ p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
+ p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
+ addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
+ (void*)p4, P4_COLLSEQ);
+ sqlite3VdbeChangeP5(pParse->pVdbe, p5);
+ return addr;
}
/*
case TK_GE:
case TK_NE:
case TK_EQ: {
+ int r1, r2;
assert( TK_LT==OP_Lt );
assert( TK_LE==OP_Le );
assert( TK_GT==OP_Gt );
assert( TK_GE==OP_Ge );
assert( TK_EQ==OP_Eq );
assert( TK_NE==OP_Ne );
- sqlite3ExprCode(pParse, pExpr->pLeft, 0);
- sqlite3ExprCode(pParse, pExpr->pRight, 0);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
+ if( target>0 ){
+ inReg = target;
+ }else{
+ inReg = ++pParse->nMem;
+ }
+ r1 = sqlite3ExprCode(pParse, pExpr->pLeft, -1);
+ r2 = sqlite3ExprCode(pParse, pExpr->pRight, -1);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ r1, r2, inReg, SQLITE_STOREP2);
break;
}
case TK_AND:
sqlite3CodeSubselect(pParse, pExpr);
}
inReg = pExpr->iColumn;
- /* sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn);
- VdbeComment((v, "load subquery result")); */
break;
}
case TK_IN: {
Expr *pLeft = pExpr->pLeft;
struct ExprList_item *pLItem = pExpr->pList->a;
Expr *pRight = pLItem->pExpr;
- sqlite3ExprCode(pParse, pLeft, 0);
- sqlite3VdbeAddOp0(v, OP_Copy);
- sqlite3ExprCode(pParse, pRight, 0);
- codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
- sqlite3VdbeAddOp1(v, OP_Pull, 1);
+ int r1, r2, r3, r4, r5;
+
+ if( target>0 ){
+ inReg = target;
+ }else{
+ inReg = ++pParse->nMem;
+ }
+ r1 = sqlite3ExprCode(pParse, pLeft, -1);
+ r2 = sqlite3ExprCode(pParse, pRight, -1);
+ r3 = ++pParse->nMem;
+ codeCompare(pParse, pLeft, pRight, OP_Ge,
+ r1, r2, r3, SQLITE_STOREP2);
pLItem++;
pRight = pLItem->pExpr;
- sqlite3ExprCode(pParse, pRight, 0);
- codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
- sqlite3VdbeAddOp0(v, OP_And);
+ r4 = sqlite3ExprCode(pParse, pRight, -1);
+ r5 = ++pParse->nMem;
+ codeCompare(pParse, pLeft, pRight, OP_Le, r1, r4, r5, SQLITE_STOREP2);
+ sqlite3VdbeAddOp3(v, OP_And, r3, r5, inReg);
break;
}
case TK_UPLUS: {
if( pExpr->pLeft ){
sqlite3VdbeAddOp1(v, OP_SCopy, -1);
jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
- OP_Ne, 0, 1);
+ OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp1(v, OP_Pop, 1);
}else{
jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
** continues straight thru if the expression is false.
**
** If the expression evaluates to NULL (neither true nor false), then
-** take the jump if the jumpIfNull flag is true.
+** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL.
**
** 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
void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
+ assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( v==0 || pExpr==0 ) return;
op = pExpr->op;
switch( op ){
case TK_AND: {
int d2 = sqlite3VdbeMakeLabel(v);
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
break;
assert( TK_NE==OP_Ne );
sqlite3ExprCode(pParse, pExpr->pLeft, 0);
sqlite3ExprCode(pParse, pExpr->pRight, 0);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ 0, 0, dest, jumpIfNull);
break;
}
case TK_ISNULL:
sqlite3ExprCode(pParse, pLeft, 0);
sqlite3VdbeAddOp0(v, OP_Copy);
sqlite3ExprCode(pParse, pRight, 0);
- addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
+ addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, 0, 0,
+ jumpIfNull ^ SQLITE_JUMPIFNULL);
pRight = pExpr->pList->a[1].pExpr;
sqlite3ExprCode(pParse, pRight, 0);
- codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
+ codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0, dest, jumpIfNull);
sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
sqlite3VdbeJumpHere(v, addr);
** continues straight thru if the expression is true.
**
** If the expression evaluates to NULL (neither true nor false) then
-** jump if jumpIfNull is true or fall through if jumpIfNull is false.
+** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull
+** is 0.
*/
void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
Vdbe *v = pParse->pVdbe;
int op = 0;
+ assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( v==0 || pExpr==0 ) return;
/* The value of pExpr->op and op are related as follows:
}
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(v);
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
break;
case TK_EQ: {
sqlite3ExprCode(pParse, pExpr->pLeft, 0);
sqlite3ExprCode(pParse, pExpr->pRight, 0);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
+ codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ 0, 0, dest, jumpIfNull);
break;
}
case TK_ISNULL:
sqlite3VdbeAddOp0(v, OP_Copy);
sqlite3ExprCode(pParse, pRight, 0);
addr = sqlite3VdbeCurrentAddr(v);
- codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
+ codeCompare(pParse, pLeft, pRight, OP_Ge,
+ 0, 0, addr+3, jumpIfNull ^ SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
pRight = pExpr->pList->a[1].pExpr;
sqlite3ExprCode(pParse, pRight, 0);
- codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
+ codeCompare(pParse, pLeft, pRight, OP_Gt,
+ 0, 0, dest, jumpIfNull);
break;
}
default: {
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.217 2008/01/08 18:57:50 drh Exp $
+** $Id: insert.c,v 1.218 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+8);
sqlite3VdbeAddOp2(v, OP_Column, iCur, 0);
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+7);
+ sqlite3VdbeAddOp2(v, OP_Ne, 0, addr+7);
+ sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, memId+1);
sqlite3VdbeAddOp3(v, OP_Column, iCur, 1, memId);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+8);
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, pTab->zName, 0);
sqlite3VdbeAddOp3(v, OP_RegMakeRec, memId-1, 2, memId-1);
sqlite3VdbeAddOp3(v, OP_Insert, iCur, memId-1, memId+1);
- sqlite3VdbeChangeP5(v, -1, OPFLAG_APPEND);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
}
if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
int allOk = sqlite3VdbeMakeLabel(v);
pParse->ckBase = regData;
- sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1);
+ sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, SQLITE_JUMPIFNULL);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
if( onError==OE_Ignore ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.392 2008/01/07 19:20:25 drh Exp $
+** $Id: select.c,v 1.393 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
finalizeAggFunctions(pParse, &sAggInfo);
if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, 1);
+ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
}
rc = selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
}
sqlite3VdbeAddOp2(v, OP_SCopy, iAMem+j, 0);
if( j==0 ){
- sqlite3VdbeAddOp2(v, OP_Eq, 0x200, addrProcessRow);
+ sqlite3VdbeAddOp2(v, OP_Eq, 0, addrProcessRow);
}else{
- sqlite3VdbeAddOp2(v, OP_Ne, 0x200, addrGroupByChange);
+ sqlite3VdbeAddOp2(v, OP_Ne, 0, addrGroupByChange);
}
sqlite3VdbeChangeP4(v, -1, (void*)pKeyInfo->aColl[j], P4_COLLSEQ);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQUAL);
}
/* Generate code that runs whenever the GROUP BY changes.
finalizeAggFunctions(pParse, &sAggInfo);
pOrderBy = 0;
if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1);
+ sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
}
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd, aff);
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.643 2008/01/08 18:57:50 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.644 2008/01/08 23:54:25 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
+/*
+** The SQLITE_AFF_MASK values masks off the significant bits of an
+** affinity value.
+*/
+#define SQLITE_AFF_MASK 0x67
+
+/*
+** Additional bit values that can be ORed with an affinity without
+** changing the affinity.
+*/
+#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
+#define SQLITE_NULLEQUAL 0x10 /* compare NULLs equal */
+#define SQLITE_STOREP2 0x80 /* Store result in reg[P2] rather than jump */
+
/*
** Each SQL table is represented in memory by an instance of the
** following structure.
sqlite3ExprDelete(whenExpr);
return 1;
}
- sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
+ sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);
sqlite3ExprDelete(whenExpr);
codeTriggerProgram(pParse, p->step_list, orconf);
** 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.688 2008/01/08 02:57:56 drh Exp $
+** $Id: vdbe.c,v 1.689 2008/01/08 23:54:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
break;
}
-/* Opcode: Push P1 * *
-**
-** Overwrite the value of the P1-th element down on the
-** stack (P1==0 is the top of the stack) with the value
-** of the top of the stack. Then pop the top of the stack.
-*/
-case OP_Push: { /* no-push */
- Mem *pTo = &pTos[-pOp->p1];
-
- assert( pTo>=p->aStack );
- sqlite3VdbeMemMove(pTo, pTos);
- pTos--;
- break;
-}
-
/* Opcode: Callback P1 * *
**
** The top P1 values on the stack represent a single result row from
}
#endif /* SQLITE_OMIT_CAST */
-/* Opcode: Eq P1 P2 P4
+/* Opcode: Lt P1 P2 P3 P4 P5
**
-** Pop the top two elements from the stack. If they are equal, then
-** jump to instruction P2. Otherwise, continue to the next instruction.
+** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
+** jump to address P2.
**
-** If the 0x100 bit of P1 is true and either operand is NULL then take the
-** jump. If the 0x100 bit of P1 is clear then fall thru if either operand
-** is NULL.
+** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
+** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL
+** bit is clear then fall thru if either operand is NULL.
**
-** If the 0x200 bit of P1 is set and either operand is NULL then
-** both operands are converted to integers prior to comparison.
-** NULL operands are converted to zero and non-NULL operands are
-** converted to 1. Thus, for example, with 0x200 set, NULL==NULL is true
-** whereas it would normally be NULL. Similarly, NULL==123 is false when
-** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
+** If the SQLITE_NULLEQUAL bit of P5 is set then treat NULL operands
+** as being equal to one another. Normally NULLs are not equal to
+** anything including other NULLs.
**
-** The least significant byte of P1 (mask 0xff) must be an affinity character -
+** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
-** to coerce both values
-** according to the affinity before the comparison is made. If the byte is
-** 0x00, then numeric affinity is used.
+** to coerce both operands according to this affinity before the
+** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
+** affinity is used.
**
** Once any conversions have taken place, and neither value is NULL,
-** the values are compared. If both values are blobs, or both are text,
-** then memcmp() is used to determine the results of the comparison. If
-** both values are numeric, then a numeric comparison is used. If the
-** two values are of different types, then they are inequal.
-**
-** If P2 is zero, do not jump. Instead, push an integer 1 onto the
-** stack if the jump would have been taken, or a 0 if not. Push a
-** NULL if either operand was NULL.
-**
-** If P4 is not NULL it is a pointer to a collating sequence (a CollSeq
-** structure) that defines how to compare text.
+** the values are compared. If both values are blobs then memcmp() is
+** used to determine the results of the comparison. If both values
+** are text, then the appropriate collating function specified in
+** P4 is used to do the comparison. If P4 is not specified then
+** memcmp() is used to compare text string. If both values are
+** numeric, then a numeric comparison is used. If the two values
+** are of different types, then numbers are considered less than
+** strings and strings are considered less than blobs.
+**
+** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
+** store a boolean result (either 0, or 1, or NULL) in register P2.
*/
/* Opcode: Ne P1 P2 P4
**
-** This works just like the Eq opcode except that the jump is taken if
-** the operands from the stack are not equal. See the Eq opcode for
+** This works just like the Lt opcode except that the jump is taken if
+** the operands in registers P1 and P3 are not equal. See the Lt opcode for
** additional information.
*/
-/* Opcode: Lt P1 P2 P4
+/* Opcode: Eq P1 P2 P4
**
-** This works just like the Eq opcode except that the jump is taken if
-** the 2nd element down on the stack is less than the top of the stack.
-** See the Eq opcode for additional information.
+** This works just like the Lt opcode except that the jump is taken if
+** the operands in registers P1 and P3 are equal.
+** See the Lt opcode for additional information.
*/
/* Opcode: Le P1 P2 P4
**
-** This works just like the Eq opcode except that the jump is taken if
-** the 2nd element down on the stack is less than or equal to the
-** top of the stack. See the Eq opcode for additional information.
+** This works just like the Lt opcode except that the jump is taken if
+** the content of register P3 is less than or equal to the content of
+** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Gt P1 P2 P4
**
-** This works just like the Eq opcode except that the jump is taken if
-** the 2nd element down on the stack is greater than the top of the stack.
-** See the Eq opcode for additional information.
+** This works just like the Lt opcode except that the jump is taken if
+** the content of register P3 is greater than the content of
+** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Ge P1 P2 P4
**
-** This works just like the Eq opcode except that the jump is taken if
-** the 2nd element down on the stack is greater than or equal to the
-** top of the stack. See the Eq opcode for additional information.
-*/
-case OP_Eq: /* same as TK_EQ, no-push, jump */
-case OP_Ne: /* same as TK_NE, no-push, jump */
-case OP_Lt: /* same as TK_LT, no-push, jump */
-case OP_Le: /* same as TK_LE, no-push, jump */
-case OP_Gt: /* same as TK_GT, no-push, jump */
-case OP_Ge: { /* same as TK_GE, no-push, jump */
- Mem *pNos;
+** This works just like the Lt opcode except that the jump is taken if
+** the content of register P3 is greater than or equal to the content of
+** register P1. See the Lt opcode for additional information.
+*/
+case OP_Eq: /* same as TK_EQ, no-push, jump, in1, in3 */
+case OP_Ne: /* same as TK_NE, no-push, jump, in1, in3 */
+case OP_Lt: /* same as TK_LT, no-push, jump, in1, in3 */
+case OP_Le: /* same as TK_LE, no-push, jump, in1, in3 */
+case OP_Gt: /* same as TK_GT, no-push, jump, in1, in3 */
+case OP_Ge: { /* same as TK_GE, no-push, jump, in1, in3 */
int flags;
int res;
char affinity;
+ Mem x1, x3;
- pNos = &pTos[-1];
- flags = pTos->flags|pNos->flags;
+ flags = pIn1->flags|pIn3->flags;
/* If either value is a NULL P2 is not zero, take the jump if the least
** significant byte of P1 is true. If P2 is zero, then push a NULL onto
** the stack.
*/
if( flags&MEM_Null ){
- if( (pOp->p1 & 0x200)!=0 ){
- /* The 0x200 bit of P1 means, roughly "do not treat NULL as the
- ** magic SQL value it normally is - treat it as if it were another
- ** integer".
- **
- ** With 0x200 set, if either operand is NULL then both operands
- ** are converted to integers prior to being passed down into the
- ** normal comparison logic below. NULL operands are converted to
- ** zero and non-NULL operands are converted to 1. Thus, for example,
- ** with 0x200 set, NULL==NULL is true whereas it would normally
- ** be NULL. Similarly, NULL!=123 is true.
+ if( (pOp->p5 & SQLITE_NULLEQUAL)!=0 ){
+ /*
+ ** When SQLITE_NULLEQUAL set and either operand is NULL
+ ** then both operands are converted to integers prior to being
+ ** passed down into the normal comparison logic below.
+ ** NULL operands are converted to zero and non-NULL operands
+ ** are converted to 1. Thus, for example, with SQLITE_NULLEQUAL
+ ** set, NULL==NULL is true whereas it would normally NULL.
+ ** Similarly, NULL!=123 is true.
*/
- sqlite3VdbeMemSetInt64(pTos, (pTos->flags & MEM_Null)==0);
- sqlite3VdbeMemSetInt64(pNos, (pNos->flags & MEM_Null)==0);
+ x1.flags = MEM_Int;
+ x1.u.i = (pIn1->flags & MEM_Null)==0;
+ pIn1 = &x1;
+ x3.flags = MEM_Int;
+ x3.u.i = (pIn3->flags & MEM_Null)==0;
+ pIn3 = &x3;
}else{
- /* If the 0x200 bit of P1 is clear and either operand is NULL then
- ** the result is always NULL. The jump is taken if the 0x100 bit
- ** of P1 is set.
+ /* If the SQLITE_NULLEQUAL bit is clear and either operand is NULL then
+ ** the result is always NULL. The jump is taken if the
+ ** SQLITE_JUMPIFNULL bit is set.
*/
- popStack(&pTos, 2);
- if( pOp->p2 ){
- if( pOp->p1 & 0x100 ){
- pc = pOp->p2-1;
- }
- }else{
- pTos++;
- pTos->flags = MEM_Null;
+ if( pOp->p5 & SQLITE_STOREP2 ){
+ pOut = &p->aMem[pOp->p2];
+ Release(pOut);
+ pOut->flags = MEM_Null;
+ REGISTER_TRACE(pOp->p2, pOut);
+ }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
+ pc = pOp->p2-1;
}
break;
}
}
- affinity = pOp->p1 & 0xFF;
+ affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity ){
- applyAffinity(pNos, affinity, encoding);
- applyAffinity(pTos, affinity, encoding);
+ applyAffinity(pIn1, affinity, encoding);
+ applyAffinity(pIn3, affinity, encoding);
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
- ExpandBlob(pNos);
- ExpandBlob(pTos);
- res = sqlite3MemCompare(pNos, pTos, pOp->p4.pColl);
+ ExpandBlob(pIn1);
+ ExpandBlob(pIn3);
+ res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
switch( pOp->opcode ){
case OP_Eq: res = res==0; break;
case OP_Ne: res = res!=0; break;
default: res = res>=0; break;
}
- popStack(&pTos, 2);
- if( pOp->p2 ){
- if( res ){
- pc = pOp->p2-1;
- }
- }else{
- pTos++;
- pTos->flags = MEM_Int;
- pTos->u.i = res;
+ if( pOp->p5 & SQLITE_STOREP2 ){
+ pOut = &p->aMem[pOp->p2];
+ Release(pOut);
+ pOut->flags = MEM_Int;
+ pOut->u.i = res;
+ REGISTER_TRACE(pOp->p2, pOut);
+ }else if( res ){
+ pc = pOp->p2-1;
}
break;
}
** 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.122 2008/01/03 11:50:30 danielk1977 Exp $
+** $Id: vdbe.h,v 1.123 2008/01/08 23:54:25 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
-void sqlite3VdbeChangeP5(Vdbe*, int addr, u8 P5);
+void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
}
/*
-** Change the value of the P5 operand for a specific instruction.
+** Change the value of the P5 operand for the most recently
+** added operation.
*/
-void sqlite3VdbeChangeP5(Vdbe *p, int addr, u8 val){
+void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
assert( p==0 || p->magic==VDBE_MAGIC_INIT );
- if( p && addr>=0 && p->nOp>addr && p->aOp ){
- p->aOp[addr].p5 = val;
+ if( p && p->aOp ){
+ assert( p->nOp>0 );
+ p->aOp[p->nOp-1].p5 = val;
}
}
** 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.277 2008/01/07 19:20:25 drh Exp $
+** $Id: where.c,v 1.278 2008/01/08 23:54:26 drh Exp $
*/
#include "sqliteInt.h"
** expression and either jump over all of the code or fall thru.
*/
if( pWhere && (pTabList->nSrc==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
- sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
+ sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
pWhere = 0;
}
if( testOp!=OP_Noop ){
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0);
- sqlite3VdbeAddOp2(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk);
+ sqlite3VdbeAddOp2(v, testOp, 0, brk);
+ sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
}else if( pLevel->flags & WHERE_COLUMN_RANGE ){
/* Case 3: The WHERE clause term that refers to the right-most
if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
continue;
}
- sqlite3ExprIfFalse(pParse, pE, cont, 1);
+ sqlite3ExprIfFalse(pParse, pE, cont, SQLITE_JUMPIFNULL);
pTerm->flags |= TERM_CODED;
}
if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->prereqAll & notReady)!=0 ) continue;
assert( pTerm->pExpr );
- sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, 1);
+ sqlite3ExprIfFalse(pParse, pTerm->pExpr, cont, SQLITE_JUMPIFNULL);
pTerm->flags |= TERM_CODED;
}
}