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)
|
||||
D 2001-10-12T17:30:04
|
||||
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-13T01:06:48
|
||||
F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd
|
||||
F Makefile.template 582916b263aa40a70521dfb3d99d574028abd47b
|
||||
F README 93d2977cc5c6595c448de16bdefc312b9d401533
|
||||
@ -21,12 +21,12 @@ F publish.sh badcd69b8e3a8bc69b162c4c9d7c209b2a0b119e
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c 7e9c33a714ed1630562f89ad19847f5f28bd6d4d
|
||||
F src/btree.h 57d653ef5137b91f2a068aaf71a2905468dd2cb7
|
||||
F src/build.c cb3607c86f20dd3c18dccbe21f1b9bcd33ef9a36
|
||||
F src/delete.c 93c9d5e160395020a25d59371625db74c97c7c4d
|
||||
F src/expr.c 2f68829d983ec3f92eeb8b89ce4b9e5704169a80
|
||||
F src/build.c 191f9ec9dd53d7b7767e6fe36d84c524eca9b731
|
||||
F src/delete.c bed54503368e0976aa2e8487d8914e7b7fb63aae
|
||||
F src/expr.c 5aa5db4d426e71b7a51edcef5d75969bc377d8f6
|
||||
F src/hash.c b7ced0735287c142a3b2db46c3cae3e6826afb75
|
||||
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
|
||||
F src/insert.c a48ba850461b203fb8dbc7add83fc6b6a9cf47f3
|
||||
F src/insert.c ae283e85a301bb3cd6af955f62bde1ca4ba4b56d
|
||||
F src/main.c 9a18e97290d41844e8c12e021fb7c42948a19dc9
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/os.c cece4ac6cabc9d377ef0a4ab4c16f6f0f6c84377
|
||||
@ -36,7 +36,7 @@ F src/pager.h a0d4c5ae271914aa07b62aee0707997d6932b6ca
|
||||
F src/parse.y 2275a832b544e8b57c422880a0d9badd4976d042
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b
|
||||
F src/select.c 0ef8ca1b7de2467fe082bcb35a5ab3b5be56153c
|
||||
F src/select.c ff4dc2271bb6de7a94f22e651be4d29b4f24ff3f
|
||||
F src/shell.c cb8c41f1b2173efd212dab3f35f1fc6bf32ead76
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in b95c161abf1d58bceb05290fa3f657d8f388fc11
|
||||
@ -47,11 +47,11 @@ F src/test1.c e4b31f62ea71963cbae44338acf477a04fc8fc49
|
||||
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
|
||||
F src/test3.c 4a0d7b882fdae731dbb759f512ad867122452f96
|
||||
F src/tokenize.c 15d349b68d9dc5722956bd7549752ace62034787
|
||||
F src/update.c 49a1edb1a3e44dfff3f799e00f2a3319f2393cd8
|
||||
F src/update.c 0b287faf0cc1d2bfa437f8a54061dd12ae6df91d
|
||||
F src/util.c 4da3be37d0fd3c640d2d3033503768afdc8e5387
|
||||
F src/vdbe.c 594050d9a8dc51b97320c52d4665de313b842c27
|
||||
F src/vdbe.h adecb0f37d2c1aa34f2cbd359b63b8c922e72c1f
|
||||
F src/where.c b676765ad0360769173b09f46265ddec8d48367a
|
||||
F src/vdbe.c e26521af3d0f12426bd8567f4236d6b61eed2a00
|
||||
F src/vdbe.h 21e4aede55ccc9d81c88cae4772310c6debbe6df
|
||||
F src/where.c 22fe910c7c8e2736eb37e9861343e90c0b513c86
|
||||
F test/all.test a2320eb40b462f25bd3e33115b1cabf3791450dd
|
||||
F test/bigrow.test a35f2de9948b24e427fb292c35947795efe182d0
|
||||
F test/btree.test 47952c7a0c22660566264c68c0664592b7da85ce
|
||||
@ -114,7 +114,7 @@ F www/speed.tcl ab7d6d3bc898472bd94320a5d3c63de928d4804b
|
||||
F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e
|
||||
F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa
|
||||
F www/vdbe.tcl bb7d620995f0a987293e9d4fb6185a3b077e9b44
|
||||
P 44d00a6f58c71ca11423df12530177baaa054a01
|
||||
R 8b125f0466bafcf592b4cb611703e2d3
|
||||
P 0a7848b6190981cb7eb673bbe68cb217694daf2e
|
||||
R d882e44ee7d8a71c7c53e113bfd46069
|
||||
U drh
|
||||
Z c3df09919ca8934d0890578a526b0048
|
||||
Z dbd2803044813be5011e55726d60bdc8
|
||||
|
@ -1 +1 @@
|
||||
0a7848b6190981cb7eb673bbe68cb217694daf2e
|
||||
288ef1247b94c6c933451d120cdc78e471efc14e
|
223
src/build.c
223
src/build.c
@ -25,7 +25,7 @@
|
||||
** ROLLBACK
|
||||
** 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 <ctype.h>
|
||||
@ -421,12 +421,13 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
|
||||
pParse->pNewTable = pTable;
|
||||
if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
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;
|
||||
n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1;
|
||||
if( !p->isTemp ){
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "table", 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
|
||||
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);
|
||||
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, -1);
|
||||
addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, 0);
|
||||
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
|
||||
p->tnum = 0;
|
||||
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);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||
changeCookie(db);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 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;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
if( !pTable->isTemp ){
|
||||
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
||||
sqliteVdbeChangeP3(v, base+2, pTable->zName, 0);
|
||||
sqliteVdbeChangeP3(v, base+2, pTable->zName, P3_STATIC);
|
||||
changeCookie(db);
|
||||
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){
|
||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp);
|
||||
}
|
||||
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( pTable!=0 ){
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "index", 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pIndex->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "index", P3_STATIC);
|
||||
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);
|
||||
sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, -1);
|
||||
addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp);
|
||||
sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER);
|
||||
pIndex->tnum = 0;
|
||||
if( pTable ){
|
||||
if( isTemp ){
|
||||
sqliteVdbeAddOp(v, OP_OpenWrAux, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrAux, 1, 0);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0);
|
||||
}
|
||||
}
|
||||
if( !isTemp ){
|
||||
addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
if( pStart && pEnd ){
|
||||
n = (int)pEnd->z - (int)pStart->z + 1;
|
||||
sqliteVdbeChangeP3(v, addr, pStart->z, n);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||
}
|
||||
if( pTable ){
|
||||
sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open,
|
||||
2, pTab->tnum, pTab->zName, 0);
|
||||
sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open, 2, pTab->tnum);
|
||||
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||
lbl1 = sqliteVdbeMakeLabel(v);
|
||||
lbl2 = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, 2, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Next, 2, lbl2, 0, lbl1);
|
||||
sqliteVdbeAddOp(v, OP_Recno, 2, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, 2, 0);
|
||||
sqliteVdbeResolveLabel(v, lbl1);
|
||||
sqliteVdbeAddOp(v, OP_Next, 2, lbl2);
|
||||
sqliteVdbeAddOp(v, OP_Recno, 2, 0);
|
||||
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_PutIdx, 1, pIndex->isUnique, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, lbl1, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, lbl2);
|
||||
sqliteVdbeAddOp(v, OP_Close, 2, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, 1, pIndex->isUnique);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, lbl1);
|
||||
sqliteVdbeResolveLabel(v, lbl2);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 2, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 1, 0);
|
||||
}
|
||||
if( pTable!=0 ){
|
||||
if( !isTemp ){
|
||||
changeCookie(db);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 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;
|
||||
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
if( !pTab->isTemp ){
|
||||
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
||||
sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0);
|
||||
sqliteVdbeChangeP3(v, base+2, pIndex->zName, P3_STATIC);
|
||||
changeCookie(db);
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1205,49 +1215,52 @@ void sqliteCopy(
|
||||
if( v ){
|
||||
int openOp;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
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);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
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++){
|
||||
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);
|
||||
addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
|
||||
if( pDelimiter ){
|
||||
sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
}else{
|
||||
sqliteVdbeChangeP3(v, addr, "\t", 1);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
if( pTab->pIndex ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
}
|
||||
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_Put, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, 0, 0);
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( pIdx->pNext ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
}
|
||||
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_PutIdx, i, pIdx->isUnique, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, i, pIdx->isUnique);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 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);
|
||||
if( v==0 ) goto vacuum_cleanup;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
if( zName ){
|
||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, zName, strlen(zName));
|
||||
}else{
|
||||
Table *pTab;
|
||||
Index *pIdx;
|
||||
HashElem *pE;
|
||||
for(pE=sqliteHashFirst(&db->tblHash); pE; pE=sqliteHashNext(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){
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
|
||||
vacuum_cleanup:
|
||||
@ -1319,8 +1335,8 @@ void sqliteBeginTransaction(Parse *pParse){
|
||||
if( db->flags & SQLITE_InTrans ) return;
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
db->flags |= SQLITE_InTrans;
|
||||
@ -1338,7 +1354,7 @@ void sqliteCommitTransaction(Parse *pParse){
|
||||
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
db->flags &= ~SQLITE_InTrans;
|
||||
}
|
||||
@ -1355,7 +1371,7 @@ void sqliteRollbackTransaction(Parse *pParse){
|
||||
if( (db->flags & SQLITE_InTrans)==0 ) return;
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteVdbeAddOp(v, OP_Rollback, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
|
||||
}
|
||||
db->flags &= ~SQLITE_InTrans;
|
||||
}
|
||||
@ -1440,13 +1456,16 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
int i;
|
||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0,
|
||||
pTab->aCol[i].zType ? pTab->aCol[i].zType : "text", 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->aCol[i].zDflt, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 5, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, pTab->aCol[i].zName, P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1,
|
||||
pTab->aCol[i].zType ? pTab->aCol[i].zType : "text", P3_STATIC);
|
||||
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
|
||||
@ -1468,11 +1487,12 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
pTab = pIdx->pTable;
|
||||
sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->aiColumn[i], 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0,
|
||||
pTab->aCol[pIdx->aiColumn[i]].zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0, 0, 0);
|
||||
int cnum = pIdx->aiColumn[i];
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, pTab->aCol[cnum].zName, P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
@ -1497,10 +1517,11 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
|
||||
|
||||
sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
|
||||
while(pIdx){
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, pIdx->zName, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->isUnique, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Integer, pIdx->isUnique, 0);
|
||||
sqliteVdbeAddOp(v, OP_Callback, 3, 0);
|
||||
++i;
|
||||
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
|
||||
** 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"
|
||||
|
||||
@ -81,8 +81,8 @@ void sqliteDeleteFrom(
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) goto delete_from_cleanup;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
|
||||
@ -91,9 +91,9 @@ void sqliteDeleteFrom(
|
||||
** It is easier just to erase the whole table.
|
||||
*/
|
||||
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){
|
||||
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
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
|
||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
@ -122,32 +122,33 @@ void sqliteDeleteFrom(
|
||||
** because deleting an item can change the scan order.
|
||||
*/
|
||||
base = pParse->nTab;
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
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){
|
||||
sqliteVdbeAddOp(v, openOp, base+i, pIdx->tnum, 0, 0);
|
||||
sqliteVdbeAddOp(v, openOp, base+i, pIdx->tnum);
|
||||
}
|
||||
end = sqliteVdbeMakeLabel(v);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
if( pTab->pIndex ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
int j;
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
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_DeleteIdx, base+i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Delete, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 0, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Delete, base, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 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
|
||||
** 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"
|
||||
|
||||
@ -234,7 +234,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
|
||||
** table. The cursor number of the temporary table has already
|
||||
** 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) );
|
||||
}else if( pExpr->pList ){
|
||||
/* Case 2: expr IN (exprlist)
|
||||
@ -262,14 +262,14 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
|
||||
case TK_FLOAT:
|
||||
case TK_INTEGER:
|
||||
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);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sqliteExprCode(pParse, pE2);
|
||||
sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -501,32 +501,32 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
switch( pExpr->op ){
|
||||
case TK_COLUMN: {
|
||||
if( pParse->useAgg ){
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
|
||||
}else if( pExpr->iColumn>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_INTEGER: {
|
||||
int i = atoi(pExpr->token.z);
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, i, 0);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
sqliteVdbeDequoteP3(v, addr);
|
||||
break;
|
||||
}
|
||||
case TK_NULL: {
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TK_AND:
|
||||
@ -537,13 +537,13 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
case TK_SLASH: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TK_CONCAT: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqliteVdbeAddOp(v, OP_Concat, 2, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Concat, 2, 0);
|
||||
break;
|
||||
}
|
||||
case TK_LT:
|
||||
@ -555,25 +555,26 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
case TK_LIKE:
|
||||
case TK_GLOB: {
|
||||
int dest;
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
dest = sqliteVdbeCurrentAddr(v) + 2;
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
|
||||
break;
|
||||
}
|
||||
case TK_UMINUS: {
|
||||
assert( pExpr->pLeft );
|
||||
if( pExpr->pLeft->op==TK_INTEGER ){
|
||||
int i = atoi(pExpr->pLeft->token.z);
|
||||
sqliteVdbeAddOp(v, OP_Integer, -i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, -i, 0);
|
||||
break;
|
||||
}else if( pExpr->pLeft->op==TK_FLOAT ){
|
||||
Token *p = &pExpr->pLeft->token;
|
||||
char *z = sqliteMalloc( p->n + 2 );
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -581,25 +582,25 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
}
|
||||
case TK_NOT: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
case TK_NOTNULL: {
|
||||
int dest;
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
dest = sqliteVdbeCurrentAddr(v) + 2;
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
|
||||
break;
|
||||
}
|
||||
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 ){
|
||||
assert( pParse->iAggCount>=0 && pParse->iAggCount<pParse->nAgg );
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Divide, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, pParse->iAggCount);
|
||||
sqliteVdbeAddOp(v, OP_Divide, 0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -610,7 +611,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
ExprList *pList = pExpr->pList;
|
||||
switch( id ){
|
||||
case FN_Fcnt: {
|
||||
sqliteVdbeAddOp(v, OP_Fcnt, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Fcnt, 0, 0);
|
||||
break;
|
||||
}
|
||||
case FN_Min:
|
||||
@ -619,21 +620,21 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
sqliteExprCode(pParse, pList->a[i].pExpr);
|
||||
if( i>0 ){
|
||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FN_Length: {
|
||||
sqliteExprCode(pParse, pList->a[0].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_Strlen, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Strlen, 0, 0);
|
||||
break;
|
||||
}
|
||||
case FN_Substr: {
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
sqliteExprCode(pParse, pList->a[i].pExpr);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Substr, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Substr, 0, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -644,27 +645,27 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
break;
|
||||
}
|
||||
case TK_SELECT: {
|
||||
sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
|
||||
break;
|
||||
}
|
||||
case TK_IN: {
|
||||
int addr;
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 1, 0);
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
addr = sqliteVdbeCurrentAddr(v);
|
||||
if( pExpr->pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+2, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+2);
|
||||
}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;
|
||||
}
|
||||
case TK_BETWEEN: {
|
||||
int lbl = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteExprIfFalse(pParse, pExpr, lbl);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
|
||||
sqliteVdbeResolveLabel(v, lbl);
|
||||
break;
|
||||
}
|
||||
@ -721,39 +722,40 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
|
||||
case TK_GLOB: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
case TK_NOTNULL: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
break;
|
||||
}
|
||||
case TK_IN: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
if( pExpr->pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_BETWEEN: {
|
||||
int lbl = sqliteVdbeMakeLabel(v);
|
||||
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);
|
||||
sqliteVdbeAddOp(v, OP_Lt, 0, lbl, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Lt, 0, lbl);
|
||||
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_Le, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0, 0, lbl);
|
||||
sqliteVdbeAddOp(v, OP_Le, 0, dest);
|
||||
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
|
||||
sqliteVdbeResolveLabel(v, lbl);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sqliteExprCode(pParse, pExpr);
|
||||
sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_If, 0, dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -806,48 +808,48 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
|
||||
case TK_EQ: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
break;
|
||||
}
|
||||
case TK_LIKE:
|
||||
case TK_GLOB: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
sqliteVdbeAddOp(v, op, 1, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 1, dest);
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
case TK_NOTNULL: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, dest);
|
||||
break;
|
||||
}
|
||||
case TK_IN: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
if( pExpr->pSelect ){
|
||||
sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest);
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_BETWEEN: {
|
||||
int addr;
|
||||
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);
|
||||
addr = sqliteVdbeCurrentAddr(v);
|
||||
sqliteVdbeAddOp(v, OP_Ge, 0, addr+3, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
|
||||
sqliteVdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, dest);
|
||||
sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_Gt, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Gt, 0, dest);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sqliteExprCode(pParse, pExpr);
|
||||
sqliteVdbeAddOp(v, OP_Not, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_If, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Not, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_If, 0, dest);
|
||||
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
|
||||
** 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"
|
||||
|
||||
@ -77,8 +77,8 @@ void sqliteInsert(
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) goto insert_cleanup;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ void sqliteInsert(
|
||||
if( pSelect ){
|
||||
int rc;
|
||||
srcTab = pParse->nTab++;
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
|
||||
rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
|
||||
if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
|
||||
assert( pSelect->pEList );
|
||||
@ -157,9 +157,11 @@ void sqliteInsert(
|
||||
*/
|
||||
base = pParse->nTab;
|
||||
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++){
|
||||
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
|
||||
@ -168,16 +170,16 @@ void sqliteInsert(
|
||||
** and the loop is not used.
|
||||
*/
|
||||
if( srcTab>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0);
|
||||
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.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
|
||||
if( pTab->pIndex ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
}
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( pColumn==0 ){
|
||||
@ -188,22 +190,23 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, i);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||
|
||||
/* Create appropriate entries for the new data row in all indices
|
||||
** of the table.
|
||||
*/
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
if( pIdx->pNext ){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
}
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
int idx = pIdx->aiColumn[i];
|
||||
@ -215,25 +218,27 @@ void sqliteInsert(
|
||||
}
|
||||
}
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, idx, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Column, srcTab, idx);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, pIdx->isUnique, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, pIdx->isUnique);
|
||||
}
|
||||
|
||||
/* The bottom of the loop, if the data source is a SELECT statement
|
||||
*/
|
||||
if( srcTab>=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||
sqliteVdbeResolveLabel(v, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 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
|
||||
** 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"
|
||||
|
||||
@ -110,7 +110,7 @@ static int selectInnerLoop(
|
||||
nColumn = pEList->nExpr;
|
||||
}else{
|
||||
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 ){
|
||||
int lbl = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", lbl);
|
||||
sqliteVdbeAddOp(v, OP_Put, distinct, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
|
||||
sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl);
|
||||
sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
|
||||
sqliteVdbeResolveLabel(v, lbl);
|
||||
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
|
||||
@ -133,7 +135,7 @@ static int selectInnerLoop(
|
||||
*/
|
||||
if( pOrderBy ){
|
||||
char *zSortOrder;
|
||||
sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
|
||||
zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
|
||||
if( zSortOrder==0 ) return 1;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
@ -141,27 +143,29 @@ static int selectInnerLoop(
|
||||
sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
|
||||
}
|
||||
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);
|
||||
sqliteVdbeAddOp(v, OP_SortPut, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
|
||||
}else
|
||||
|
||||
/* In this mode, write each query result to the key of the temporary
|
||||
** table iParm.
|
||||
*/
|
||||
if( eDest==SRT_Union ){
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, iParm, 0, "", 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, iParm, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||
}else
|
||||
|
||||
/* Store the result as data using a unique key.
|
||||
*/
|
||||
if( eDest==SRT_Table ){
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pull, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||
}else
|
||||
|
||||
/* Construct a record from the query result, but instead of
|
||||
@ -169,9 +173,9 @@ static int selectInnerLoop(
|
||||
** the temporary table iParm.
|
||||
*/
|
||||
if( eDest==SRT_Except ){
|
||||
int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
|
||||
int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3);
|
||||
sqliteVdbeAddOp(v, OP_Delete, iParm, 0);
|
||||
}else
|
||||
|
||||
/* If we are creating a set for an "expr IN (SELECT ...)" construct,
|
||||
@ -180,8 +184,9 @@ static int selectInnerLoop(
|
||||
*/
|
||||
if( eDest==SRT_Set ){
|
||||
assert( nColumn==1 );
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0);
|
||||
}else
|
||||
|
||||
|
||||
@ -191,14 +196,14 @@ static int selectInnerLoop(
|
||||
*/
|
||||
if( eDest==SRT_Mem ){
|
||||
assert( nColumn==1 );
|
||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iBreak, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iBreak);
|
||||
}else
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@ -212,11 +217,12 @@ static int selectInnerLoop(
|
||||
static void generateSortTail(Vdbe *v, int nColumn){
|
||||
int end = sqliteVdbeMakeLabel(v);
|
||||
int addr;
|
||||
sqliteVdbeAddOp(v, OP_Sort, 0, 0, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_SortClose, 0, 0, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Sort, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_SortClose, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -230,25 +236,26 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
||||
int i;
|
||||
if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
|
||||
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++){
|
||||
Expr *p;
|
||||
int addr;
|
||||
if( 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;
|
||||
}
|
||||
p = pEList->a[i].pExpr;
|
||||
if( p==0 ) continue;
|
||||
if( p->span.z && p->span.z[0] ){
|
||||
addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0, 0, 0);
|
||||
sqliteVdbeChangeP3(v, addr, p->span.z, p->span.n);
|
||||
int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0);
|
||||
sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n);
|
||||
sqliteVdbeCompressSpace(v, addr);
|
||||
}else if( p->op!=TK_COLUMN || pTabList==0 ){
|
||||
char zName[30];
|
||||
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{
|
||||
if( pTabList->nId>1 || (pParse->db->flags & SQLITE_FullColNames)!=0 ){
|
||||
char *zName = 0;
|
||||
@ -258,12 +265,14 @@ void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
|
||||
zTab = pTabList->a[p->iTable].zAlias;
|
||||
if( zTab==0 ) zTab = pTab->zName;
|
||||
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);
|
||||
}else{
|
||||
Table *pTab = pTabList->a[0].pTab;
|
||||
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;
|
||||
}
|
||||
if( p->op!=TK_ALL ){
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1);
|
||||
}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 );
|
||||
generateColumnNames(pParse, 0, p->pEList);
|
||||
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);
|
||||
iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
|
||||
iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak);
|
||||
rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
|
||||
p->pOrderBy, -1, eDest, iParm,
|
||||
iCont, iBreak);
|
||||
if( rc ) return 1;
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, unionTab, 0, 0, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||
sqliteVdbeResolveLabel(v, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Close, unionTab, 0);
|
||||
if( p->pOrderBy ){
|
||||
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) ){
|
||||
return 1;
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1);
|
||||
|
||||
/* 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"
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 0);
|
||||
sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1);
|
||||
p->pPrior = 0;
|
||||
rc = sqliteSelect(pParse, p, SRT_Union, tab2);
|
||||
p->pPrior = pPrior;
|
||||
@ -589,20 +599,21 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
|
||||
assert( p->pEList );
|
||||
generateColumnNames(pParse, 0, p->pEList);
|
||||
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);
|
||||
iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
|
||||
iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
|
||||
rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
|
||||
p->pOrderBy, -1, eDest, iParm,
|
||||
iCont, iBreak);
|
||||
if( rc ) return 1;
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, tab2, 0, 0, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Close, tab1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, iCont);
|
||||
sqliteVdbeResolveLabel(v, iBreak);
|
||||
sqliteVdbeAddOp(v, OP_Close, tab2, 0);
|
||||
sqliteVdbeAddOp(v, OP_Close, tab1, 0);
|
||||
if( p->pOrderBy ){
|
||||
generateSortTail(v, p->pEList->nExpr);
|
||||
}
|
||||
@ -842,7 +853,7 @@ int sqliteSelect(
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) return 1;
|
||||
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
|
||||
@ -855,20 +866,20 @@ int sqliteSelect(
|
||||
/* Reset the aggregator
|
||||
*/
|
||||
if( isAgg ){
|
||||
sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
|
||||
}
|
||||
|
||||
/* Initialize the memory cell to NULL
|
||||
*/
|
||||
if( eDest==SRT_Mem ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MemStore, iParm, 0);
|
||||
}
|
||||
|
||||
/* Begin the database scan
|
||||
*/
|
||||
if( isDistinct ){
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 0);
|
||||
}
|
||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0);
|
||||
if( pWInfo==0 ) return 1;
|
||||
@ -892,7 +903,7 @@ int sqliteSelect(
|
||||
for(i=0; i<pGroupBy->nExpr; i++){
|
||||
sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
|
||||
doFocus = 1;
|
||||
}else{
|
||||
doFocus = 0;
|
||||
@ -903,16 +914,17 @@ int sqliteSelect(
|
||||
}
|
||||
}
|
||||
if( doFocus ){
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "", P3_STATIC);
|
||||
}
|
||||
}
|
||||
if( doFocus ){
|
||||
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++){
|
||||
if( pParse->aAgg[i].isAgg ) continue;
|
||||
sqliteExprCode(pParse, pParse->aAgg[i].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i);
|
||||
}
|
||||
sqliteVdbeResolveLabel(v, lbl1);
|
||||
}
|
||||
@ -922,21 +934,21 @@ int sqliteSelect(
|
||||
if( !pParse->aAgg[i].isAgg ) continue;
|
||||
pE = pParse->aAgg[i].pExpr;
|
||||
if( pE==0 ){
|
||||
sqliteVdbeAddOp(v, OP_AggIncr, 1, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggIncr, 1, i);
|
||||
continue;
|
||||
}
|
||||
assert( pE->op==TK_AGG_FUNCTION );
|
||||
assert( pE->pList!=0 && pE->pList->nExpr==1 );
|
||||
sqliteExprCode(pParse, pE->pList->a[0].pExpr);
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggGet, 0, i);
|
||||
switch( pE->iColumn ){
|
||||
case FN_Min: op = OP_Min; break;
|
||||
case FN_Max: op = OP_Max; break;
|
||||
case FN_Avg: op = OP_Add; break;
|
||||
case FN_Sum: op = OP_Add; break;
|
||||
}
|
||||
sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, op, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AggSet, 0, i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -951,7 +963,7 @@ int sqliteSelect(
|
||||
if( isAgg ){
|
||||
int endagg = sqliteVdbeMakeLabel(v);
|
||||
int startagg;
|
||||
startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg, 0, 0);
|
||||
startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg);
|
||||
pParse->useAgg = 1;
|
||||
if( pHaving ){
|
||||
sqliteExprIfFalse(pParse, pHaving, startagg);
|
||||
@ -960,8 +972,9 @@ int sqliteSelect(
|
||||
startagg, endagg) ){
|
||||
return 1;
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, startagg, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, endagg);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, startagg);
|
||||
sqliteVdbeResolveLabel(v, endagg);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 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
|
||||
** 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"
|
||||
|
||||
@ -136,20 +136,20 @@ void sqliteUpdate(
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v==0 ) goto update_cleanup;
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
|
||||
/* Begin the database scan
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
|
||||
pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
|
||||
if( pWInfo==0 ) goto update_cleanup;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
@ -158,12 +158,12 @@ void sqliteUpdate(
|
||||
/* Rewind the list of records that need to be updated and
|
||||
** open every index that needs updating.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
|
||||
base = pParse->nTab;
|
||||
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++){
|
||||
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
|
||||
@ -172,20 +172,20 @@ void sqliteUpdate(
|
||||
** Also, the old data is needed to delete the old index entires.
|
||||
*/
|
||||
end = sqliteVdbeMakeLabel(v);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0);
|
||||
addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
|
||||
|
||||
/* Delete the old indices for the current record.
|
||||
*/
|
||||
for(i=0; i<nIdx; i++){
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
|
||||
pIdx = apIdx[i];
|
||||
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_DeleteIdx, base+i+1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_DeleteIdx, base+i+1, 0);
|
||||
}
|
||||
|
||||
/* Compute a completely new data for this record.
|
||||
@ -193,7 +193,7 @@ void sqliteUpdate(
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
j = aXRef[i];
|
||||
if( j<0 ){
|
||||
sqliteVdbeAddOp(v, OP_Column, base, i, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Column, base, i);
|
||||
}else{
|
||||
sqliteExprCode(pParse, pChanges->a[j].pExpr);
|
||||
}
|
||||
@ -202,27 +202,28 @@ void sqliteUpdate(
|
||||
/* Insert new index entries that correspond to the new data
|
||||
*/
|
||||
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];
|
||||
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_PutIdx, base+i+1, pIdx->isUnique, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_PutIdx, base+i+1, pIdx->isUnique);
|
||||
}
|
||||
|
||||
/* Write the new data back into the database.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqliteVdbeAddOp(v, OP_Put, base, 0);
|
||||
|
||||
/* Repeat the above with the next record to be updated, until
|
||||
** all record selected by the WHERE clause have been updated.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 0, 0, end);
|
||||
sqliteVdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqliteVdbeResolveLabel(v, end);
|
||||
sqliteVdbeAddOp(v, OP_ListClose, 0, 0);
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0);
|
||||
}
|
||||
|
||||
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
|
||||
** 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 <ctype.h>
|
||||
@ -233,24 +233,20 @@ void sqliteVdbeTrace(Vdbe *p, FILE *trace){
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** Symbolic labels are negative numbers that stand for the address
|
||||
** 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.
|
||||
** Use the sqliteVdbeResolveLabel() function to fix an address and
|
||||
** the sqliteVdbeChangeP3() function to change the value of the P3
|
||||
** operand.
|
||||
*/
|
||||
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2, const char *p3, int lbl){
|
||||
int i, j;
|
||||
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
int i;
|
||||
|
||||
i = p->nOp;
|
||||
p->nOp++;
|
||||
if( i>=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));
|
||||
if( p->aOp==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];
|
||||
}
|
||||
p->aOp[i].p2 = p2;
|
||||
if( p3 && p3[0] ){
|
||||
p->aOp[i].p3 = sqliteStrDup(p3);
|
||||
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;
|
||||
}
|
||||
}
|
||||
p->aOp[i].p3 = 0;
|
||||
p->aOp[i].p3type = P3_NOTUSED;
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -323,9 +309,11 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
|
||||
int i;
|
||||
for(i=0; i<nOp; i++){
|
||||
int p2 = aOp[i].p2;
|
||||
if( p2<0 ) p2 = addr + ADDR(p2);
|
||||
sqliteVdbeAddOp(p, aOp[i].opcode, aOp[i].p1, p2, aOp[i].p3, 0);
|
||||
p->aOp[i+addr] = aOp[i];
|
||||
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;
|
||||
}
|
||||
@ -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
|
||||
** 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.
|
||||
** P3 is made to point directly to this string without any copying.
|
||||
** If n==P3_STATIC it means that zP3 is a pointer to a constant static
|
||||
** 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){
|
||||
if( p && addr>=0 && p->nOp>addr && zP3 ){
|
||||
Op *pOp = &p->aOp[addr];
|
||||
if( pOp->p3 && pOp->p3dyn ){
|
||||
sqliteFree(pOp->p3);
|
||||
}
|
||||
if( n<0 ){
|
||||
pOp->p3 = zP3;
|
||||
pOp->p3dyn = 0;
|
||||
}else{
|
||||
sqliteSetNString(&p->aOp[addr].p3, zP3, n, 0);
|
||||
pOp->p3dyn = 1;
|
||||
}
|
||||
Op *pOp;
|
||||
if( p==0 ) return;
|
||||
if( addr<0 || addr>=p->nOp ){
|
||||
addr = p->nOp - 1;
|
||||
if( addr<0 ) return;
|
||||
}
|
||||
pOp = &p->aOp[addr];
|
||||
if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
|
||||
sqliteFree(pOp->p3);
|
||||
pOp->p3 = 0;
|
||||
}
|
||||
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;
|
||||
pOp = &p->aOp[addr];
|
||||
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->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;
|
||||
if( addr<0 || addr>=p->nOp ) return;
|
||||
pOp = &p->aOp[addr];
|
||||
if( !pOp->p3dyn ){
|
||||
if( pOp->p3type!=P3_DYNAMIC ){
|
||||
pOp->p3 = sqliteStrDup(pOp->p3);
|
||||
pOp->p3dyn = 1;
|
||||
pOp->p3type = P3_DYNAMIC;
|
||||
}else if( pOp->p3type!=P3_STATIC ){
|
||||
return;
|
||||
}
|
||||
z = pOp->p3;
|
||||
if( z==0 ) return;
|
||||
@ -770,7 +772,7 @@ void sqliteVdbeDelete(Vdbe *p){
|
||||
p->nOp = 0;
|
||||
}
|
||||
for(i=0; i<p->nOp; i++){
|
||||
if( p->aOp[i].p3dyn ){
|
||||
if( p->aOp[i].p3type==P3_DYNAMIC ){
|
||||
sqliteFree(p->aOp[i].p3);
|
||||
}
|
||||
}
|
||||
@ -873,7 +875,7 @@ int sqliteVdbeList(
|
||||
sprintf(zAddr,"%d",i);
|
||||
sprintf(zP1,"%d", p->aOp[i].p1);
|
||||
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];
|
||||
if( xCallback(pArg, 5, azValue, azColumnNames) ){
|
||||
rc = SQLITE_ABORT;
|
||||
@ -2871,7 +2873,7 @@ case OP_CreateTable: {
|
||||
int i = ++p->tos;
|
||||
int pgno;
|
||||
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);
|
||||
if( rc==SQLITE_OK ){
|
||||
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
|
||||
** 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_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@ -38,10 +38,18 @@ struct VdbeOp {
|
||||
int p1; /* First operand */
|
||||
int p2; /* Second parameter (often the jump destination) */
|
||||
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;
|
||||
|
||||
/*
|
||||
** 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
|
||||
** of a VdbeOp structure into a negative number so that
|
||||
@ -199,7 +207,7 @@ typedef struct VdbeOp VdbeOp;
|
||||
*/
|
||||
Vdbe *sqliteVdbeCreate(sqlite*);
|
||||
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);
|
||||
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
|
||||
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
|
||||
** 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"
|
||||
|
||||
@ -290,15 +290,16 @@ WhereInfo *sqliteWhereBegin(
|
||||
|
||||
pTab = pTabList->a[i].pTab;
|
||||
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 &&
|
||||
(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;
|
||||
}
|
||||
if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){
|
||||
sqliteVdbeAddOp(v, openOp, base+pTabList->nId+i, aIdx[i]->tnum,
|
||||
aIdx[i]->zName, 0);
|
||||
sqliteVdbeAddOp(v, openOp, base+pTabList->nId+i, aIdx[i]->tnum);
|
||||
sqliteVdbeChangeP3(v, -1, aIdx[i]->zName, P3_STATIC);
|
||||
}
|
||||
}
|
||||
memcpy(pWInfo->aIdx, aIdx, sizeof(aIdx));
|
||||
@ -344,20 +345,21 @@ WhereInfo *sqliteWhereBegin(
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 0, 0);
|
||||
if( i==pTabList->nId-1 && pushKey ){
|
||||
haveKey = 1;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_NotFound, base+idx, brk, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NotFound, base+idx, brk);
|
||||
haveKey = 0;
|
||||
}
|
||||
}else if( pIdx==0 ){
|
||||
/* Case 2: There was no usable index. We must do a complete
|
||||
** scan of the table.
|
||||
*/
|
||||
sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0);
|
||||
cont = sqliteVdbeMakeLabel(v);
|
||||
sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
|
||||
sqliteVdbeResolveLabel(v, cont);
|
||||
sqliteVdbeAddOp(v, OP_Next, base+idx, brk);
|
||||
haveKey = 0;
|
||||
}else{
|
||||
/* 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_BeginIdx, base+pTabList->nId+i, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk, 0, cont);
|
||||
sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0);
|
||||
sqliteVdbeAddOp(v, OP_BeginIdx, base+pTabList->nId+i, 0);
|
||||
sqliteVdbeResolveLabel(v, cont);
|
||||
sqliteVdbeAddOp(v, OP_NextIdx, base+pTabList->nId+i, brk);
|
||||
if( i==pTabList->nId-1 && pushKey ){
|
||||
haveKey = 1;
|
||||
}else{
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||
haveKey = 0;
|
||||
}
|
||||
}
|
||||
@ -405,7 +408,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
if( (aExpr[j].prereqLeft & loopMask)!=aExpr[j].prereqLeft ) continue;
|
||||
if( haveKey ){
|
||||
haveKey = 0;
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0);
|
||||
}
|
||||
sqliteExprIfFalse(pParse, aExpr[j].p, cont);
|
||||
aExpr[j].p = 0;
|
||||
@ -414,7 +417,7 @@ WhereInfo *sqliteWhereBegin(
|
||||
}
|
||||
pWInfo->iContinue = cont;
|
||||
if( pushKey && !haveKey ){
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Recno, base, 0);
|
||||
}
|
||||
sqliteFree(aOrder);
|
||||
return pWInfo;
|
||||
@ -429,16 +432,18 @@ void sqliteWhereEnd(WhereInfo *pWInfo){
|
||||
int brk = pWInfo->iBreak;
|
||||
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++){
|
||||
sqliteVdbeAddOp(v, OP_Close, base+i, 0, 0, brk);
|
||||
sqliteVdbeResolveLabel(v, brk);
|
||||
sqliteVdbeAddOp(v, OP_Close, base+i, 0);
|
||||
brk = 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 ){
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, brk);
|
||||
sqliteVdbeResolveLabel(v, brk);
|
||||
sqliteVdbeAddOp(v, OP_Noop, 0, 0);
|
||||
}
|
||||
sqliteFree(pWInfo);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user