Implement the out2-prerelease opcode design pattern. (CVS 4681)
FossilOrigin-Name: fe057a88d0038ac349ea41883b979ceba6ae410a
This commit is contained in:
parent
d298151587
commit
4c583128bd
36
manifest
36
manifest
@ -1,5 +1,5 @@
|
||||
C Allow\sthe\sP2\soperand\sto\sbe\snegative\son\sopcodes\sthat\sare\snot\sjumps.\s(CVS\s4680)
|
||||
D 2008-01-04T19:33:49
|
||||
C Implement\sthe\sout2-prerelease\sopcode\sdesign\spattern.\s(CVS\s4681)
|
||||
D 2008-01-04T22:01:03
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -69,7 +69,7 @@ F mkdll.sh 5f8438dcac98e795d7df6529159a1ec566de0183
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
|
||||
F mkopcodec.awk 3fb9bf077053c968451f4dd03d11661ac373f9d1
|
||||
F mkopcodeh.awk a500ebdc9058f40297a66d612fbdc6ea5edbea3b
|
||||
F mkopcodeh.awk 71abda1cad4c3c7385834ced713c0271f2b13161
|
||||
F mkso.sh 24bde4c09e6fe80f718db3c31c068f45e13a2f2c
|
||||
F publish.sh 1c0658c63d70f182a8f5e17cc28422f1b237f51d
|
||||
F publish_osx.sh eca87df1e3d43d128d97d3261fd48b3d6877996e
|
||||
@ -78,25 +78,25 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
||||
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
||||
F src/alter.c b59c881008f5d32d3d6dde6cf49735467cf5aac4
|
||||
F src/analyze.c addc8e75cc43eb7ad699cd3ffc0a9157b4bf9405
|
||||
F src/alter.c 5a54f58d9481ac14c4e58b702f3f8758dee84d04
|
||||
F src/analyze.c 117e600989d4308578140b646f5caaec6b751f16
|
||||
F src/attach.c 1c96631e56cdc51d3d70736bf61f1fe01c62cbea
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
||||
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
||||
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
||||
F src/build.c b7874b45716fa56e6fd1291ffb0b97a55e470728
|
||||
F src/build.c eac0f7e670035ee1087edc7ca223da844bf8940d
|
||||
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||
F src/delete.c bc1fedf48f97d52b691bc057164b732409dcd9eb
|
||||
F src/delete.c 056f96bbbfaf27cb90f03e1d21abeab88a26235c
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c e60ee4f48194469bf7b101fb7a14e56abea3daa4
|
||||
F src/expr.c 57f7c39724c8dee8b4a547dfa58c344bee528996
|
||||
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
||||
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||
F src/insert.c 9011065ed43b939c77083e9be3b721e7dfe39c71
|
||||
F src/insert.c 907fa2dfde1330d9971ba180ad735ea4daf6ad03
|
||||
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||
@ -127,11 +127,11 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 0cb6ccea4b9615627d61d7c4417cedc45776d429
|
||||
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
||||
F src/parse.y 2ae06e8d3190faace49c5b82e7cea1fc60d084a1
|
||||
F src/pragma.c ac8d91bb15dd475d239b9d7bd5dbd7d69a9428e7
|
||||
F src/pragma.c ff8841222bb9779f1ebed0c4d0016530221e7fe8
|
||||
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
|
||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||
F src/select.c 62b9cfb2c7c90570834816975ee1ceaf2e5a74e3
|
||||
F src/select.c 30110ce6ce891dcb93a922ee4a51946983df0a33
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b
|
||||
F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f
|
||||
@ -164,20 +164,20 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
||||
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
||||
F src/trigger.c 713b501b12ea41bf0297a2cf78f7d954c4a25d13
|
||||
F src/update.c b54161c624120d8249c9ed9442b24452557fe665
|
||||
F src/update.c e57d0083b0800ae514f3226761d019f195f15cb2
|
||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
||||
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
||||
F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
|
||||
F src/vdbe.c 9ccdc8ab9cb027f7ef759259f515ead5e89c5bb3
|
||||
F src/vdbe.c a2d9e868ef2ac65310478d32a33e9bdffc74281e
|
||||
F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
|
||||
F src/vdbeInt.h 31bd686595356284d5484592e2dc6e58025aa346
|
||||
F src/vdbeapi.c f14174843bf4be2c9afdf2ef48b61e7c3ac62d7c
|
||||
F src/vdbeaux.c 83262e81a0390fb52990ea52c54d6be49bf60ea5
|
||||
F src/vdbeaux.c ae45ffeee9f503e2cce2f1db51893934e7c669a5
|
||||
F src/vdbeblob.c b90f7494c408d47ce6835000b01e40b371e27baf
|
||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
|
||||
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
||||
F src/where.c ce1e6c53fa443d8adb06358726d66c891429e769
|
||||
F src/where.c d015536e273de18196554f13265d80ec9e988766
|
||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba
|
||||
@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 59d3dfa41f99e99b836649a0870cbfc1c275a654
|
||||
R 9c7ea80dc841cb7f5d5845a6354029fd
|
||||
P 717bcd11a222fe100e25c5b2eb6de8b6b9930de1
|
||||
R 4486249090525dc5e5cc1ca96f44eb9a
|
||||
U drh
|
||||
Z 42f5b8efcd6264386055bebf1bee5cb4
|
||||
Z c5a3c782e07a8605f750b96c4ed10a88
|
||||
|
@ -1 +1 @@
|
||||
717bcd11a222fe100e25c5b2eb6de8b6b9930de1
|
||||
fe057a88d0038ac349ea41883b979ceba6ae410a
|
@ -50,14 +50,9 @@
|
||||
sub(/:/,"",name)
|
||||
sub("\r","",name)
|
||||
op[name] = -1
|
||||
out1[name] = 0
|
||||
out2[name] = 0
|
||||
out3[name] = 0
|
||||
jump[name] = 0
|
||||
in1[name] = 0
|
||||
in2[name] = 0
|
||||
in3[name] = 0
|
||||
nopush[name] = 0
|
||||
out2_prerelease[name] = 0
|
||||
for(i=3; i<NF; i++){
|
||||
if($i=="same" && $(i+1)=="as"){
|
||||
sym = $(i+2)
|
||||
@ -70,20 +65,10 @@
|
||||
sub(",","",x)
|
||||
if(x=="no-push"){
|
||||
nopush[name] = 1
|
||||
}else if(x=="out1"){
|
||||
out1[name] = 1
|
||||
}else if(x=="out2"){
|
||||
out2[name] = 2
|
||||
}else if(x=="out3"){
|
||||
out3[name] = 3
|
||||
}else if(x=="in1"){
|
||||
in1[name] = 1
|
||||
}else if(x=="in2"){
|
||||
in2[name] = 1
|
||||
}else if(x=="in3"){
|
||||
in3[name] = 1
|
||||
}else if(x=="jump"){
|
||||
jump[name] = 1
|
||||
}else if(x=="out2-prerelease"){
|
||||
out2_prerelease[name] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,26 +108,16 @@ END {
|
||||
# Generate the bitvectors:
|
||||
#
|
||||
# bit 0: jump
|
||||
# bit 1: output on P1
|
||||
# bit 2: output on P2
|
||||
# bit 3: output on P3
|
||||
# bit 4: input on P1
|
||||
# bit 5: input on P2
|
||||
# bit 6: input on P3
|
||||
# bit 7: pushes a result onto stack
|
||||
# bit 1: pushes a result onto stack
|
||||
# bit 2: output to p1. release p1 before opcode runs
|
||||
#
|
||||
for(i=0; i<=max; i++) bv[i] = 0;
|
||||
for(name in op){
|
||||
x = op[name]
|
||||
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
|
||||
if( jump[name] ) a0 = 1;
|
||||
if( out1[name] ) a1 = 2;
|
||||
if( out2[name] ) a2 = 4;
|
||||
if( out3[name] ) a3 = 8;
|
||||
if( in1[name] ) a4 = 16;
|
||||
if( in2[name] ) a5 = 32;
|
||||
if( in3[name] ) a6 = 64;
|
||||
if( nopush[name]==0 ) a7 = 128;
|
||||
if( nopush[name]==0 ) a1 = 2;
|
||||
if( out2_prerelease[name] ) a2 = 4;
|
||||
bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||
}
|
||||
print "\n"
|
||||
@ -150,18 +125,13 @@ END {
|
||||
print "** comments following the "case" for each opcode in the vdbe.c"
|
||||
print "** are encoded into bitvectors as follows:"
|
||||
print "*/"
|
||||
print "#define OPFLG_JUMP 0x01 /* jump: P2 holds a jump target */"
|
||||
print "#define OPFLG_OUT1 0x02 /* out1: P1 specifies output reg */"
|
||||
print "#define OPFLG_OUT2 0x04 /* out2: P2 specifies output reg */"
|
||||
print "#define OPFLG_OUT3 0x08 /* out3: P3 specifies output reg */"
|
||||
print "#define OPFLG_IN1 0x10 /* in1: P1 is an input reg */"
|
||||
print "#define OPFLG_IN2 0x20 /* in2: P2 is an input reg */"
|
||||
print "#define OPFLG_IN3 0x40 /* in3: P3 is an input reg */"
|
||||
print "#define OPFLG_PUSH 0x80 /* omits no-push: Does not push */"
|
||||
print "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */"
|
||||
print "#define OPFLG_PUSH 0x02 /* ~no-push: Does not push */"
|
||||
print "#define OPFLG_OUT2_PRERELEASE 0x04 /* out2-prerelease: */"
|
||||
print "#define OPFLG_INITIALIZER {\\"
|
||||
for(i=0; i<=max; i++){
|
||||
printf " 0x%02x,", bv[i]
|
||||
if( i%10==9 ) printf("\\\n");
|
||||
if( i%8==7 ) printf("\\\n");
|
||||
}
|
||||
print "}"
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that used to generate VDBE code
|
||||
** that implements the ALTER TABLE command.
|
||||
**
|
||||
** $Id: alter.c,v 1.38 2008/01/04 11:01:04 danielk1977 Exp $
|
||||
** $Id: alter.c,v 1.39 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -363,9 +363,7 @@ void sqlite3AlterRenameTable(
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( isVirtualRename ){
|
||||
int i = ++pParse->nMem;
|
||||
sqlite3_value *pVal = sqlite3ValueNew(db);
|
||||
sqlite3ValueSetStr(pVal, -1, zName, SQLITE_UTF8, SQLITE_TRANSIENT);
|
||||
sqlite3VdbeAddOp4(v, OP_MemSet, i, 0, 0, (char *)pVal, P4_MEM);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
|
||||
}
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code associated with the ANALYZE command.
|
||||
**
|
||||
** @(#) $Id: analyze.c,v 1.30 2008/01/03 18:03:09 drh Exp $
|
||||
** @(#) $Id: analyze.c,v 1.31 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_ANALYZE
|
||||
#include "sqliteInt.h"
|
||||
@ -144,10 +144,10 @@ static void analyzeOneTable(
|
||||
** are initialized to NULL.
|
||||
*/
|
||||
for(i=0; i<=nCol; i++){
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iMem+i);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
|
||||
}
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iMem+nCol+i+1);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
|
||||
}
|
||||
|
||||
/* Do the analysis.
|
||||
|
@ -22,7 +22,7 @@
|
||||
** COMMIT
|
||||
** ROLLBACK
|
||||
**
|
||||
** $Id: build.c,v 1.456 2008/01/03 18:03:09 drh Exp $
|
||||
** $Id: build.c,v 1.457 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -851,7 +851,7 @@ void sqlite3StartTable(
|
||||
/* If the file format and encoding in the database have not been set,
|
||||
** set them now.
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 1); /* file_format */
|
||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 1); /* file_format */
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
lbl = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp2(v, OP_If, 0, lbl);
|
||||
@ -2719,7 +2719,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
|
||||
Vdbe *v;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v ){
|
||||
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 1);
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
sqlite3VdbeAddOp1(v, OP_Integer, minFormat);
|
||||
sqlite3VdbeAddOp2(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||
|
@ -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.147 2008/01/04 19:10:29 danielk1977 Exp $
|
||||
** $Id: delete.c,v 1.148 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -274,7 +274,7 @@ void sqlite3DeleteFrom(
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
memCnt = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
|
||||
}
|
||||
|
||||
/* Special case: A DELETE without a WHERE clause deletes everything.
|
||||
@ -369,7 +369,7 @@ void sqlite3DeleteFrom(
|
||||
if( old_col_mask ){
|
||||
sqlite3VdbeAddOp3(v, OP_RowData, iCur, 0, iData);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iData);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iData);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid);
|
||||
|
||||
|
12
src/expr.c
12
src/expr.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.329 2008/01/03 23:44:53 drh Exp $
|
||||
** $Id: expr.c,v 1.330 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -1608,7 +1608,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
||||
|
||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
||||
|
||||
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
|
||||
eType = IN_INDEX_ROWID;
|
||||
@ -1645,7 +1645,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
||||
|
||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
||||
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
||||
|
||||
sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
|
||||
pKey,P4_KEYINFO_HANDOFF);
|
||||
@ -1703,7 +1703,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
sqlite3VdbeAddOp1(v, OP_MemLoad, mem);
|
||||
testAddr = sqlite3VdbeAddOp0(v, OP_If);
|
||||
assert( testAddr>0 || pParse->db->mallocFailed );
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, mem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
|
||||
}
|
||||
|
||||
switch( pExpr->op ){
|
||||
@ -1807,11 +1807,11 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
dest.iParm = ++pParse->nMem;
|
||||
if( pExpr->op==TK_SELECT ){
|
||||
dest.eDest = SRT_Mem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, dest.iParm);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
|
||||
VdbeComment((v, "Init subquery result"));
|
||||
}else{
|
||||
dest.eDest = SRT_Exists;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, dest.iParm);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
|
||||
VdbeComment((v, "Init EXISTS result"));
|
||||
}
|
||||
sqlite3ExprDelete(pSel->pLimit);
|
||||
|
24
src/insert.c
24
src/insert.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.210 2008/01/04 19:10:29 danielk1977 Exp $
|
||||
** $Id: insert.c,v 1.211 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -217,7 +217,7 @@ static void autoIncEnd(
|
||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
|
||||
sqlite3VdbeAddOp1(v, OP_NewRowid, iCur);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
|
||||
@ -509,7 +509,7 @@ void sqlite3Insert(
|
||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
|
||||
sqlite3VdbeAddOp1(v, OP_NewRowid, srcTab);
|
||||
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||
sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND);
|
||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||
@ -619,7 +619,7 @@ void sqlite3Insert(
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
iCntMem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iCntMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iCntMem);
|
||||
}
|
||||
|
||||
/* If this is not a view, open the table and and all indices */
|
||||
@ -722,7 +722,7 @@ void sqlite3Insert(
|
||||
|
||||
if( IsVirtual(pTab) ){
|
||||
/* The row that the VUpdate opcode will delete: none */
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iReg);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
|
||||
}
|
||||
if( keyColumn>=0 ){
|
||||
if( useTempTable ){
|
||||
@ -739,8 +739,8 @@ void sqlite3Insert(
|
||||
appendFlag = 1;
|
||||
pOp->opcode = OP_NewRowid;
|
||||
pOp->p1 = base;
|
||||
pOp->p2 = counterMem;
|
||||
pOp->p3 = iRowid;
|
||||
pOp->p2 = iRowid;
|
||||
pOp->p3 = counterMem;
|
||||
}else{
|
||||
/* TODO: Avoid this use of the stack. */
|
||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
||||
@ -752,13 +752,13 @@ void sqlite3Insert(
|
||||
if( !appendFlag ){
|
||||
sqlite3VdbeAddOp2(v, OP_IfMemNull, iRowid, sqlite3VdbeCurrentAddr(v)+2);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
|
||||
sqlite3VdbeAddOp3(v, OP_NewRowid, base, counterMem, iRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_NewRowid, base, iRowid, counterMem);
|
||||
sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, iRowid);
|
||||
}
|
||||
}else if( IsVirtual(pTab) ){
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iRowid);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||
sqlite3VdbeAddOp3(v, OP_NewRowid, base, 0, counterMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
||||
appendFlag = 1;
|
||||
}
|
||||
@ -775,7 +775,7 @@ void sqlite3Insert(
|
||||
** Whenever this column is read, the record number will be substituted
|
||||
** in its place. So will fill this column with a NULL to avoid
|
||||
** taking up data space with information that will never be used. */
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRegStore);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
|
||||
continue;
|
||||
}
|
||||
if( pColumn==0 ){
|
||||
@ -1573,7 +1573,7 @@ static int xferOptimization(
|
||||
sqlite3VdbeJumpHere(v, addr2);
|
||||
autoIncStep(pParse, counterMem, 0);
|
||||
}else if( pDest->pIndex==0 ){
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
|
||||
addr1 = sqlite3VdbeAddOp1(v, OP_NewRowid, iDest);
|
||||
}else{
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||
assert( pDest->autoInc==0 );
|
||||
|
20
src/pragma.c
20
src/pragma.c
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the PRAGMA command.
|
||||
**
|
||||
** $Id: pragma.c,v 1.157 2008/01/03 18:03:09 drh Exp $
|
||||
** $Id: pragma.c,v 1.158 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -148,7 +148,7 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int mem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, value, mem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, value, mem);
|
||||
if( pParse->explain==0 ){
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P4_STATIC);
|
||||
@ -298,7 +298,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
||||
static const VdbeOpList getCacheSize[] = {
|
||||
{ OP_ReadCookie, 0, 2, 0}, /* 0 */
|
||||
{ OP_ReadCookie, 0, 0, 2}, /* 0 */
|
||||
{ OP_AbsValue, 0, 0, 0},
|
||||
{ OP_Dup, 0, 0, 0},
|
||||
{ OP_Integer, 0, 0, 0},
|
||||
@ -320,7 +320,7 @@ void sqlite3Pragma(
|
||||
if( size<0 ) size = -size;
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, size, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_ReadCookie, iDb, 2);
|
||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 0, 2);
|
||||
addr = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Ge, 0, addr+3);
|
||||
sqlite3VdbeAddOp2(v, OP_Negative, 0, 0);
|
||||
@ -457,7 +457,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
static const VdbeOpList setMeta6[] = {
|
||||
{ OP_Transaction, 0, 1, 0}, /* 0 */
|
||||
{ OP_ReadCookie, 0, 3, 0}, /* 1 */
|
||||
{ OP_ReadCookie, 0, 0, 3}, /* 1 */
|
||||
{ OP_If, 0, 0, 0}, /* 2 */
|
||||
{ OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
|
||||
{ OP_Integer, 0, 0, 0}, /* 4 */
|
||||
@ -492,7 +492,7 @@ void sqlite3Pragma(
|
||||
iLimit = 0x7fffffff;
|
||||
}
|
||||
sqlite3BeginWriteOperation(pParse, 0, iDb);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, iLimit, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
|
||||
addr = sqlite3VdbeAddOp2(v, OP_IncrVacuum, iDb, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Callback, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemIncr, -1, 1);
|
||||
@ -852,7 +852,7 @@ void sqlite3Pragma(
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, mxErr, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1);
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@ -903,7 +903,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, 2);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);
|
||||
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, 2);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
@ -929,7 +929,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, loopTop);
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
static const VdbeOpList cntIdx[] = {
|
||||
{ OP_MemInt, 0, 3, 0},
|
||||
{ OP_Integer, 0, 3, 0},
|
||||
{ OP_Rewind, 0, 0, 0}, /* 1 */
|
||||
{ OP_MemIncr, 1, 3, 0},
|
||||
{ OP_Next, 0, 0, 0}, /* 3 */
|
||||
@ -1107,7 +1107,7 @@ void sqlite3Pragma(
|
||||
};
|
||||
int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
|
||||
sqlite3VdbeChangeP1(v, addr, iDb);
|
||||
sqlite3VdbeChangeP2(v, addr, iCookie);
|
||||
sqlite3VdbeChangeP3(v, addr, iCookie);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P4_TRANSIENT);
|
||||
}
|
||||
|
24
src/select.c
24
src/select.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.383 2008/01/03 23:44:53 drh Exp $
|
||||
** $Id: select.c,v 1.384 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -543,7 +543,7 @@ static int selectInnerLoop(
|
||||
}
|
||||
iMem = ++pParse->nMem;
|
||||
pParse->nMem += n+1;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, n, iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, n, iMem);
|
||||
if( nColumn>0 ){
|
||||
for(i=0; i<nColumn; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, iMem+i+1);
|
||||
@ -611,7 +611,7 @@ static int selectInnerLoop(
|
||||
if( pOrderBy ){
|
||||
pushOntoSorter(pParse, pOrderBy, p);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
|
||||
sqlite3VdbeAddOp1(v, OP_NewRowid, iParm);
|
||||
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||
sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
|
||||
}
|
||||
@ -647,7 +647,7 @@ static int selectInnerLoop(
|
||||
/* If any row exist in the result set, record that fact and abort.
|
||||
*/
|
||||
case SRT_Exists: {
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iParm);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm);
|
||||
/* The LIMIT clause will terminate the loop for us */
|
||||
break;
|
||||
}
|
||||
@ -789,7 +789,7 @@ static void generateSortTail(
|
||||
switch( eDest ){
|
||||
case SRT_Table:
|
||||
case SRT_EphemTab: {
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
|
||||
sqlite3VdbeAddOp1(v, OP_NewRowid, iParm);
|
||||
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||
sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
|
||||
break;
|
||||
@ -1776,7 +1776,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
||||
if( p->pLimit ){
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iLimit, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, -1, iLimit+1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
|
||||
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
sqlite3VdbeAddOp2(v, OP_MemStore, iLimit+1, 1);
|
||||
@ -2927,10 +2927,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
return;
|
||||
}
|
||||
for(i=0; i<pAggInfo->nColumn; i++){
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, pAggInfo->aCol[i].iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
|
||||
}
|
||||
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
|
||||
sqlite3VdbeAddOp2(v, OP_MemNull, 0, pFunc->iMem);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
|
||||
if( pFunc->iDistinct>=0 ){
|
||||
Expr *pE = pFunc->pExpr;
|
||||
if( pE->pList==0 || pE->pList->nExpr!=1 ){
|
||||
@ -3454,9 +3454,9 @@ int sqlite3Select(
|
||||
pParse->nMem += pGroupBy->nExpr;
|
||||
iBMem = pParse->nMem + 1;
|
||||
pParse->nMem += pGroupBy->nExpr;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iAbortFlag);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
|
||||
VdbeComment((v, "clear abort flag"));
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iUseFlag);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
|
||||
VdbeComment((v, "indicate accumulator empty"));
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInitializeLoop);
|
||||
|
||||
@ -3468,7 +3468,7 @@ int sqlite3Select(
|
||||
** order to signal the caller to abort.
|
||||
*/
|
||||
addrSetAbort = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iAbortFlag);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
|
||||
VdbeComment((v, "set abort flag"));
|
||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||
addrOutputRow = sqlite3VdbeCurrentAddr(v);
|
||||
@ -3587,7 +3587,7 @@ int sqlite3Select(
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, addrProcessRow);
|
||||
updateAccumulator(pParse, &sAggInfo);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, iUseFlag);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
|
||||
VdbeComment((v, "indicate data in accumulator"));
|
||||
|
||||
/* End of the loop
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.157 2008/01/04 19:10:29 danielk1977 Exp $
|
||||
** $Id: update.c,v 1.158 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -356,7 +356,7 @@ void sqlite3Update(
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
|
||||
memCnt = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, memCnt);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
|
||||
}
|
||||
|
||||
if( !isView && !IsVirtual(pTab) ){
|
||||
|
307
src/vdbe.c
307
src/vdbe.c
@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.678 2008/01/04 19:10:29 danielk1977 Exp $
|
||||
** $Id: vdbe.c,v 1.679 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -177,14 +177,6 @@ static void _storeTypeInfo(Mem *pMem){
|
||||
** created by mkopcodeh.awk during compilation. Data is obtained
|
||||
** from the comments following the "case OP_xxxx:" statements in
|
||||
** this file.
|
||||
**
|
||||
** jump: OPFLG_JUMP
|
||||
** out1: OPFLG_OUT1
|
||||
** out2: OPFLG_OUT2
|
||||
** out3: OPFLG_OUT3
|
||||
** in1: OPFLG_IN1
|
||||
** in2: OPFLG_IN2
|
||||
** in3: OPFLG_IN3
|
||||
*/
|
||||
static unsigned char opcodeProperty[] = OPFLG_INITIALIZER;
|
||||
|
||||
@ -475,6 +467,9 @@ int sqlite3VdbeExec(
|
||||
sqlite3 *db = p->db; /* The database */
|
||||
u8 encoding = ENC(db); /* The database encoding */
|
||||
Mem *pTos; /* Top entry in the operand stack */
|
||||
Mem *pIn1, *pIn2; /* Input operands */
|
||||
Mem *pOut; /* Output operand */
|
||||
int nPop = 0; /* Number of times to pop the stack */
|
||||
#ifdef VDBE_PROFILE
|
||||
unsigned long long start; /* CPU clock count at start of opcode */
|
||||
int origPc; /* Program counter at start of opcode */
|
||||
@ -594,6 +589,25 @@ int sqlite3VdbeExec(
|
||||
assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit );
|
||||
#endif
|
||||
|
||||
/* Do common setup processing for any opcode that is marked
|
||||
** with the "out2-prerelease" tag. Such opcodes have a single
|
||||
** output which is specified by the P2 parameter. The output
|
||||
** is normally written into the P2-th register. But if P2==0
|
||||
** then the output is pushed onto the stack. The P2 operand
|
||||
** is initialized to a NULL.
|
||||
*/
|
||||
if( (opcodeProperty[pOp->opcode]&OPFLG_OUT2_PRERELEASE)!=0 ){
|
||||
assert( pOp->p2>=0 );
|
||||
if( pOp->p2==0 ){
|
||||
pOut = ++pTos;
|
||||
}else{
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pOut = &p->aMem[pOp->p2];
|
||||
sqlite3VdbeMemRelease(pOut);
|
||||
}
|
||||
pOut->flags = MEM_Null;
|
||||
}
|
||||
|
||||
switch( pOp->opcode ){
|
||||
|
||||
/*****************************************************************************
|
||||
@ -734,39 +748,37 @@ case OP_StackDepth: { /* no-push */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Integer P1 * *
|
||||
/* Opcode: Integer P1 P2 * * *
|
||||
**
|
||||
** The 32-bit integer value P1 is pushed onto the stack.
|
||||
** The 32-bit integer value P1 is written into register P2, or
|
||||
** pushed onto the stack if P2==0.
|
||||
*/
|
||||
case OP_Integer: {
|
||||
pTos++;
|
||||
pTos->flags = MEM_Int;
|
||||
pTos->u.i = pOp->p1;
|
||||
case OP_Integer: { /* out2-prerelease */
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = pOp->p1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Int64 * * P4
|
||||
/* Opcode: Int64 * P2 * P4 *
|
||||
**
|
||||
** P4 is a pointer to a 64-bit integer value.
|
||||
** Push that value onto the stack.
|
||||
** Write that value into register P2 or push onto the stack if P2 is 0.
|
||||
*/
|
||||
case OP_Int64: {
|
||||
pTos++;
|
||||
case OP_Int64: { /* out2-prerelease */
|
||||
assert( pOp->p4.pI64!=0 );
|
||||
pTos->flags = MEM_Int;
|
||||
memcpy(&pTos->u.i, pOp->p4.pI64, 8);
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = *pOp->p4.pI64;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Real * * P4
|
||||
/* Opcode: Real * P2 * P4 *
|
||||
**
|
||||
** P4 is a pointer to a 64-bit floating point value. Push that value
|
||||
** onto the stack.
|
||||
** P4 is a pointer to a 64-bit floating point value.
|
||||
** Write that value into register P2 or push onto the stack if P2 is 0.
|
||||
*/
|
||||
case OP_Real: { /* same as TK_FLOAT, */
|
||||
pTos++;
|
||||
pTos->flags = MEM_Real;
|
||||
memcpy(&pTos->r, pOp->p4.pReal, 8);
|
||||
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
|
||||
pOut->flags = MEM_Real;
|
||||
pOut->r = *pOp->p4.pReal;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -775,25 +787,24 @@ case OP_Real: { /* same as TK_FLOAT, */
|
||||
** 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.
|
||||
*/
|
||||
case OP_String8: { /* same as TK_STRING */
|
||||
case OP_String8: { /* same as TK_STRING, out2-prerelease */
|
||||
assert( pOp->p4.z!=0 );
|
||||
pOp->opcode = OP_String;
|
||||
pOp->p1 = strlen(pOp->p4.z);
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( encoding!=SQLITE_UTF8 ){
|
||||
pTos++;
|
||||
sqlite3VdbeMemSetStr(pTos, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
|
||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
|
||||
pTos->flags &= ~(MEM_Dyn);
|
||||
pTos->flags |= MEM_Static;
|
||||
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
|
||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
|
||||
pOut->flags &= ~(MEM_Dyn);
|
||||
pOut->flags |= MEM_Static;
|
||||
if( pOp->p4type==P4_DYNAMIC ){
|
||||
sqlite3_free(pOp->p4.z);
|
||||
}
|
||||
pOp->p4type = P4_DYNAMIC;
|
||||
pOp->p4.z = pTos->z;
|
||||
pOp->p1 = pTos->n;
|
||||
pOp->p4.z = pOut->z;
|
||||
pOp->p1 = pOut->n;
|
||||
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
||||
goto too_big;
|
||||
}
|
||||
@ -806,42 +817,40 @@ case OP_String8: { /* same as TK_STRING */
|
||||
/* Fall through to the next case, OP_String */
|
||||
}
|
||||
|
||||
/* Opcode: String P1 * P4
|
||||
/* Opcode: String P1 P2 * P4 *
|
||||
**
|
||||
** The string value P4 of length P1 (bytes) is pushed onto the stack.
|
||||
** The string value P4 of length P1 (bytes) is stored in register P2
|
||||
** or is pushed onto the stack if P2==0.
|
||||
*/
|
||||
case OP_String: {
|
||||
pTos++;
|
||||
case OP_String: { /* out2-prerelease */
|
||||
assert( pOp->p4.z!=0 );
|
||||
pTos->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||
pTos->z = pOp->p4.z;
|
||||
pTos->n = pOp->p1;
|
||||
pTos->enc = encoding;
|
||||
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||
pOut->z = pOp->p4.z;
|
||||
pOut->n = pOp->p1;
|
||||
pOut->enc = encoding;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Null * * *
|
||||
/* Opcode: Null * P2 * * *
|
||||
**
|
||||
** Push a NULL onto the stack.
|
||||
** Write a NULL into register P2 or push a NULL onto the stack
|
||||
** if P2==0.
|
||||
*/
|
||||
case OP_Null: {
|
||||
pTos++;
|
||||
pTos->flags = MEM_Null;
|
||||
pTos->n = 0;
|
||||
case OP_Null: { /* out2-prerelease */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||
/* Opcode: HexBlob * * P4
|
||||
/* Opcode: HexBlob * P2 * P4 *
|
||||
**
|
||||
** P4 is an UTF-8 SQL hex encoding of a blob. The blob is pushed onto the
|
||||
** vdbe stack.
|
||||
** P4 is an UTF-8 SQL hex encoding of a blob. The blob is stored in
|
||||
** register P2 or pushed onto the stack if P2 is zero.
|
||||
**
|
||||
** The first time this instruction executes, in transforms itself into a
|
||||
** 'Blob' opcode with a binary blob as P4.
|
||||
*/
|
||||
case OP_HexBlob: { /* same as TK_BLOB */
|
||||
case OP_HexBlob: { /* same as TK_BLOB, out2-prerelease */
|
||||
pOp->opcode = OP_Blob;
|
||||
pOp->p1 = strlen(pOp->p4.z)/2;
|
||||
if( pOp->p1>SQLITE_MAX_LENGTH ){
|
||||
@ -875,10 +884,9 @@ case OP_HexBlob: { /* same as TK_BLOB */
|
||||
** the blob as P4. This opcode is transformed to an OP_Blob
|
||||
** the first time it is executed.
|
||||
*/
|
||||
case OP_Blob: {
|
||||
pTos++;
|
||||
case OP_Blob: { /* out2-prerelease */
|
||||
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
|
||||
sqlite3VdbeMemSetStr(pTos, pOp->p4.z, pOp->p1, 0, 0);
|
||||
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
|
||||
pTos->enc = encoding;
|
||||
break;
|
||||
}
|
||||
@ -886,14 +894,15 @@ case OP_Blob: {
|
||||
|
||||
/* Opcode: Variable P1 * *
|
||||
**
|
||||
** Push the value of variable P1 onto the stack. A variable is
|
||||
** The value of variable P1 is written into register P2 or pushed
|
||||
** onto the stack if P2 is zero. A variable is
|
||||
** an unknown in the original SQL string as handed to sqlite3_compile().
|
||||
** Any occurance of the '?' character in the original SQL is considered
|
||||
** a variable. Variables in the SQL string are number from left to
|
||||
** right beginning with 1. The values of variables are set using the
|
||||
** sqlite3_bind() API.
|
||||
*/
|
||||
case OP_Variable: {
|
||||
case OP_Variable: { /* out2-prerelease */
|
||||
int j = pOp->p1 - 1;
|
||||
Mem *pVar;
|
||||
assert( j>=0 && j<p->nVar );
|
||||
@ -902,8 +911,7 @@ case OP_Variable: {
|
||||
if( sqlite3VdbeMemTooBig(pVar) ){
|
||||
goto too_big;
|
||||
}
|
||||
pTos++;
|
||||
sqlite3VdbeMemShallowCopy(pTos, &p->aVar[j], MEM_Static);
|
||||
sqlite3VdbeMemShallowCopy(pOut, &p->aVar[j], MEM_Static);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2673,16 +2681,17 @@ case OP_Transaction: { /* no-push */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: ReadCookie P1 P2 *
|
||||
/* Opcode: ReadCookie P1 P2 P3
|
||||
**
|
||||
** Read cookie number P2 from database P1 and push it onto the stack.
|
||||
** P2==0 is the schema version. P2==1 is the database format.
|
||||
** P2==2 is the recommended pager cache size, and so forth. P1==0 is
|
||||
** Read cookie number P3 from database P1 and write it into register
|
||||
** P2 or push it onto the stack if P2==0.
|
||||
** P3==0 is the schema version. P3==1 is the database format.
|
||||
** P3==2 is the recommended pager cache size, and so forth. P1==0 is
|
||||
** the main database file and P1==1 is the database file used to store
|
||||
** temporary tables.
|
||||
**
|
||||
** If P1 is negative, then this is a request to read the size of a
|
||||
** databases free-list. P2 must be set to 1 in this case. The actual
|
||||
** databases free-list. P3 must be set to 1 in this case. The actual
|
||||
** database accessed is ((P1+1)*-1). For example, a P1 parameter of -1
|
||||
** corresponds to database 0 ("main"), a P1 of -2 is database 1 ("temp").
|
||||
**
|
||||
@ -2690,10 +2699,10 @@ case OP_Transaction: { /* no-push */
|
||||
** must be started or there must be an open cursor) before
|
||||
** executing this instruction.
|
||||
*/
|
||||
case OP_ReadCookie: {
|
||||
case OP_ReadCookie: { /* out2-prerelease */
|
||||
int iMeta;
|
||||
int iDb = pOp->p1;
|
||||
int iCookie = pOp->p2;
|
||||
int iCookie = pOp->p3;
|
||||
|
||||
assert( pOp->p2<SQLITE_N_BTREE_META );
|
||||
if( iDb<0 ){
|
||||
@ -2711,9 +2720,8 @@ case OP_ReadCookie: {
|
||||
** by one in the following statement.
|
||||
*/
|
||||
rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta);
|
||||
pTos++;
|
||||
pTos->u.i = iMeta;
|
||||
pTos->flags = MEM_Int;
|
||||
pOut->u.i = iMeta;
|
||||
pOut->flags = MEM_Int;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3426,20 +3434,21 @@ case OP_NotExists: { /* no-push, jump */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Sequence P1 * *
|
||||
/* Opcode: Sequence P1 P2 * * *
|
||||
**
|
||||
** Push an integer onto the stack which is the next available
|
||||
** sequence number for cursor P1. The sequence number on the
|
||||
** cursor is incremented after the push.
|
||||
** Find the next available sequence number for cursor P1.
|
||||
** Write the sequence number into register P2, or push it onto
|
||||
** the stack if P2==0.
|
||||
** The sequence number on the cursor is incremented after this
|
||||
** instruction.
|
||||
*/
|
||||
case OP_Sequence: {
|
||||
case OP_Sequence: { /* out2-prerelease */
|
||||
int i = pOp->p1;
|
||||
assert( pTos>=p->aStack );
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
assert( p->apCsr[i]!=0 );
|
||||
pTos++;
|
||||
pTos->u.i = p->apCsr[i]->seqCount++;
|
||||
pTos->flags = MEM_Int;
|
||||
pOut->u.i = p->apCsr[i]->seqCount++;
|
||||
pOut->flags = MEM_Int;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3449,16 +3458,16 @@ case OP_Sequence: {
|
||||
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
|
||||
** The record number is not previously used as a key in the database
|
||||
** table that cursor P1 points to. The new record number is pushed
|
||||
** onto the stack if P3 is 0 or written to memory cell P3 otherwise.
|
||||
** onto the stack if P2 is 0 or written to memory cell P2 otherwise.
|
||||
**
|
||||
** If P2>0 then P2 is a memory cell that holds the largest previously
|
||||
** If P3>0 then P3 is a memory cell that holds the largest previously
|
||||
** generated record number. No new record numbers are allowed to be less
|
||||
** than this value. When this value reaches its maximum, a SQLITE_FULL
|
||||
** error is generated. The P2 memory cell is updated with the generated
|
||||
** record number. This P2 mechanism is used to help implement the
|
||||
** error is generated. The P3 memory cell is updated with the generated
|
||||
** record number. This P3 mechanism is used to help implement the
|
||||
** AUTOINCREMENT feature.
|
||||
*/
|
||||
case OP_NewRowid: {
|
||||
case OP_NewRowid: { /* out2-prerelease */
|
||||
int i = pOp->p1;
|
||||
i64 v = 0;
|
||||
Cursor *pC;
|
||||
@ -3541,12 +3550,12 @@ case OP_NewRowid: {
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
if( pOp->p2 ){
|
||||
if( pOp->p3 ){
|
||||
Mem *pMem;
|
||||
assert( pOp->p2>0 && pOp->p2<=p->nMem ); /* P2 is a valid memory cell */
|
||||
pMem = &p->aMem[pOp->p2];
|
||||
assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
|
||||
pMem = &p->aMem[pOp->p3];
|
||||
sqlite3VdbeMemIntegerify(pMem);
|
||||
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P2) holds an integer */
|
||||
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
|
||||
if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
|
||||
rc = SQLITE_FULL;
|
||||
goto abort_due_to_error;
|
||||
@ -3566,7 +3575,7 @@ case OP_NewRowid: {
|
||||
}
|
||||
}
|
||||
if( pC->useRandomRowid ){
|
||||
assert( pOp->p2==0 ); /* SQLITE_FULL must have occurred prior to this */
|
||||
assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */
|
||||
v = db->priorNewRowid;
|
||||
cnt = 0;
|
||||
do{
|
||||
@ -3593,13 +3602,8 @@ case OP_NewRowid: {
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
}
|
||||
if( pOp->p3 ){
|
||||
sqlite3VdbeMemSetInt64(&p->aMem[pOp->p3], v);
|
||||
}else{
|
||||
pTos++;
|
||||
pTos->u.i = v;
|
||||
pTos->flags = MEM_Int;
|
||||
}
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = v;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3860,40 +3864,32 @@ case OP_RowData: {
|
||||
/* Opcode: Rowid P1 P2 * * *
|
||||
**
|
||||
** Store in register P2 an integer which is the key of the table entry that
|
||||
** P1 is currently point to. If p2==0 then pust the integer.
|
||||
** P1 is currently point to. If p2==0 then push the integer.
|
||||
*/
|
||||
case OP_Rowid: {
|
||||
case OP_Rowid: { /* out2-prerelease */
|
||||
int i = pOp->p1;
|
||||
Cursor *pC;
|
||||
i64 v;
|
||||
Mem *pDest;
|
||||
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
pC = p->apCsr[i];
|
||||
assert( pC!=0 );
|
||||
rc = sqlite3VdbeCursorMoveto(pC);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
if( pOp->p2>0 ){
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pDest = &p->aMem[pOp->p2];
|
||||
sqlite3VdbeMemRelease(pDest);
|
||||
}else{
|
||||
pDest = ++pTos;
|
||||
}
|
||||
if( pC->rowidIsValid ){
|
||||
v = pC->lastRowid;
|
||||
}else if( pC->pseudoTable ){
|
||||
v = keyToInt(pC->iKey);
|
||||
}else if( pC->nullRow || pC->pCursor==0 ){
|
||||
pDest->flags = MEM_Null;
|
||||
/* Leave the rowid set to a NULL */
|
||||
break;
|
||||
}else{
|
||||
assert( pC->pCursor!=0 );
|
||||
sqlite3BtreeKeySize(pC->pCursor, &v);
|
||||
v = keyToInt(v);
|
||||
}
|
||||
pDest->u.i = v;
|
||||
pDest->flags = MEM_Int;
|
||||
pOut->u.i = v;
|
||||
pOut->flags = MEM_Int;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4121,36 +4117,25 @@ case OP_IdxDelete: { /* no-push */
|
||||
**
|
||||
** See also: Rowid, MakeIdxRec.
|
||||
*/
|
||||
case OP_IdxRowid: {
|
||||
case OP_IdxRowid: { /* out2-prerelease */
|
||||
int i = pOp->p1;
|
||||
BtCursor *pCrsr;
|
||||
Cursor *pC;
|
||||
Mem *pDest;
|
||||
|
||||
assert( i>=0 && i<p->nCursor );
|
||||
assert( p->apCsr[i]!=0 );
|
||||
if( pOp->p2>0 ){
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pDest = &p->aMem[pOp->p2];
|
||||
sqlite3VdbeMemRelease(pDest);
|
||||
}else{
|
||||
pDest = ++pTos;
|
||||
}
|
||||
pDest->flags = MEM_Null;
|
||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||
i64 rowid;
|
||||
|
||||
assert( pC->deferredMoveto==0 );
|
||||
assert( pC->isTable==0 );
|
||||
if( pC->nullRow ){
|
||||
pDest->flags = MEM_Null;
|
||||
}else{
|
||||
if( !pC->nullRow ){
|
||||
rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
pDest->flags = MEM_Int;
|
||||
pDest->u.i = rowid;
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = rowid;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4342,11 +4327,12 @@ case OP_Clear: { /* no-push */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: CreateTable P1 * *
|
||||
/* Opcode: CreateTable P1 P2 * * *
|
||||
**
|
||||
** Allocate a new table in the main database file if P2==0 or in the
|
||||
** auxiliary database file if P2==1. Push the page number
|
||||
** for the root page of the new table onto the stack.
|
||||
** Allocate a new table in the main database file if P1==0 or in the
|
||||
** auxiliary database file if P1==1 or in an attached database if
|
||||
** P1>1. Write the root page number of the new table into
|
||||
** register P2 or push it onto the stack if P2==0.
|
||||
**
|
||||
** The difference between a table and an index is this: A table must
|
||||
** have a 4-byte integer key and can have arbitrary data. An index
|
||||
@ -4354,16 +4340,17 @@ case OP_Clear: { /* no-push */
|
||||
**
|
||||
** See also: CreateIndex
|
||||
*/
|
||||
/* Opcode: CreateIndex P1 * *
|
||||
/* Opcode: CreateIndex P1 P2 * * *
|
||||
**
|
||||
** Allocate a new index in the main database file if P2==0 or in the
|
||||
** auxiliary database file if P2==1. Push the page number of the
|
||||
** root page of the new index onto the stack.
|
||||
** Allocate a new index in the main database file if P1==0 or in the
|
||||
** auxiliary database file if P1==1 or in an attached database if
|
||||
** P1>1. Write the root page number of the new table into
|
||||
** register P2 or push it onto the stack if P2==0.
|
||||
**
|
||||
** See documentation on OP_CreateTable for additional information.
|
||||
*/
|
||||
case OP_CreateIndex:
|
||||
case OP_CreateTable: {
|
||||
case OP_CreateIndex: /* out2-prerelease */
|
||||
case OP_CreateTable: { /* out2-prerelease */
|
||||
int pgno;
|
||||
int flags;
|
||||
Db *pDb;
|
||||
@ -4378,12 +4365,9 @@ case OP_CreateTable: {
|
||||
flags = BTREE_ZERODATA;
|
||||
}
|
||||
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
|
||||
pTos++;
|
||||
if( rc==SQLITE_OK ){
|
||||
pTos->u.i = pgno;
|
||||
pTos->flags = MEM_Int;
|
||||
}else{
|
||||
pTos->flags = MEM_Null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4784,26 +4768,6 @@ case OP_IfMemNull: { /* no-push, jump */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemNull * P2 *
|
||||
**
|
||||
** Store a NULL in memory cell P2
|
||||
*/
|
||||
case OP_MemNull: {
|
||||
assert( pOp->p2>0 && pOp->p2<=p->nMem );
|
||||
sqlite3VdbeMemSetNull(&p->aMem[pOp->p2]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemInt P1 P2 *
|
||||
**
|
||||
** Store the integer value P1 in memory cell P2.
|
||||
*/
|
||||
case OP_MemInt: {
|
||||
assert( pOp->p2>0 && pOp->p2<=p->nMem );
|
||||
sqlite3VdbeMemSetInt64(&p->aMem[pOp->p2], pOp->p1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemMove P1 P2 *
|
||||
**
|
||||
** Move the content of memory cell P2 over to memory cell P1.
|
||||
@ -4817,18 +4781,6 @@ case OP_MemMove: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: MemSet P1 * * P4
|
||||
**
|
||||
** The P4 should be set to contain a P4_MEM value. The value is copied
|
||||
** to memory cell P1.
|
||||
*/
|
||||
case OP_MemSet: {
|
||||
assert( pOp->p1>0 && pOp->p1<=p->nMem );
|
||||
assert( pOp->p4type==P4_MEM );
|
||||
rc = sqlite3VdbeMemCopy(&p->aMem[pOp->p1], pOp->p4.pMem);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: AggStep P1 P2 P4
|
||||
**
|
||||
** Execute the step function for an aggregate. The
|
||||
@ -5141,7 +5093,7 @@ case OP_VFilter: { /* no-push, jump */
|
||||
** the virtual-table that the P1 cursor is pointing to.
|
||||
** If P2==0, push the value onto the stack.
|
||||
*/
|
||||
case OP_VRowid: {
|
||||
case OP_VRowid: { /* out2-prerelease */
|
||||
const sqlite3_module *pModule;
|
||||
|
||||
Cursor *pCur = p->apCsr[pOp->p1];
|
||||
@ -5152,21 +5104,12 @@ case OP_VRowid: {
|
||||
rc = SQLITE_ERROR;
|
||||
} else {
|
||||
sqlite_int64 iRow;
|
||||
Mem *pDest;
|
||||
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
|
||||
if( pOp->p2>0 ){
|
||||
assert( pOp->p2<=p->nMem );
|
||||
pDest = &p->aMem[pOp->p2];
|
||||
sqlite3VdbeMemRelease(pDest);
|
||||
}else{
|
||||
pDest = ++pTos;
|
||||
}
|
||||
pDest->flags = MEM_Int;
|
||||
pDest->u.i = iRow;
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = iRow;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -291,7 +291,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
|
||||
}else if( opcode==OP_VFilter ){
|
||||
int n;
|
||||
assert( p->nOp - i >= 3 );
|
||||
assert( pOp[-1].opcode==OP_MemInt );
|
||||
assert( pOp[-1].opcode==OP_Integer );
|
||||
n = pOp[-1].p1;
|
||||
if( n>nMaxArgs ) nMaxArgs = n;
|
||||
#endif
|
||||
|
10
src/where.c
10
src/where.c
@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.272 2008/01/03 23:44:53 drh Exp $
|
||||
** $Id: where.c,v 1.273 2008/01/04 22:01:03 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -2261,7 +2261,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
*/
|
||||
if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
|
||||
pLevel->iLeftJoin = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, pLevel->iLeftJoin);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
|
||||
VdbeComment((v, "init LEFT JOIN no-match flag"));
|
||||
}
|
||||
|
||||
@ -2293,8 +2293,8 @@ WhereInfo *sqlite3WhereBegin(
|
||||
iReg = ++pParse->nMem;
|
||||
pParse->nMem++;
|
||||
sqlite3StackToReg(pParse, j-1);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, pBestIdx->idxNum, iReg);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, j-1, iReg+1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, iReg);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
|
||||
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, iReg, pBestIdx->idxStr,
|
||||
pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
|
||||
pBestIdx->needToFreeIdxStr = 0;
|
||||
@ -2608,7 +2608,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
*/
|
||||
if( pLevel->iLeftJoin ){
|
||||
pLevel->top = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 1, pLevel->iLeftJoin);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
|
||||
VdbeComment((v, "record LEFT JOIN hit"));
|
||||
for(pTerm=wc.a, j=0; j<wc.nTerm; j++, pTerm++){
|
||||
if( pTerm->flags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
|
Loading…
Reference in New Issue
Block a user