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:
drh 2001-10-13 01:06:47 +00:00
parent 81a20f21d5
commit 99fcd718e1
11 changed files with 444 additions and 386 deletions

View File

@ -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

View File

@ -1 +1 @@
0a7848b6190981cb7eb673bbe68cb217694daf2e
288ef1247b94c6c933451d120cdc78e471efc14e

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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;