Some modifications to insert.c to work without using the stack. (CVS 4678)
FossilOrigin-Name: d9ac6beef538376d0ea0a1daa95cf1dfe36143cf
This commit is contained in:
parent
3a40f696d4
commit
287fb61c6b
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
|||||||
C Replace\sthe\sNOPUSH_MASKs\swith\sa\sbit-vector\smechanism\sthat\scan\scontain\nseveral\sdifferent\sproperties\sabout\seach\sopcode.\s(CVS\s4677)
|
C Some\smodifications\sto\sinsert.c\sto\swork\swithout\susing\sthe\sstack.\s(CVS\s4678)
|
||||||
D 2008-01-04T16:50:09
|
D 2008-01-04T19:10:29
|
||||||
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 1ae5b01fef9105aa04c3b943223b80ad116e7161
|
F mkopcodeh.awk 533dc52704d097a8482964d17b8009e485546246
|
||||||
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
|
||||||
@ -90,13 +90,13 @@ F src/build.c b7874b45716fa56e6fd1291ffb0b97a55e470728
|
|||||||
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 5601acbbad10e0a6190e6d1822a776ad058c661d
|
F src/delete.c bc1fedf48f97d52b691bc057164b732409dcd9eb
|
||||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||||
F src/expr.c e60ee4f48194469bf7b101fb7a14e56abea3daa4
|
F src/expr.c e60ee4f48194469bf7b101fb7a14e56abea3daa4
|
||||||
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 7a8c825953ab6435fef1823e83cbe627860dd6d5
|
F src/insert.c 9011065ed43b939c77083e9be3b721e7dfe39c71
|
||||||
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
|
||||||
@ -136,7 +136,7 @@ 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
|
||||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||||
F src/sqliteInt.h df036b69e3c5c6a87354a10668f165b22994f264
|
F src/sqliteInt.h 80f81e0a0b712a74f1c841e6336b51126d781df0
|
||||||
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
|
||||||
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
||||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
||||||
@ -164,11 +164,11 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
|||||||
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||||
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
||||||
F src/trigger.c 713b501b12ea41bf0297a2cf78f7d954c4a25d13
|
F src/trigger.c 713b501b12ea41bf0297a2cf78f7d954c4a25d13
|
||||||
F src/update.c eaacf59269bd076adca6fab6f5d16ce53419380b
|
F src/update.c b54161c624120d8249c9ed9442b24452557fe665
|
||||||
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 8e42b5ce4d69ecf2d17bffd8e520343324785d3e
|
F src/vdbe.c 9ccdc8ab9cb027f7ef759259f515ead5e89c5bb3
|
||||||
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
|
||||||
@ -195,7 +195,7 @@ F test/attach3.test 7b92dc8e40c1ebca9732ca6f2d3fefbd46f196df
|
|||||||
F test/attachmalloc.test 56c5e55563dba6d64641ef2f70ce06900df16912
|
F test/attachmalloc.test 56c5e55563dba6d64641ef2f70ce06900df16912
|
||||||
F test/auth.test be181f70ced0c84ecb5e2515d9b620f89f6a7b87
|
F test/auth.test be181f70ced0c84ecb5e2515d9b620f89f6a7b87
|
||||||
F test/auth2.test 65ac294b8d52cbdd463f61e77ad0165268373126
|
F test/auth2.test 65ac294b8d52cbdd463f61e77ad0165268373126
|
||||||
F test/autoinc.test 0e67964f4855081e3a325e484adfebaab41f23a1
|
F test/autoinc.test 0555aa5c789520f16d86a39c6c49b87998e01bea
|
||||||
F test/autovacuum.test 4339e66003b9cf813dd667a83aed2dee27c4c36d
|
F test/autovacuum.test 4339e66003b9cf813dd667a83aed2dee27c4c36d
|
||||||
F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31
|
F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31
|
||||||
F test/autovacuum_ioerr.test c46a76869cb6eddbbb40b419b2b6c4c001766b1f
|
F test/autovacuum_ioerr.test c46a76869cb6eddbbb40b419b2b6c4c001766b1f
|
||||||
@ -442,7 +442,7 @@ F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
|||||||
F test/tableapi.test 92651a95c23cf955e92407928e640536402fa3cc
|
F test/tableapi.test 92651a95c23cf955e92407928e640536402fa3cc
|
||||||
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl 675147144b4e661e31277876bb1bb0d9f6afb442
|
F test/tester.tcl 191b1b06da24f2bff246495d727f1b35798e8e48
|
||||||
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
||||||
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
@ -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 2c913908a47e7ace7d964067e3566d232ee2d494
|
P 042dcb9621934d0318a7c6e9cd08b20a569db367
|
||||||
R 7c9e5a234b0556d1a08e9283ee39d755
|
R 23122a1c7ba45624bb7ec24bd9213db7
|
||||||
U drh
|
U danielk1977
|
||||||
Z 240c930bb8f98d16c4e85e184409b234
|
Z 01db8752e7bca636624abb4391a1c05d
|
||||||
|
@ -1 +1 @@
|
|||||||
042dcb9621934d0318a7c6e9cd08b20a569db367
|
d9ac6beef538376d0ea0a1daa95cf1dfe36143cf
|
@ -57,6 +57,7 @@
|
|||||||
in1[name] = 0
|
in1[name] = 0
|
||||||
in2[name] = 0
|
in2[name] = 0
|
||||||
in3[name] = 0
|
in3[name] = 0
|
||||||
|
nopush[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)
|
||||||
@ -131,7 +132,6 @@ END {
|
|||||||
#
|
#
|
||||||
for(i=0; i<=max; i++) bv[i] = 0;
|
for(i=0; i<=max; i++) bv[i] = 0;
|
||||||
for(name in op){
|
for(name in op){
|
||||||
x = op[name]
|
|
||||||
if( jump[name] ) bv[x] += 0x01;
|
if( jump[name] ) bv[x] += 0x01;
|
||||||
if( out1[name] ) bv[x] += 0x02;
|
if( out1[name] ) bv[x] += 0x02;
|
||||||
if( out2[name] ) bv[x] += 0x04;
|
if( out2[name] ) bv[x] += 0x04;
|
||||||
@ -139,7 +139,7 @@ END {
|
|||||||
if( in1[name] ) bv[x] += 0x10;
|
if( in1[name] ) bv[x] += 0x10;
|
||||||
if( in2[name] ) bv[x] += 0x20;
|
if( in2[name] ) bv[x] += 0x20;
|
||||||
if( in3[name] ) bv[x] += 0x40;
|
if( in3[name] ) bv[x] += 0x40;
|
||||||
if( !nopush[name] ) bv[x] += 0x80;
|
if( 0 == nopush[name] ) bv[x] = bv[x] + 0x80;
|
||||||
}
|
}
|
||||||
print "\n"
|
print "\n"
|
||||||
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
|
||||||
|
10
src/delete.c
10
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.146 2008/01/04 13:57:26 danielk1977 Exp $
|
** $Id: delete.c,v 1.147 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -91,6 +91,14 @@ int sqlite3StackToReg(Parse *p, int nVal){
|
|||||||
}
|
}
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
void sqlite3RegToStack(Parse *p, int iReg, int nVal){
|
||||||
|
int i;
|
||||||
|
Vdbe *v = sqlite3GetVdbe(p);
|
||||||
|
assert(v);
|
||||||
|
for(i=0; i<nVal; i++){
|
||||||
|
sqlite3VdbeAddOp2(v, OP_MemLoad, iReg+i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate code that will open a table for reading.
|
** Generate code that will open a table for reading.
|
||||||
|
56
src/insert.c
56
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.209 2008/01/04 13:24:29 danielk1977 Exp $
|
** $Id: insert.c,v 1.210 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -189,9 +189,9 @@ static int autoIncBegin(
|
|||||||
** larger than the maximum rowid in the memId memory cell, then the
|
** larger than the maximum rowid in the memId memory cell, then the
|
||||||
** memory cell is updated. The stack is unchanged.
|
** memory cell is updated. The stack is unchanged.
|
||||||
*/
|
*/
|
||||||
static void autoIncStep(Parse *pParse, int memId){
|
static void autoIncStep(Parse *pParse, int memId, int iRowid){
|
||||||
if( memId>0 ){
|
if( memId>0 ){
|
||||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, 0);
|
sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, iRowid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ static void autoIncEnd(
|
|||||||
** above are all no-ops
|
** above are all no-ops
|
||||||
*/
|
*/
|
||||||
# define autoIncBegin(A,B,C) (0)
|
# define autoIncBegin(A,B,C) (0)
|
||||||
# define autoIncStep(A,B)
|
# define autoIncStep(A,B,C)
|
||||||
# define autoIncEnd(A,B,C,D)
|
# define autoIncEnd(A,B,C,D)
|
||||||
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
#endif /* SQLITE_OMIT_AUTOINCREMENT */
|
||||||
|
|
||||||
@ -716,15 +716,21 @@ void sqlite3Insert(
|
|||||||
** case the record number is the same as that column.
|
** case the record number is the same as that column.
|
||||||
*/
|
*/
|
||||||
if( !isView ){
|
if( !isView ){
|
||||||
|
int iReg = pParse->nMem+1;
|
||||||
|
int iRowid = iReg+(IsVirtual(pTab)?1:0);
|
||||||
|
pParse->nMem += pTab->nCol + (IsVirtual(pTab)?2:1);
|
||||||
|
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
/* The row that the VUpdate opcode will delete: none */
|
/* The row that the VUpdate opcode will delete: none */
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iReg);
|
||||||
}
|
}
|
||||||
if( keyColumn>=0 ){
|
if( keyColumn>=0 ){
|
||||||
if( useTempTable ){
|
if( useTempTable ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
sqlite3VdbeAddOp3(v, OP_Dup, nColumn - keyColumn - 1, 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);
|
||||||
@ -734,36 +740,42 @@ void sqlite3Insert(
|
|||||||
pOp->opcode = OP_NewRowid;
|
pOp->opcode = OP_NewRowid;
|
||||||
pOp->p1 = base;
|
pOp->p1 = base;
|
||||||
pOp->p2 = counterMem;
|
pOp->p2 = counterMem;
|
||||||
|
pOp->p3 = iRowid;
|
||||||
|
}else{
|
||||||
|
/* TODO: Avoid this use of the stack. */
|
||||||
|
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
|
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
|
||||||
** to generate a unique primary key value.
|
** to generate a unique primary key value.
|
||||||
*/
|
*/
|
||||||
if( !appendFlag ){
|
if( !appendFlag ){
|
||||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
sqlite3VdbeAddOp2(v, OP_IfMemNull, iRowid, sqlite3VdbeCurrentAddr(v)+2);
|
||||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
sqlite3VdbeAddOp3(v, OP_NewRowid, base, counterMem, iRowid);
|
||||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, iRowid);
|
||||||
}
|
}
|
||||||
}else if( IsVirtual(pTab) ){
|
}else if( IsVirtual(pTab) ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRowid);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||||
|
sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
|
||||||
appendFlag = 1;
|
appendFlag = 1;
|
||||||
}
|
}
|
||||||
autoIncStep(pParse, counterMem);
|
autoIncStep(pParse, counterMem, iRowid);
|
||||||
|
|
||||||
/* Push onto the stack, data for all columns of the new entry, beginning
|
/* Push onto the stack, data for all columns of the new entry, beginning
|
||||||
** with the first column.
|
** with the first column.
|
||||||
*/
|
*/
|
||||||
nHidden = 0;
|
nHidden = 0;
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
|
int iRegStore = iRowid+1+i;
|
||||||
if( i==pTab->iPKey ){
|
if( i==pTab->iPKey ){
|
||||||
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
|
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
|
||||||
** Whenever this column is read, the record number will be substituted
|
** Whenever this column is read, the record number will be substituted
|
||||||
** in its place. So will fill this column with a NULL to avoid
|
** in its place. So will fill this column with a NULL to avoid
|
||||||
** taking up data space with information that will never be used. */
|
** taking up data space with information that will never be used. */
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRegStore);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( pColumn==0 ){
|
if( pColumn==0 ){
|
||||||
@ -780,13 +792,15 @@ void sqlite3Insert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
|
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
|
||||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0);
|
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
|
||||||
}else if( useTempTable ){
|
}else if( useTempTable ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
|
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
|
||||||
}else if( pSelect ){
|
}else if( pSelect ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
|
sqlite3VdbeAddOp2(v, OP_Dup, nColumn-j-1, 1);
|
||||||
|
/* TODO: Avoid this use of the stack */
|
||||||
|
sqlite3VdbeAddOp2(v, OP_MemStore, iRegStore, 1);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprCode(pParse, pList->a[j].pExpr, 0);
|
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,13 +809,13 @@ void sqlite3Insert(
|
|||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
if( IsVirtual(pTab) ){
|
if( IsVirtual(pTab) ){
|
||||||
int iReg = sqlite3StackToReg(pParse, pTab->nCol+2);
|
|
||||||
pParse->pVirtualLock = pTab;
|
pParse->pVirtualLock = pTab;
|
||||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, iReg,
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, iReg,
|
||||||
(const char*)pTab->pVtab, P4_VTAB);
|
(const char*)pTab->pVtab, P4_VTAB);
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
sqlite3RegToStack(pParse, iReg, pTab->nCol+1);
|
||||||
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
|
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
|
||||||
0, onError, endOfLoop);
|
0, onError, endOfLoop);
|
||||||
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
|
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
|
||||||
@ -1557,7 +1571,7 @@ static int xferOptimization(
|
|||||||
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);
|
||||||
sqlite3VdbeJumpHere(v, addr2);
|
sqlite3VdbeJumpHere(v, addr2);
|
||||||
autoIncStep(pParse, counterMem);
|
autoIncStep(pParse, counterMem, 0);
|
||||||
}else if( pDest->pIndex==0 ){
|
}else if( pDest->pIndex==0 ){
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
|
||||||
}else{
|
}else{
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.637 2008/01/04 13:24:29 danielk1977 Exp $
|
** @(#) $Id: sqliteInt.h,v 1.638 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@ -1919,6 +1919,7 @@ char *sqlite3StrAccumFinish(StrAccum*);
|
|||||||
void sqlite3StrAccumReset(StrAccum*);
|
void sqlite3StrAccumReset(StrAccum*);
|
||||||
void sqlite3CodeInsert(Parse *, int, u8);
|
void sqlite3CodeInsert(Parse *, int, u8);
|
||||||
int sqlite3StackToReg(Parse *, int);
|
int sqlite3StackToReg(Parse *, int);
|
||||||
|
void sqlite3RegToStack(Parse *, int, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The interface to the LEMON-generated parser
|
** The interface to the LEMON-generated parser
|
||||||
|
26
src/update.c
26
src/update.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 UPDATE statements.
|
** to handle UPDATE statements.
|
||||||
**
|
**
|
||||||
** $Id: update.c,v 1.156 2008/01/04 13:57:26 danielk1977 Exp $
|
** $Id: update.c,v 1.157 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -592,7 +592,9 @@ static void updateVirtualTable(
|
|||||||
int ephemTab; /* Table holding the result of the SELECT */
|
int ephemTab; /* Table holding the result of the SELECT */
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
int addr; /* Address of top of loop */
|
int addr; /* Address of top of loop */
|
||||||
|
int iReg; /* First register in set passed to OP_VUpdate */
|
||||||
sqlite3 *db = pParse->db; /* Database connection */
|
sqlite3 *db = pParse->db; /* Database connection */
|
||||||
|
const char *pVtab = (const char*)pTab->pVtab;
|
||||||
SelectDest dest = {SRT_Table, 0, 0};
|
SelectDest dest = {SRT_Table, 0, 0};
|
||||||
|
|
||||||
/* Construct the SELECT statement that will find the new values for
|
/* Construct the SELECT statement that will find the new values for
|
||||||
@ -627,26 +629,18 @@ static void updateVirtualTable(
|
|||||||
dest.iParm = ephemTab;
|
dest.iParm = ephemTab;
|
||||||
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
|
||||||
|
|
||||||
/*
|
/* Generate code to scan the ephemeral table and call VUpdate. */
|
||||||
** Generate code to scan the ephemeral table and call VDelete and
|
iReg = ++pParse->nMem;
|
||||||
** VInsert
|
pParse->nMem += pTab->nCol+1;
|
||||||
*/
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, 0);
|
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
|
||||||
if( pRowid ){
|
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, 1);
|
|
||||||
}else{
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
|
||||||
}
|
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, i+1+(pRowid!=0));
|
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
|
||||||
}
|
}
|
||||||
pParse->pVirtualLock = pTab;
|
pParse->pVirtualLock = pTab;
|
||||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2,
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVtab, P4_VTAB);
|
||||||
sqlite3StackToReg(pParse, pTab->nCol+2),
|
|
||||||
(const char*)pTab->pVtab, P4_VTAB
|
|
||||||
);
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr);
|
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr);
|
||||||
sqlite3VdbeJumpHere(v, addr-1);
|
sqlite3VdbeJumpHere(v, addr-1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
||||||
|
52
src/vdbe.c
52
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.677 2008/01/04 16:50:09 drh Exp $
|
** $Id: vdbe.c,v 1.678 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -591,6 +591,7 @@ int sqlite3VdbeExec(
|
|||||||
if( sqlite3VdbeOpcodeHasProperty(pOp->opcode, OPFLG_PUSH) ){
|
if( sqlite3VdbeOpcodeHasProperty(pOp->opcode, OPFLG_PUSH) ){
|
||||||
pStackLimit++;
|
pStackLimit++;
|
||||||
}
|
}
|
||||||
|
assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch( pOp->opcode ){
|
switch( pOp->opcode ){
|
||||||
@ -1526,7 +1527,7 @@ case OP_ForceInt: { /* no-push, jump */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Opcode: MustBeInt P1 P2 *
|
/* Opcode: MustBeInt P1 P2 P3
|
||||||
**
|
**
|
||||||
** Force the top of the stack to be an integer. If the top of the
|
** Force the top of the stack to be an integer. If the top of the
|
||||||
** stack is not an integer and cannot be converted into an integer
|
** stack is not an integer and cannot be converted into an integer
|
||||||
@ -1536,21 +1537,26 @@ case OP_ForceInt: { /* no-push, jump */
|
|||||||
** If the top of the stack is not an integer and P2 is not zero and
|
** If the top of the stack is not an integer and P2 is not zero and
|
||||||
** P1 is 1, then the stack is popped. In all other cases, the depth
|
** P1 is 1, then the stack is popped. In all other cases, the depth
|
||||||
** of the stack is unchanged.
|
** of the stack is unchanged.
|
||||||
|
**
|
||||||
|
** If P3 is not zero, then act on the value in register P3 instead
|
||||||
|
** of using the stack.
|
||||||
*/
|
*/
|
||||||
case OP_MustBeInt: { /* no-push, jump */
|
case OP_MustBeInt: { /* no-push, jump */
|
||||||
assert( pTos>=p->aStack );
|
Mem *pMem = ((pOp->p3==0)?pTos:&p->aMem[pOp->p3]);
|
||||||
applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
|
assert( pOp->p3 || pTos>=p->aStack );
|
||||||
if( (pTos->flags & MEM_Int)==0 ){
|
assert( pOp->p3>=0 && pOp->p3<=p->nMem );
|
||||||
|
applyAffinity(pMem, SQLITE_AFF_NUMERIC, encoding);
|
||||||
|
if( (pMem->flags & MEM_Int)==0 ){
|
||||||
if( pOp->p2==0 ){
|
if( pOp->p2==0 ){
|
||||||
rc = SQLITE_MISMATCH;
|
rc = SQLITE_MISMATCH;
|
||||||
goto abort_due_to_error;
|
goto abort_due_to_error;
|
||||||
}else{
|
}else if( pMem==pTos ){
|
||||||
if( pOp->p1 ) popStack(&pTos, 1);
|
if( pOp->p1 ) popStack(&pTos, 1);
|
||||||
pc = pOp->p2 - 1;
|
pc = pOp->p2 - 1;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
Release(pTos);
|
Release(pMem);
|
||||||
pTos->flags = MEM_Int;
|
pMem->flags = MEM_Int;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3438,12 +3444,12 @@ case OP_Sequence: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opcode: NewRowid P1 P2 *
|
/* Opcode: NewRowid P1 P2 P3
|
||||||
**
|
**
|
||||||
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
|
** 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
|
** 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
|
** table that cursor P1 points to. The new record number is pushed
|
||||||
** onto the stack.
|
** onto the stack if P3 is 0 or written to memory cell P3 otherwise.
|
||||||
**
|
**
|
||||||
** If P2>0 then P2 is a memory cell that holds the largest previously
|
** If P2>0 then P2 is a memory cell that holds the largest previously
|
||||||
** generated record number. No new record numbers are allowed to be less
|
** generated record number. No new record numbers are allowed to be less
|
||||||
@ -3587,9 +3593,13 @@ case OP_NewRowid: {
|
|||||||
pC->deferredMoveto = 0;
|
pC->deferredMoveto = 0;
|
||||||
pC->cacheStatus = CACHE_STALE;
|
pC->cacheStatus = CACHE_STALE;
|
||||||
}
|
}
|
||||||
pTos++;
|
if( pOp->p3 ){
|
||||||
pTos->u.i = v;
|
sqlite3VdbeMemSetInt64(&p->aMem[pOp->p3], v);
|
||||||
pTos->flags = MEM_Int;
|
}else{
|
||||||
|
pTos++;
|
||||||
|
pTos->u.i = v;
|
||||||
|
pTos->flags = MEM_Int;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4662,10 +4672,11 @@ case OP_MemLoad: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||||
/* Opcode: MemMax P1 * *
|
/* Opcode: MemMax P1 P2 *
|
||||||
**
|
**
|
||||||
** Set the value of memory cell P1 to the maximum of its current value
|
** Set the value of memory cell P1 to the maximum of its current value
|
||||||
** and the value on the top of the stack. The stack is unchanged.
|
** and the value in cell P2, or the value on the top of the stack if P2
|
||||||
|
** is zero. The stack is unchanged in either case.
|
||||||
**
|
**
|
||||||
** This instruction throws an error if the memory cell is not initially
|
** This instruction throws an error if the memory cell is not initially
|
||||||
** an integer.
|
** an integer.
|
||||||
@ -4673,13 +4684,14 @@ case OP_MemLoad: {
|
|||||||
case OP_MemMax: { /* no-push */
|
case OP_MemMax: { /* no-push */
|
||||||
int i = pOp->p1;
|
int i = pOp->p1;
|
||||||
Mem *pMem;
|
Mem *pMem;
|
||||||
assert( pTos>=p->aStack );
|
Mem *pNew = (pOp->p2?(&p->aMem[pOp->p2]):pTos);
|
||||||
|
assert( pOp->p2 || pTos>=p->aStack );
|
||||||
assert( i>0 && i<=p->nMem );
|
assert( i>0 && i<=p->nMem );
|
||||||
pMem = &p->aMem[i];
|
pMem = &p->aMem[i];
|
||||||
sqlite3VdbeMemIntegerify(pMem);
|
sqlite3VdbeMemIntegerify(pMem);
|
||||||
sqlite3VdbeMemIntegerify(pTos);
|
sqlite3VdbeMemIntegerify(pNew);
|
||||||
if( pMem->u.i<pTos->u.i){
|
if( pMem->u.i<pNew->u.i){
|
||||||
pMem->u.i = pTos->u.i;
|
pMem->u.i = pNew->u.i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -5352,7 +5364,7 @@ default: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the stack limit was not exceeded */
|
/* Make sure the stack limit was not exceeded */
|
||||||
assert( pTos<=pStackLimit );
|
assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit );
|
||||||
|
|
||||||
#ifdef VDBE_PROFILE
|
#ifdef VDBE_PROFILE
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is testing the AUTOINCREMENT features.
|
# focus of this script is testing the AUTOINCREMENT features.
|
||||||
#
|
#
|
||||||
# $Id: autoinc.test,v 1.10 2007/10/09 08:29:32 danielk1977 Exp $
|
# $Id: autoinc.test,v 1.11 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -240,6 +240,8 @@ ifcapable tempdb {
|
|||||||
do_test autoinc-2.52 {
|
do_test autoinc-2.52 {
|
||||||
execsql {
|
execsql {
|
||||||
CREATE TEMP TABLE t2 AS SELECT y FROM t1;
|
CREATE TEMP TABLE t2 AS SELECT y FROM t1;
|
||||||
|
}
|
||||||
|
execsql {
|
||||||
INSERT INTO t1 SELECT NULL, y+4 FROM t2;
|
INSERT INTO t1 SELECT NULL, y+4 FROM t2;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# testing the SQLite library
|
||||||
#
|
#
|
||||||
# $Id: tester.tcl,v 1.94 2007/10/23 14:49:59 drh Exp $
|
# $Id: tester.tcl,v 1.95 2008/01/04 19:10:29 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set tcl_precision 15
|
set tcl_precision 15
|
||||||
@ -238,10 +238,12 @@ proc catchsql {sql {db db}} {
|
|||||||
#
|
#
|
||||||
proc explain {sql {db db}} {
|
proc explain {sql {db db}} {
|
||||||
puts ""
|
puts ""
|
||||||
puts "addr opcode p1 p2 p3 "
|
puts "addr opcode p1 p2 p3 p4 p5 #"
|
||||||
puts "---- ------------ ------ ------ ---------------"
|
puts "---- ------------ ------ ------ ------ --------------- -- -"
|
||||||
$db eval "explain $sql" {} {
|
$db eval "explain $sql" {} {
|
||||||
puts [format {%-4d %-12.12s %-6d %-6d %s} $addr $opcode $p1 $p2 $p3]
|
puts [format {%-4d %-12.12s %-6d %-6d %-6d % -17s %s %s} \
|
||||||
|
$addr $opcode $p1 $p2 $p3 $p4 $p5 $comment
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user