Remove the P3 and label arguments from the internal sqliteVdbeAddOp()
function. This makes the code easier to read and perhaps smaller as well. (CVS 286) FossilOrigin-Name: 288ef1247b94c6c933451d120cdc78e471efc14e
This commit is contained in:
parent
81a20f21d5
commit
99fcd718e1
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\san\sassertion\sfailure\swhen\sthe\sdisk\sfills\sup.\s\sAdd\stests\sfor\sa\sfull\ndisk\ssituation.\s(CVS\s285)
|
C Remove\sthe\sP3\sand\slabel\sarguments\sfrom\sthe\sinternal\ssqliteVdbeAddOp()\nfunction.\s\sThis\smakes\sthe\scode\seasier\sto\sread\sand\sperhaps\ssmaller\sas\nwell.\s(CVS\s286)
|
||||||
D 2001-10-12T17:30:04
|
D 2001-10-13T01:06:48
|
||||||
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
||||||
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
|
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
|
||||||
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
||||||
@ -21,12 +21,12 @@ F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
|||||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||||
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
|
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
|
||||||
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
||||||
F src/build.c cb3607c86f20dd3c18dccbe21f1b9bcd33ef9a36
|
F src/build.c 191f9ec9dd53d7b7767e6fe36d84c524eca9b731
|
||||||
F src/delete.c 93c9d5e160395020a25d59371625db74c97c7c4d
|
F src/delete.c bed54503368e0976aa2e8487d8914e7b7fb63aae
|
||||||
F src/expr.c 2f68829d983ec3f92eeb8b89ce4b9e5704169a80
|
F src/expr.c 5aa5db4d426e71b7a51edcef5d75969bc377d8f6
|
||||||
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
||||||
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
||||||
F src/insert.c a48ba850461b203fb8dbc7add83fc6b6a9cf47f3
|
F src/insert.c ae283e85a301bb3cd6af955f62bde1ca4ba4b56d
|
||||||
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
|
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
|
||||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||||
F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
|
F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
|
||||||
@ -36,7 +36,7 @@ F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
|||||||
F src/parse.y 2275a832b544e8b57c422880a0d9badd4976d042
|
F src/parse.y 2275a832b544e8b57c422880a0d9badd4976d042
|
||||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||||
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
||||||
F src/select.c 0ef8ca1b7de2467fe082bcb35a5ab3b5be56153c
|
F src/select.c ff4dc2271bb6de7a94f22e651be4d29b4f24ff3f
|
||||||
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
|
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
||||||
@ -47,11 +47,11 @@ F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
|||||||
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
||||||
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
||||||
F src/tokenize.c 15d349b68d9dc5722956bd7549752ace62034787
|
F src/tokenize.c 15d349b68d9dc5722956bd7549752ace62034787
|
||||||
F src/update.c 49a1edb1a3e44dfff3f799e00f2a3319f2393cd8
|
F src/update.c 0b287faf0cc1d2bfa437f8a54061dd12ae6df91d
|
||||||
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
||||||
F src/vdbe.c 594050d9a8dc51b97320c52d4665de313b842c27
|
F src/vdbe.c e26521af3d0f12426bd8567f4236d6b61eed2a00
|
||||||
F src/vdbe.h adecb0f37d2c1aa34f2cbd359b63b8c922e72c1f
|
F src/vdbe.h 21e4aede55ccc9d81c88cae4772310c6debbe6df
|
||||||
F src/where.c b676765ad0360769173b09f46265ddec8d48367a
|
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
|
||||||
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
|
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
|
||||||
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
||||||
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
||||||
@ -114,7 +114,7 @@ F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
|
|||||||
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
||||||
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
||||||
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
||||||
P 44d00a6f58c71ca11423df12530177baaa054a01
|
P 0a7848b6190981cb7eb673bbe68cb217694daf2e
|
||||||
R 8b125f0466bafcf592b4cb611703e2d3
|
R d882e44ee7d8a71c7c53e113bfd46069
|
||||||
U drh
|
U drh
|
||||||
Z c3df09919ca8934d0890578a526b0048
|
Z dbd2803044813be5011e55726d60bdc8
|
||||||
|
@ -1 +1 @@
|
|||||||
0a7848b6190981cb7eb673bbe68cb217694daf2e
|
288ef1247b94c6c933451d120cdc78e471efc14e
|
223
src/build.c
223
src/build.c
@ -25,7 +25,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.47 2001/10/12 17:30:05 drh Exp $
|
** $Id: build.c,v 1.48 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -421,12 +421,13 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
|
|||||||
pParse->pNewTable = pTable;
|
pParse->pNewTable = pTable;
|
||||||
if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
|
if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( !isTemp ){
|
if( !isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0);
|
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
|
||||||
|
sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -605,25 +606,28 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1;
|
n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1;
|
||||||
if( !p->isTemp ){
|
if( !p->isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "table", 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0);
|
sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, 0, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, -1);
|
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
|
||||||
p->tnum = 0;
|
p->tnum = 0;
|
||||||
if( !p->isTemp ){
|
if( !p->isTemp ){
|
||||||
addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n);
|
sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n);
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||||
changeCookie(db);
|
changeCookie(db);
|
||||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,22 +691,22 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
|||||||
};
|
};
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( !pTable->isTemp ){
|
if( !pTable->isTemp ){
|
||||||
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
||||||
sqliteVdbeChangeP3(v, base+2, pTable->zName, 0);
|
sqliteVdbeChangeP3(v, base+2, pTable->zName, P3_STATIC);
|
||||||
changeCookie(db);
|
changeCookie(db);
|
||||||
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->isTemp, 0, 0);
|
sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->isTemp);
|
||||||
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp, 0, 0);
|
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp);
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,66 +920,72 @@ void sqliteCreateIndex(
|
|||||||
if( v==0 ) goto exit_create_index;
|
if( v==0 ) goto exit_create_index;
|
||||||
if( pTable!=0 ){
|
if( pTable!=0 ){
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( !isTemp ){
|
if( !isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0);
|
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
|
||||||
|
sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !isTemp ){
|
if( !isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "index", 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pIndex->zName, 0);
|
sqliteVdbeChangeP3(v, -1, "index", P3_STATIC);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->zName, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pIndex->zName, P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp);
|
||||||
sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, -1);
|
sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER);
|
||||||
pIndex->tnum = 0;
|
pIndex->tnum = 0;
|
||||||
if( pTable ){
|
if( pTable ){
|
||||||
if( isTemp ){
|
if( isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_OpenWrAux, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenWrAux, 1, 0);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !isTemp ){
|
if( !isTemp ){
|
||||||
addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
if( pStart && pEnd ){
|
if( pStart && pEnd ){
|
||||||
n = (int)pEnd->z - (int)pStart->z + 1;
|
n = (int)pEnd->z - (int)pStart->z + 1;
|
||||||
sqliteVdbeChangeP3(v, addr, pStart->z, n);
|
sqliteVdbeChangeP3(v, addr, pStart->z, n);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||||
}
|
}
|
||||||
if( pTable ){
|
if( pTable ){
|
||||||
sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open,
|
sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open, 2, pTab->tnum);
|
||||||
2, pTab->tnum, pTab->zName, 0);
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
lbl1 = sqliteVdbeMakeLabel(v);
|
lbl1 = sqliteVdbeMakeLabel(v);
|
||||||
lbl2 = sqliteVdbeMakeLabel(v);
|
lbl2 = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, 2, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, 2, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Next, 2, lbl2, 0, lbl1);
|
sqliteVdbeResolveLabel(v, lbl1);
|
||||||
sqliteVdbeAddOp(v, OP_Recno, 2, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Next, 2, lbl2);
|
||||||
|
sqliteVdbeAddOp(v, OP_Recno, 2, 0);
|
||||||
for(i=0; i<pIndex->nColumn; i++){
|
for(i=0; i<pIndex->nColumn; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Column, 2, pIndex->aiColumn[i], 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, 2, pIndex->aiColumn[i]);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutIdx, 1, pIndex->isUnique, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIdx, 1, pIndex->isUnique);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, lbl1, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, lbl1);
|
||||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, lbl2);
|
sqliteVdbeResolveLabel(v, lbl2);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 2, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, 2, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_Close, 1, 0);
|
||||||
}
|
}
|
||||||
if( pTable!=0 ){
|
if( pTable!=0 ){
|
||||||
if( !isTemp ){
|
if( !isTemp ){
|
||||||
changeCookie(db);
|
changeCookie(db);
|
||||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1028,19 +1038,19 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
|
|||||||
Table *pTab = pIndex->pTable;
|
Table *pTab = pIndex->pTable;
|
||||||
|
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( !pTab->isTemp ){
|
if( !pTab->isTemp ){
|
||||||
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
||||||
sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0);
|
sqliteVdbeChangeP3(v, base+2, pIndex->zName, P3_STATIC);
|
||||||
changeCookie(db);
|
changeCookie(db);
|
||||||
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pTab->isTemp, 0, 0);
|
sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pTab->isTemp);
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1205,49 +1215,52 @@ void sqliteCopy(
|
|||||||
if( v ){
|
if( v ){
|
||||||
int openOp;
|
int openOp;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
|
sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
|
||||||
sqliteVdbeDequoteP3(v, addr);
|
sqliteVdbeDequoteP3(v, addr);
|
||||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||||
sqliteVdbeAddOp(v, openOp, 0, pTab->tnum, pTab->zName, 0);
|
sqliteVdbeAddOp(v, openOp, 0, pTab->tnum);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
sqliteVdbeAddOp(v, openOp, i, pIdx->tnum, pIdx->zName, 0);
|
sqliteVdbeAddOp(v, openOp, i, pIdx->tnum);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
end = sqliteVdbeMakeLabel(v);
|
end = sqliteVdbeMakeLabel(v);
|
||||||
addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
|
||||||
if( pDelimiter ){
|
if( pDelimiter ){
|
||||||
sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
|
sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
|
||||||
sqliteVdbeDequoteP3(v, addr);
|
sqliteVdbeDequoteP3(v, addr);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeChangeP3(v, addr, "\t", 1);
|
sqliteVdbeChangeP3(v, addr, "\t", 1);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||||
if( pTab->pIndex ){
|
if( pTab->pIndex ){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
sqliteVdbeAddOp(v, OP_FileColumn, i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_FileColumn, i, 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
if( pIdx->pNext ){
|
if( pIdx->pNext ){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
sqliteVdbeAddOp(v, OP_FileColumn, pIdx->aiColumn[j], 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_FileColumn, pIdx->aiColumn[j], 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutIdx, i, pIdx->isUnique, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIdx, i, pIdx->isUnique);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
|
sqliteVdbeResolveLabel(v, end);
|
||||||
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,26 +1293,29 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) goto vacuum_cleanup;
|
if( v==0 ) goto vacuum_cleanup;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( zName ){
|
if( zName ){
|
||||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||||
}else{
|
}else{
|
||||||
Table *pTab;
|
Table *pTab;
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
HashElem *pE;
|
HashElem *pE;
|
||||||
for(pE=sqliteHashFirst(&db->tblHash); pE; pE=sqliteHashNext(pE)){
|
for(pE=sqliteHashFirst(&db->tblHash); pE; pE=sqliteHashNext(pE)){
|
||||||
pTab = sqliteHashData(pE);
|
pTab = sqliteHashData(pE);
|
||||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pTab->zName, 0);
|
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pIdx->zName, 0);
|
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vacuum_cleanup:
|
vacuum_cleanup:
|
||||||
@ -1319,8 +1335,8 @@ void sqliteBeginTransaction(Parse *pParse){
|
|||||||
if( db->flags & SQLITE_InTrans ) return;
|
if( db->flags & SQLITE_InTrans ) return;
|
||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
db->flags |= SQLITE_InTrans;
|
db->flags |= SQLITE_InTrans;
|
||||||
@ -1338,7 +1354,7 @@ void sqliteCommitTransaction(Parse *pParse){
|
|||||||
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
db->flags &= ~SQLITE_InTrans;
|
db->flags &= ~SQLITE_InTrans;
|
||||||
}
|
}
|
||||||
@ -1355,7 +1371,7 @@ void sqliteRollbackTransaction(Parse *pParse){
|
|||||||
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v ){
|
if( v ){
|
||||||
sqliteVdbeAddOp(v, OP_Rollback, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
|
||||||
}
|
}
|
||||||
db->flags &= ~SQLITE_InTrans;
|
db->flags &= ~SQLITE_InTrans;
|
||||||
}
|
}
|
||||||
@ -1440,13 +1456,16 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
|||||||
int i;
|
int i;
|
||||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0,
|
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zName, P3_STATIC);
|
||||||
pTab->aCol[i].zType ? pTab->aCol[i].zType : "text", 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0, 0, 0);
|
sqliteVdbeChangeP3(v, -1,
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[i].zDflt, 0);
|
pTab->aCol[i].zType ? pTab->aCol[i].zType : "text", P3_STATIC);
|
||||||
sqliteVdbeAddOp(v, OP_Callback, 5, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zDflt, P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_Callback, 5, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@ -1468,11 +1487,12 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
|||||||
pTab = pIdx->pTable;
|
pTab = pIdx->pTable;
|
||||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
int cnum = pIdx->aiColumn[i];
|
||||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->aiColumn[i], 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0,
|
sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
|
||||||
pTab->aCol[pIdx->aiColumn[i]].zName, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0, 0, 0);
|
sqliteVdbeChangeP3(v, -1, pTab->aCol[cnum].zName, P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@ -1497,10 +1517,11 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
|||||||
|
|
||||||
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||||
while(pIdx){
|
while(pIdx){
|
||||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pIdx->zName, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->isUnique, 0, 0, 0);
|
sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
|
||||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, pIdx->isUnique, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||||
++i;
|
++i;
|
||||||
pIdx = pIdx->pNext;
|
pIdx = pIdx->pNext;
|
||||||
}
|
}
|
||||||
|
41
src/delete.c
41
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
|
||||||
** to handle DELETE FROM statements.
|
** to handle DELETE FROM statements.
|
||||||
**
|
**
|
||||||
** $Id: delete.c,v 1.16 2001/10/08 13:22:32 drh Exp $
|
** $Id: delete.c,v 1.17 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -81,8 +81,8 @@ void sqliteDeleteFrom(
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) goto delete_from_cleanup;
|
if( v==0 ) goto delete_from_cleanup;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,9 +91,9 @@ void sqliteDeleteFrom(
|
|||||||
** It is easier just to erase the whole table.
|
** It is easier just to erase the whole table.
|
||||||
*/
|
*/
|
||||||
if( pWhere==0 ){
|
if( pWhere==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->isTemp, 0, 0);
|
sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->isTemp);
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pTab->isTemp, 0, 0);
|
sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pTab->isTemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,13 +105,13 @@ void sqliteDeleteFrom(
|
|||||||
|
|
||||||
/* Begin the database scan
|
/* Begin the database scan
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
|
||||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
||||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||||
|
|
||||||
/* Remember the key of every item to be deleted.
|
/* Remember the key of every item to be deleted.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
*/
|
*/
|
||||||
@ -122,32 +122,33 @@ void sqliteDeleteFrom(
|
|||||||
** because deleting an item can change the scan order.
|
** because deleting an item can change the scan order.
|
||||||
*/
|
*/
|
||||||
base = pParse->nTab;
|
base = pParse->nTab;
|
||||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||||
sqliteVdbeAddOp(v, openOp, base, pTab->tnum, 0, 0);
|
sqliteVdbeAddOp(v, openOp, base, pTab->tnum);
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
sqliteVdbeAddOp(v, openOp, base+i, pIdx->tnum, 0, 0);
|
sqliteVdbeAddOp(v, openOp, base+i, pIdx->tnum);
|
||||||
}
|
}
|
||||||
end = sqliteVdbeMakeLabel(v);
|
end = sqliteVdbeMakeLabel(v);
|
||||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||||
if( pTab->pIndex ){
|
if( pTab->pIndex ){
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
int j;
|
int j;
|
||||||
sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j], 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j]);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Delete, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Delete, base, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 0, 0, end);
|
sqliteVdbeResolveLabel(v, end);
|
||||||
|
sqliteVdbeAddOp(v, OP_ListClose, 0, 0);
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
118
src/expr.c
118
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.29 2001/10/06 16:33:03 drh Exp $
|
** $Id: expr.c,v 1.30 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
|
|||||||
** table. The cursor number of the temporary table has already
|
** table. The cursor number of the temporary table has already
|
||||||
** been put in iTable by sqliteExprResolveInSelect().
|
** been put in iTable by sqliteExprResolveInSelect().
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 0);
|
||||||
if( sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable) );
|
if( sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable) );
|
||||||
}else if( pExpr->pList ){
|
}else if( pExpr->pList ){
|
||||||
/* Case 2: expr IN (exprlist)
|
/* Case 2: expr IN (exprlist)
|
||||||
@ -262,14 +262,14 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
|
|||||||
case TK_FLOAT:
|
case TK_FLOAT:
|
||||||
case TK_INTEGER:
|
case TK_INTEGER:
|
||||||
case TK_STRING: {
|
case TK_STRING: {
|
||||||
int addr = sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0);
|
int addr = sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, pE2->token.z, pE2->token.n);
|
sqliteVdbeChangeP3(v, addr, pE2->token.z, pE2->token.n);
|
||||||
sqliteVdbeDequoteP3(v, addr);
|
sqliteVdbeDequoteP3(v, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqliteExprCode(pParse, pE2);
|
sqliteExprCode(pParse, pE2);
|
||||||
sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -501,32 +501,32 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
switch( pExpr->op ){
|
switch( pExpr->op ){
|
||||||
case TK_COLUMN: {
|
case TK_COLUMN: {
|
||||||
if( pParse->useAgg ){
|
if( pParse->useAgg ){
|
||||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
|
||||||
}else if( pExpr->iColumn>=0 ){
|
}else if( pExpr->iColumn>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn, 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_INTEGER: {
|
case TK_INTEGER: {
|
||||||
int i = atoi(pExpr->token.z);
|
int i = atoi(pExpr->token.z);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_FLOAT: {
|
case TK_FLOAT: {
|
||||||
int addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
int addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
|
sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_STRING: {
|
case TK_STRING: {
|
||||||
int addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
int addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
|
sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n);
|
||||||
sqliteVdbeDequoteP3(v, addr);
|
sqliteVdbeDequoteP3(v, addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_NULL: {
|
case TK_NULL: {
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_AND:
|
case TK_AND:
|
||||||
@ -537,13 +537,13 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
case TK_SLASH: {
|
case TK_SLASH: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_CONCAT: {
|
case TK_CONCAT: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
sqliteVdbeAddOp(v, OP_Concat, 2, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Concat, 2, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_LT:
|
case TK_LT:
|
||||||
@ -555,25 +555,26 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
case TK_LIKE:
|
case TK_LIKE:
|
||||||
case TK_GLOB: {
|
case TK_GLOB: {
|
||||||
int dest;
|
int dest;
|
||||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
dest = sqliteVdbeCurrentAddr(v) + 2;
|
dest = sqliteVdbeCurrentAddr(v) + 2;
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_UMINUS: {
|
case TK_UMINUS: {
|
||||||
assert( pExpr->pLeft );
|
assert( pExpr->pLeft );
|
||||||
if( pExpr->pLeft->op==TK_INTEGER ){
|
if( pExpr->pLeft->op==TK_INTEGER ){
|
||||||
int i = atoi(pExpr->pLeft->token.z);
|
int i = atoi(pExpr->pLeft->token.z);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, -i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, -i, 0);
|
||||||
break;
|
break;
|
||||||
}else if( pExpr->pLeft->op==TK_FLOAT ){
|
}else if( pExpr->pLeft->op==TK_FLOAT ){
|
||||||
Token *p = &pExpr->pLeft->token;
|
Token *p = &pExpr->pLeft->token;
|
||||||
char *z = sqliteMalloc( p->n + 2 );
|
char *z = sqliteMalloc( p->n + 2 );
|
||||||
sprintf(z, "-%.*s", p->n, p->z);
|
sprintf(z, "-%.*s", p->n, p->z);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, z, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, z, p->n+1);
|
||||||
sqliteFree(z);
|
sqliteFree(z);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -581,25 +582,25 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
}
|
}
|
||||||
case TK_NOT: {
|
case TK_NOT: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_ISNULL:
|
case TK_ISNULL:
|
||||||
case TK_NOTNULL: {
|
case TK_NOTNULL: {
|
||||||
int dest;
|
int dest;
|
||||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
dest = sqliteVdbeCurrentAddr(v) + 2;
|
dest = sqliteVdbeCurrentAddr(v) + 2;
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_AGG_FUNCTION: {
|
case TK_AGG_FUNCTION: {
|
||||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
|
||||||
if( pExpr->iColumn==FN_Avg ){
|
if( pExpr->iColumn==FN_Avg ){
|
||||||
assert( pParse->iAggCount>=0 && pParse->iAggCount<pParse->nAgg );
|
assert( pParse->iAggCount>=0 && pParse->iAggCount<pParse->nAgg );
|
||||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount);
|
||||||
sqliteVdbeAddOp(v, OP_Divide, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Divide, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -610,7 +611,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
ExprList *pList = pExpr->pList;
|
ExprList *pList = pExpr->pList;
|
||||||
switch( id ){
|
switch( id ){
|
||||||
case FN_Fcnt: {
|
case FN_Fcnt: {
|
||||||
sqliteVdbeAddOp(v, OP_Fcnt, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Fcnt, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN_Min:
|
case FN_Min:
|
||||||
@ -619,21 +620,21 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
for(i=0; i<pList->nExpr; i++){
|
for(i=0; i<pList->nExpr; i++){
|
||||||
sqliteExprCode(pParse, pList->a[i].pExpr);
|
sqliteExprCode(pParse, pList->a[i].pExpr);
|
||||||
if( i>0 ){
|
if( i>0 ){
|
||||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN_Length: {
|
case FN_Length: {
|
||||||
sqliteExprCode(pParse, pList->a[0].pExpr);
|
sqliteExprCode(pParse, pList->a[0].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_Strlen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Strlen, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FN_Substr: {
|
case FN_Substr: {
|
||||||
for(i=0; i<pList->nExpr; i++){
|
for(i=0; i<pList->nExpr; i++){
|
||||||
sqliteExprCode(pParse, pList->a[i].pExpr);
|
sqliteExprCode(pParse, pList->a[i].pExpr);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Substr, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Substr, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -644,27 +645,27 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_SELECT: {
|
case TK_SELECT: {
|
||||||
sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_IN: {
|
case TK_IN: {
|
||||||
int addr;
|
int addr;
|
||||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
addr = sqliteVdbeCurrentAddr(v);
|
addr = sqliteVdbeCurrentAddr(v);
|
||||||
if( pExpr->pSelect ){
|
if( pExpr->pSelect ){
|
||||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+2, 0, 0);
|
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+2);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+2, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+2);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_BETWEEN: {
|
case TK_BETWEEN: {
|
||||||
int lbl = sqliteVdbeMakeLabel(v);
|
int lbl = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||||
sqliteExprIfFalse(pParse, pExpr, lbl);
|
sqliteExprIfFalse(pParse, pExpr, lbl);
|
||||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||||
sqliteVdbeResolveLabel(v, lbl);
|
sqliteVdbeResolveLabel(v, lbl);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -721,39 +722,40 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
|
|||||||
case TK_GLOB: {
|
case TK_GLOB: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_ISNULL:
|
case TK_ISNULL:
|
||||||
case TK_NOTNULL: {
|
case TK_NOTNULL: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_IN: {
|
case TK_IN: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
if( pExpr->pSelect ){
|
if( pExpr->pSelect ){
|
||||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_BETWEEN: {
|
case TK_BETWEEN: {
|
||||||
int lbl = sqliteVdbeMakeLabel(v);
|
int lbl = sqliteVdbeMakeLabel(v);
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
|
sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_Lt, 0, lbl, 0, 0);
|
sqliteVdbeAddOp(v, OP_Lt, 0, lbl);
|
||||||
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_Le, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_Le, 0, dest);
|
||||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0, 0, lbl);
|
sqliteVdbeResolveLabel(v, lbl);
|
||||||
|
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqliteExprCode(pParse, pExpr);
|
sqliteExprCode(pParse, pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_If, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,48 +808,48 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
|
|||||||
case TK_EQ: {
|
case TK_EQ: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_LIKE:
|
case TK_LIKE:
|
||||||
case TK_GLOB: {
|
case TK_GLOB: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteExprCode(pParse, pExpr->pRight);
|
sqliteExprCode(pParse, pExpr->pRight);
|
||||||
sqliteVdbeAddOp(v, op, 1, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 1, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_ISNULL:
|
case TK_ISNULL:
|
||||||
case TK_NOTNULL: {
|
case TK_NOTNULL: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_IN: {
|
case TK_IN: {
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
if( pExpr->pSelect ){
|
if( pExpr->pSelect ){
|
||||||
sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_BETWEEN: {
|
case TK_BETWEEN: {
|
||||||
int addr;
|
int addr;
|
||||||
sqliteExprCode(pParse, pExpr->pLeft);
|
sqliteExprCode(pParse, pExpr->pLeft);
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
|
sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
|
||||||
addr = sqliteVdbeCurrentAddr(v);
|
addr = sqliteVdbeCurrentAddr(v);
|
||||||
sqliteVdbeAddOp(v, OP_Ge, 0, addr+3, 0, 0);
|
sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, dest);
|
||||||
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_Gt, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_Gt, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sqliteExprCode(pParse, pExpr);
|
sqliteExprCode(pParse, pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_Not, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Not, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
|
sqliteVdbeAddOp(v, OP_If, 0, dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
src/insert.c
49
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.22 2001/10/08 13:22:33 drh Exp $
|
** $Id: insert.c,v 1.23 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ void sqliteInsert(
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) goto insert_cleanup;
|
if( v==0 ) goto insert_cleanup;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ void sqliteInsert(
|
|||||||
if( pSelect ){
|
if( pSelect ){
|
||||||
int rc;
|
int rc;
|
||||||
srcTab = pParse->nTab++;
|
srcTab = pParse->nTab++;
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
|
||||||
rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
|
rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
|
||||||
if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
|
if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
|
||||||
assert( pSelect->pEList );
|
assert( pSelect->pEList );
|
||||||
@ -157,9 +157,11 @@ void sqliteInsert(
|
|||||||
*/
|
*/
|
||||||
base = pParse->nTab;
|
base = pParse->nTab;
|
||||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||||
sqliteVdbeAddOp(v, openOp, base, pTab->tnum, pTab->zName, 0);
|
sqliteVdbeAddOp(v, openOp, base, pTab->tnum);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||||
sqliteVdbeAddOp(v, openOp, idx+base, pIdx->tnum, pIdx->zName, 0);
|
sqliteVdbeAddOp(v, openOp, idx+base, pIdx->tnum);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the data source is a SELECT statement, then we have to create
|
/* If the data source is a SELECT statement, then we have to create
|
||||||
@ -168,16 +170,16 @@ void sqliteInsert(
|
|||||||
** and the loop is not used.
|
** and the loop is not used.
|
||||||
*/
|
*/
|
||||||
if( srcTab>=0 ){
|
if( srcTab>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0);
|
||||||
iBreak = sqliteVdbeMakeLabel(v);
|
iBreak = sqliteVdbeMakeLabel(v);
|
||||||
iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0);
|
iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new entry in the table and fill it with data.
|
/* Create a new entry in the table and fill it with data.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
|
||||||
if( pTab->pIndex ){
|
if( pTab->pIndex ){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
if( pColumn==0 ){
|
if( pColumn==0 ){
|
||||||
@ -188,22 +190,23 @@ void sqliteInsert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pColumn && j>=pColumn->nId ){
|
if( pColumn && j>=pColumn->nId ){
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[i].zDflt, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zDflt, P3_STATIC);
|
||||||
}else if( srcTab>=0 ){
|
}else if( srcTab>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Column, srcTab, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, srcTab, i);
|
||||||
}else{
|
}else{
|
||||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||||
|
|
||||||
/* Create appropriate entries for the new data row in all indices
|
/* Create appropriate entries for the new data row in all indices
|
||||||
** of the table.
|
** of the table.
|
||||||
*/
|
*/
|
||||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||||
if( pIdx->pNext ){
|
if( pIdx->pNext ){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
int idx = pIdx->aiColumn[i];
|
int idx = pIdx->aiColumn[i];
|
||||||
@ -215,25 +218,27 @@ void sqliteInsert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pColumn && j>=pColumn->nId ){
|
if( pColumn && j>=pColumn->nId ){
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[idx].zDflt, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->aCol[idx].zDflt, P3_STATIC);
|
||||||
}else if( srcTab>=0 ){
|
}else if( srcTab>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Column, srcTab, idx, 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, srcTab, idx);
|
||||||
}else{
|
}else{
|
||||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, pIdx->isUnique, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, pIdx->isUnique);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The bottom of the loop, if the data source is a SELECT statement
|
/* The bottom of the loop, if the data source is a SELECT statement
|
||||||
*/
|
*/
|
||||||
if( srcTab>=0 ){
|
if( srcTab>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak);
|
sqliteVdbeResolveLabel(v, iBreak);
|
||||||
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||||
}
|
}
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
163
src/select.c
163
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.38 2001/10/06 16:33:03 drh Exp $
|
** $Id: select.c,v 1.39 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ static int selectInnerLoop(
|
|||||||
nColumn = pEList->nExpr;
|
nColumn = pEList->nExpr;
|
||||||
}else{
|
}else{
|
||||||
for(i=0; i<nColumn; i++){
|
for(i=0; i<nColumn; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Column, srcTab, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, srcTab, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,12 +120,14 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( distinct>=0 ){
|
if( distinct>=0 ){
|
||||||
int lbl = sqliteVdbeMakeLabel(v);
|
int lbl = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
|
||||||
sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl, 0, 0);
|
sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl);
|
||||||
sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", lbl);
|
sqliteVdbeResolveLabel(v, lbl);
|
||||||
sqliteVdbeAddOp(v, OP_Put, distinct, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_Put, distinct, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is an ORDER BY clause, then store the results
|
/* If there is an ORDER BY clause, then store the results
|
||||||
@ -133,7 +135,7 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
char *zSortOrder;
|
char *zSortOrder;
|
||||||
sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
|
||||||
zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
|
zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
|
||||||
if( zSortOrder==0 ) return 1;
|
if( zSortOrder==0 ) return 1;
|
||||||
for(i=0; i<pOrderBy->nExpr; i++){
|
for(i=0; i<pOrderBy->nExpr; i++){
|
||||||
@ -141,27 +143,29 @@ static int selectInnerLoop(
|
|||||||
sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
|
sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
|
||||||
}
|
}
|
||||||
zSortOrder[pOrderBy->nExpr] = 0;
|
zSortOrder[pOrderBy->nExpr] = 0;
|
||||||
sqliteVdbeAddOp(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, 0);
|
sqliteVdbeAddOp(v, OP_SortMakeKey, pOrderBy->nExpr, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zSortOrder, strlen(zSortOrder));
|
||||||
sqliteFree(zSortOrder);
|
sqliteFree(zSortOrder);
|
||||||
sqliteVdbeAddOp(v, OP_SortPut, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/* In this mode, write each query result to the key of the temporary
|
/* In this mode, write each query result to the key of the temporary
|
||||||
** table iParm.
|
** table iParm.
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Union ){
|
if( eDest==SRT_Union ){
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, iParm, 0, "", 0);
|
sqliteVdbeAddOp(v, OP_String, iParm, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/* Store the result as data using a unique key.
|
/* Store the result as data using a unique key.
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Table ){
|
if( eDest==SRT_Table ){
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Pull, 1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/* Construct a record from the query result, but instead of
|
/* Construct a record from the query result, but instead of
|
||||||
@ -169,9 +173,9 @@ static int selectInnerLoop(
|
|||||||
** the temporary table iParm.
|
** the temporary table iParm.
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Except ){
|
if( eDest==SRT_Except ){
|
||||||
int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3, 0, 0);
|
sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3);
|
||||||
sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Delete, iParm, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
|
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
|
||||||
@ -180,8 +184,9 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( eDest==SRT_Set ){
|
if( eDest==SRT_Set ){
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||||
|
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
|
||||||
@ -191,14 +196,14 @@ static int selectInnerLoop(
|
|||||||
*/
|
*/
|
||||||
if( eDest==SRT_Mem ){
|
if( eDest==SRT_Mem ){
|
||||||
assert( nColumn==1 );
|
assert( nColumn==1 );
|
||||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iBreak, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iBreak);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
/* If none of the above, send the data to the callback function.
|
/* If none of the above, send the data to the callback function.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
sqliteVdbeAddOp(v, OP_Callback, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -212,11 +217,12 @@ static int selectInnerLoop(
|
|||||||
static void generateSortTail(Vdbe *v, int nColumn){
|
static void generateSortTail(Vdbe *v, int nColumn){
|
||||||
int end = sqliteVdbeMakeLabel(v);
|
int end = sqliteVdbeMakeLabel(v);
|
||||||
int addr;
|
int addr;
|
||||||
sqliteVdbeAddOp(v, OP_Sort, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
||||||
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
|
||||||
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqliteVdbeAddOp(v, OP_SortClose, 0, 0, 0, end);
|
sqliteVdbeResolveLabel(v, end);
|
||||||
|
sqliteVdbeAddOp(v, OP_SortClose, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -230,25 +236,26 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
|||||||
int i;
|
int i;
|
||||||
if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
|
if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
|
||||||
pParse->colNamesSet = 1;
|
pParse->colNamesSet = 1;
|
||||||
sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0);
|
||||||
for(i=0; i<pEList->nExpr; i++){
|
for(i=0; i<pEList->nExpr; i++){
|
||||||
Expr *p;
|
Expr *p;
|
||||||
int addr;
|
|
||||||
if( pEList->a[i].zName ){
|
if( pEList->a[i].zName ){
|
||||||
char *zName = pEList->a[i].zName;
|
char *zName = pEList->a[i].zName;
|
||||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p = pEList->a[i].pExpr;
|
p = pEList->a[i].pExpr;
|
||||||
if( p==0 ) continue;
|
if( p==0 ) continue;
|
||||||
if( p->span.z && p->span.z[0] ){
|
if( p->span.z && p->span.z[0] ){
|
||||||
addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0, 0, 0);
|
int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, p->span.z, p->span.n);
|
sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
|
||||||
sqliteVdbeCompressSpace(v, addr);
|
sqliteVdbeCompressSpace(v, addr);
|
||||||
}else if( p->op!=TK_COLUMN || pTabList==0 ){
|
}else if( p->op!=TK_COLUMN || pTabList==0 ){
|
||||||
char zName[30];
|
char zName[30];
|
||||||
sprintf(zName, "column%d", i+1);
|
sprintf(zName, "column%d", i+1);
|
||||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||||
}else{
|
}else{
|
||||||
if( pTabList->nId>1 || (pParse->db->flags & SQLITE_FullColNames)!=0 ){
|
if( pTabList->nId>1 || (pParse->db->flags & SQLITE_FullColNames)!=0 ){
|
||||||
char *zName = 0;
|
char *zName = 0;
|
||||||
@ -258,12 +265,14 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
|||||||
zTab = pTabList->a[p->iTable].zAlias;
|
zTab = pTabList->a[p->iTable].zAlias;
|
||||||
if( zTab==0 ) zTab = pTab->zName;
|
if( zTab==0 ) zTab = pTab->zName;
|
||||||
sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iColumn].zName, 0);
|
sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iColumn].zName, 0);
|
||||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||||
sqliteFree(zName);
|
sqliteFree(zName);
|
||||||
}else{
|
}else{
|
||||||
Table *pTab = pTabList->a[0].pTab;
|
Table *pTab = pTabList->a[0].pTab;
|
||||||
char *zName = pTab->aCol[p->iColumn].zName;
|
char *zName = pTab->aCol[p->iColumn].zName;
|
||||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_ColumnName, i, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,10 +513,10 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if( p->op!=TK_ALL ){
|
if( p->op!=TK_ALL ){
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
|
||||||
sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1, 0, 0);
|
sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,17 +545,18 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
assert( p->pEList );
|
assert( p->pEList );
|
||||||
generateColumnNames(pParse, 0, p->pEList);
|
generateColumnNames(pParse, 0, p->pEList);
|
||||||
if( p->pOrderBy ){
|
if( p->pOrderBy ){
|
||||||
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0);
|
||||||
iBreak = sqliteVdbeMakeLabel(v);
|
iBreak = sqliteVdbeMakeLabel(v);
|
||||||
iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
|
iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak);
|
||||||
rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
|
||||||
p->pOrderBy, -1, eDest, iParm,
|
p->pOrderBy, -1, eDest, iParm,
|
||||||
iCont, iBreak);
|
iCont, iBreak);
|
||||||
if( rc ) return 1;
|
if( rc ) return 1;
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||||
sqliteVdbeAddOp(v, OP_Close, unionTab, 0, 0, iBreak);
|
sqliteVdbeResolveLabel(v, iBreak);
|
||||||
|
sqliteVdbeAddOp(v, OP_Close, unionTab, 0);
|
||||||
if( p->pOrderBy ){
|
if( p->pOrderBy ){
|
||||||
generateSortTail(v, p->pEList->nExpr);
|
generateSortTail(v, p->pEList->nExpr);
|
||||||
}
|
}
|
||||||
@ -566,8 +576,8 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
|
if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1, 0, 0);
|
sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1);
|
||||||
|
|
||||||
/* Code the SELECTs to our left into temporary table "tab1".
|
/* Code the SELECTs to our left into temporary table "tab1".
|
||||||
*/
|
*/
|
||||||
@ -576,8 +586,8 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
|
|
||||||
/* Code the current SELECT into temporary table "tab2"
|
/* Code the current SELECT into temporary table "tab2"
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 0);
|
||||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1, 0, 0);
|
sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1);
|
||||||
p->pPrior = 0;
|
p->pPrior = 0;
|
||||||
rc = sqliteSelect(pParse, p, SRT_Union, tab2);
|
rc = sqliteSelect(pParse, p, SRT_Union, tab2);
|
||||||
p->pPrior = pPrior;
|
p->pPrior = pPrior;
|
||||||
@ -589,20 +599,21 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
|||||||
assert( p->pEList );
|
assert( p->pEList );
|
||||||
generateColumnNames(pParse, 0, p->pEList);
|
generateColumnNames(pParse, 0, p->pEList);
|
||||||
if( p->pOrderBy ){
|
if( p->pOrderBy ){
|
||||||
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, tab1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, tab1, 0);
|
||||||
iBreak = sqliteVdbeMakeLabel(v);
|
iBreak = sqliteVdbeMakeLabel(v);
|
||||||
iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
|
iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak);
|
||||||
sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
|
||||||
sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
|
sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
|
||||||
rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
|
rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
|
||||||
p->pOrderBy, -1, eDest, iParm,
|
p->pOrderBy, -1, eDest, iParm,
|
||||||
iCont, iBreak);
|
iCont, iBreak);
|
||||||
if( rc ) return 1;
|
if( rc ) return 1;
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||||
sqliteVdbeAddOp(v, OP_Close, tab2, 0, 0, iBreak);
|
sqliteVdbeResolveLabel(v, iBreak);
|
||||||
sqliteVdbeAddOp(v, OP_Close, tab1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, tab2, 0);
|
||||||
|
sqliteVdbeAddOp(v, OP_Close, tab1, 0);
|
||||||
if( p->pOrderBy ){
|
if( p->pOrderBy ){
|
||||||
generateSortTail(v, p->pEList->nExpr);
|
generateSortTail(v, p->pEList->nExpr);
|
||||||
}
|
}
|
||||||
@ -842,7 +853,7 @@ int sqliteSelect(
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) return 1;
|
if( v==0 ) return 1;
|
||||||
if( pOrderBy ){
|
if( pOrderBy ){
|
||||||
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Identify column names if we will be using in the callback. This
|
/* Identify column names if we will be using in the callback. This
|
||||||
@ -855,20 +866,20 @@ int sqliteSelect(
|
|||||||
/* Reset the aggregator
|
/* Reset the aggregator
|
||||||
*/
|
*/
|
||||||
if( isAgg ){
|
if( isAgg ){
|
||||||
sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the memory cell to NULL
|
/* Initialize the memory cell to NULL
|
||||||
*/
|
*/
|
||||||
if( eDest==SRT_Mem ){
|
if( eDest==SRT_Mem ){
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Begin the database scan
|
/* Begin the database scan
|
||||||
*/
|
*/
|
||||||
if( isDistinct ){
|
if( isDistinct ){
|
||||||
sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 0);
|
||||||
}
|
}
|
||||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
|
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
|
||||||
if( pWInfo==0 ) return 1;
|
if( pWInfo==0 ) return 1;
|
||||||
@ -892,7 +903,7 @@ int sqliteSelect(
|
|||||||
for(i=0; i<pGroupBy->nExpr; i++){
|
for(i=0; i<pGroupBy->nExpr; i++){
|
||||||
sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
|
sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
|
||||||
doFocus = 1;
|
doFocus = 1;
|
||||||
}else{
|
}else{
|
||||||
doFocus = 0;
|
doFocus = 0;
|
||||||
@ -903,16 +914,17 @@ int sqliteSelect(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( doFocus ){
|
if( doFocus ){
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
|
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( doFocus ){
|
if( doFocus ){
|
||||||
int lbl1 = sqliteVdbeMakeLabel(v);
|
int lbl1 = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
|
||||||
for(i=0; i<pParse->nAgg; i++){
|
for(i=0; i<pParse->nAgg; i++){
|
||||||
if( pParse->aAgg[i].isAgg ) continue;
|
if( pParse->aAgg[i].isAgg ) continue;
|
||||||
sqliteExprCode(pParse, pParse->aAgg[i].pExpr);
|
sqliteExprCode(pParse, pParse->aAgg[i].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggSet, 0, i);
|
||||||
}
|
}
|
||||||
sqliteVdbeResolveLabel(v, lbl1);
|
sqliteVdbeResolveLabel(v, lbl1);
|
||||||
}
|
}
|
||||||
@ -922,21 +934,21 @@ int sqliteSelect(
|
|||||||
if( !pParse->aAgg[i].isAgg ) continue;
|
if( !pParse->aAgg[i].isAgg ) continue;
|
||||||
pE = pParse->aAgg[i].pExpr;
|
pE = pParse->aAgg[i].pExpr;
|
||||||
if( pE==0 ){
|
if( pE==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_AggIncr, 1, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggIncr, 1, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert( pE->op==TK_AGG_FUNCTION );
|
assert( pE->op==TK_AGG_FUNCTION );
|
||||||
assert( pE->pList!=0 && pE->pList->nExpr==1 );
|
assert( pE->pList!=0 && pE->pList->nExpr==1 );
|
||||||
sqliteExprCode(pParse, pE->pList->a[0].pExpr);
|
sqliteExprCode(pParse, pE->pList->a[0].pExpr);
|
||||||
sqliteVdbeAddOp(v, OP_AggGet, 0, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggGet, 0, i);
|
||||||
switch( pE->iColumn ){
|
switch( pE->iColumn ){
|
||||||
case FN_Min: op = OP_Min; break;
|
case FN_Min: op = OP_Min; break;
|
||||||
case FN_Max: op = OP_Max; break;
|
case FN_Max: op = OP_Max; break;
|
||||||
case FN_Avg: op = OP_Add; break;
|
case FN_Avg: op = OP_Add; break;
|
||||||
case FN_Sum: op = OP_Add; break;
|
case FN_Sum: op = OP_Add; break;
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, op, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_AggSet, 0, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,7 +963,7 @@ int sqliteSelect(
|
|||||||
if( isAgg ){
|
if( isAgg ){
|
||||||
int endagg = sqliteVdbeMakeLabel(v);
|
int endagg = sqliteVdbeMakeLabel(v);
|
||||||
int startagg;
|
int startagg;
|
||||||
startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg, 0, 0);
|
startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg);
|
||||||
pParse->useAgg = 1;
|
pParse->useAgg = 1;
|
||||||
if( pHaving ){
|
if( pHaving ){
|
||||||
sqliteExprIfFalse(pParse, pHaving, startagg);
|
sqliteExprIfFalse(pParse, pHaving, startagg);
|
||||||
@ -960,8 +972,9 @@ int sqliteSelect(
|
|||||||
startagg, endagg) ){
|
startagg, endagg) ){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, startagg, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, startagg);
|
||||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, endagg);
|
sqliteVdbeResolveLabel(v, endagg);
|
||||||
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||||
pParse->useAgg = 0;
|
pParse->useAgg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
src/update.c
51
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.17 2001/10/08 13:22:33 drh Exp $
|
** $Id: update.c,v 1.18 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -136,20 +136,20 @@ void sqliteUpdate(
|
|||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) goto update_cleanup;
|
if( v==0 ) goto update_cleanup;
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Begin the database scan
|
/* Begin the database scan
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
|
||||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
||||||
if( pWInfo==0 ) goto update_cleanup;
|
if( pWInfo==0 ) goto update_cleanup;
|
||||||
|
|
||||||
/* Remember the index of every item to be updated.
|
/* Remember the index of every item to be updated.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
|
||||||
|
|
||||||
/* End the database scan loop.
|
/* End the database scan loop.
|
||||||
*/
|
*/
|
||||||
@ -158,12 +158,12 @@ void sqliteUpdate(
|
|||||||
/* Rewind the list of records that need to be updated and
|
/* Rewind the list of records that need to be updated and
|
||||||
** open every index that needs updating.
|
** open every index that needs updating.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||||
base = pParse->nTab;
|
base = pParse->nTab;
|
||||||
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||||
sqliteVdbeAddOp(v, openOp, base, pTab->tnum, 0, 0);
|
sqliteVdbeAddOp(v, openOp, base, pTab->tnum);
|
||||||
for(i=0; i<nIdx; i++){
|
for(i=0; i<nIdx; i++){
|
||||||
sqliteVdbeAddOp(v, openOp, base+i+1, apIdx[i]->tnum, 0, 0);
|
sqliteVdbeAddOp(v, openOp, base+i+1, apIdx[i]->tnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop over every record that needs updating. We have to load
|
/* Loop over every record that needs updating. We have to load
|
||||||
@ -172,20 +172,20 @@ void sqliteUpdate(
|
|||||||
** Also, the old data is needed to delete the old index entires.
|
** Also, the old data is needed to delete the old index entires.
|
||||||
*/
|
*/
|
||||||
end = sqliteVdbeMakeLabel(v);
|
end = sqliteVdbeMakeLabel(v);
|
||||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||||
|
|
||||||
/* Delete the old indices for the current record.
|
/* Delete the old indices for the current record.
|
||||||
*/
|
*/
|
||||||
for(i=0; i<nIdx; i++){
|
for(i=0; i<nIdx; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||||
pIdx = apIdx[i];
|
pIdx = apIdx[i];
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j], 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j]);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i+1, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i+1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute a completely new data for this record.
|
/* Compute a completely new data for this record.
|
||||||
@ -193,7 +193,7 @@ void sqliteUpdate(
|
|||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pTab->nCol; i++){
|
||||||
j = aXRef[i];
|
j = aXRef[i];
|
||||||
if( j<0 ){
|
if( j<0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Column, base, i, 0, 0);
|
sqliteVdbeAddOp(v, OP_Column, base, i);
|
||||||
}else{
|
}else{
|
||||||
sqliteExprCode(pParse, pChanges->a[j].pExpr);
|
sqliteExprCode(pParse, pChanges->a[j].pExpr);
|
||||||
}
|
}
|
||||||
@ -202,27 +202,28 @@ void sqliteUpdate(
|
|||||||
/* Insert new index entries that correspond to the new data
|
/* Insert new index entries that correspond to the new data
|
||||||
*/
|
*/
|
||||||
for(i=0; i<nIdx; i++){
|
for(i=0; i<nIdx; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, pTab->nCol, 0, 0, 0); /* The KEY */
|
sqliteVdbeAddOp(v, OP_Dup, pTab->nCol, 0); /* The KEY */
|
||||||
pIdx = apIdx[i];
|
pIdx = apIdx[i];
|
||||||
for(j=0; j<pIdx->nColumn; j++){
|
for(j=0; j<pIdx->nColumn; j++){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiColumn[j], 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Dup, j+pTab->nCol-pIdx->aiColumn[j], 0);
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutIdx, base+i+1, pIdx->isUnique, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIdx, base+i+1, pIdx->isUnique);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the new data back into the database.
|
/* Write the new data back into the database.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||||
|
|
||||||
/* Repeat the above with the next record to be updated, until
|
/* Repeat the above with the next record to be updated, until
|
||||||
** all record selected by the WHERE clause have been updated.
|
** all record selected by the WHERE clause have been updated.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 0, 0, end);
|
sqliteVdbeResolveLabel(v, end);
|
||||||
|
sqliteVdbeAddOp(v, OP_ListClose, 0, 0);
|
||||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_cleanup:
|
update_cleanup:
|
||||||
|
98
src/vdbe.c
98
src/vdbe.c
@ -30,7 +30,7 @@
|
|||||||
** But other routines are also provided to help in building up
|
** But other routines are also provided to help in building up
|
||||||
** a program instruction by instruction.
|
** a program instruction by instruction.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.82 2001/10/09 04:19:47 drh Exp $
|
** $Id: vdbe.c,v 1.83 2001/10/13 01:06:48 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -233,24 +233,20 @@ void sqliteVdbeTrace(Vdbe *p, FILE *trace){
|
|||||||
**
|
**
|
||||||
** op The opcode for this instruction
|
** op The opcode for this instruction
|
||||||
**
|
**
|
||||||
** p1, p2, p3 Three operands.
|
** p1, p2 First two of the three possible operands.
|
||||||
**
|
**
|
||||||
** lbl A symbolic label for this instruction.
|
** Use the sqliteVdbeResolveLabel() function to fix an address and
|
||||||
**
|
** the sqliteVdbeChangeP3() function to change the value of the P3
|
||||||
** Symbolic labels are negative numbers that stand for the address
|
** operand.
|
||||||
** of instructions that have yet to be coded. When the instruction
|
|
||||||
** is coded, its real address is substituted in the p2 field of
|
|
||||||
** prior and subsequent instructions that have the lbl value in
|
|
||||||
** their p2 fields.
|
|
||||||
*/
|
*/
|
||||||
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2, const char *p3, int lbl){
|
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
i = p->nOp;
|
i = p->nOp;
|
||||||
p->nOp++;
|
p->nOp++;
|
||||||
if( i>=p->nOpAlloc ){
|
if( i>=p->nOpAlloc ){
|
||||||
int oldSize = p->nOpAlloc;
|
int oldSize = p->nOpAlloc;
|
||||||
p->nOpAlloc = p->nOpAlloc*2 + 10;
|
p->nOpAlloc = p->nOpAlloc*2 + 100;
|
||||||
p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
p->aOp = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
|
||||||
if( p->aOp==0 ){
|
if( p->aOp==0 ){
|
||||||
p->nOp = 0;
|
p->nOp = 0;
|
||||||
@ -265,18 +261,8 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2, const char *p3, int lbl){
|
|||||||
p2 = p->aLabel[-1-p2];
|
p2 = p->aLabel[-1-p2];
|
||||||
}
|
}
|
||||||
p->aOp[i].p2 = p2;
|
p->aOp[i].p2 = p2;
|
||||||
if( p3 && p3[0] ){
|
p->aOp[i].p3 = 0;
|
||||||
p->aOp[i].p3 = sqliteStrDup(p3);
|
p->aOp[i].p3type = P3_NOTUSED;
|
||||||
p->aOp[i].p3dyn = 1;
|
|
||||||
}else{
|
|
||||||
p->aOp[i].p3 = 0;
|
|
||||||
}
|
|
||||||
if( lbl<0 && (-lbl)<=p->nLabel ){
|
|
||||||
p->aLabel[-1-lbl] = i;
|
|
||||||
for(j=0; j<i; j++){
|
|
||||||
if( p->aOp[j].p2==lbl ) p->aOp[j].p2 = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,9 +309,11 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
|
|||||||
int i;
|
int i;
|
||||||
for(i=0; i<nOp; i++){
|
for(i=0; i<nOp; i++){
|
||||||
int p2 = aOp[i].p2;
|
int p2 = aOp[i].p2;
|
||||||
if( p2<0 ) p2 = addr + ADDR(p2);
|
p->aOp[i+addr] = aOp[i];
|
||||||
sqliteVdbeAddOp(p, aOp[i].opcode, aOp[i].p1, p2, aOp[i].p3, 0);
|
if( p2<0 ) p->aOp[i+addr].p2 = addr + ADDR(p2);
|
||||||
|
p->aOp[i+addr].p3type = aOp[i].p3 ? P3_STATIC : P3_NOTUSED;
|
||||||
}
|
}
|
||||||
|
p->nOp += nOp;
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
@ -353,22 +341,33 @@ void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
|
|||||||
** A value of n==0 means copy bytes of zP3 up to and including the
|
** A value of n==0 means copy bytes of zP3 up to and including the
|
||||||
** first null byte. If n>0 then copy n+1 bytes of zP3.
|
** first null byte. If n>0 then copy n+1 bytes of zP3.
|
||||||
**
|
**
|
||||||
** If n<0 then zP3 is assumed to be a pointer to a static string.
|
** If n==P3_STATIC it means that zP3 is a pointer to a constant static
|
||||||
** P3 is made to point directly to this string without any copying.
|
** string we can just copy the pointer. n==P3_POINTER means zP3 is
|
||||||
|
** a pointer to some object other than a string.
|
||||||
|
**
|
||||||
|
** If addr<0 then change P3 on the most recently inserted instruction.
|
||||||
*/
|
*/
|
||||||
void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
|
void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
|
||||||
if( p && addr>=0 && p->nOp>addr && zP3 ){
|
Op *pOp;
|
||||||
Op *pOp = &p->aOp[addr];
|
if( p==0 ) return;
|
||||||
if( pOp->p3 && pOp->p3dyn ){
|
if( addr<0 || addr>=p->nOp ){
|
||||||
sqliteFree(pOp->p3);
|
addr = p->nOp - 1;
|
||||||
}
|
if( addr<0 ) return;
|
||||||
if( n<0 ){
|
}
|
||||||
pOp->p3 = zP3;
|
pOp = &p->aOp[addr];
|
||||||
pOp->p3dyn = 0;
|
if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
|
||||||
}else{
|
sqliteFree(pOp->p3);
|
||||||
sqliteSetNString(&p->aOp[addr].p3, zP3, n, 0);
|
pOp->p3 = 0;
|
||||||
pOp->p3dyn = 1;
|
}
|
||||||
}
|
if( zP3==0 ){
|
||||||
|
pOp->p3 = 0;
|
||||||
|
pOp->p3type = P3_NOTUSED;
|
||||||
|
}else if( n<0 ){
|
||||||
|
pOp->p3 = zP3;
|
||||||
|
pOp->p3type = n;
|
||||||
|
}else{
|
||||||
|
sqliteSetNString(&pOp->p3, zP3, n, 0);
|
||||||
|
pOp->p3type = P3_DYNAMIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,11 +385,12 @@ void sqliteVdbeDequoteP3(Vdbe *p, int addr){
|
|||||||
if( addr<0 || addr>=p->nOp ) return;
|
if( addr<0 || addr>=p->nOp ) return;
|
||||||
pOp = &p->aOp[addr];
|
pOp = &p->aOp[addr];
|
||||||
if( pOp->p3==0 || pOp->p3[0]==0 ) return;
|
if( pOp->p3==0 || pOp->p3[0]==0 ) return;
|
||||||
if( !pOp->p3dyn ){
|
if( pOp->p3type==P3_POINTER ) return;
|
||||||
|
if( pOp->p3type!=P3_DYNAMIC ){
|
||||||
pOp->p3 = sqliteStrDup(pOp->p3);
|
pOp->p3 = sqliteStrDup(pOp->p3);
|
||||||
pOp->p3dyn = 1;
|
pOp->p3type = P3_DYNAMIC;
|
||||||
}
|
}
|
||||||
if( pOp->p3 ) sqliteDequote(pOp->p3);
|
sqliteDequote(pOp->p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -404,9 +404,11 @@ void sqliteVdbeCompressSpace(Vdbe *p, int addr){
|
|||||||
Op *pOp;
|
Op *pOp;
|
||||||
if( addr<0 || addr>=p->nOp ) return;
|
if( addr<0 || addr>=p->nOp ) return;
|
||||||
pOp = &p->aOp[addr];
|
pOp = &p->aOp[addr];
|
||||||
if( !pOp->p3dyn ){
|
if( pOp->p3type!=P3_DYNAMIC ){
|
||||||
pOp->p3 = sqliteStrDup(pOp->p3);
|
pOp->p3 = sqliteStrDup(pOp->p3);
|
||||||
pOp->p3dyn = 1;
|
pOp->p3type = P3_DYNAMIC;
|
||||||
|
}else if( pOp->p3type!=P3_STATIC ){
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
z = pOp->p3;
|
z = pOp->p3;
|
||||||
if( z==0 ) return;
|
if( z==0 ) return;
|
||||||
@ -770,7 +772,7 @@ void sqliteVdbeDelete(Vdbe *p){
|
|||||||
p->nOp = 0;
|
p->nOp = 0;
|
||||||
}
|
}
|
||||||
for(i=0; i<p->nOp; i++){
|
for(i=0; i<p->nOp; i++){
|
||||||
if( p->aOp[i].p3dyn ){
|
if( p->aOp[i].p3type==P3_DYNAMIC ){
|
||||||
sqliteFree(p->aOp[i].p3);
|
sqliteFree(p->aOp[i].p3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -873,7 +875,7 @@ int sqliteVdbeList(
|
|||||||
sprintf(zAddr,"%d",i);
|
sprintf(zAddr,"%d",i);
|
||||||
sprintf(zP1,"%d", p->aOp[i].p1);
|
sprintf(zP1,"%d", p->aOp[i].p1);
|
||||||
sprintf(zP2,"%d", p->aOp[i].p2);
|
sprintf(zP2,"%d", p->aOp[i].p2);
|
||||||
azValue[4] = p->aOp[i].p3;
|
azValue[4] = p->aOp[i].p3type!=P3_POINTER ? p->aOp[i].p3 : "";
|
||||||
azValue[1] = zOpName[p->aOp[i].opcode];
|
azValue[1] = zOpName[p->aOp[i].opcode];
|
||||||
if( xCallback(pArg, 5, azValue, azColumnNames) ){
|
if( xCallback(pArg, 5, azValue, azColumnNames) ){
|
||||||
rc = SQLITE_ABORT;
|
rc = SQLITE_ABORT;
|
||||||
@ -2871,7 +2873,7 @@ case OP_CreateTable: {
|
|||||||
int i = ++p->tos;
|
int i = ++p->tos;
|
||||||
int pgno;
|
int pgno;
|
||||||
VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
|
VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
|
||||||
assert( pOp->p3!=0 && pOp->p3dyn==0 );
|
assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
|
||||||
rc = sqliteBtreeCreateTable(pOp->p2 ? db->pBeTemp : pBt, &pgno);
|
rc = sqliteBtreeCreateTable(pOp->p2 ? db->pBeTemp : pBt, &pgno);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
aStack[i].i = pgno;
|
aStack[i].i = pgno;
|
||||||
|
14
src/vdbe.h
14
src/vdbe.h
@ -15,7 +15,7 @@
|
|||||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||||
** simple program to access and modify the underlying database.
|
** simple program to access and modify the underlying database.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.h,v 1.27 2001/10/12 17:30:05 drh Exp $
|
** $Id: vdbe.h,v 1.28 2001/10/13 01:06:49 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITE_VDBE_H_
|
#ifndef _SQLITE_VDBE_H_
|
||||||
#define _SQLITE_VDBE_H_
|
#define _SQLITE_VDBE_H_
|
||||||
@ -38,10 +38,18 @@ struct VdbeOp {
|
|||||||
int p1; /* First operand */
|
int p1; /* First operand */
|
||||||
int p2; /* Second parameter (often the jump destination) */
|
int p2; /* Second parameter (often the jump destination) */
|
||||||
char *p3; /* Third parameter */
|
char *p3; /* Third parameter */
|
||||||
int p3dyn; /* True if p3 is malloced. False if it is static */
|
int p3type; /* P3_STATIC, P3_DYNAMIC or P3_POINTER */
|
||||||
};
|
};
|
||||||
typedef struct VdbeOp VdbeOp;
|
typedef struct VdbeOp VdbeOp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Allowed values of VdbeOp.p3type
|
||||||
|
*/
|
||||||
|
#define P3_NOTUSED 0 /* The P3 parameter is not used */
|
||||||
|
#define P3_DYNAMIC 1 /* Pointer to a string obtained from sqliteMalloc() */
|
||||||
|
#define P3_STATIC (-1) /* Pointer to a static string */
|
||||||
|
#define P3_POINTER (-2) /* P3 is a pointer to some structure or object */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The following macro converts a relative address in the p2 field
|
** The following macro converts a relative address in the p2 field
|
||||||
** of a VdbeOp structure into a negative number so that
|
** of a VdbeOp structure into a negative number so that
|
||||||
@ -199,7 +207,7 @@ typedef struct VdbeOp VdbeOp;
|
|||||||
*/
|
*/
|
||||||
Vdbe *sqliteVdbeCreate(sqlite*);
|
Vdbe *sqliteVdbeCreate(sqlite*);
|
||||||
void sqliteVdbeCreateCallback(Vdbe*, int*);
|
void sqliteVdbeCreateCallback(Vdbe*, int*);
|
||||||
int sqliteVdbeAddOp(Vdbe*,int,int,int,const char*,int);
|
int sqliteVdbeAddOp(Vdbe*,int,int,int);
|
||||||
int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOp const *aOp);
|
int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOp const *aOp);
|
||||||
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
|
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
|
||||||
void sqliteVdbeChangeP3(Vdbe*, int addr, char *zP1, int N);
|
void sqliteVdbeChangeP3(Vdbe*, int addr, char *zP1, int N);
|
||||||
|
43
src/where.c
43
src/where.c
@ -13,7 +13,7 @@
|
|||||||
** the WHERE clause of SQL statements. Also found here are subroutines
|
** the WHERE clause of SQL statements. Also found here are subroutines
|
||||||
** to generate VDBE code to evaluate expressions.
|
** to generate VDBE code to evaluate expressions.
|
||||||
**
|
**
|
||||||
** $Id: where.c,v 1.22 2001/10/08 13:22:33 drh Exp $
|
** $Id: where.c,v 1.23 2001/10/13 01:06:49 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@ -290,15 +290,16 @@ WhereInfo *sqliteWhereBegin(
|
|||||||
|
|
||||||
pTab = pTabList->a[i].pTab;
|
pTab = pTabList->a[i].pTab;
|
||||||
openOp = pTab->isTemp ? OP_OpenAux : OP_Open;
|
openOp = pTab->isTemp ? OP_OpenAux : OP_Open;
|
||||||
sqliteVdbeAddOp(v, openOp, base+i, pTab->tnum, pTab->zName, 0);
|
sqliteVdbeAddOp(v, openOp, base+i, pTab->tnum);
|
||||||
|
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||||
if( i==0 && !pParse->schemaVerified &&
|
if( i==0 && !pParse->schemaVerified &&
|
||||||
(pParse->db->flags & SQLITE_InTrans)==0 ){
|
(pParse->db->flags & SQLITE_InTrans)==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);
|
||||||
pParse->schemaVerified = 1;
|
pParse->schemaVerified = 1;
|
||||||
}
|
}
|
||||||
if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){
|
if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){
|
||||||
sqliteVdbeAddOp(v, openOp, base+pTabList->nId+i, aIdx[i]->tnum,
|
sqliteVdbeAddOp(v, openOp, base+pTabList->nId+i, aIdx[i]->tnum);
|
||||||
aIdx[i]->zName, 0);
|
sqliteVdbeChangeP3(v, -1, aIdx[i]->zName, P3_STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(pWInfo->aIdx, aIdx, sizeof(aIdx));
|
memcpy(pWInfo->aIdx, aIdx, sizeof(aIdx));
|
||||||
@ -344,20 +345,21 @@ WhereInfo *sqliteWhereBegin(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_AddImm, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_AddImm, 0, 0);
|
||||||
if( i==pTabList->nId-1 && pushKey ){
|
if( i==pTabList->nId-1 && pushKey ){
|
||||||
haveKey = 1;
|
haveKey = 1;
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_NotFound, base+idx, brk, 0, 0);
|
sqliteVdbeAddOp(v, OP_NotFound, base+idx, brk);
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
}
|
}
|
||||||
}else if( pIdx==0 ){
|
}else if( pIdx==0 ){
|
||||||
/* Case 2: There was no usable index. We must do a complete
|
/* Case 2: There was no usable index. We must do a complete
|
||||||
** scan of the table.
|
** scan of the table.
|
||||||
*/
|
*/
|
||||||
sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0);
|
||||||
cont = sqliteVdbeMakeLabel(v);
|
cont = sqliteVdbeMakeLabel(v);
|
||||||
sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
|
sqliteVdbeResolveLabel(v, cont);
|
||||||
|
sqliteVdbeAddOp(v, OP_Next, base+idx, brk);
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
}else{
|
}else{
|
||||||
/* Case 3: We do have a usable index in pIdx.
|
/* Case 3: We do have a usable index in pIdx.
|
||||||
@ -384,13 +386,14 @@ WhereInfo *sqliteWhereBegin(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0);
|
||||||
sqliteVdbeAddOp(v, OP_BeginIdx, base+pTabList->nId+i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_BeginIdx, base+pTabList->nId+i, 0);
|
||||||
sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk, 0, cont);
|
sqliteVdbeResolveLabel(v, cont);
|
||||||
|
sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk);
|
||||||
if( i==pTabList->nId-1 && pushKey ){
|
if( i==pTabList->nId-1 && pushKey ){
|
||||||
haveKey = 1;
|
haveKey = 1;
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,7 +408,7 @@ WhereInfo *sqliteWhereBegin(
|
|||||||
if( (aExpr[j].prereqLeft & loopMask)!=aExpr[j].prereqLeft ) continue;
|
if( (aExpr[j].prereqLeft & loopMask)!=aExpr[j].prereqLeft ) continue;
|
||||||
if( haveKey ){
|
if( haveKey ){
|
||||||
haveKey = 0;
|
haveKey = 0;
|
||||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||||
}
|
}
|
||||||
sqliteExprIfFalse(pParse, aExpr[j].p, cont);
|
sqliteExprIfFalse(pParse, aExpr[j].p, cont);
|
||||||
aExpr[j].p = 0;
|
aExpr[j].p = 0;
|
||||||
@ -414,7 +417,7 @@ WhereInfo *sqliteWhereBegin(
|
|||||||
}
|
}
|
||||||
pWInfo->iContinue = cont;
|
pWInfo->iContinue = cont;
|
||||||
if( pushKey && !haveKey ){
|
if( pushKey && !haveKey ){
|
||||||
sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||||
}
|
}
|
||||||
sqliteFree(aOrder);
|
sqliteFree(aOrder);
|
||||||
return pWInfo;
|
return pWInfo;
|
||||||
@ -429,16 +432,18 @@ void sqliteWhereEnd(WhereInfo *pWInfo){
|
|||||||
int brk = pWInfo->iBreak;
|
int brk = pWInfo->iBreak;
|
||||||
int base = pWInfo->base;
|
int base = pWInfo->base;
|
||||||
|
|
||||||
sqliteVdbeAddOp(v, OP_Goto, 0, pWInfo->iContinue, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, pWInfo->iContinue);
|
||||||
for(i=0; i<pWInfo->pTabList->nId; i++){
|
for(i=0; i<pWInfo->pTabList->nId; i++){
|
||||||
sqliteVdbeAddOp(v, OP_Close, base+i, 0, 0, brk);
|
sqliteVdbeResolveLabel(v, brk);
|
||||||
|
sqliteVdbeAddOp(v, OP_Close, base+i, 0);
|
||||||
brk = 0;
|
brk = 0;
|
||||||
if( i<ARRAYSIZE(pWInfo->aIdx) && pWInfo->aIdx[i]!=0 ){
|
if( i<ARRAYSIZE(pWInfo->aIdx) && pWInfo->aIdx[i]!=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Close, base+pWInfo->pTabList->nId+i, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, base+pWInfo->pTabList->nId+i, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( brk!=0 ){
|
if( brk!=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, brk);
|
sqliteVdbeResolveLabel(v, brk);
|
||||||
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||||
}
|
}
|
||||||
sqliteFree(pWInfo);
|
sqliteFree(pWInfo);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user