]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Registerify the comparison opcodes. (CVS 4697)
authordrh <drh@noemail.net>
Tue, 8 Jan 2008 23:54:25 +0000 (23:54 +0000)
committerdrh <drh@noemail.net>
Tue, 8 Jan 2008 23:54:25 +0000 (23:54 +0000)
FossilOrigin-Name: 8862ce9ceefba4f5d1ffbd51d824c05f42a58c22

13 files changed:
manifest
manifest.uuid
src/analyze.c
src/delete.c
src/expr.c
src/insert.c
src/select.c
src/sqliteInt.h
src/trigger.c
src/vdbe.c
src/vdbe.h
src/vdbeaux.c
src/where.c

index b40b7ed61b201e82a2641ac858d33377c25e978e..48bf47b5ee9afc06ac2a7157034ec2dbd683aa42 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -79,7 +79,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 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
@@ -90,13 +90,13 @@ F src/build.c 22b50a462d7b2be82e29071069d1c3daf29e953f
 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
@@ -131,12 +131,12 @@ F src/pragma.c ebf841efccc8d2df410fc10aa556a64256457ab4
 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
@@ -163,21 +163,21 @@ F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
 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
@@ -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 87b4ac4b73fb84411ced9e9a859dd0e2d211c4b3
-R ea42342909fb8c895292e16f7eae74b2
+P 5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c
+R 22639e8ca20a12d23612d55375b01a67
 U drh
-Z c9e18a2ce9ff1c41852f6d73afcc5930
+Z 654c7ee149d8fd3c6129fb629505622c
index 7428ee30255e0051d3a5b5fcf6dc7697705e9f05..4f8be3394d436b131ba49c6f708394da972cbd14 100644 (file)
@@ -1 +1 @@
-5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c
\ No newline at end of file
+8862ce9ceefba4f5d1ffbd51d824c05f42a58c22
\ No newline at end of file
index 9b5494a2d5311e65515fbea42cd80365c86156ad..afb9c0af8fd272cebd960b3198583c308fd02bb2 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** 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"
@@ -159,7 +159,8 @@ static void analyzeOneTable(
     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++){
index 2a416e93d261656a3be1508f80fff84cf584edf5..21f9ce0d63445e6f91287cdc012622247d5c9eac 100644 (file)
@@ -12,7 +12,7 @@
 ** 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"
 
@@ -71,7 +71,7 @@ void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){
   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);
 }
 
 /*
index 651f1cd9ace724a6d177a40265cb89a23ca87a96..5aa1b747f02b9ec8dba32b0c9bb9a3f51d87b16e 100644 (file)
@@ -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.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>
@@ -158,15 +158,13 @@ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
 }
 
 /*
-** 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;
 }
 
 /*
@@ -211,13 +209,20 @@ static int codeCompare(
   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;
 }
 
 /*
@@ -2058,15 +2063,22 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
     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:
@@ -2205,8 +2217,6 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
         sqlite3CodeSubselect(pParse, pExpr);
       }
       inReg = pExpr->iColumn;
-      /* sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn);
-      VdbeComment((v, "load subquery result")); */
       break;
     }
     case TK_IN: {
@@ -2254,16 +2264,24 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
       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: {
@@ -2293,7 +2311,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
         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);
@@ -2411,7 +2429,7 @@ int sqlite3ExprCodeExprList(
 ** 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
@@ -2422,12 +2440,13 @@ int sqlite3ExprCodeExprList(
 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;
@@ -2455,7 +2474,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
       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:
@@ -2479,11 +2499,12 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
       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);
@@ -2504,11 +2525,13 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
 ** 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:
@@ -2550,7 +2573,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
     }
     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;
@@ -2567,7 +2590,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
     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:
@@ -2590,13 +2614,15 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
       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: {
index 26f5408e6af80626ee8722bcbdd1feccafb32cc0..cf6c8ac3ad75fd619b98b79235cc8831fa150742 100644 (file)
@@ -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.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"
 
@@ -173,7 +173,8 @@ static int autoIncBegin(
     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);
@@ -222,7 +223,7 @@ static void autoIncEnd(
     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);
   }
 }
@@ -1082,7 +1083,7 @@ void sqlite3GenerateConstraintChecks(
   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);
index 4e39192d64e97b1e9acf73e6fe8b1fb9b466d19a..6f1d1dc93be1a0e5303068f39f72976325769b9a 100644 (file)
@@ -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.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"
 
@@ -3525,7 +3525,7 @@ int sqlite3Select(
       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,
@@ -3603,11 +3603,12 @@ int sqlite3Select(
         }
         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.
@@ -3712,7 +3713,7 @@ int sqlite3Select(
       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);
index ec6da6da53b7dc1b2b2282e6061dd9f065811d94..b48e1cd6271abbc4d43a78918d3fbdc0e4a85610 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** 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_
@@ -714,6 +714,20 @@ struct CollSeq {
 
 #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.
index a5ee6a447ebf283ee75de1c80cd14e4a841dd987..bd928916c9f3c714317b95a4f7766ec8fb4cce29 100644 (file)
@@ -850,7 +850,7 @@ int sqlite3CodeRowTrigger(
         sqlite3ExprDelete(whenExpr);
         return 1;
       }
-      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
+      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);
       sqlite3ExprDelete(whenExpr);
 
       codeTriggerProgram(pParse, p->step_list, orconf); 
index 7ac12ffeae16b92ca6c6bde5718b87c5d3074704..f090e97fade35a55a604961a4ae516788e5174bd 100644 (file)
@@ -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.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>
@@ -1168,21 +1168,6 @@ case OP_Pull: {            /* no-push */
   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
@@ -1811,132 +1796,129 @@ case OP_ToReal: {                  /* same as TK_TO_REAL, no-push, in1 */
 }
 #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;
@@ -1946,15 +1928,14 @@ case OP_Ge: {             /* same as TK_GE, no-push, jump */
     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;
 }
index 33f091d80530025633a30b93ce408ffd3a446ed7..d9665474ddf78a7c78f7c30d7d3b2a6ceb8c4807 100644 (file)
@@ -15,7 +15,7 @@
 ** 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_
@@ -150,7 +150,7 @@ int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
 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);
index 391b0d0dca1645ac5a9d4ce8efe1dd6172ca6a3a..a8853f3ee09f5352665109c59f2bfec5af87a60e 100644 (file)
@@ -411,12 +411,14 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
 }
 
 /*
-** 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;
   }
 }
 
index 4d9454fbbc43697dd9f81627bd5d3a794f6552b6..f5f86e9bd9060c416c41ffaaac21aed377c5ead7 100644 (file)
@@ -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.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"
 
@@ -2024,7 +2024,7 @@ WhereInfo *sqlite3WhereBegin(
   ** 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;
   }
 
@@ -2384,7 +2384,8 @@ WhereInfo *sqlite3WhereBegin(
       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
@@ -2651,7 +2652,7 @@ WhereInfo *sqlite3WhereBegin(
       if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
         continue;
       }
-      sqlite3ExprIfFalse(pParse, pE, cont, 1);
+      sqlite3ExprIfFalse(pParse, pE, cont, SQLITE_JUMPIFNULL);
       pTerm->flags |= TERM_CODED;
     }
 
@@ -2666,7 +2667,7 @@ WhereInfo *sqlite3WhereBegin(
         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;
       }
     }