mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
Continued work toward converting to a register-based VM. (CVS 4698)
FossilOrigin-Name: 92deff07bba2089bbe011f44defb3a0ac1362d56
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Registerify\sthe\scomparison\sopcodes.\s(CVS\s4697)
|
C Continued\swork\stoward\sconverting\sto\sa\sregister-based\sVM.\s(CVS\s4698)
|
||||||
D 2008-01-08T23:54:25
|
D 2008-01-09T02:15:39
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -92,11 +92,11 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
|||||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||||
F src/delete.c 971f5f774d121cfb790630a878a54c939b5b1494
|
F src/delete.c 971f5f774d121cfb790630a878a54c939b5b1494
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c 26b29dabea522d13b8da8cb41b35ed61aca6706c
|
F src/expr.c f1bee4f35fef3078fdbf9075f2b18e41202ccb09
|
||||||
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
||||||
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
||||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||||
F src/insert.c c79591d68740681bc28883206763595168ef15d4
|
F src/insert.c 4443b9026fe9be6c64a689879c564dcd8b7cbcb3
|
||||||
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
||||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
||||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||||
@@ -127,11 +127,11 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
|||||||
F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
|
F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
|
||||||
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
||||||
F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
|
F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
|
||||||
F src/pragma.c ebf841efccc8d2df410fc10aa556a64256457ab4
|
F src/pragma.c 355d53bc64b70d2dfcd9a1c4a9c5c2ea87da2857
|
||||||
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
|
F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd
|
||||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||||
F src/select.c d6bdf86c76c899991f7339291f124718028e8446
|
F src/select.c 8570d4db93e115227393fd3cdf88be28d9ac585b
|
||||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||||
F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
|
F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
|
||||||
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
||||||
@@ -164,11 +164,11 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
|||||||
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||||
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
||||||
F src/trigger.c 1e77b3c21c129ad01f7f23a497ae1d224b4e5bc4
|
F src/trigger.c 1e77b3c21c129ad01f7f23a497ae1d224b4e5bc4
|
||||||
F src/update.c 89ba318306daa20d901ed698018fe6e3d16b3586
|
F src/update.c 93c7bca744988798c8898d024512954683e3e370
|
||||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
||||||
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
||||||
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
||||||
F src/vdbe.c 926b4630c583f355d5c7376ebc17d82f43a91866
|
F src/vdbe.c cf1f4de3b96226da2b53fd01b843d5bb0d58f723
|
||||||
F src/vdbe.h c686e1b73011e74b764971b83c97069ece3c04cb
|
F src/vdbe.h c686e1b73011e74b764971b83c97069ece3c04cb
|
||||||
F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
|
F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
|
||||||
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
|
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
|
||||||
@@ -177,7 +177,7 @@ F src/vdbeblob.c b90f7494c408d47ce6835000b01e40b371e27baf
|
|||||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||||
F src/vdbemem.c a94f3e9e85578ba457133ad3446fc6114a03ec5a
|
F src/vdbemem.c a94f3e9e85578ba457133ad3446fc6114a03ec5a
|
||||||
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
||||||
F src/where.c 8f55e7257daf93d9c715df7cb312dede6f2d45d2
|
F src/where.c 8c2bedcc61961a470c358b8c1466c7d8915bc722
|
||||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
|
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
|
||||||
@@ -605,7 +605,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P 5fd1036788dbbc48ff1c746d2e1ba12b04a7e58c
|
P 8862ce9ceefba4f5d1ffbd51d824c05f42a58c22
|
||||||
R 22639e8ca20a12d23612d55375b01a67
|
R 0091ff2603f4efdcadacf8e9bc937331
|
||||||
U drh
|
U drh
|
||||||
Z 654c7ee149d8fd3c6129fb629505622c
|
Z 95c6f21519b46535c3e92448c74b125f
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
8862ce9ceefba4f5d1ffbd51d824c05f42a58c22
|
92deff07bba2089bbe011f44defb3a0ac1362d56
|
||||||
20
src/expr.c
20
src/expr.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** 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 "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -2121,10 +2121,14 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
}else{
|
}else{
|
||||||
codeInteger(v, (char*)p->z, p->n, 1, target);
|
codeInteger(v, (char*)p->z, p->n, 1, target);
|
||||||
}
|
}
|
||||||
inReg = target;
|
}else{
|
||||||
break;
|
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_BITNOT:
|
||||||
case TK_NOT: {
|
case TK_NOT: {
|
||||||
@@ -2245,7 +2249,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
j2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
j2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, j1);
|
sqlite3VdbeJumpHere(v, j1);
|
||||||
if( eType==IN_INDEX_ROWID ){
|
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);
|
j4 = sqlite3VdbeAddOp1(v, OP_NotExists, pExpr->iTable);
|
||||||
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
|
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, j3);
|
sqlite3VdbeJumpHere(v, j3);
|
||||||
@@ -2314,7 +2318,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL);
|
OP_Ne, 0, 0, 0, SQLITE_JUMPIFNULL);
|
||||||
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
||||||
}else{
|
}else{
|
||||||
jumpInst = sqlite3VdbeAddOp2(v, OP_IfNot, 1, 0);
|
jumpInst = sqlite3VdbeAddOp3(v, OP_IfNot, 0, 0, 1);
|
||||||
}
|
}
|
||||||
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
|
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, expr_end_label);
|
||||||
@@ -2513,7 +2517,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqlite3ExprCode(pParse, pExpr, 0);
|
sqlite3ExprCode(pParse, pExpr, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_If, jumpIfNull, dest);
|
sqlite3VdbeAddOp3(v, OP_If, 0, dest, jumpIfNull!=0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2627,7 +2631,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqlite3ExprCode(pParse, pExpr, 0);
|
sqlite3ExprCode(pParse, pExpr, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfNot, jumpIfNull, dest);
|
sqlite3VdbeAddOp3(v, OP_IfNot, 0, dest, jumpIfNull!=0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -779,10 +779,10 @@ void sqlite3Insert(
|
|||||||
** to generate a unique primary key value.
|
** to generate a unique primary key value.
|
||||||
*/
|
*/
|
||||||
if( !appendFlag ){
|
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);
|
sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
|
||||||
sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
|
sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
|
||||||
sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regRowid);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
|
||||||
}
|
}
|
||||||
}else if( IsVirtual(pTab) ){
|
}else if( IsVirtual(pTab) ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
|
||||||
|
|||||||
37
src/pragma.c
37
src/pragma.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to implement the PRAGMA command.
|
** 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 "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -298,13 +298,13 @@ void sqlite3Pragma(
|
|||||||
*/
|
*/
|
||||||
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
||||||
static const VdbeOpList getCacheSize[] = {
|
static const VdbeOpList getCacheSize[] = {
|
||||||
{ OP_ReadCookie, 0, 0, 2}, /* 0 */
|
{ OP_ReadCookie, 0, 1, 2}, /* 0 */
|
||||||
{ OP_AbsValue, 0, 0, 0},
|
{ OP_IfPos, 1, 6, 0},
|
||||||
{ OP_Copy, 0, 0, 0},
|
{ OP_Integer, 0, 2, 0},
|
||||||
{ OP_Integer, 0, 0, 0},
|
{ OP_Subtract, 1, 2, 1},
|
||||||
{ OP_Ne, 0, 6, 0},
|
{ OP_IfPos, 1, 6, 0},
|
||||||
{ OP_Integer, 0, 0, 0}, /* 5 */
|
{ OP_Integer, 0, 1, 0}, /* 5 */
|
||||||
{ OP_Callback, 1, 0, 0},
|
{ OP_ResultRow, 1, 1, 0},
|
||||||
};
|
};
|
||||||
int addr;
|
int addr;
|
||||||
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
||||||
@@ -312,6 +312,7 @@ void sqlite3Pragma(
|
|||||||
if( !zRight ){
|
if( !zRight ){
|
||||||
sqlite3VdbeSetNumCols(v, 1);
|
sqlite3VdbeSetNumCols(v, 1);
|
||||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);
|
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P4_STATIC);
|
||||||
|
pParse->nMem += 2;
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
|
||||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||||
sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
|
sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE);
|
||||||
@@ -319,11 +320,11 @@ void sqlite3Pragma(
|
|||||||
int size = atoi(zRight);
|
int size = atoi(zRight);
|
||||||
if( size<0 ) size = -size;
|
if( size<0 ) size = -size;
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, size, 0);
|
sqlite3VdbeAddOp1(v, OP_Integer, size);
|
||||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2);
|
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2);
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_IfPos, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3);
|
sqlite3VdbeAddOp1(v, OP_Integer, -size);
|
||||||
sqlite3VdbeAddOp2(v, OP_Negative, 0, 0);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2);
|
sqlite3VdbeAddOp2(v, OP_SetCookie, iDb, 2);
|
||||||
pDb->pSchema->cache_size = size;
|
pDb->pSchema->cache_size = size;
|
||||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||||
@@ -493,10 +494,10 @@ void sqlite3Pragma(
|
|||||||
}
|
}
|
||||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
|
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Callback, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Callback);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, addr);
|
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
@@ -863,7 +864,7 @@ void sqlite3Pragma(
|
|||||||
if( OMIT_TEMPDB && i==1 ) continue;
|
if( OMIT_TEMPDB && i==1 ) continue;
|
||||||
|
|
||||||
sqlite3CodeVerifySchema(pParse, i);
|
sqlite3CodeVerifySchema(pParse, i);
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
|
|
||||||
@@ -899,7 +900,7 @@ void sqlite3Pragma(
|
|||||||
int loopTop;
|
int loopTop;
|
||||||
|
|
||||||
if( pTab->pIndex==0 ) continue;
|
if( pTab->pIndex==0 ) continue;
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
||||||
@@ -945,7 +946,7 @@ void sqlite3Pragma(
|
|||||||
{ OP_Callback, 1, 0, 0},
|
{ OP_Callback, 1, 0, 0},
|
||||||
};
|
};
|
||||||
if( pIdx->tnum==0 ) continue;
|
if( pIdx->tnum==0 ) continue;
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, 1, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
** interface, and routines that contribute to loading the database schema
|
** interface, and routines that contribute to loading the database schema
|
||||||
** from disk.
|
** 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 "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -269,6 +269,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
|||||||
|
|
||||||
size = meta[2];
|
size = meta[2];
|
||||||
if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
|
if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
|
||||||
|
if( size<0 ) size = -size;
|
||||||
pDb->pSchema->cache_size = size;
|
pDb->pSchema->cache_size = size;
|
||||||
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
||||||
|
|
||||||
|
|||||||
48
src/select.c
48
src/select.c
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements in SQLite.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -398,18 +398,18 @@ static void pushOntoSorter(
|
|||||||
){
|
){
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
|
sqlite3ExprCodeExprList(pParse, pOrderBy, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor);
|
||||||
sqlite3VdbeAddOp2(v, OP_Pull, pOrderBy->nExpr + 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, pOrderBy->nExpr + 2, 0);
|
sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor);
|
||||||
if( pSelect->iLimit>=0 ){
|
if( pSelect->iLimit>=0 ){
|
||||||
int addr1, addr2;
|
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);
|
sqlite3VdbeAddOp2(v, OP_AddImm, pSelect->iLimit+1, -1);
|
||||||
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Last, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
|
||||||
sqlite3VdbeAddOp2(v, OP_Delete, pOrderBy->iECursor, 0);
|
sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
pSelect->iLimit = -1;
|
pSelect->iLimit = -1;
|
||||||
}
|
}
|
||||||
@@ -427,9 +427,9 @@ static void codeOffset(
|
|||||||
if( p->iOffset>=0 && iContinue!=0 ){
|
if( p->iOffset>=0 && iContinue!=0 ){
|
||||||
int addr;
|
int addr;
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
|
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 ){
|
if( nPop>0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Pop, nPop, 0);
|
sqlite3VdbeAddOp1(v, OP_Pop, nPop);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
|
||||||
VdbeComment((v, "skip OFFSET records"));
|
VdbeComment((v, "skip OFFSET records"));
|
||||||
@@ -641,7 +641,7 @@ static int selectInnerLoop(
|
|||||||
int addr2;
|
int addr2;
|
||||||
|
|
||||||
assert( nColumn==1 );
|
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);
|
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
/* At first glance you would think we could optimize out the
|
/* At first glance you would think we could optimize out the
|
||||||
@@ -717,7 +717,7 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( p->iLimit>=0 && pOrderBy==0 ){
|
if( p->iLimit>=0 && pOrderBy==0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemZero, p->iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -852,7 +852,7 @@ static void generateSortTail(
|
|||||||
*/
|
*/
|
||||||
if( p->iLimit>=0 ){
|
if( p->iLimit>=0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
|
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
|
/* The bottom of the loop
|
||||||
@@ -1768,10 +1768,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pLimit, 0);
|
sqlite3ExprCode(pParse, p->pLimit, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_MustBeInt);
|
||||||
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
|
||||||
VdbeComment((v, "LIMIT counter"));
|
VdbeComment((v, "LIMIT counter"));
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
|
||||||
}
|
}
|
||||||
if( p->pOffset ){
|
if( p->pOffset ){
|
||||||
@@ -1779,10 +1779,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pOffset, 0);
|
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);
|
sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset);
|
||||||
VdbeComment((v, "OFFSET counter"));
|
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_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
@@ -1791,10 +1791,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( p->pLimit ){
|
if( p->pLimit ){
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0);
|
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
|
||||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
|
||||||
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
|
||||||
VdbeComment((v, "LIMIT+OFFSET"));
|
VdbeComment((v, "LIMIT+OFFSET"));
|
||||||
@@ -1948,7 +1948,7 @@ static int multiSelect(
|
|||||||
p->iLimit = pPrior->iLimit;
|
p->iLimit = pPrior->iLimit;
|
||||||
p->iOffset = pPrior->iOffset;
|
p->iOffset = pPrior->iOffset;
|
||||||
if( p->iLimit>=0 ){
|
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"));
|
VdbeComment((v, "Jump ahead if LIMIT reached"));
|
||||||
}
|
}
|
||||||
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
|
||||||
@@ -3520,7 +3520,7 @@ int sqlite3Select(
|
|||||||
VdbeComment((v, "set abort flag"));
|
VdbeComment((v, "set abort flag"));
|
||||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemPos, iUseFlag, addrOutputRow+2);
|
sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
|
||||||
VdbeComment((v, "Groupby result generator entry point"));
|
VdbeComment((v, "Groupby result generator entry point"));
|
||||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||||
finalizeAggFunctions(pParse, &sAggInfo);
|
finalizeAggFunctions(pParse, &sAggInfo);
|
||||||
@@ -3626,7 +3626,7 @@ int sqlite3Select(
|
|||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
||||||
VdbeComment((v, "output one row"));
|
VdbeComment((v, "output one row"));
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemPos, iAbortFlag, addrEnd);
|
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
|
||||||
VdbeComment((v, "check abort flag"));
|
VdbeComment((v, "check abort flag"));
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
|
||||||
VdbeComment((v, "reset accumulator"));
|
VdbeComment((v, "reset accumulator"));
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle UPDATE statements.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -468,7 +468,7 @@ void sqlite3Update(
|
|||||||
*/
|
*/
|
||||||
if( chngRowid ){
|
if( chngRowid ){
|
||||||
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
|
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
|
||||||
sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, regNewRowid);
|
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute new data for this record.
|
/* Compute new data for this record.
|
||||||
|
|||||||
239
src/vdbe.c
239
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** 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 "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -913,7 +913,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: String8 * * P4
|
/* Opcode: String8 * P2 * P4 *
|
||||||
**
|
**
|
||||||
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
|
** 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.
|
** 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 */
|
#endif /* SQLITE_OMIT_BLOB_LITERAL */
|
||||||
|
|
||||||
/* Opcode: Variable P1 * *
|
/* Opcode: Variable P1 P2 * * *
|
||||||
**
|
**
|
||||||
** The value of variable P1 is written into register P2 or pushed
|
** The value of variable P1 is written into register P2 or pushed
|
||||||
** onto the stack if P2 is zero. A variable is
|
** onto the stack if P2 is zero. A variable is
|
||||||
@@ -1046,7 +1046,7 @@ case OP_Variable: { /* out2-prerelease */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Pop P1 * *
|
/* Opcode: Pop P1 * * * *
|
||||||
**
|
**
|
||||||
** P1 elements are popped off of the top of stack and discarded.
|
** 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Add * * *
|
/* Opcode: Add P1 P2 P3 * *
|
||||||
**
|
**
|
||||||
** Pop the top two elements from the stack, add them together,
|
** Add the value in P1 to the value in P2 and store the result in P3.
|
||||||
** 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.
|
|
||||||
** If either operand is NULL, the result is NULL.
|
** 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
|
** Multiply the value in P1 by the value in P2 and store the result in P3.
|
||||||
** is a string then it is converted to a double using the atof()
|
|
||||||
** function before the multiplication.
|
|
||||||
** If either operand is NULL, the result is NULL.
|
** 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
|
** Subtract the value in P1 from the value in P2 and store the result
|
||||||
** first (what was on top of the stack) from the second (the
|
** in P3.
|
||||||
** 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.
|
|
||||||
** If either operand is NULL, the result is NULL.
|
** If either operand is NULL, the result is NULL.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Divide * * *
|
/* Opcode: Divide * * *
|
||||||
**
|
**
|
||||||
** Pop the top two elements from the stack, divide the
|
** Divide the value in P1 by the value in P2 and store the result
|
||||||
** first (what was on top of the stack) from the second (the
|
** in P3. If the value in P2 is zero, then the result is NULL.
|
||||||
** 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.
|
|
||||||
** If either operand is NULL, the result is NULL.
|
** If either operand is NULL, the result is NULL.
|
||||||
*/
|
*/
|
||||||
/* Opcode: Remainder * * *
|
/* Opcode: Remainder * * *
|
||||||
**
|
**
|
||||||
** Pop the top two elements from the stack, divide the
|
** Compute the remainder after integer division of the value in
|
||||||
** first (what was on top of the stack) from the second (the
|
** register P1 by the value in register P2 and store the result in P3.
|
||||||
** next on stack)
|
** If the value in register P2 is zero the result is NULL.
|
||||||
** 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.
|
|
||||||
** If either operand is NULL, the result is NULL.
|
** If either operand is NULL, the result is NULL.
|
||||||
*/
|
*/
|
||||||
case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
|
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
|
/* Opcode: MustBeInt P1 P2 P3
|
||||||
**
|
**
|
||||||
** Force the top of the stack to be an integer. If the top of the
|
** Force the value in register P1 to be an integer. If P1==0 then
|
||||||
** stack is not an integer and cannot be converted into an integer
|
** 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
|
** without data loss, then jump immediately to P2, or if P2==0
|
||||||
** raise an SQLITE_MISMATCH exception.
|
** raise an SQLITE_MISMATCH exception.
|
||||||
**
|
**
|
||||||
** If the top of the stack is not an integer and P2 is not zero and
|
** If the P1==0 and the top of the stack is not an integer
|
||||||
** P1 is 1, then the stack is popped. In all other cases, the depth
|
** and P2 is not zero and P3 is 1, then the stack is popped.
|
||||||
** of the stack is unchanged.
|
** 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.
|
|
||||||
*/
|
*/
|
||||||
case OP_MustBeInt: { /* no-push, jump */
|
case OP_MustBeInt: { /* no-push, jump, in1 */
|
||||||
Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]);
|
nPop = 0;
|
||||||
assert( pOp->p3 || pTos>=p->aStack );
|
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
|
||||||
assert( pOp->p3>=0 && pOp->p3<=p->nMem );
|
if( (pIn1->flags & MEM_Int)==0 ){
|
||||||
REGISTER_TRACE(pOp->p3, pMem);
|
|
||||||
applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding);
|
|
||||||
if( (pMem->flags & MEM_Int)==0 ){
|
|
||||||
if( pOp->p2==0 ){
|
if( pOp->p2==0 ){
|
||||||
rc = SQLITE_MISMATCH;
|
rc = SQLITE_MISMATCH;
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}else if( pMem==pTos ){
|
}else{
|
||||||
if( pOp->p1 ) popStack(&pTos, 1);
|
if( pOp->p3 && pOp->p1==0 ){
|
||||||
|
popStack(&pTos, 1);
|
||||||
|
}
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Release(pMem);
|
Release(pIn1);
|
||||||
pMem->flags = MEM_Int;
|
pIn1->flags = MEM_Int;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1989,53 +1970,19 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
|||||||
break;
|
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 * * *
|
/* Opcode: Not * * *
|
||||||
**
|
**
|
||||||
** Interpret the top of the stack as a boolean value. Replace it
|
** 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
|
** with its complement. If the top of the stack is NULL its value
|
||||||
** is unchanged.
|
** is unchanged.
|
||||||
*/
|
*/
|
||||||
case OP_Not: { /* same as TK_NOT, no-push */
|
case OP_Not: { /* same as TK_NOT, no-push, in1 */
|
||||||
assert( pTos>=p->aStack );
|
nPop = 0;
|
||||||
if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
||||||
sqlite3VdbeMemIntegerify(pTos);
|
sqlite3VdbeMemIntegerify(pIn1);
|
||||||
assert( (pTos->flags & MEM_Dyn)==0 );
|
assert( (pIn1->flags & MEM_Dyn)==0 );
|
||||||
pTos->u.i = !pTos->u.i;
|
pIn1->u.i = !pTos->u.i;
|
||||||
pTos->flags = MEM_Int;
|
pIn1->flags = MEM_Int;
|
||||||
break;
|
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
|
** with its ones-complement. If the top of the stack is NULL its
|
||||||
** value is unchanged.
|
** value is unchanged.
|
||||||
*/
|
*/
|
||||||
case OP_BitNot: { /* same as TK_BITNOT, no-push */
|
case OP_BitNot: { /* same as TK_BITNOT, no-push, in1 */
|
||||||
assert( pTos>=p->aStack );
|
nPop = 0;
|
||||||
if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
if( pIn1->flags & MEM_Null ) break; /* Do nothing to NULLs */
|
||||||
sqlite3VdbeMemIntegerify(pTos);
|
sqlite3VdbeMemIntegerify(pIn1);
|
||||||
assert( (pTos->flags & MEM_Dyn)==0 );
|
assert( (pIn1->flags & MEM_Dyn)==0 );
|
||||||
pTos->u.i = ~pTos->u.i;
|
pIn1->u.i = ~pTos->u.i;
|
||||||
pTos->flags = MEM_Int;
|
pIn1->flags = MEM_Int;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2071,43 +2018,34 @@ case OP_Noop: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: If P1 P2 *
|
/* Opcode: If P1 P2 P3 * *
|
||||||
**
|
**
|
||||||
** Pop a single boolean from the stack. If the boolean popped is
|
** Jump to P2 if the value in register P1 is true. The value is
|
||||||
** true, then jump to p2. Otherwise continue to the next instruction.
|
** is considered true if it is numeric and non-zero. If the value
|
||||||
** An integer is false if zero and true otherwise. A string is
|
** in P1 is NULL then take the jump if P3 is true.
|
||||||
** 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.
|
|
||||||
*/
|
*/
|
||||||
/* Opcode: IfNot P1 P2 *
|
/* Opcode: IfNot P1 P2 P3 * *
|
||||||
**
|
**
|
||||||
** Pop a single boolean from the stack. If the boolean popped is
|
** Jump to P2 if the value in register P1 is False. The value is
|
||||||
** false, then jump to p2. Otherwise continue to the next instruction.
|
** is considered true if it has a numeric value of zero. If the value
|
||||||
** An integer is false if zero and true otherwise. A string is
|
** in P1 is NULL then take the jump if P3 is true.
|
||||||
** 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.
|
|
||||||
*/
|
*/
|
||||||
case OP_If: /* no-push, jump */
|
case OP_If: /* no-push, jump, in1 */
|
||||||
case OP_IfNot: { /* no-push, jump */
|
case OP_IfNot: { /* no-push, jump, in1 */
|
||||||
int c;
|
int c;
|
||||||
assert( pTos>=p->aStack );
|
if( pIn1->flags & MEM_Null ){
|
||||||
if( pTos->flags & MEM_Null ){
|
c = pOp->p3;
|
||||||
c = pOp->p1;
|
|
||||||
}else{
|
}else{
|
||||||
#ifdef SQLITE_OMIT_FLOATING_POINT
|
#ifdef SQLITE_OMIT_FLOATING_POINT
|
||||||
c = sqlite3VdbeIntValue(pTos);
|
c = sqlite3VdbeIntValue(pIn1);
|
||||||
#else
|
#else
|
||||||
c = sqlite3VdbeRealValue(pTos)!=0.0;
|
c = sqlite3VdbeRealValue(pIn1)!=0.0;
|
||||||
#endif
|
#endif
|
||||||
if( pOp->opcode==OP_IfNot ) c = !c;
|
if( pOp->opcode==OP_IfNot ) c = !c;
|
||||||
}
|
}
|
||||||
Release(pTos);
|
if( c ){
|
||||||
pTos--;
|
pc = pOp->p2-1;
|
||||||
if( c ) pc = pOp->p2-1;
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4758,71 +4696,46 @@ case OP_MemMax: { /* no-push */
|
|||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
#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.
|
** 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
|
** 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.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfMemPos: { /* no-push, jump */
|
case OP_IfPos: { /* no-push, jump, in1 */
|
||||||
int i = pOp->p1;
|
assert( pIn1->flags==MEM_Int );
|
||||||
Mem *pMem;
|
if( pIn1->u.i>0 ){
|
||||||
assert( i>0 && i<=p->nMem );
|
|
||||||
pMem = &p->aMem[i];
|
|
||||||
assert( pMem->flags==MEM_Int );
|
|
||||||
if( pMem->u.i>0 ){
|
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: IfMemNeg P1 P2 *
|
/* Opcode: IfNeg P1 P2 *
|
||||||
**
|
**
|
||||||
** If the value of memory cell P1 is less than zero, jump to 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
|
** 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.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfMemNeg: { /* no-push, jump */
|
case OP_IfNeg: { /* no-push, jump, in1 */
|
||||||
int i = pOp->p1;
|
assert( pIn1->flags==MEM_Int );
|
||||||
Mem *pMem;
|
if( pIn1->u.i<0 ){
|
||||||
assert( i>0 && i<=p->nMem );
|
|
||||||
pMem = &p->aMem[i];
|
|
||||||
assert( pMem->flags==MEM_Int );
|
|
||||||
if( pMem->u.i<0 ){
|
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: IfMemZero P1 P2 *
|
/* Opcode: IfZero P1 P2 *
|
||||||
**
|
**
|
||||||
** If the value of memory cell P1 is exactly 0, jump to 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
|
** 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.
|
** not contain an integer. An assertion fault will result if you try.
|
||||||
*/
|
*/
|
||||||
case OP_IfMemZero: { /* no-push, jump */
|
case OP_IfZero: { /* no-push, jump, in1 */
|
||||||
int i = pOp->p1;
|
assert( pIn1->flags==MEM_Int );
|
||||||
Mem *pMem;
|
if( pIn1->u.i==0 ){
|
||||||
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 ){
|
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
14
src/where.c
14
src/where.c
@@ -16,7 +16,7 @@
|
|||||||
** so is applicable. Because this module is responsible for selecting
|
** so is applicable. Because this module is responsible for selecting
|
||||||
** indices, you might also think of this module as the "query optimizer".
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -2329,7 +2329,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( omitTable==0 );
|
assert( omitTable==0 );
|
||||||
codeEqualityTerm(pParse, pTerm, pLevel);
|
codeEqualityTerm(pParse, pTerm, pLevel);
|
||||||
nxt = pLevel->nxt;
|
nxt = pLevel->nxt;
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 1, nxt);
|
sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, nxt, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_NotExists, iCur, nxt);
|
||||||
VdbeComment((v, "pk"));
|
VdbeComment((v, "pk"));
|
||||||
pLevel->op = OP_Noop;
|
pLevel->op = OP_Noop;
|
||||||
@@ -2766,10 +2766,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
sqlite3VdbeResolveLabel(v, pLevel->brk);
|
||||||
if( pLevel->iLeftJoin ){
|
if( pLevel->iLeftJoin ){
|
||||||
int addr;
|
int addr;
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_IfMemPos, pLevel->iLeftJoin, 0);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
|
||||||
sqlite3VdbeAddOp2(v, OP_NullRow, pTabList->a[i].iCursor, 0);
|
sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
|
||||||
if( pLevel->iIdxCur>=0 ){
|
if( pLevel->iIdxCur>=0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_NullRow, pLevel->iIdxCur, 0);
|
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->top);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
@@ -2789,10 +2789,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
assert( pTab!=0 );
|
assert( pTab!=0 );
|
||||||
if( pTab->isEphem || pTab->pSelect ) continue;
|
if( pTab->isEphem || pTab->pSelect ) continue;
|
||||||
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, pTabItem->iCursor, 0);
|
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
|
||||||
}
|
}
|
||||||
if( pLevel->pIdx!=0 ){
|
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
|
/* If this scan uses an index, make code substitutions to read data
|
||||||
|
|||||||
Reference in New Issue
Block a user