Everything is working on Linux. This is release 2.0-Alpha-1. (CVS 246)
FossilOrigin-Name: 14474fa144fe7c5dc63e0990d6cc92d769e6013e
This commit is contained in:
parent
f57b14a657
commit
50e5dadf2c
36
manifest
36
manifest
@ -1,5 +1,5 @@
|
||||
C Added\sa\sPRAGMA\sstatement.\s\sTook\sout\sthe\sspecial\scomment\sparsing.\s(CVS\s245)
|
||||
D 2001-09-14T18:54:08
|
||||
C Everything\sis\sworking\son\sLinux.\s\sThis\sis\srelease\s2.0-Alpha-1.\s(CVS\s246)
|
||||
D 2001-09-15T00:57:28
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
@ -12,11 +12,11 @@ F notes/notes1.txt b7c0812b704a022e88c621146ae50955c923d464
|
||||
F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
|
||||
F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3
|
||||
F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
|
||||
F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c 3adf545b8e072000923f7e0f7f91d33072a9f869
|
||||
F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b
|
||||
F src/build.c b5c682960b5889555cd059f3b5157668778b8834
|
||||
F src/delete.c 62500a09606c0f714b651756475cd42979ef08e8
|
||||
F src/build.c 8359e553db8138d09f44957e2d1bcc9b8720117b
|
||||
F src/delete.c c84b5a26e29fda3c3de51345073a76bb161271fd
|
||||
F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
|
||||
F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
|
||||
F src/ex/db.h 3f2933ee20c147fe494835786e4c6f3a562def4e
|
||||
@ -26,10 +26,10 @@ F src/ex/pg.c 2bbf6a94f37226d06337868b6bf4d7affc60197f
|
||||
F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd
|
||||
F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
|
||||
F src/expr.c bcd91d0487c71cfa44413a46efe5e2c2244901b6
|
||||
F src/insert.c edf098ecbbe00e3ecde6b5f22404a8230590c9fd
|
||||
F src/main.c a2c142626b46e3eb3e01436626df6c2d0a8f3ae6
|
||||
F src/insert.c 750a44c0d205779b2c42b0791a163937cfb00e74
|
||||
F src/main.c 73be8d00a8a9bbec715a6260840a19020a074090
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/pager.c bb0891d49b9068711e4b8bab14db2959f56f5be9
|
||||
F src/pager.c 048c20ac85485ca87ed33d6b7711375a3444f817
|
||||
F src/pager.h bb9136e833de46bc84aafd8403713d3c46fcbfdf
|
||||
F src/parse.y 8b30e072208c3dfabd97c7d06f0924f194919533
|
||||
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
|
||||
@ -37,19 +37,19 @@ F src/random.c b626726c4f0066610739e52e7431adae7ccd9651
|
||||
F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84
|
||||
F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70
|
||||
F src/sqliteInt.h 11d74bfd90777afafc529434b86c413fed44f0bf
|
||||
F src/sqlite.h.in 1d6a7d13284c3861e61bd0b71491fda613613c68
|
||||
F src/sqliteInt.h c7c0580ceb9b5ce92c6fc7ef9434320952b14dc0
|
||||
F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
|
||||
F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
|
||||
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
|
||||
F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670
|
||||
F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53
|
||||
F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6
|
||||
F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda
|
||||
F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b
|
||||
F src/vdbe.c 244c86e406170c76b89ab07de4c7258f716c36ff
|
||||
F src/vdbe.h 9f32bd12c47bd2b4bdd7e93092bb796f2a3b649f
|
||||
F src/where.c fef978a9a2234b01e30e36833ab63e14bbc626d3
|
||||
F src/update.c 8a9d514c7f3bfe5d99fe3dfc1ad92ed3e9daea47
|
||||
F src/util.c f3f1550fb7a02348c3d0a0969951e489806e055b
|
||||
F src/vdbe.c d5bb5d8dda994779e4d20de5e4a31edf995269ff
|
||||
F src/vdbe.h b9d60d90aeb3acb5dbc1cdac6b0201991921b272
|
||||
F src/where.c b831b506e17cb592d9781ed066f3459cef768318
|
||||
F test/all.test 5cefdb035b45639ddbb9f80324185b0f0a9ebda2
|
||||
F test/btree.test 5e1eeb03cda22161eec827dc5224ce6c500eaaf9
|
||||
F test/btree2.test 061365dfc2a6cd784e17a014b67b277a4cd374ee
|
||||
@ -107,7 +107,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P 7da856cd94d2572070e40762e5bc477679e60042
|
||||
R 07caee6e3ed361d3efc95a7817451754
|
||||
P 5e3724603e6f52bb74deb1c62e6e8f323d7b64b7
|
||||
R f702824af0e6fb733e46f0ad203329d6
|
||||
U drh
|
||||
Z 4e11150d8699ec673e8745d72c606c4d
|
||||
Z 7366e408d799dcad27172164daf780cc
|
||||
|
@ -1 +1 @@
|
||||
5e3724603e6f52bb74deb1c62e6e8f323d7b64b7
|
||||
14474fa144fe7c5dc63e0990d6cc92d769e6013e
|
1
src/TODO
1
src/TODO
@ -3,5 +3,4 @@
|
||||
* "OPTIMIZE select" statement to automatically create indices and/or
|
||||
invoke a CLUSTER command.
|
||||
* "CREATE INDEX FOR select" to automatically generate needed indices.
|
||||
* Implement a PRAGMA command
|
||||
* Parse and use constraints.
|
||||
|
48
src/build.c
48
src/build.c
@ -33,7 +33,7 @@
|
||||
** COPY
|
||||
** VACUUM
|
||||
**
|
||||
** $Id: build.c,v 1.34 2001/09/14 18:54:08 drh Exp $
|
||||
** $Id: build.c,v 1.35 2001/09/15 00:57:28 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -67,6 +67,7 @@ void sqliteExec(Parse *pParse){
|
||||
pParse->pVdbe = 0;
|
||||
pParse->colNamesSet = 0;
|
||||
pParse->rc = rc;
|
||||
pParse->schemaVerified = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,6 +279,7 @@ static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){
|
||||
void sqliteCommitInternalChanges(sqlite *db){
|
||||
int i;
|
||||
if( (db->flags & SQLITE_InternChanges)==0 ) return;
|
||||
db->schema_cookie = db->next_cookie;
|
||||
for(i=0; i<N_HASH; i++){
|
||||
Table *pTable, *pNext;
|
||||
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
||||
@ -314,6 +316,7 @@ void sqliteCommitInternalChanges(sqlite *db){
|
||||
void sqliteRollbackInternalChanges(sqlite *db){
|
||||
int i;
|
||||
if( (db->flags & SQLITE_InternChanges)==0 ) return;
|
||||
db->next_cookie = db->schema_cookie;
|
||||
for(i=0; i<N_HASH; i++){
|
||||
Table *pTable, *pNext;
|
||||
for(pTable = db->apTblHash[i]; pTable; pTable=pNext){
|
||||
@ -398,6 +401,7 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){
|
||||
Vdbe *v = sqliteGetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -450,6 +454,30 @@ void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){
|
||||
sqliteDequote(*pz);
|
||||
}
|
||||
|
||||
/*
|
||||
** Come up with a new random value for the schema cookie. Make sure
|
||||
** the new value is different from the old.
|
||||
**
|
||||
** The schema cookie is used to determine when the schema for the
|
||||
** database changes. After each schema change, the cookie value
|
||||
** changes. When a process first reads the schema it records the
|
||||
** cookie. Thereafter, whenever it goes to access the database,
|
||||
** it checks the cookie to make sure the schema has not changed
|
||||
** since it was last read.
|
||||
**
|
||||
** This plan is not completely bullet-proof. It is possible for
|
||||
** the schema to change multiple times and for the cookie to be
|
||||
** set back to prior value. But schema changes are infrequent
|
||||
** and the probability of hitting the same cookie value is only
|
||||
** 1 chance in 2^32. So we're safe enough.
|
||||
*/
|
||||
static void changeCookie(sqlite *db){
|
||||
if( db->next_cookie==db->schema_cookie ){
|
||||
db->next_cookie = db->schema_cookie + sqliteRandomByte() + 1;
|
||||
db->flags |= SQLITE_InternChanges;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called to report the final ")" that terminates
|
||||
** a CREATE TABLE statement.
|
||||
@ -503,6 +531,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
||||
{ OP_String, 0, 0, 0}, /* 6 */
|
||||
{ OP_MakeRecord, 5, 0, 0},
|
||||
{ OP_Put, 0, 0, 0},
|
||||
{ OP_SetCookie, 0, 0, 0}, /* 9 */
|
||||
};
|
||||
int n, base;
|
||||
Vdbe *v;
|
||||
@ -515,6 +544,8 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
||||
sqliteVdbeTableRootAddr(v, &p->tnum);
|
||||
sqliteVdbeChangeP3(v, base+5, p->zName, 0);
|
||||
sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n);
|
||||
changeCookie(db);
|
||||
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
||||
if( p->pIndex ){
|
||||
/* If the table has a primary key, create an index in the database
|
||||
@ -586,15 +617,19 @@ void sqliteDropTable(Parse *pParse, Token *pName){
|
||||
{ OP_Delete, 0, 0, 0},
|
||||
{ OP_Goto, 0, ADDR(3), 0},
|
||||
{ OP_Destroy, 0, 0, 0}, /* 9 */
|
||||
{ OP_SetCookie, 0, 0, 0}, /* 10 */
|
||||
{ OP_Close, 0, 0, 0},
|
||||
};
|
||||
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);
|
||||
}
|
||||
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
|
||||
sqliteVdbeChangeP3(v, base+2, pTable->zName, 0);
|
||||
sqliteVdbeChangeP1(v, base+9, pTable->tnum);
|
||||
changeCookie(db);
|
||||
sqliteVdbeChangeP1(v, base+10, db->next_cookie);
|
||||
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
|
||||
}
|
||||
@ -772,6 +807,7 @@ void sqliteCreateIndex(
|
||||
{ OP_String, 0, 0, 0}, /* 8 */
|
||||
{ OP_MakeRecord, 5, 0, 0},
|
||||
{ OP_Put, 2, 0, 0},
|
||||
{ OP_SetCookie, 0, 0, 0}, /* 11 */
|
||||
{ OP_Close, 2, 0, 0},
|
||||
};
|
||||
int n;
|
||||
@ -783,6 +819,7 @@ void sqliteCreateIndex(
|
||||
if( v==0 ) goto exit_create_index;
|
||||
if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
if( pStart && pEnd ){
|
||||
int base;
|
||||
@ -793,6 +830,8 @@ void sqliteCreateIndex(
|
||||
sqliteVdbeChangeP3(v, base+6, pIndex->zName, 0);
|
||||
sqliteVdbeChangeP3(v, base+7, pTab->zName, 0);
|
||||
sqliteVdbeChangeP3(v, base+8, pStart->z, n);
|
||||
changeCookie(db);
|
||||
sqliteVdbeChangeP1(v, base+11, db->next_cookie);
|
||||
}
|
||||
sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0);
|
||||
lbl1 = sqliteVdbeMakeLabel(v);
|
||||
@ -861,16 +900,20 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
|
||||
{ OP_Ne, 0, ADDR(3), 0},
|
||||
{ OP_Delete, 0, 0, 0},
|
||||
{ OP_Destroy, 0, 0, 0}, /* 8 */
|
||||
{ OP_SetCookie, 0, 0, 0}, /* 9 */
|
||||
{ OP_Close, 0, 0, 0},
|
||||
};
|
||||
int base;
|
||||
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
|
||||
sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0);
|
||||
sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
|
||||
changeCookie(db);
|
||||
sqliteVdbeChangeP1(v, base+9, db->next_cookie);
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
|
||||
}
|
||||
@ -1037,6 +1080,7 @@ void sqliteCopy(
|
||||
if( v ){
|
||||
if( (db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0);
|
||||
sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
|
||||
@ -1109,6 +1153,7 @@ void sqliteVacuum(Parse *pParse, Token *pTableName){
|
||||
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);
|
||||
}
|
||||
if( zName ){
|
||||
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0);
|
||||
@ -1147,6 +1192,7 @@ void sqliteBeginTransaction(Parse *pParse){
|
||||
v = sqliteGetVdbe(pParse);
|
||||
if( v ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
db->flags |= SQLITE_InTrans;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.12 2001/09/13 21:53:10 drh Exp $
|
||||
** $Id: delete.c,v 1.13 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -92,6 +92,7 @@ void sqliteDeleteFrom(
|
||||
if( v==0 ) goto delete_from_cleanup;
|
||||
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements.
|
||||
**
|
||||
** $Id: insert.c,v 1.16 2001/09/14 03:24:25 drh Exp $
|
||||
** $Id: insert.c,v 1.17 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -87,6 +87,7 @@ void sqliteInsert(
|
||||
if( v==0 ) goto insert_cleanup;
|
||||
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Figure out how many columns of data are supplied. If the data
|
||||
|
39
src/main.c
39
src/main.c
@ -26,7 +26,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: main.c,v 1.35 2001/09/14 16:42:12 drh Exp $
|
||||
** $Id: main.c,v 1.36 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#if defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
@ -51,7 +51,12 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
|
||||
assert( argc==4 );
|
||||
switch( argv[0][0] ){
|
||||
case 'm': { /* Meta information */
|
||||
sscanf(argv[1],"file format %d",&db->file_format);
|
||||
if( strcmp(argv[1],"file-format")==0 ){
|
||||
db->file_format = atoi(argv[3]);
|
||||
}else if( strcmp(argv[1],"schema-cookie")==0 ){
|
||||
db->schema_cookie = atoi(argv[3]);
|
||||
db->next_cookie = db->schema_cookie;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
@ -170,7 +175,12 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
{ OP_Column, 0, 4, 0},
|
||||
{ OP_Callback, 4, 0, 0},
|
||||
{ OP_Goto, 0, 24, 0},
|
||||
{ OP_Close, 0, 0, 0}, /* 34 */
|
||||
{ OP_String, 0, 0, "meta"}, /* 34 */
|
||||
{ OP_String, 0, 0, "schema-cookie"},
|
||||
{ OP_String, 0, 0, ""},
|
||||
{ OP_ReadCookie,0,0, 0},
|
||||
{ OP_Callback, 4, 0, 0},
|
||||
{ OP_Close, 0, 0, 0},
|
||||
{ OP_Halt, 0, 0, 0},
|
||||
};
|
||||
|
||||
@ -281,11 +291,16 @@ no_mem_on_open:
|
||||
}
|
||||
|
||||
/*
|
||||
** Close an existing SQLite database
|
||||
** Erase all schema information from the schema hash table.
|
||||
**
|
||||
** The database schema is normally read in once when the database
|
||||
** is first opened and stored in a hash table in the sqlite structure.
|
||||
** This routine erases the stored schema. This erasure occurs because
|
||||
** either the database is being closed or because some other process
|
||||
** changed the schema and this process needs to reread it.
|
||||
*/
|
||||
void sqlite_close(sqlite *db){
|
||||
static void clearHashTable(sqlite *db){
|
||||
int i;
|
||||
sqliteBtreeClose(db->pBe);
|
||||
for(i=0; i<N_HASH; i++){
|
||||
Table *pNext, *pList = db->apTblHash[i];
|
||||
db->apTblHash[i] = 0;
|
||||
@ -296,6 +311,15 @@ void sqlite_close(sqlite *db){
|
||||
pList = pNext;
|
||||
}
|
||||
}
|
||||
db->flags &= ~SQLITE_Initialized;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close an existing SQLite database
|
||||
*/
|
||||
void sqlite_close(sqlite *db){
|
||||
sqliteBtreeClose(db->pBe);
|
||||
clearHashTable(db);
|
||||
sqliteFree(db);
|
||||
}
|
||||
|
||||
@ -387,6 +411,9 @@ int sqlite_exec(
|
||||
sParse.rc = SQLITE_NOMEM;
|
||||
}
|
||||
sqliteStrRealloc(pzErrMsg);
|
||||
if( sParse.rc==SQLITE_SCHEMA ){
|
||||
clearHashTable(db);
|
||||
}
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
|
45
src/pager.c
45
src/pager.c
@ -27,7 +27,7 @@
|
||||
** all writes in order to support rollback. Locking is used to limit
|
||||
** access to one or more reader or to one writer.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.18 2001/09/14 18:54:09 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.19 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@ -683,6 +683,28 @@ int sqlitepager_ref(void *pData){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sync the journal and write all free dirty pages to the database file.
|
||||
*/
|
||||
static int syncAllPages(Pager *pPager){
|
||||
PgHdr *pPg;
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->needSync ){
|
||||
rc = fsync(pPager->jfd);
|
||||
if( rc!=0 ) return rc;
|
||||
pPager->needSync = 0;
|
||||
}
|
||||
for(pPg=pPager->pFirst; pPg; pPg=pPg->pNextFree){
|
||||
if( pPg->dirty ){
|
||||
pager_seek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE);
|
||||
rc = pager_write(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
pPg->dirty = 0;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Acquire a page.
|
||||
**
|
||||
@ -791,15 +813,28 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
/* Recycle an older page. First locate the page to be recycled.
|
||||
** Try to find one that is not dirty and is near the head of
|
||||
** of the free list */
|
||||
/* int cnt = pPager->mxPage/2; */
|
||||
int cnt = 10;
|
||||
int cnt = pPager->mxPage/2;
|
||||
pPg = pPager->pFirst;
|
||||
while( pPg->dirty && 0<cnt-- && pPg->pNextFree ){
|
||||
pPg = pPg->pNextFree;
|
||||
}
|
||||
if( pPg==0 || pPg->dirty ) pPg = pPager->pFirst;
|
||||
if( pPg==0 || pPg->dirty ){
|
||||
int rc = syncAllPages(pPager);
|
||||
if( rc!=0 ){
|
||||
sqlitepager_rollback(pPager);
|
||||
*ppPage = 0;
|
||||
return SQLITE_IOERR;
|
||||
}
|
||||
pPg = pPager->pFirst;
|
||||
}
|
||||
assert( pPg->nRef==0 );
|
||||
|
||||
|
||||
#if 0
|
||||
/**** Since putting in the call to syncAllPages() above, this code
|
||||
** is no longer used. I've kept it here for historical reference
|
||||
** only.
|
||||
*/
|
||||
/* If the page to be recycled is dirty, sync the journal and write
|
||||
** the old page into the database. */
|
||||
if( pPg->dirty ){
|
||||
@ -825,6 +860,8 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
assert( pPg->dirty==0 );
|
||||
|
||||
/* Unlink the old page from the free list and the hash table
|
||||
*/
|
||||
|
@ -24,7 +24,7 @@
|
||||
** This header file defines the interface that the sqlite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.14 2001/09/13 13:46:57 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.15 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_H_
|
||||
#define _SQLITE_H_
|
||||
@ -160,6 +160,7 @@ int sqlite_exec(
|
||||
#define SQLITE_CANTOPEN 13 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 14 /* Database lock protocol error */
|
||||
#define SQLITE_EMPTY 15 /* Database table is empty */
|
||||
#define SQLITE_SCHEMA 16 /* The database schema changed */
|
||||
|
||||
/* This function causes any pending database operation to abort and
|
||||
** return at its earliest opportunity. This routine is typically
|
||||
|
@ -23,7 +23,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.47 2001/09/14 18:54:09 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.48 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include "vdbe.h"
|
||||
@ -143,6 +143,8 @@ struct sqlite {
|
||||
Btree *pBe; /* The B*Tree backend */
|
||||
int flags; /* Miscellanous flags. See below */
|
||||
int file_format; /* What file format version is this database? */
|
||||
int schema_cookie; /* Magic number that changes with the schema */
|
||||
int next_cookie; /* Value of schema_cookie after commit */
|
||||
int nTable; /* Number of tables in the database */
|
||||
void *pBusyArg; /* 1st Argument to the busy callback */
|
||||
int (*xBusyCallback)(void *,const char*,int); /* The busy callback */
|
||||
@ -376,6 +378,8 @@ struct Parse {
|
||||
int iAggCount; /* Index of the count(*) aggregate in aAgg[] */
|
||||
int useAgg; /* If true, extract field values from the aggregator
|
||||
** while generating expressions. Normally false */
|
||||
int schemaVerified; /* True if an OP_VerifySchema has been coded someplace
|
||||
** other than after an OP_Transaction */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -24,7 +24,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.12 2001/09/13 13:46:57 drh Exp $
|
||||
** $Id: update.c,v 1.13 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -146,6 +146,7 @@ void sqliteUpdate(
|
||||
if( v==0 ) goto update_cleanup;
|
||||
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Begin the database scan
|
||||
|
39
src/util.c
39
src/util.c
@ -26,7 +26,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.22 2001/09/13 13:46:57 drh Exp $
|
||||
** $Id: util.c,v 1.23 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@ -978,25 +978,26 @@ sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
|
||||
** argument.
|
||||
*/
|
||||
const char *sqliteErrStr(int rc){
|
||||
char *z = 0;
|
||||
const char *z;
|
||||
switch( rc ){
|
||||
case SQLITE_OK: z = "not an error"; break;
|
||||
case SQLITE_ERROR: z = "SQL logic error or missing database"; break;
|
||||
case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break;
|
||||
case SQLITE_PERM: z = "access permission denied"; break;
|
||||
case SQLITE_ABORT: z = "callback requested query abort"; break;
|
||||
case SQLITE_BUSY: z = "database in use by another process"; break;
|
||||
case SQLITE_NOMEM: z = "out of memory"; break;
|
||||
case SQLITE_READONLY: z = "attempt to write a readonly database"; break;
|
||||
case SQLITE_INTERRUPT: z = "interrupted"; break;
|
||||
case SQLITE_IOERR: z = "disk I/O error"; break;
|
||||
case SQLITE_CORRUPT: z = "database disk image is malformed"; break;
|
||||
case SQLITE_NOTFOUND: z = "table or record not found"; break;
|
||||
case SQLITE_FULL: z = "database is full"; break;
|
||||
case SQLITE_CANTOPEN: z = "unable to open database file"; break;
|
||||
case SQLITE_PROTOCOL: z = "database locking protocol failure"; break;
|
||||
case SQLITE_EMPTY: z = "table contains no data";
|
||||
default:
|
||||
case SQLITE_OK: z = "not an error"; break;
|
||||
case SQLITE_ERROR: z = "SQL logic error or missing database"; break;
|
||||
case SQLITE_INTERNAL: z = "internal SQLite implementation flaw"; break;
|
||||
case SQLITE_PERM: z = "access permission denied"; break;
|
||||
case SQLITE_ABORT: z = "callback requested query abort"; break;
|
||||
case SQLITE_BUSY: z = "database in use by another process"; break;
|
||||
case SQLITE_NOMEM: z = "out of memory"; break;
|
||||
case SQLITE_READONLY: z = "attempt to write a readonly database"; break;
|
||||
case SQLITE_INTERRUPT: z = "interrupted"; break;
|
||||
case SQLITE_IOERR: z = "disk I/O error"; break;
|
||||
case SQLITE_CORRUPT: z = "database disk image is malformed"; break;
|
||||
case SQLITE_NOTFOUND: z = "table or record not found"; break;
|
||||
case SQLITE_FULL: z = "database is full"; break;
|
||||
case SQLITE_CANTOPEN: z = "unable to open database file"; break;
|
||||
case SQLITE_PROTOCOL: z = "database locking protocol failure"; break;
|
||||
case SQLITE_EMPTY: z = "table contains no data"; break;
|
||||
case SQLITE_SCHEMA: z = "database schema has changed"; break;
|
||||
default: z = "unknown error"; break;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
170
src/vdbe.c
170
src/vdbe.c
@ -41,7 +41,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.66 2001/09/14 16:42:12 drh Exp $
|
||||
** $Id: vdbe.c,v 1.67 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -759,6 +759,23 @@ static void KeylistFree(Keylist *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a cursor and release all the resources that cursor happens
|
||||
** to hold.
|
||||
*/
|
||||
static void cleanupCursor(Cursor *pCx){
|
||||
if( pCx->pCursor ){
|
||||
sqliteBtreeCloseCursor(pCx->pCursor);
|
||||
}
|
||||
if( pCx->zKey ){
|
||||
sqliteFree(pCx->zKey);
|
||||
}
|
||||
if( pCx->pBt ){
|
||||
sqliteBtreeClose(pCx->pBt);
|
||||
}
|
||||
memset(pCx, 0, sizeof(Cursor));
|
||||
}
|
||||
|
||||
/*
|
||||
** Clean up the VM after execution.
|
||||
**
|
||||
@ -771,19 +788,7 @@ static void Cleanup(Vdbe *p){
|
||||
sqliteFree(p->azColName);
|
||||
p->azColName = 0;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
Cursor *pCx = &p->aCsr[i];
|
||||
if( pCx->pCursor ){
|
||||
sqliteBtreeCloseCursor(pCx->pCursor);
|
||||
pCx->pCursor = 0;
|
||||
}
|
||||
if( pCx->zKey ){
|
||||
sqliteFree(pCx->zKey);
|
||||
pCx->zKey = 0;
|
||||
}
|
||||
if( pCx->pBt ){
|
||||
sqliteBtreeClose(pCx->pBt);
|
||||
pCx->pBt = 0;
|
||||
}
|
||||
cleanupCursor(&p->aCsr[i]);
|
||||
}
|
||||
sqliteFree(p->aCsr);
|
||||
p->aCsr = 0;
|
||||
@ -871,31 +876,32 @@ void sqliteVdbeDelete(Vdbe *p){
|
||||
** this array, then copy and paste it into this file, if you want.
|
||||
*/
|
||||
static char *zOpName[] = { 0,
|
||||
"Transaction", "Commit", "Rollback", "Open",
|
||||
"OpenTemp", "Close", "MoveTo", "Fcnt",
|
||||
"NewRecno", "Put", "Distinct", "Found",
|
||||
"NotFound", "Delete", "Column", "KeyAsData",
|
||||
"Recno", "FullKey", "Rewind", "Next",
|
||||
"Destroy", "Clear", "CreateIndex", "CreateTable",
|
||||
"Reorganize", "BeginIdx", "NextIdx", "PutIdx",
|
||||
"DeleteIdx", "MemLoad", "MemStore", "ListOpen",
|
||||
"ListWrite", "ListRewind", "ListRead", "ListClose",
|
||||
"SortOpen", "SortPut", "SortMakeRec", "SortMakeKey",
|
||||
"Sort", "SortNext", "SortKey", "SortCallback",
|
||||
"SortClose", "FileOpen", "FileRead", "FileColumn",
|
||||
"FileClose", "AggReset", "AggFocus", "AggIncr",
|
||||
"AggNext", "AggSet", "AggGet", "SetInsert",
|
||||
"SetFound", "SetNotFound", "SetClear", "MakeRecord",
|
||||
"MakeKey", "MakeIdxKey", "Goto", "If",
|
||||
"Halt", "ColumnCount", "ColumnName", "Callback",
|
||||
"Integer", "String", "Null", "Pop",
|
||||
"Dup", "Pull", "Add", "AddImm",
|
||||
"Subtract", "Multiply", "Divide", "Min",
|
||||
"Max", "Like", "Glob", "Eq",
|
||||
"Ne", "Lt", "Le", "Gt",
|
||||
"Ge", "IsNull", "NotNull", "Negative",
|
||||
"And", "Or", "Not", "Concat",
|
||||
"Noop", "Strlen", "Substr",
|
||||
"Transaction", "Commit", "Rollback", "ReadCookie",
|
||||
"SetCookie", "VerifyCookie", "Open", "OpenTemp",
|
||||
"Close", "MoveTo", "Fcnt", "NewRecno",
|
||||
"Put", "Distinct", "Found", "NotFound",
|
||||
"Delete", "Column", "KeyAsData", "Recno",
|
||||
"FullKey", "Rewind", "Next", "Destroy",
|
||||
"Clear", "CreateIndex", "CreateTable", "Reorganize",
|
||||
"BeginIdx", "NextIdx", "PutIdx", "DeleteIdx",
|
||||
"MemLoad", "MemStore", "ListOpen", "ListWrite",
|
||||
"ListRewind", "ListRead", "ListClose", "SortOpen",
|
||||
"SortPut", "SortMakeRec", "SortMakeKey", "Sort",
|
||||
"SortNext", "SortKey", "SortCallback", "SortClose",
|
||||
"FileOpen", "FileRead", "FileColumn", "FileClose",
|
||||
"AggReset", "AggFocus", "AggIncr", "AggNext",
|
||||
"AggSet", "AggGet", "SetInsert", "SetFound",
|
||||
"SetNotFound", "SetClear", "MakeRecord", "MakeKey",
|
||||
"MakeIdxKey", "Goto", "If", "Halt",
|
||||
"ColumnCount", "ColumnName", "Callback", "Integer",
|
||||
"String", "Null", "Pop", "Dup",
|
||||
"Pull", "Add", "AddImm", "Subtract",
|
||||
"Multiply", "Divide", "Min", "Max",
|
||||
"Like", "Glob", "Eq", "Ne",
|
||||
"Lt", "Le", "Gt", "Ge",
|
||||
"IsNull", "NotNull", "Negative", "And",
|
||||
"Or", "Not", "Concat", "Noop",
|
||||
"Strlen", "Substr",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1974,6 +1980,73 @@ case OP_Rollback: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: ReadCookie * * *
|
||||
**
|
||||
** Read the magic cookie from the database file and push it onto the
|
||||
** stack. The magic cookie is an integer that is used like a version
|
||||
** number for the database schema. Everytime the schema changes, the
|
||||
** cookie changes to a new random value. This opcode is used during
|
||||
** initialization to read the initial cookie value so that subsequent
|
||||
** database accesses can verify that the cookie has not changed.
|
||||
**
|
||||
** There must be a read-lock on the database (either a transaction
|
||||
** must be started or there must be a prior OP_Open opcode) before
|
||||
** executing this instruction.
|
||||
*/
|
||||
case OP_ReadCookie: {
|
||||
int i = ++p->tos;
|
||||
int aMeta[SQLITE_N_BTREE_META];
|
||||
VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; )
|
||||
rc = sqliteBtreeGetMeta(pBt, aMeta);
|
||||
aStack[i].i = aMeta[1];
|
||||
aStack[i].flags = STK_Int;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: SetCookie P1 * *
|
||||
**
|
||||
** This operation changes the value of the cookie on the database.
|
||||
** The new value is P1.
|
||||
**
|
||||
** The cookie changes its value whenever the database schema changes.
|
||||
** That way, other processes can recognize when the schema has changed
|
||||
** and reread it.
|
||||
**
|
||||
** A transaction must be started before executing this opcode.
|
||||
*/
|
||||
case OP_SetCookie: {
|
||||
int aMeta[SQLITE_N_BTREE_META];
|
||||
rc = sqliteBtreeGetMeta(pBt, aMeta);
|
||||
if( rc==SQLITE_OK ){
|
||||
aMeta[1] = pOp->p1;
|
||||
rc = sqliteBtreeUpdateMeta(pBt, aMeta);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: VerifyCookie P1 * *
|
||||
**
|
||||
** Check the current value of the database cookie and make sure it is
|
||||
** equal to P1. If it is not, abort with an SQLITE_SCHEMA error.
|
||||
**
|
||||
** The cookie changes its value whenever the database schema changes.
|
||||
** This operation is used to detech when that the cookie has changed
|
||||
** and that the current process needs to reread the schema.
|
||||
**
|
||||
** Either a transaction needs to have been started or an OP_Open needs
|
||||
** to be executed (to establish a read lock) before this opcode is
|
||||
** invoked.
|
||||
*/
|
||||
case OP_VerifyCookie: {
|
||||
int aMeta[SQLITE_N_BTREE_META];
|
||||
rc = sqliteBtreeGetMeta(pBt, aMeta);
|
||||
if( rc==SQLITE_OK && aMeta[1]!=pOp->p1 ){
|
||||
sqliteSetString(pzErrMsg, "database schema has changed", 0);
|
||||
rc = SQLITE_SCHEMA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Open P1 P2 P3
|
||||
**
|
||||
** Open a new cursor for the database table whose root page is
|
||||
@ -2013,9 +2086,8 @@ case OP_Open: {
|
||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
||||
}
|
||||
p->nCursor = i+1;
|
||||
}else if( p->aCsr[i].pCursor ){
|
||||
sqliteBtreeCloseCursor(p->aCsr[i].pCursor);
|
||||
}
|
||||
cleanupCursor(&p->aCsr[i]);
|
||||
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
||||
do{
|
||||
rc = sqliteBtreeCursor(pBt, p2, &p->aCsr[i].pCursor);
|
||||
@ -2058,10 +2130,9 @@ case OP_OpenTemp: {
|
||||
memset(&p->aCsr[j], 0, sizeof(Cursor));
|
||||
}
|
||||
p->nCursor = i+1;
|
||||
}else if( p->aCsr[i].pCursor ){
|
||||
sqliteBtreeCloseCursor(p->aCsr[i].pCursor);
|
||||
}
|
||||
pCx = &p->aCsr[i];
|
||||
cleanupCursor(pCx);
|
||||
memset(pCx, 0, sizeof(*pCx));
|
||||
rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt);
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -2081,17 +2152,7 @@ case OP_OpenTemp: {
|
||||
case OP_Close: {
|
||||
int i = pOp->p1;
|
||||
if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
|
||||
Cursor *pCx = &p->aCsr[i];
|
||||
sqliteBtreeCloseCursor(pCx->pCursor);
|
||||
pCx->pCursor = 0;
|
||||
if( pCx->zKey ){
|
||||
sqliteFree(pCx->zKey);
|
||||
pCx->zKey = 0;
|
||||
}
|
||||
if( pCx->pBt ){
|
||||
sqliteBtreeClose(pCx->pBt);
|
||||
pCx->pBt = 0;
|
||||
}
|
||||
cleanupCursor(&p->aCsr[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2523,6 +2584,7 @@ case OP_BeginIdx: {
|
||||
VERIFY( if( tos<0 ) goto not_enough_stack; )
|
||||
if( i>=0 && i<p->nCursor && (pCrsr = &p->aCsr[i])->pCursor!=0 ){
|
||||
if( Stringify(p, tos) ) goto no_mem;
|
||||
if( pCrsr->zKey ) sqliteFree(pCrsr->zKey);
|
||||
pCrsr->nKey = aStack[tos].n;
|
||||
pCrsr->zKey = sqliteMalloc( 2*(pCrsr->nKey + 1) );
|
||||
if( pCrsr->zKey==0 ) goto no_mem;
|
||||
|
200
src/vdbe.h
200
src/vdbe.h
@ -27,7 +27,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.21 2001/09/13 21:53:10 drh Exp $
|
||||
** $Id: vdbe.h,v 1.22 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_VDBE_H_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@ -75,118 +75,122 @@ typedef struct VdbeOp VdbeOp;
|
||||
#define OP_Commit 2
|
||||
#define OP_Rollback 3
|
||||
|
||||
#define OP_Open 4
|
||||
#define OP_OpenTemp 5
|
||||
#define OP_Close 6
|
||||
#define OP_MoveTo 7
|
||||
#define OP_Fcnt 8
|
||||
#define OP_NewRecno 9
|
||||
#define OP_Put 10
|
||||
#define OP_Distinct 11
|
||||
#define OP_Found 12
|
||||
#define OP_NotFound 13
|
||||
#define OP_Delete 14
|
||||
#define OP_Column 15
|
||||
#define OP_KeyAsData 16
|
||||
#define OP_Recno 17
|
||||
#define OP_FullKey 18
|
||||
#define OP_Rewind 19
|
||||
#define OP_Next 20
|
||||
#define OP_ReadCookie 4
|
||||
#define OP_SetCookie 5
|
||||
#define OP_VerifyCookie 6
|
||||
|
||||
#define OP_Destroy 21
|
||||
#define OP_Clear 22
|
||||
#define OP_CreateIndex 23
|
||||
#define OP_CreateTable 24
|
||||
#define OP_Reorganize 25
|
||||
#define OP_Open 7
|
||||
#define OP_OpenTemp 8
|
||||
#define OP_Close 9
|
||||
#define OP_MoveTo 10
|
||||
#define OP_Fcnt 11
|
||||
#define OP_NewRecno 12
|
||||
#define OP_Put 13
|
||||
#define OP_Distinct 14
|
||||
#define OP_Found 15
|
||||
#define OP_NotFound 16
|
||||
#define OP_Delete 17
|
||||
#define OP_Column 18
|
||||
#define OP_KeyAsData 19
|
||||
#define OP_Recno 20
|
||||
#define OP_FullKey 21
|
||||
#define OP_Rewind 22
|
||||
#define OP_Next 23
|
||||
|
||||
#define OP_BeginIdx 26
|
||||
#define OP_NextIdx 27
|
||||
#define OP_PutIdx 28
|
||||
#define OP_DeleteIdx 29
|
||||
#define OP_Destroy 24
|
||||
#define OP_Clear 25
|
||||
#define OP_CreateIndex 26
|
||||
#define OP_CreateTable 27
|
||||
#define OP_Reorganize 28
|
||||
|
||||
#define OP_MemLoad 30
|
||||
#define OP_MemStore 31
|
||||
#define OP_BeginIdx 29
|
||||
#define OP_NextIdx 30
|
||||
#define OP_PutIdx 31
|
||||
#define OP_DeleteIdx 32
|
||||
|
||||
#define OP_ListOpen 32
|
||||
#define OP_ListWrite 33
|
||||
#define OP_ListRewind 34
|
||||
#define OP_ListRead 35
|
||||
#define OP_ListClose 36
|
||||
#define OP_MemLoad 33
|
||||
#define OP_MemStore 34
|
||||
|
||||
#define OP_SortOpen 37
|
||||
#define OP_SortPut 38
|
||||
#define OP_SortMakeRec 39
|
||||
#define OP_SortMakeKey 40
|
||||
#define OP_Sort 41
|
||||
#define OP_SortNext 42
|
||||
#define OP_SortKey 43
|
||||
#define OP_SortCallback 44
|
||||
#define OP_SortClose 45
|
||||
#define OP_ListOpen 35
|
||||
#define OP_ListWrite 36
|
||||
#define OP_ListRewind 37
|
||||
#define OP_ListRead 38
|
||||
#define OP_ListClose 39
|
||||
|
||||
#define OP_FileOpen 46
|
||||
#define OP_FileRead 47
|
||||
#define OP_FileColumn 48
|
||||
#define OP_FileClose 49
|
||||
#define OP_SortOpen 40
|
||||
#define OP_SortPut 41
|
||||
#define OP_SortMakeRec 42
|
||||
#define OP_SortMakeKey 43
|
||||
#define OP_Sort 44
|
||||
#define OP_SortNext 45
|
||||
#define OP_SortKey 46
|
||||
#define OP_SortCallback 47
|
||||
#define OP_SortClose 48
|
||||
|
||||
#define OP_AggReset 50
|
||||
#define OP_AggFocus 51
|
||||
#define OP_AggIncr 52
|
||||
#define OP_AggNext 53
|
||||
#define OP_AggSet 54
|
||||
#define OP_AggGet 55
|
||||
#define OP_FileOpen 49
|
||||
#define OP_FileRead 50
|
||||
#define OP_FileColumn 51
|
||||
#define OP_FileClose 52
|
||||
|
||||
#define OP_SetInsert 56
|
||||
#define OP_SetFound 57
|
||||
#define OP_SetNotFound 58
|
||||
#define OP_SetClear 59
|
||||
#define OP_AggReset 53
|
||||
#define OP_AggFocus 54
|
||||
#define OP_AggIncr 55
|
||||
#define OP_AggNext 56
|
||||
#define OP_AggSet 57
|
||||
#define OP_AggGet 58
|
||||
|
||||
#define OP_MakeRecord 60
|
||||
#define OP_MakeKey 61
|
||||
#define OP_MakeIdxKey 62
|
||||
#define OP_SetInsert 59
|
||||
#define OP_SetFound 60
|
||||
#define OP_SetNotFound 61
|
||||
#define OP_SetClear 62
|
||||
|
||||
#define OP_Goto 63
|
||||
#define OP_If 64
|
||||
#define OP_Halt 65
|
||||
#define OP_MakeRecord 63
|
||||
#define OP_MakeKey 64
|
||||
#define OP_MakeIdxKey 65
|
||||
|
||||
#define OP_ColumnCount 66
|
||||
#define OP_ColumnName 67
|
||||
#define OP_Callback 68
|
||||
#define OP_Goto 66
|
||||
#define OP_If 67
|
||||
#define OP_Halt 68
|
||||
|
||||
#define OP_Integer 69
|
||||
#define OP_String 70
|
||||
#define OP_Null 71
|
||||
#define OP_Pop 72
|
||||
#define OP_Dup 73
|
||||
#define OP_Pull 74
|
||||
#define OP_ColumnCount 69
|
||||
#define OP_ColumnName 70
|
||||
#define OP_Callback 71
|
||||
|
||||
#define OP_Add 75
|
||||
#define OP_AddImm 76
|
||||
#define OP_Subtract 77
|
||||
#define OP_Multiply 78
|
||||
#define OP_Divide 79
|
||||
#define OP_Min 80
|
||||
#define OP_Max 81
|
||||
#define OP_Like 82
|
||||
#define OP_Glob 83
|
||||
#define OP_Eq 84
|
||||
#define OP_Ne 85
|
||||
#define OP_Lt 86
|
||||
#define OP_Le 87
|
||||
#define OP_Gt 88
|
||||
#define OP_Ge 89
|
||||
#define OP_IsNull 90
|
||||
#define OP_NotNull 91
|
||||
#define OP_Negative 92
|
||||
#define OP_And 93
|
||||
#define OP_Or 94
|
||||
#define OP_Not 95
|
||||
#define OP_Concat 96
|
||||
#define OP_Noop 97
|
||||
#define OP_Integer 72
|
||||
#define OP_String 73
|
||||
#define OP_Null 74
|
||||
#define OP_Pop 75
|
||||
#define OP_Dup 76
|
||||
#define OP_Pull 77
|
||||
|
||||
#define OP_Strlen 98
|
||||
#define OP_Substr 99
|
||||
#define OP_Add 78
|
||||
#define OP_AddImm 79
|
||||
#define OP_Subtract 80
|
||||
#define OP_Multiply 81
|
||||
#define OP_Divide 82
|
||||
#define OP_Min 83
|
||||
#define OP_Max 84
|
||||
#define OP_Like 85
|
||||
#define OP_Glob 86
|
||||
#define OP_Eq 87
|
||||
#define OP_Ne 88
|
||||
#define OP_Lt 89
|
||||
#define OP_Le 90
|
||||
#define OP_Gt 91
|
||||
#define OP_Ge 92
|
||||
#define OP_IsNull 93
|
||||
#define OP_NotNull 94
|
||||
#define OP_Negative 95
|
||||
#define OP_And 96
|
||||
#define OP_Or 97
|
||||
#define OP_Not 98
|
||||
#define OP_Concat 99
|
||||
#define OP_Noop 100
|
||||
|
||||
#define OP_MAX 99
|
||||
#define OP_Strlen 101
|
||||
#define OP_Substr 102
|
||||
|
||||
#define OP_MAX 102
|
||||
|
||||
/*
|
||||
** Prototypes for the VDBE interface. See comments on the implementation
|
||||
|
@ -25,7 +25,7 @@
|
||||
** the WHERE clause of SQL statements. Also found here are subroutines
|
||||
** to generate VDBE code to evaluate expressions.
|
||||
**
|
||||
** $Id: where.c,v 1.18 2001/09/13 16:18:55 drh Exp $
|
||||
** $Id: where.c,v 1.19 2001/09/15 00:57:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -299,6 +299,11 @@ WhereInfo *sqliteWhereBegin(
|
||||
for(i=0; i<pTabList->nId; i++){
|
||||
sqliteVdbeAddOp(v, OP_Open, base+i, pTabList->a[i].pTab->tnum,
|
||||
pTabList->a[i].pTab->zName, 0);
|
||||
if( i==0 && !pParse->schemaVerified &&
|
||||
(pParse->db->flags & SQLITE_InTrans)==0 ){
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0);
|
||||
pParse->schemaVerified = 1;
|
||||
}
|
||||
if( i<ARRAYSIZE(aIdx) && aIdx[i]!=0 ){
|
||||
sqliteVdbeAddOp(v, OP_Open, base+pTabList->nId+i, aIdx[i]->tnum,
|
||||
aIdx[i]->zName, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user