mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Get rid of OP_Dup, OP_MemStore, OP_MemLoad, and OP_MemMove. Replace
with OP_Copy, OP_SCopy, and OP_Move. Add the infrastructure for operation properties in1, in2, in3, out2, and out3 but do not yet use any of these. (CVS 4682) FossilOrigin-Name: cc149eb9ca3c672cc6fea3528353234ac2ed5745
This commit is contained in:
36
manifest
36
manifest
@ -1,5 +1,5 @@
|
|||||||
C Implement\sthe\sout2-prerelease\sopcode\sdesign\spattern.\s(CVS\s4681)
|
C Get\srid\sof\sOP_Dup,\sOP_MemStore,\sOP_MemLoad,\sand\sOP_MemMove.\s\sReplace\nwith\sOP_Copy,\sOP_SCopy,\sand\sOP_Move.\s\sAdd\sthe\sinfrastructure\sfor\noperation\sproperties\sin1,\sin2,\sin3,\sout2,\sand\sout3\sbut\sdo\snot\syet\nuse\sany\sof\sthese.\s(CVS\s4682)
|
||||||
D 2008-01-04T22:01:03
|
D 2008-01-05T04:06:04
|
||||||
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
|
||||||
@ -69,7 +69,7 @@ F mkdll.sh 5f8438dcac98e795d7df6529159a1ec566de0183
|
|||||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||||
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
|
F mkextw.sh 1a866b53637dab137191341cc875575a5ca110fb
|
||||||
F mkopcodec.awk 3fb9bf077053c968451f4dd03d11661ac373f9d1
|
F mkopcodec.awk 3fb9bf077053c968451f4dd03d11661ac373f9d1
|
||||||
F mkopcodeh.awk 71abda1cad4c3c7385834ced713c0271f2b13161
|
F mkopcodeh.awk b5b810762528f195111fb9b72bbd224a007a5260
|
||||||
F mkso.sh 24bde4c09e6fe80f718db3c31c068f45e13a2f2c
|
F mkso.sh 24bde4c09e6fe80f718db3c31c068f45e13a2f2c
|
||||||
F publish.sh 1c0658c63d70f182a8f5e17cc28422f1b237f51d
|
F publish.sh 1c0658c63d70f182a8f5e17cc28422f1b237f51d
|
||||||
F publish_osx.sh eca87df1e3d43d128d97d3261fd48b3d6877996e
|
F publish_osx.sh eca87df1e3d43d128d97d3261fd48b3d6877996e
|
||||||
@ -79,24 +79,24 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
|||||||
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
|
||||||
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
|
||||||
F src/alter.c 5a54f58d9481ac14c4e58b702f3f8758dee84d04
|
F src/alter.c 5a54f58d9481ac14c4e58b702f3f8758dee84d04
|
||||||
F src/analyze.c 117e600989d4308578140b646f5caaec6b751f16
|
F src/analyze.c 4e24deeee2b93e91a2197953515fa175bfab27f2
|
||||||
F src/attach.c 1c96631e56cdc51d3d70736bf61f1fe01c62cbea
|
F src/attach.c 1c96631e56cdc51d3d70736bf61f1fe01c62cbea
|
||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||||
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
||||||
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
||||||
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
||||||
F src/build.c eac0f7e670035ee1087edc7ca223da844bf8940d
|
F src/build.c 739eeee868e97a69c27e72636ca5be824da87703
|
||||||
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||||
F src/delete.c 056f96bbbfaf27cb90f03e1d21abeab88a26235c
|
F src/delete.c f943c27bf37f2f37d7e16dc4e94421870ce68c6c
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c 57f7c39724c8dee8b4a547dfa58c344bee528996
|
F src/expr.c d317c8081a05eaa5720a10e0067dfa0864f762db
|
||||||
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 907fa2dfde1330d9971ba180ad735ea4daf6ad03
|
F src/insert.c fb46be04638fca9b319a216e83e2bb57e8621fcc
|
||||||
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 ff8841222bb9779f1ebed0c4d0016530221e7fe8
|
F src/pragma.c 6f5918141e1a100975666d88a4bd3c6cd6da4f3d
|
||||||
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
|
F src/prepare.c f1bb8eb642082e618a359c08e3e107490eafe0e3
|
||||||
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910
|
||||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||||
F src/select.c 30110ce6ce891dcb93a922ee4a51946983df0a33
|
F src/select.c 1a6664131fb0e250826fd26189b0e615d726fbcd
|
||||||
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
|
||||||
@ -163,12 +163,12 @@ F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5
|
|||||||
F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
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 713b501b12ea41bf0297a2cf78f7d954c4a25d13
|
F src/trigger.c 91ff1552b5c2cd66a077563a026d183c1dc993d6
|
||||||
F src/update.c e57d0083b0800ae514f3226761d019f195f15cb2
|
F src/update.c 3dc744343c81c7ed97d9e1ed5e5887e256921062
|
||||||
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 a2d9e868ef2ac65310478d32a33e9bdffc74281e
|
F src/vdbe.c 8a2d438d47e38542ca4ee519528ea859cee9ecfa
|
||||||
F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
|
F src/vdbe.h bb128757b84280504a1243c450fd13ead248ede5
|
||||||
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 123994fcd344993d2fb050a83b91b341bbbd08b4
|
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
|
||||||
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
F src/vtab.c 03014b2bfa8096ecac5fcdc80d34cd76e06af52a
|
||||||
F src/where.c d015536e273de18196554f13265d80ec9e988766
|
F src/where.c af005c6a5875b230648e7f1a38993cd848161313
|
||||||
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
|
||||||
@ -323,7 +323,7 @@ F test/icu.test e6bfae7f625c88fd14df6f540fe835bdfc1e4329
|
|||||||
F test/in.test 87270d14e2dd870da77d178985b43fea4675eb56
|
F test/in.test 87270d14e2dd870da77d178985b43fea4675eb56
|
||||||
F test/in2.test b1f447f4f0f67e9f83ff931e7e2e30873f9ea055
|
F test/in2.test b1f447f4f0f67e9f83ff931e7e2e30873f9ea055
|
||||||
F test/in3.test e335959db24d71d6cfdff9553c90ce2b56fb978c
|
F test/in3.test e335959db24d71d6cfdff9553c90ce2b56fb978c
|
||||||
F test/incrblob.test 602dbfa956904d6e58c45635b58850ad0f02d927
|
F test/incrblob.test 854c23b7ff8dd3822f675936b22c094655b3c739
|
||||||
F test/incrblob_err.test 5273097dc7c97f9b7008423a6ffd5c80d21923cb
|
F test/incrblob_err.test 5273097dc7c97f9b7008423a6ffd5c80d21923cb
|
||||||
F test/incrvacuum.test 1ed44535e89a0fa10c48c1aa0a3d48ee72bcc733
|
F test/incrvacuum.test 1ed44535e89a0fa10c48c1aa0a3d48ee72bcc733
|
||||||
F test/incrvacuum2.test a958e378c193c4012cb3787804d863487f1dfad1
|
F test/incrvacuum2.test a958e378c193c4012cb3787804d863487f1dfad1
|
||||||
@ -603,7 +603,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 717bcd11a222fe100e25c5b2eb6de8b6b9930de1
|
P fe057a88d0038ac349ea41883b979ceba6ae410a
|
||||||
R 4486249090525dc5e5cc1ca96f44eb9a
|
R 42deacb2e7b246f14ca2d74e7526fed1
|
||||||
U drh
|
U drh
|
||||||
Z c5a3c782e07a8605f750b96c4ed10a88
|
Z b60a5382e66d036aa3cd3e890b046e32
|
||||||
|
@ -1 +1 @@
|
|||||||
fe057a88d0038ac349ea41883b979ceba6ae410a
|
cc149eb9ca3c672cc6fea3528353234ac2ed5745
|
@ -53,6 +53,11 @@
|
|||||||
jump[name] = 0
|
jump[name] = 0
|
||||||
nopush[name] = 0
|
nopush[name] = 0
|
||||||
out2_prerelease[name] = 0
|
out2_prerelease[name] = 0
|
||||||
|
in1[name] = 0
|
||||||
|
in2[name] = 0
|
||||||
|
in3[name] = 0
|
||||||
|
out2[name] = 0
|
||||||
|
out3[name] = 0
|
||||||
for(i=3; i<NF; i++){
|
for(i=3; i<NF; i++){
|
||||||
if($i=="same" && $(i+1)=="as"){
|
if($i=="same" && $(i+1)=="as"){
|
||||||
sym = $(i+2)
|
sym = $(i+2)
|
||||||
@ -69,6 +74,16 @@
|
|||||||
jump[name] = 1
|
jump[name] = 1
|
||||||
}else if(x=="out2-prerelease"){
|
}else if(x=="out2-prerelease"){
|
||||||
out2_prerelease[name] = 1
|
out2_prerelease[name] = 1
|
||||||
|
}else if(x=="in1"){
|
||||||
|
in1[name] = 1
|
||||||
|
}else if(x=="in2"){
|
||||||
|
in2[name] = 1
|
||||||
|
}else if(x=="in3"){
|
||||||
|
in3[name] = 1
|
||||||
|
}else if(x=="out2"){
|
||||||
|
out2[name] = 1
|
||||||
|
}else if(x=="out3"){
|
||||||
|
out3[name] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,6 +133,11 @@ END {
|
|||||||
if( jump[name] ) a0 = 1;
|
if( jump[name] ) a0 = 1;
|
||||||
if( nopush[name]==0 ) a1 = 2;
|
if( nopush[name]==0 ) a1 = 2;
|
||||||
if( out2_prerelease[name] ) a2 = 4;
|
if( out2_prerelease[name] ) a2 = 4;
|
||||||
|
if( in1[name] ) a3 = 8;
|
||||||
|
if( in2[name] ) a4 = 16;
|
||||||
|
if( in3[name] ) a5 = 32;
|
||||||
|
if( out2[name] ) a6 = 64;
|
||||||
|
if( out3[name] ) a7 = 128;
|
||||||
bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
|
bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
|
||||||
}
|
}
|
||||||
print "\n"
|
print "\n"
|
||||||
@ -128,6 +148,11 @@ END {
|
|||||||
print "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */"
|
print "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */"
|
||||||
print "#define OPFLG_PUSH 0x02 /* ~no-push: Does not push */"
|
print "#define OPFLG_PUSH 0x02 /* ~no-push: Does not push */"
|
||||||
print "#define OPFLG_OUT2_PRERELEASE 0x04 /* out2-prerelease: */"
|
print "#define OPFLG_OUT2_PRERELEASE 0x04 /* out2-prerelease: */"
|
||||||
|
print "#define OPFLG_IN1 0x08 /* in1: P1 is an input */"
|
||||||
|
print "#define OPFLG_IN2 0x10 /* in2: P2 is an input */"
|
||||||
|
print "#define OPFLG_IN3 0x20 /* in3: P3 is an input */"
|
||||||
|
print "#define OPFLG_OUT2 0x40 /* out2: P2 is an output */"
|
||||||
|
print "#define OPFLG_OUT3 0x80 /* out3: P3 is an output */"
|
||||||
print "#define OPFLG_INITIALIZER {\\"
|
print "#define OPFLG_INITIALIZER {\\"
|
||||||
for(i=0; i<=max; i++){
|
for(i=0; i<=max; i++){
|
||||||
printf " 0x%02x,", bv[i]
|
printf " 0x%02x,", bv[i]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code associated with the ANALYZE command.
|
** This file contains code associated with the ANALYZE command.
|
||||||
**
|
**
|
||||||
** @(#) $Id: analyze.c,v 1.31 2008/01/04 22:01:03 drh Exp $
|
** @(#) $Id: analyze.c,v 1.32 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_ANALYZE
|
#ifndef SQLITE_OMIT_ANALYZE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@ -158,15 +158,14 @@ static void analyzeOneTable(
|
|||||||
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
|
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+nCol+i+1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem+nCol+i+1);
|
||||||
sqlite3VdbeAddOp1(v, OP_Ne, 0x100);
|
sqlite3VdbeAddOp1(v, OP_Ne, 0x100);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem+i+1);
|
addr = sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem+i+1);
|
||||||
sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
|
sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i);
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iMem+nCol+i+1, 1);
|
|
||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
|
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
|
||||||
@ -190,25 +189,25 @@ static void analyzeOneTable(
|
|||||||
** If K>0 then it is always the case the D>0 so division by zero
|
** If K>0 then it is always the case the D>0 so division by zero
|
||||||
** is never possible.
|
** is never possible.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
|
||||||
addr = sqlite3VdbeAddOp0(v, OP_IfNot);
|
addr = sqlite3VdbeAddOp0(v, OP_IfNot);
|
||||||
sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur);
|
sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0);
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, " ", 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, " ", 0);
|
||||||
for(i=0; i<nCol; i++){
|
for(i=0; i<nCol; i++){
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem+i+1);
|
||||||
sqlite3VdbeAddOp0(v, OP_Add);
|
sqlite3VdbeAddOp0(v, OP_Add);
|
||||||
sqlite3VdbeAddOp1(v, OP_AddImm, -1);
|
sqlite3VdbeAddOp1(v, OP_AddImm, -1);
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem+i+1);
|
||||||
sqlite3VdbeAddOp0(v, OP_Divide);
|
sqlite3VdbeAddOp0(v, OP_Divide);
|
||||||
sqlite3VdbeAddOp0(v, OP_ToInt);
|
sqlite3VdbeAddOp0(v, OP_ToInt);
|
||||||
if( i==nCol-1 ){
|
if( i==nCol-1 ){
|
||||||
sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1);
|
sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp1(v, OP_Dup, 1);
|
sqlite3VdbeAddOp1(v, OP_Copy, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
|
sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
|
||||||
|
10
src/build.c
10
src/build.c
@ -22,7 +22,7 @@
|
|||||||
** COMMIT
|
** COMMIT
|
||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.457 2008/01/04 22:01:03 drh Exp $
|
** $Id: build.c,v 1.458 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -881,7 +881,7 @@ void sqlite3StartTable(
|
|||||||
}
|
}
|
||||||
sqlite3OpenMasterTable(pParse, iDb);
|
sqlite3OpenMasterTable(pParse, iDb);
|
||||||
sqlite3VdbeAddOp0(v, OP_NewRowid);
|
sqlite3VdbeAddOp0(v, OP_NewRowid);
|
||||||
sqlite3VdbeAddOp0(v, OP_Dup);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
sqlite3VdbeAddOp0(v, OP_Null);
|
sqlite3VdbeAddOp0(v, OP_Null);
|
||||||
sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND);
|
sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp0(v, OP_Close);
|
sqlite3VdbeAddOp0(v, OP_Close);
|
||||||
@ -1493,7 +1493,7 @@ void sqlite3EndTable(
|
|||||||
if( pSelect ){
|
if( pSelect ){
|
||||||
SelectDest dest = {SRT_Table, 1, 0};
|
SelectDest dest = {SRT_Table, 1, 0};
|
||||||
Table *pSelTab;
|
Table *pSelTab;
|
||||||
sqlite3VdbeAddOp1(v, OP_Dup, 0);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
|
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
|
||||||
pParse->nTab = 2;
|
pParse->nTab = 2;
|
||||||
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
||||||
@ -2235,7 +2235,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
if( memRootPage>=0 ){
|
if( memRootPage>=0 ){
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, memRootPage);
|
sqlite3VdbeAddOp1(v, OP_SCopy, memRootPage);
|
||||||
tnum = 0;
|
tnum = 0;
|
||||||
}else{
|
}else{
|
||||||
tnum = pIndex->tnum;
|
tnum = pIndex->tnum;
|
||||||
@ -2638,7 +2638,7 @@ void sqlite3CreateIndex(
|
|||||||
*/
|
*/
|
||||||
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
||||||
sqlite3VdbeAddOp1(v, OP_CreateIndex, iDb);
|
sqlite3VdbeAddOp1(v, OP_CreateIndex, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_Copy, 0, iMem);
|
||||||
|
|
||||||
/* Gather the complete text of the CREATE INDEX statement into
|
/* Gather the complete text of the CREATE INDEX statement into
|
||||||
** the zStmt variable
|
** the zStmt variable
|
||||||
|
12
src/delete.c
12
src/delete.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
|
||||||
** in order to generate code for DELETE FROM statements.
|
** in order to generate code for DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.148 2008/01/04 22:01:03 drh Exp $
|
** $Id: delete.c,v 1.149 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -68,8 +68,8 @@ void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){
|
|||||||
int iData = ++p->nMem;
|
int iData = ++p->nMem;
|
||||||
int iKey = ++p->nMem;
|
int iKey = ++p->nMem;
|
||||||
Vdbe *v = sqlite3GetVdbe(p);
|
Vdbe *v = sqlite3GetVdbe(p);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iData, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iData);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iKey, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iKey);
|
||||||
sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
|
sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
|
||||||
sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags);
|
sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags);
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ int sqlite3StackToReg(Parse *p, int nVal){
|
|||||||
assert(v);
|
assert(v);
|
||||||
p->nMem += nVal;
|
p->nMem += nVal;
|
||||||
for(i=nVal-1; i>=0; i--){
|
for(i=nVal-1; i>=0; i--){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRet+i, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iRet+i);
|
||||||
}
|
}
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ void sqlite3RegToStack(Parse *p, int iReg, int nVal){
|
|||||||
Vdbe *v = sqlite3GetVdbe(p);
|
Vdbe *v = sqlite3GetVdbe(p);
|
||||||
assert(v);
|
assert(v);
|
||||||
for(i=0; i<nVal; i++){
|
for(i=0; i<nVal; i++){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iReg+i, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iReg+i, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +520,7 @@ void sqlite3GenerateIndexKey(
|
|||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
int idx = pIdx->aiColumn[j];
|
int idx = pIdx->aiColumn[j];
|
||||||
if( idx==pTab->iPKey ){
|
if( idx==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp1(v, OP_Dup, j);
|
sqlite3VdbeAddOp1(v, OP_Copy, -j);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, iCur, idx);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, idx);
|
||||||
sqlite3ColumnDefault(v, pTab, idx);
|
sqlite3ColumnDefault(v, pTab, idx);
|
||||||
|
33
src/expr.c
33
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.330 2008/01/04 22:01:03 drh Exp $
|
** $Id: expr.c,v 1.331 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -308,8 +308,7 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
|
|||||||
}
|
}
|
||||||
depth = atoi((char*)&pToken->z[1]);
|
depth = atoi((char*)&pToken->z[1]);
|
||||||
p->iTable = ++pParse->nMem;
|
p->iTable = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp1(v, OP_Dup, depth);
|
sqlite3VdbeAddOp2(v, OP_Copy, -depth, p->iTable);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, p->iTable, 1);
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1606,7 +1605,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
|||||||
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
|
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
|
||||||
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
||||||
|
|
||||||
@ -1643,7 +1642,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
|
|||||||
iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
|
iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
|
||||||
sqlite3VdbeUsesBtree(v, iDb);
|
sqlite3VdbeUsesBtree(v, iDb);
|
||||||
|
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, iMem);
|
||||||
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem);
|
||||||
|
|
||||||
@ -1700,7 +1699,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
|||||||
*/
|
*/
|
||||||
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
|
if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){
|
||||||
int mem = ++pParse->nMem;
|
int mem = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, mem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, mem);
|
||||||
testAddr = sqlite3VdbeAddOp0(v, OP_If);
|
testAddr = sqlite3VdbeAddOp0(v, OP_If);
|
||||||
assert( testAddr>0 || pParse->db->mallocFailed );
|
assert( testAddr>0 || pParse->db->mallocFailed );
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, mem);
|
||||||
@ -1966,7 +1965,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
AggInfo *pAggInfo = pExpr->pAggInfo;
|
AggInfo *pAggInfo = pExpr->pAggInfo;
|
||||||
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
|
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
|
||||||
if( !pAggInfo->directMode ){
|
if( !pAggInfo->directMode ){
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, pCol->iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, pCol->iMem);
|
||||||
break;
|
break;
|
||||||
}else if( pAggInfo->useSortingIdx ){
|
}else if( pAggInfo->useSortingIdx ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
|
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx,
|
||||||
@ -1980,7 +1979,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
if( pExpr->iTable<0 ){
|
if( pExpr->iTable<0 ){
|
||||||
/* This only happens when coding check constraints */
|
/* This only happens when coding check constraints */
|
||||||
assert( pParse->ckOffset>0 );
|
assert( pParse->ckOffset>0 );
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(pParse->ckOffset-pExpr->iColumn-1));
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCodeGetColumn(v, pExpr->pTab,
|
sqlite3ExprCodeGetColumn(v, pExpr->pTab,
|
||||||
pExpr->iColumn, pExpr->iTable, target);
|
pExpr->iColumn, pExpr->iTable, target);
|
||||||
@ -2029,7 +2028,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_REGISTER: {
|
case TK_REGISTER: {
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iTable);
|
sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iTable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_CAST
|
#ifndef SQLITE_OMIT_CAST
|
||||||
@ -2138,7 +2137,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
|
sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
|
||||||
&pExpr->span);
|
&pExpr->span);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem);
|
sqlite3VdbeAddOp1(v, OP_SCopy, pInfo->aFunc[pExpr->iAgg].iMem);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2202,7 +2201,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
if( pExpr->iColumn==0 ){
|
if( pExpr->iColumn==0 ){
|
||||||
sqlite3CodeSubselect(pParse, pExpr);
|
sqlite3CodeSubselect(pParse, pExpr);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iColumn);
|
sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn);
|
||||||
VdbeComment((v, "load subquery result"));
|
VdbeComment((v, "load subquery result"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2254,7 +2253,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
struct ExprList_item *pLItem = pExpr->pList->a;
|
struct ExprList_item *pLItem = pExpr->pList->a;
|
||||||
Expr *pRight = pLItem->pExpr;
|
Expr *pRight = pLItem->pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft, 0);
|
sqlite3ExprCode(pParse, pLeft, 0);
|
||||||
sqlite3VdbeAddOp0(v, OP_Dup);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
sqlite3ExprCode(pParse, pRight, 0);
|
sqlite3ExprCode(pParse, pRight, 0);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
|
codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
|
||||||
sqlite3VdbeAddOp1(v, OP_Pull, 1);
|
sqlite3VdbeAddOp1(v, OP_Pull, 1);
|
||||||
@ -2291,7 +2290,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
for(i=0; i<nExpr; i=i+2){
|
for(i=0; i<nExpr; i=i+2){
|
||||||
sqlite3ExprCode(pParse, aListelem[i].pExpr, 0);
|
sqlite3ExprCode(pParse, aListelem[i].pExpr, 0);
|
||||||
if( pExpr->pLeft ){
|
if( pExpr->pLeft ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -1);
|
||||||
jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
|
jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
|
||||||
OP_Ne, 0, 1);
|
OP_Ne, 0, 1);
|
||||||
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
sqlite3VdbeAddOp1(v, OP_Pop, 1);
|
||||||
@ -2339,7 +2338,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if( target && !inReg ){
|
if( target && !inReg ){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, target, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, target);
|
||||||
stackChng = 0;
|
stackChng = 0;
|
||||||
}
|
}
|
||||||
if( pParse->ckOffset ){
|
if( pParse->ckOffset ){
|
||||||
@ -2372,7 +2371,7 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){
|
|||||||
if( addr2>addr1+1
|
if( addr2>addr1+1
|
||||||
|| ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){
|
|| ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){
|
||||||
iMem = pExpr->iTable = ++pParse->nMem;
|
iMem = pExpr->iTable = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_Copy, 0, iMem);
|
||||||
pExpr->op = TK_REGISTER;
|
pExpr->op = TK_REGISTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2479,7 +2478,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
Expr *pLeft = pExpr->pLeft;
|
Expr *pLeft = pExpr->pLeft;
|
||||||
Expr *pRight = pExpr->pList->a[0].pExpr;
|
Expr *pRight = pExpr->pList->a[0].pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft, 0);
|
sqlite3ExprCode(pParse, pLeft, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
sqlite3ExprCode(pParse, pRight, 0);
|
sqlite3ExprCode(pParse, pRight, 0);
|
||||||
addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
|
addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
|
||||||
|
|
||||||
@ -2591,7 +2590,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
|||||||
Expr *pLeft = pExpr->pLeft;
|
Expr *pLeft = pExpr->pLeft;
|
||||||
Expr *pRight = pExpr->pList->a[0].pExpr;
|
Expr *pRight = pExpr->pList->a[0].pExpr;
|
||||||
sqlite3ExprCode(pParse, pLeft, 0);
|
sqlite3ExprCode(pParse, pLeft, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
sqlite3ExprCode(pParse, pRight, 0);
|
sqlite3ExprCode(pParse, pRight, 0);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
|
codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
|
||||||
|
53
src/insert.c
53
src/insert.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 INSERT statements in SQLite.
|
** to handle INSERT statements in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: insert.c,v 1.211 2008/01/04 22:01:03 drh Exp $
|
** $Id: insert.c,v 1.212 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -171,9 +171,9 @@ static int autoIncBegin(
|
|||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+11);
|
sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+11);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, memId-1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
|
sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, memId);
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+12);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+12);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+3);
|
sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+3);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||||
@ -214,12 +214,12 @@ static void autoIncEnd(
|
|||||||
assert( v );
|
assert( v );
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, memId-1, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
|
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
|
||||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
sqlite3VdbeAddOp1(v, OP_NewRowid, iCur);
|
sqlite3VdbeAddOp1(v, OP_NewRowid, iCur);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, memId, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
|
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
|
||||||
sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND);
|
sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||||
@ -728,9 +728,7 @@ void sqlite3Insert(
|
|||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Dup, nColumn - keyColumn - 1, 1, iRowid);
|
sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn - keyColumn - 1), iRowid);
|
||||||
/* TODO: Avoid this use of the stack. */
|
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
|
||||||
}else{
|
}else{
|
||||||
VdbeOp *pOp;
|
VdbeOp *pOp;
|
||||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0);
|
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0);
|
||||||
@ -743,7 +741,7 @@ void sqlite3Insert(
|
|||||||
pOp->p3 = counterMem;
|
pOp->p3 = counterMem;
|
||||||
}else{
|
}else{
|
||||||
/* TODO: Avoid this use of the stack. */
|
/* TODO: Avoid this use of the stack. */
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iRowid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
|
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
|
||||||
@ -758,8 +756,7 @@ void sqlite3Insert(
|
|||||||
}else if( IsVirtual(pTab) ){
|
}else if( IsVirtual(pTab) ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, iRowid);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, iRowid);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp3(v, OP_NewRowid, base, 0, counterMem);
|
sqlite3VdbeAddOp3(v, OP_NewRowid, base, iRowid, counterMem);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
|
||||||
appendFlag = 1;
|
appendFlag = 1;
|
||||||
}
|
}
|
||||||
autoIncStep(pParse, counterMem, iRowid);
|
autoIncStep(pParse, counterMem, iRowid);
|
||||||
@ -796,9 +793,7 @@ void sqlite3Insert(
|
|||||||
}else if( useTempTable ){
|
}else if( useTempTable ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nColumn-j-1, 1);
|
sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn-j-1), iRegStore);
|
||||||
/* TODO: Avoid this use of the stack */
|
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iRegStore, 1);
|
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
|
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
|
||||||
}
|
}
|
||||||
@ -1005,7 +1000,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
|
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
|
||||||
onError = OE_Abort;
|
onError = OE_Abort;
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol-1-i, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol-1-i));
|
||||||
addr = sqlite3VdbeAddOp2(v, OP_NotNull, 1, 0);
|
addr = sqlite3VdbeAddOp2(v, OP_NotNull, 1, 0);
|
||||||
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
||||||
|| onError==OE_Ignore || onError==OE_Replace );
|
|| onError==OE_Ignore || onError==OE_Replace );
|
||||||
@ -1027,7 +1022,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0);
|
sqlite3VdbeAddOp1(v, OP_Push, nCol-i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1068,11 +1063,11 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1));
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1));
|
||||||
jumpInst1 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
|
jumpInst1 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -nCol);
|
||||||
jumpInst2 = sqlite3VdbeAddOp2(v, OP_NotExists, base, 0);
|
jumpInst2 = sqlite3VdbeAddOp2(v, OP_NotExists, base, 0);
|
||||||
switch( onError ){
|
switch( onError ){
|
||||||
default: {
|
default: {
|
||||||
@ -1089,7 +1084,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
case OE_Replace: {
|
case OE_Replace: {
|
||||||
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
|
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+hasTwoRowids, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+hasTwoRowids));
|
||||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
@ -1105,7 +1100,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
sqlite3VdbeJumpHere(v, jumpInst2);
|
sqlite3VdbeJumpHere(v, jumpInst2);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeJumpHere(v, jumpInst1);
|
sqlite3VdbeJumpHere(v, jumpInst1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1));
|
||||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1120,13 +1115,13 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
extra++;
|
extra++;
|
||||||
|
|
||||||
/* Create a key for accessing the index entry */
|
/* Create a key for accessing the index entry */
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+extra));
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
int idx = pIdx->aiColumn[i];
|
int idx = pIdx->aiColumn[i];
|
||||||
if( idx==pTab->iPKey ){
|
if( idx==pTab->iPKey ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol+1, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(i+extra+nCol+1));
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol-idx, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(i+extra+nCol-idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jumpInst1 = sqlite3VdbeAddOp2(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
jumpInst1 = sqlite3VdbeAddOp2(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
||||||
@ -1147,7 +1142,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
|
|
||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(extra+nCol+1+hasTwoRowids));
|
||||||
jumpInst2 = sqlite3VdbeAddOp2(v, OP_IsUnique, base+iCur+1, 0);
|
jumpInst2 = sqlite3VdbeAddOp2(v, OP_IsUnique, base+iCur+1, 0);
|
||||||
|
|
||||||
/* Generate code that executes if the new index entry is not unique */
|
/* Generate code that executes if the new index entry is not unique */
|
||||||
@ -1193,7 +1188,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
int iRowid = sqlite3StackToReg(pParse, 1);
|
int iRowid = sqlite3StackToReg(pParse, 1);
|
||||||
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, iRowid, 0);
|
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, iRowid, 0);
|
||||||
if( isUpdate ){
|
if( isUpdate ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+extra+1+hasTwoRowids));
|
||||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||||
}
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
@ -1245,8 +1240,8 @@ void sqlite3CompleteInsertion(
|
|||||||
sqlite3TableAffinityStr(v, pTab);
|
sqlite3TableAffinityStr(v, pTab);
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
if( newIdx>=0 ){
|
if( newIdx>=0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Copy, -1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
sqlite3VdbeAddOp1(v, OP_Copy, -1);
|
||||||
sqlite3CodeInsert(pParse, newIdx, 0);
|
sqlite3CodeInsert(pParse, newIdx, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1566,7 +1561,7 @@ static int xferOptimization(
|
|||||||
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
||||||
if( pDest->iPKey>=0 ){
|
if( pDest->iPKey>=0 ){
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
sqlite3VdbeAddOp0(v, OP_Copy);
|
||||||
addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0);
|
||||||
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
||||||
"PRIMARY KEY must be unique", P4_STATIC);
|
"PRIMARY KEY must be unique", P4_STATIC);
|
||||||
|
10
src/pragma.c
10
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.158 2008/01/04 22:01:03 drh Exp $
|
** $Id: pragma.c,v 1.159 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -300,7 +300,7 @@ void sqlite3Pragma(
|
|||||||
static const VdbeOpList getCacheSize[] = {
|
static const VdbeOpList getCacheSize[] = {
|
||||||
{ OP_ReadCookie, 0, 0, 2}, /* 0 */
|
{ OP_ReadCookie, 0, 0, 2}, /* 0 */
|
||||||
{ OP_AbsValue, 0, 0, 0},
|
{ OP_AbsValue, 0, 0, 0},
|
||||||
{ OP_Dup, 0, 0, 0},
|
{ OP_Copy, 0, 0, 0},
|
||||||
{ OP_Integer, 0, 0, 0},
|
{ OP_Integer, 0, 0, 0},
|
||||||
{ OP_Ne, 0, 6, 0},
|
{ OP_Ne, 0, 6, 0},
|
||||||
{ OP_Integer, 0, 0, 0}, /* 5 */
|
{ OP_Integer, 0, 0, 0}, /* 5 */
|
||||||
@ -830,7 +830,7 @@ void sqlite3Pragma(
|
|||||||
** error message
|
** error message
|
||||||
*/
|
*/
|
||||||
static const VdbeOpList endCode[] = {
|
static const VdbeOpList endCode[] = {
|
||||||
{ OP_MemLoad, 1, 0, 0},
|
{ OP_SCopy, 1, 0, 0},
|
||||||
{ OP_Integer, 0, 0, 0},
|
{ OP_Integer, 0, 0, 0},
|
||||||
{ OP_Ne, 0, 0, 0}, /* 2 */
|
{ OP_Ne, 0, 0, 0}, /* 2 */
|
||||||
{ OP_String8, 0, 0, 0}, /* 3 */
|
{ OP_String8, 0, 0, 0}, /* 3 */
|
||||||
@ -933,8 +933,8 @@ void sqlite3Pragma(
|
|||||||
{ OP_Rewind, 0, 0, 0}, /* 1 */
|
{ OP_Rewind, 0, 0, 0}, /* 1 */
|
||||||
{ OP_MemIncr, 1, 3, 0},
|
{ OP_MemIncr, 1, 3, 0},
|
||||||
{ OP_Next, 0, 0, 0}, /* 3 */
|
{ OP_Next, 0, 0, 0}, /* 3 */
|
||||||
{ OP_MemLoad, 2, 0, 0},
|
{ OP_SCopy, 2, 0, 0},
|
||||||
{ OP_MemLoad, 3, 0, 0},
|
{ OP_SCopy, 3, 0, 0},
|
||||||
{ OP_Eq, 0, 0, 0}, /* 6 */
|
{ OP_Eq, 0, 0, 0}, /* 6 */
|
||||||
{ OP_MemIncr, -1, 1, 0},
|
{ OP_MemIncr, -1, 1, 0},
|
||||||
{ OP_String8, 0, 0, 0}, /* 8 */
|
{ OP_String8, 0, 0, 0}, /* 8 */
|
||||||
|
28
src/select.c
28
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.384 2008/01/04 22:01:03 drh Exp $
|
** $Id: select.c,v 1.385 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -634,7 +634,7 @@ static int selectInnerLoop(
|
|||||||
** ORDER BY in this case since the order of entries in the set
|
** ORDER BY in this case since the order of entries in the set
|
||||||
** does not matter. But there might be a LIMIT clause, in which
|
** does not matter. But there might be a LIMIT clause, in which
|
||||||
** case the order does matter */
|
** case the order does matter */
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0);
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 0, 0, &p->affinity, 1);
|
sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 0, 0, &p->affinity, 1);
|
||||||
@ -658,11 +658,11 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0);
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iParm);
|
||||||
/* The LIMIT clause will jump out of the loop for us */
|
/* The LIMIT clause will jump out of the loop for us */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -679,7 +679,7 @@ static int selectInnerLoop(
|
|||||||
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
|
||||||
pushOntoSorter(pParse, pOrderBy, p);
|
pushOntoSorter(pParse, pOrderBy, p);
|
||||||
}else if( eDest==SRT_Subroutine ){
|
}else if( eDest==SRT_Subroutine ){
|
||||||
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+i+1, 0);
|
for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i+1, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_ResultRow, iMem+1, nColumn);
|
sqlite3VdbeAddOp2(v, OP_ResultRow, iMem+1, nColumn);
|
||||||
@ -806,7 +806,7 @@ static void generateSortTail(
|
|||||||
}
|
}
|
||||||
case SRT_Mem: {
|
case SRT_Mem: {
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iParm);
|
||||||
/* The LIMIT clause will terminate the loop for us */
|
/* The LIMIT clause will terminate the loop for us */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1752,10 +1752,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pLimit, 0);
|
sqlite3ExprCode(pParse, p->pLimit, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit);
|
||||||
VdbeComment((v, "LIMIT counter"));
|
VdbeComment((v, "LIMIT counter"));
|
||||||
sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak);
|
sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iLimit, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0);
|
||||||
}
|
}
|
||||||
if( p->pOffset ){
|
if( p->pOffset ){
|
||||||
p->iOffset = iOffset = ++pParse->nMem;
|
p->iOffset = iOffset = ++pParse->nMem;
|
||||||
@ -1763,7 +1763,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
sqlite3ExprCode(pParse, p->pOffset, 0);
|
sqlite3ExprCode(pParse, p->pOffset, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0);
|
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 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||||
@ -1779,7 +1779,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
|
|||||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
|
sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1);
|
||||||
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iLimit+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1);
|
||||||
VdbeComment((v, "LIMIT+OFFSET"));
|
VdbeComment((v, "LIMIT+OFFSET"));
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
}
|
}
|
||||||
@ -3547,13 +3547,13 @@ int sqlite3Select(
|
|||||||
sAggInfo.directMode = 1;
|
sAggInfo.directMode = 1;
|
||||||
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, 0);
|
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1);
|
sqlite3VdbeAddOp2(v, j<pGroupBy->nExpr-1?OP_Move:OP_Copy, 0, iBMem+j);
|
||||||
}
|
}
|
||||||
for(j=pGroupBy->nExpr-1; j>=0; j--){
|
for(j=pGroupBy->nExpr-1; j>=0; j--){
|
||||||
if( j<pGroupBy->nExpr-1 ){
|
if( j<pGroupBy->nExpr-1 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iBMem+j, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iBMem+j, 0);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iAMem+j, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iAMem+j, 0);
|
||||||
if( j==0 ){
|
if( j==0 ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Eq, 0x200, addrProcessRow);
|
sqlite3VdbeAddOp2(v, OP_Eq, 0x200, addrProcessRow);
|
||||||
}else{
|
}else{
|
||||||
@ -3573,7 +3573,7 @@ int sqlite3Select(
|
|||||||
*/
|
*/
|
||||||
sqlite3VdbeResolveLabel(v, addrGroupByChange);
|
sqlite3VdbeResolveLabel(v, addrGroupByChange);
|
||||||
for(j=0; j<pGroupBy->nExpr; j++){
|
for(j=0; j<pGroupBy->nExpr; j++){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemMove, iAMem+j, iBMem+j);
|
sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
|
||||||
VdbeComment((v, "output one row"));
|
VdbeComment((v, "output one row"));
|
||||||
|
@ -237,8 +237,8 @@ void sqlite3FinishTrigger(
|
|||||||
{ OP_String8, 0, 0, 0 }, /* 6: SQL */
|
{ OP_String8, 0, 0, 0 }, /* 6: SQL */
|
||||||
{ OP_Concat, 0, 0, 0 },
|
{ OP_Concat, 0, 0, 0 },
|
||||||
{ OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */
|
{ OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */
|
||||||
{ OP_MemStore, 0, 1, 0 }, /* 9: Store data */
|
{ OP_Move, 0, 0, 0 }, /* 9: Store data */
|
||||||
{ OP_MemStore, 0, 1, 0 }, /* 10: Store key */
|
{ OP_Move, 0, 0, 0 }, /* 10: Store key */
|
||||||
{ OP_Insert, 0, 0, 0 },
|
{ OP_Insert, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
int addr;
|
int addr;
|
||||||
@ -258,9 +258,9 @@ void sqlite3FinishTrigger(
|
|||||||
sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC);
|
sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC);
|
||||||
sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
|
sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
|
||||||
sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC);
|
sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC);
|
||||||
sqlite3VdbeChangeP1(v, addr+9, iData);
|
sqlite3VdbeChangeP2(v, addr+9, iData);
|
||||||
|
sqlite3VdbeChangeP2(v, addr+10, iKey);
|
||||||
sqlite3VdbeChangeP2(v, addr+11, iData);
|
sqlite3VdbeChangeP2(v, addr+11, iData);
|
||||||
sqlite3VdbeChangeP1(v, addr+10, iKey);
|
|
||||||
sqlite3VdbeChangeP3(v, addr+11, iKey);
|
sqlite3VdbeChangeP3(v, addr+11, iKey);
|
||||||
sqlite3ChangeCookie(db, v, iDb);
|
sqlite3ChangeCookie(db, v, iDb);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
|
||||||
|
@ -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.158 2008/01/04 22:01:03 drh Exp $
|
** $Id: update.c,v 1.159 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ void sqlite3Update(
|
|||||||
** So make the cursor point at the old record.
|
** So make the cursor point at the old record.
|
||||||
*/
|
*/
|
||||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid);
|
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, iRowid, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, iRowid, 0);
|
||||||
|
|
||||||
/* If the record number will change, push the record number as it
|
/* If the record number will change, push the record number as it
|
||||||
** will be after the update. (The old record number is currently
|
** will be after the update. (The old record number is currently
|
||||||
|
219
src/vdbe.c
219
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.679 2008/01/04 22:01:03 drh Exp $
|
** $Id: vdbe.c,v 1.680 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -470,6 +470,7 @@ int sqlite3VdbeExec(
|
|||||||
Mem *pIn1, *pIn2; /* Input operands */
|
Mem *pIn1, *pIn2; /* Input operands */
|
||||||
Mem *pOut; /* Output operand */
|
Mem *pOut; /* Output operand */
|
||||||
int nPop = 0; /* Number of times to pop the stack */
|
int nPop = 0; /* Number of times to pop the stack */
|
||||||
|
u8 opProperty;
|
||||||
#ifdef VDBE_PROFILE
|
#ifdef VDBE_PROFILE
|
||||||
unsigned long long start; /* CPU clock count at start of opcode */
|
unsigned long long start; /* CPU clock count at start of opcode */
|
||||||
int origPc; /* Program counter at start of opcode */
|
int origPc; /* Program counter at start of opcode */
|
||||||
@ -596,7 +597,8 @@ int sqlite3VdbeExec(
|
|||||||
** then the output is pushed onto the stack. The P2 operand
|
** then the output is pushed onto the stack. The P2 operand
|
||||||
** is initialized to a NULL.
|
** is initialized to a NULL.
|
||||||
*/
|
*/
|
||||||
if( (opcodeProperty[pOp->opcode]&OPFLG_OUT2_PRERELEASE)!=0 ){
|
opProperty = opcodeProperty[pOp->opcode];
|
||||||
|
if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
|
||||||
assert( pOp->p2>=0 );
|
assert( pOp->p2>=0 );
|
||||||
if( pOp->p2==0 ){
|
if( pOp->p2==0 ){
|
||||||
pOut = ++pTos;
|
pOut = ++pTos;
|
||||||
@ -606,6 +608,71 @@ int sqlite3VdbeExec(
|
|||||||
sqlite3VdbeMemRelease(pOut);
|
sqlite3VdbeMemRelease(pOut);
|
||||||
}
|
}
|
||||||
pOut->flags = MEM_Null;
|
pOut->flags = MEM_Null;
|
||||||
|
}else
|
||||||
|
|
||||||
|
/* Do common setup for opcodes marked with one of the following
|
||||||
|
** combinations of properties.
|
||||||
|
**
|
||||||
|
** in1
|
||||||
|
** in1 in2
|
||||||
|
** in1 in2 out3
|
||||||
|
** in1 in3
|
||||||
|
** in1 out2
|
||||||
|
**
|
||||||
|
** Variables pIn1 and pIn2 are made to point to the first two
|
||||||
|
** inputs and pOut points to the output. Variable nPop holds the
|
||||||
|
** number of times that the stack should be popped after the
|
||||||
|
** the instruction.
|
||||||
|
*/
|
||||||
|
if( (opProperty & OPFLG_IN1)!=0 ){
|
||||||
|
assert( pOp->p1>=0 );
|
||||||
|
if( pOp->p1==0 ){
|
||||||
|
pIn1 = pTos;
|
||||||
|
nPop = 1;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p1<=p->nMem );
|
||||||
|
pIn1 = &p->aMem[pOp->p1];
|
||||||
|
}
|
||||||
|
if( (opProperty & OPFLG_IN2)!=0 ){
|
||||||
|
assert( pOp->p2>=0 );
|
||||||
|
if( pOp->p2==0 ){
|
||||||
|
pIn2 = &pTos[-nPop];
|
||||||
|
nPop++;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p2<=p->nMem );
|
||||||
|
pIn2 = &p->aMem[pOp->p2];
|
||||||
|
}
|
||||||
|
if( (opProperty & OPFLG_OUT3)!=0 ){
|
||||||
|
assert( pOp->p3>=0 );
|
||||||
|
if( pOp->p3==0 ){
|
||||||
|
pTos++;
|
||||||
|
pOut = &pTos[-nPop];
|
||||||
|
pOut->flags = MEM_Null;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p3<=p->nMem );
|
||||||
|
pOut = &p->aMem[pOp->p3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if( (opProperty & OPFLG_IN3)!=0 ){
|
||||||
|
assert( pOp->p3>=0 );
|
||||||
|
if( pOp->p3==0 ){
|
||||||
|
pIn2 = &pTos[-nPop];
|
||||||
|
nPop++;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p3<=p->nMem );
|
||||||
|
pIn2 = &p->aMem[pOp->p3];
|
||||||
|
}
|
||||||
|
}else if( (opProperty & OPFLG_OUT2)!=0 ){
|
||||||
|
assert( pOp->p2>=0 );
|
||||||
|
if( pOp->p2==0 ){
|
||||||
|
pTos++;
|
||||||
|
pOut = &pTos[-nPop];
|
||||||
|
pOut->flags = MEM_Null;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p2<=p->nMem );
|
||||||
|
pOut = &p->aMem[pOp->p2];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( pOp->opcode ){
|
switch( pOp->opcode ){
|
||||||
@ -926,28 +993,77 @@ case OP_Pop: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: Dup P1 P2 *
|
/* Opcode: Move P1 P2 * * *
|
||||||
**
|
**
|
||||||
** A copy of the P1-th element of the stack
|
** Move the value in P1 into P2. If P1 is positive then read from the
|
||||||
** is made and pushed onto the top of the stack.
|
** P1-th register. If P1 is zero or negative read from the stack.
|
||||||
** The top of the stack is element 0. So the
|
** When P1 is 0 read from the top the stack. When P1 is -1 read from
|
||||||
** instruction "Dup 0 0 0" will make a copy of the
|
** the next entry down on the stack. And so forth.
|
||||||
** top of the stack.
|
|
||||||
**
|
**
|
||||||
** If the content of the P1-th element is a dynamically
|
** If P2 is zero, push the new value onto the top of the stack.
|
||||||
** allocated string, then a new copy of that string
|
** If P2 is positive, write into the P2-th register.
|
||||||
** is made if P2==0. If P2!=0, then just a pointer
|
|
||||||
** to the string is copied.
|
|
||||||
**
|
**
|
||||||
** Also see the Pull instruction.
|
** If P1 is zero then the stack is popped once. The stack is
|
||||||
|
** unchanged for all other values of P1. The P1 value contains
|
||||||
|
** a NULL after this operation.
|
||||||
*/
|
*/
|
||||||
case OP_Dup: {
|
/* Opcode: Copy P1 P2 * * *
|
||||||
Mem *pFrom = &pTos[-pOp->p1];
|
**
|
||||||
assert( pFrom<=pTos && pFrom>=p->aStack );
|
** Make a copy of P1 into P2. If P1 is positive then read from the
|
||||||
pTos++;
|
** P1-th register. If P1 is zero or negative read from the stack.
|
||||||
sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);
|
** When P1 is 0 read from the top the stack. When P1 is -1 read from
|
||||||
if( pOp->p2 ){
|
** the next entry down on the stack. And so forth.
|
||||||
Deephemeralize(pTos);
|
**
|
||||||
|
** If P2 is zero, push the new value onto the top of the stack.
|
||||||
|
** If P2 is positive, write into the P2-th register.
|
||||||
|
**
|
||||||
|
** This instruction makes a deep copy of the value. A duplicate
|
||||||
|
** is made of any string or blob constant. See also OP_SCopy.
|
||||||
|
*/
|
||||||
|
/* Opcode: SCopy P1 P2 * * *
|
||||||
|
**
|
||||||
|
** Make a shallow copy of P1 into P2. If P1 is positive then read from the
|
||||||
|
** P1-th register. If P1 is zero or negative read from the stack.
|
||||||
|
** When P1 is 0 read from the top the stack. When P1 is -1 read from
|
||||||
|
** the next entry down on the stack. And so forth.
|
||||||
|
**
|
||||||
|
** If P2 is zero, push the new value onto the top of the stack.
|
||||||
|
** If P2 is positive, write into the P2-th register.
|
||||||
|
**
|
||||||
|
** This instruction makes a shallow copy of the value. If the value
|
||||||
|
** is a string or blob, then the copy is only a pointer to the
|
||||||
|
** original and hence if the original changes so will the copy.
|
||||||
|
** Worse, if the original is deallocated, the copy becomes invalid.
|
||||||
|
** Thus the program must guarantee that the original will not change
|
||||||
|
** during the lifetime of the copy. Use OP_Copy to make a complete
|
||||||
|
** copy.
|
||||||
|
*/
|
||||||
|
case OP_Move:
|
||||||
|
case OP_Copy:
|
||||||
|
case OP_SCopy: {
|
||||||
|
if( pOp->p1<=0 ){
|
||||||
|
pIn1 = &pTos[pOp->p1];
|
||||||
|
assert( pIn1>=p->aStack );
|
||||||
|
}else{
|
||||||
|
assert( pOp->p1<=p->nMem );
|
||||||
|
pIn1 = &p->aMem[pOp->p1];
|
||||||
|
}
|
||||||
|
assert( pOp->p2>=0 );
|
||||||
|
if( pOp->p2==0 ){
|
||||||
|
pOut = ++pTos;
|
||||||
|
pOut->flags = MEM_Null;
|
||||||
|
}else{
|
||||||
|
assert( pOp->p2<=p->nMem );
|
||||||
|
pOut = &p->aMem[pOp->p2];
|
||||||
|
}
|
||||||
|
if( pOp->opcode==OP_Move ){
|
||||||
|
rc = sqlite3VdbeMemMove(pOut, pIn1);
|
||||||
|
if( pOp->p1==0 ) pTos--;
|
||||||
|
}else{
|
||||||
|
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||||
|
if( pOp->opcode==OP_Copy ){
|
||||||
|
Deephemeralize(pOut);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -959,8 +1075,6 @@ case OP_Dup: {
|
|||||||
** top of the stack is element 0, so "Pull 0 0 0" is
|
** top of the stack is element 0, so "Pull 0 0 0" is
|
||||||
** a no-op. "Pull 1 0 0" swaps the top two elements of
|
** a no-op. "Pull 1 0 0" swaps the top two elements of
|
||||||
** the stack.
|
** the stack.
|
||||||
**
|
|
||||||
** See also the Dup instruction.
|
|
||||||
*/
|
*/
|
||||||
case OP_Pull: { /* no-push */
|
case OP_Pull: { /* no-push */
|
||||||
Mem *pFrom = &pTos[-pOp->p1];
|
Mem *pFrom = &pTos[-pOp->p1];
|
||||||
@ -2681,7 +2795,7 @@ case OP_Transaction: { /* no-push */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: ReadCookie P1 P2 P3
|
/* Opcode: ReadCookie P1 P2 P3 * *
|
||||||
**
|
**
|
||||||
** Read cookie number P3 from database P1 and write it into register
|
** Read cookie number P3 from database P1 and write it into register
|
||||||
** P2 or push it onto the stack if P2==0.
|
** P2 or push it onto the stack if P2==0.
|
||||||
@ -4615,46 +4729,6 @@ case OP_ContextPop: { /* no-push */
|
|||||||
}
|
}
|
||||||
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
|
||||||
|
|
||||||
/* Opcode: MemStore P1 P2 *
|
|
||||||
**
|
|
||||||
** Write the top of the stack into memory location P1.
|
|
||||||
** P1 should be a small integer since space is allocated
|
|
||||||
** for all memory locations between 0 and P1 inclusive.
|
|
||||||
**
|
|
||||||
** After the data is stored in the memory location, the
|
|
||||||
** stack is popped once if P2 is 1. If P2 is zero, then
|
|
||||||
** the original data remains on the stack.
|
|
||||||
*/
|
|
||||||
case OP_MemStore: { /* no-push */
|
|
||||||
assert( pTos>=p->aStack );
|
|
||||||
assert( pOp->p1>0 && pOp->p1<=p->nMem );
|
|
||||||
rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
|
|
||||||
pTos--;
|
|
||||||
|
|
||||||
/* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
|
|
||||||
** restore the top of the stack to its original value.
|
|
||||||
*/
|
|
||||||
if( pOp->p2 ){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Opcode: MemLoad P1 * *
|
|
||||||
**
|
|
||||||
** Push a copy of the value in memory location P1 onto the stack.
|
|
||||||
**
|
|
||||||
** If the value is a string, then the value pushed is a pointer to
|
|
||||||
** the string that is stored in the memory location. If the memory
|
|
||||||
** location is subsequently changed (using OP_MemStore) then the
|
|
||||||
** value pushed onto the stack will change too.
|
|
||||||
*/
|
|
||||||
case OP_MemLoad: {
|
|
||||||
int i = pOp->p1;
|
|
||||||
assert( i>0 && i<=p->nMem );
|
|
||||||
pTos++;
|
|
||||||
sqlite3VdbeMemShallowCopy(pTos, &p->aMem[i], MEM_Ephem);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
/* Opcode: MemMax P1 P2 *
|
/* Opcode: MemMax P1 P2 *
|
||||||
**
|
**
|
||||||
@ -4768,19 +4842,6 @@ case OP_IfMemNull: { /* no-push, jump */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: MemMove P1 P2 *
|
|
||||||
**
|
|
||||||
** Move the content of memory cell P2 over to memory cell P1.
|
|
||||||
** Any prior content of P1 is erased. Memory cell P2 is left
|
|
||||||
** containing a NULL.
|
|
||||||
*/
|
|
||||||
case OP_MemMove: {
|
|
||||||
assert( pOp->p1>0 && pOp->p1<=p->nMem );
|
|
||||||
assert( pOp->p2>0 && pOp->p2<=p->nMem );
|
|
||||||
rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], &p->aMem[pOp->p2]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Opcode: AggStep P1 P2 P4
|
/* Opcode: AggStep P1 P2 P4
|
||||||
**
|
**
|
||||||
** Execute the step function for an aggregate. The
|
** Execute the step function for an aggregate. The
|
||||||
@ -5306,6 +5367,12 @@ default: {
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pop the stack if necessary */
|
||||||
|
if( nPop ){
|
||||||
|
popStack(&pTos, nPop);
|
||||||
|
nPop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the stack limit was not exceeded */
|
/* Make sure the stack limit was not exceeded */
|
||||||
assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit );
|
assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit );
|
||||||
|
|
||||||
|
24
src/where.c
24
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.273 2008/01/04 22:01:03 drh Exp $
|
** $Id: where.c,v 1.274 2008/01/05 04:06:04 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -1827,7 +1827,7 @@ static void codeAllEqualityTerms(
|
|||||||
sqlite3VdbeAddOp2(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk);
|
sqlite3VdbeAddOp2(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk);
|
||||||
}
|
}
|
||||||
if( termsInMem ){
|
if( termsInMem ){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem+j+1, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem+j+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1835,7 +1835,7 @@ static void codeAllEqualityTerms(
|
|||||||
*/
|
*/
|
||||||
if( termsInMem ){
|
if( termsInMem ){
|
||||||
for(j=0; j<nEq; j++){
|
for(j=0; j<nEq; j++){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem+j+1, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem+j+1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2362,7 +2362,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
assert( pEnd->leftCursor==iCur );
|
assert( pEnd->leftCursor==iCur );
|
||||||
sqlite3ExprCode(pParse, pX->pRight, 0);
|
sqlite3ExprCode(pParse, pX->pRight, 0);
|
||||||
pLevel->iMem = ++pParse->nMem;
|
pLevel->iMem = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem);
|
||||||
if( pX->op==TK_LT || pX->op==TK_GT ){
|
if( pX->op==TK_LT || pX->op==TK_GT ){
|
||||||
testOp = bRev ? OP_Le : OP_Ge;
|
testOp = bRev ? OP_Le : OP_Ge;
|
||||||
}else{
|
}else{
|
||||||
@ -2376,7 +2376,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
pLevel->p2 = start;
|
pLevel->p2 = start;
|
||||||
if( testOp!=OP_Noop ){
|
if( testOp!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp2(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk);
|
sqlite3VdbeAddOp2(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk);
|
||||||
}
|
}
|
||||||
}else if( pLevel->flags & WHERE_COLUMN_RANGE ){
|
}else if( pLevel->flags & WHERE_COLUMN_RANGE ){
|
||||||
@ -2410,7 +2410,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** start key.
|
** start key.
|
||||||
*/
|
*/
|
||||||
for(j=0; j<nEq; j++){
|
for(j=0; j<nEq; j++){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nEq-1, 0);
|
sqlite3VdbeAddOp1(v, OP_Copy, 1-nEq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out what comparison operators to use for top and bottom
|
/* Figure out what comparison operators to use for top and bottom
|
||||||
@ -2459,7 +2459,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
int op = topEq ? OP_MoveLe : OP_MoveLt;
|
int op = topEq ? OP_MoveLe : OP_MoveLt;
|
||||||
sqlite3VdbeAddOp2(v, op, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, op, iIdxCur, nxt);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem);
|
||||||
}
|
}
|
||||||
}else if( bRev ){
|
}else if( bRev ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Last, iIdxCur, brk);
|
sqlite3VdbeAddOp2(v, OP_Last, iIdxCur, brk);
|
||||||
@ -2493,7 +2493,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
buildIndexProbe(v, nCol, pIdx);
|
buildIndexProbe(v, nCol, pIdx);
|
||||||
if( bRev ){
|
if( bRev ){
|
||||||
pLevel->iMem = ++pParse->nMem;
|
pLevel->iMem = ++pParse->nMem;
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1);
|
sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem);
|
||||||
testOp = OP_IdxLT;
|
testOp = OP_IdxLT;
|
||||||
}else{
|
}else{
|
||||||
int op = btmEq ? OP_MoveGe : OP_MoveGt;
|
int op = btmEq ? OP_MoveGe : OP_MoveGt;
|
||||||
@ -2511,7 +2511,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
*/
|
*/
|
||||||
start = sqlite3VdbeCurrentAddr(v);
|
start = sqlite3VdbeCurrentAddr(v);
|
||||||
if( testOp!=OP_Noop ){
|
if( testOp!=OP_Noop ){
|
||||||
sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp2(v, testOp, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, testOp, iIdxCur, nxt);
|
||||||
if( (topEq && !bRev) || (!btmEq && bRev) ){
|
if( (topEq && !bRev) || (!btmEq && bRev) ){
|
||||||
sqlite3VdbeChangeP4(v, -1, "+", P4_STATIC);
|
sqlite3VdbeChangeP4(v, -1, "+", P4_STATIC);
|
||||||
@ -2548,7 +2548,7 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
** the search
|
** the search
|
||||||
*/
|
*/
|
||||||
buildIndexProbe(v, nEq, pIdx);
|
buildIndexProbe(v, nEq, pIdx);
|
||||||
sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 0);
|
sqlite3VdbeAddOp2(v, OP_Copy, 0, pLevel->iMem);
|
||||||
|
|
||||||
/* Generate code (1) to move to the first matching element of the table.
|
/* Generate code (1) to move to the first matching element of the table.
|
||||||
** Then generate code (2) that jumps to "nxt" after the cursor is past
|
** Then generate code (2) that jumps to "nxt" after the cursor is past
|
||||||
@ -2558,13 +2558,13 @@ WhereInfo *sqlite3WhereBegin(
|
|||||||
if( bRev ){
|
if( bRev ){
|
||||||
/* Scan in reverse order */
|
/* Scan in reverse order */
|
||||||
sqlite3VdbeAddOp2(v, OP_MoveLe, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_MoveLe, iIdxCur, nxt);
|
||||||
start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
start = sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxLT, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_IdxLT, iIdxCur, nxt);
|
||||||
pLevel->op = OP_Prev;
|
pLevel->op = OP_Prev;
|
||||||
}else{
|
}else{
|
||||||
/* Scan in the forward order */
|
/* Scan in the forward order */
|
||||||
sqlite3VdbeAddOp2(v, OP_MoveGe, iIdxCur, nxt);
|
sqlite3VdbeAddOp2(v, OP_MoveGe, iIdxCur, nxt);
|
||||||
start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0);
|
start = sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0);
|
||||||
sqlite3VdbeAddOp4(v, OP_IdxGE, iIdxCur, nxt, 0, "+", P4_STATIC);
|
sqlite3VdbeAddOp4(v, OP_IdxGE, iIdxCur, nxt, 0, "+", P4_STATIC);
|
||||||
pLevel->op = OP_Next;
|
pLevel->op = OP_Next;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#
|
#
|
||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
#
|
#
|
||||||
# $Id: incrblob.test,v 1.17 2007/10/09 08:29:32 danielk1977 Exp $
|
# $Id: incrblob.test,v 1.18 2008/01/05 04:06:04 drh Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -83,7 +83,6 @@ do_test incrblob-1.3.10 {
|
|||||||
close $::blob
|
close $::blob
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
# incrblob-2.*:
|
# incrblob-2.*:
|
||||||
#
|
#
|
||||||
|
Reference in New Issue
Block a user