diff --git a/manifest b/manifest index af8704ffb8..a3ec3901f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sin\sthe\strigger\scode.\s(CVS\s884) -D 2003-03-27T13:01:29 +C Regression\stests\snow\swork\s-\sexcept\sfor\ssome\schanges\sin\serror\smessage\ntext.\s\sThe\slibrary\sis\snow\ssafe\sto\suse\sfor\sexperimental\swork.\s(CVS\s885) +D 2003-03-27T13:50:00 F Makefile.in 6917c2149a586f11b47c428f2ba748eb1da04f69 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -22,14 +22,14 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2 F src/auth.c f37bfc9451b8c1fa52f34adff474560018892729 F src/btree.c 327819bb858d534072f5004973f8bcdd50f133d6 F src/btree.h 8209bfadf5845d4fdaa60f471bb360f894cd4095 -F src/build.c abd5da38923bba6c5dc14d0e24b8e05f68ff459b -F src/delete.c e1552bd5a26418c32b8516cb5602bf5473651c68 +F src/build.c 0c14b18192a825a18c5c03df5c2db0e6f85ed44b +F src/delete.c 923497248e0ff9097a595c6333ec6d67fe6650b5 F src/encode.c faf03741efe921755ec371cf4a6984536de00042 F src/expr.c eae205a27ec45232f234f281f8827c3be58b303d F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 -F src/insert.c 8d23a2d9995d5bee5b7eb44cb9dc354e0874e70a +F src/insert.c 95e7ab3fb51909351273a6c6f8aa831201130ce7 F src/main.c e0d9a86541f0644be5c875c6d8f5062c325c653d F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/os.c dfed46091f69cd2d1e601f8a214d41344f2b00b6 @@ -43,7 +43,7 @@ F src/select.c afdc06d4606d14ab5793ef480206def6b02a2f19 F src/shell.c 0d260a007e0668fc7dda2b0c89bd597ef2966ec6 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 6f648803f2ffb9beb35cb1cfa42b323d55519171 -F src/sqliteInt.h c4338bc3c75784840d51fd8a744a63e444ec496d +F src/sqliteInt.h 5335f694cba9f07538cf8207aab11d48e0b9a2f8 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 F src/tclsqlite.c 8167d40fd34036701e07492d07a6f9e5c4015241 F src/test1.c 7ad4e6308dde0bf5a0f0775ce20cb2ec37a328f8 @@ -51,8 +51,8 @@ F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700 F src/test3.c c12ea7f1c3fbbd58904e81e6cb10ad424e6fc728 F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/tokenize.c 675b4718d17c69fe7609dc8e85e426ef002be811 -F src/trigger.c 5e2b4cd05dc1ece62911bae2c6d0c1da486910b8 -F src/update.c 785e0e1c8df2043dc96ad7c298fb11aaa3ebc8af +F src/trigger.c 64ad4be538e524b0dff0c377debf62fe54cc8c17 +F src/update.c ab8c48ce00747ccf8f449f7f51ae56e08b5428ba F src/util.c 73b668d1ed468df650dc00685a5e4ffa6887feb4 F src/vdbe.c 7171dbe873760f403b2501e96fd3d1bd852b3ce8 F src/vdbe.h ed43771f1dc2b994d5c484fdf2eab357c6ef0ee3 @@ -156,7 +156,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 9ac71c329e17a0934d2a824eacc33e9a2ebce7c3 -R 73acb81d40c3749321870765682932e8 +P 7672914b196cd55744edda8e5d8f1b7b86f898f9 +R ef1de606572d96575e808b13bdc2a270 U drh -Z a17b58550476cb426e51600a2c69c02b +Z 5cf2b764f7e1375be431b06267e44f31 diff --git a/manifest.uuid b/manifest.uuid index 4c1978dc32..85379b11b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7672914b196cd55744edda8e5d8f1b7b86f898f9 \ No newline at end of file +8a593e9c2d57e758739a7ef54fa40ca6a0071a9a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 4900e92316..12f54a59b4 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.134 2003/03/27 12:51:24 drh Exp $ +** $Id: build.c,v 1.135 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" #include @@ -117,8 +117,9 @@ Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; for(i=0; inDb; i++){ - if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[i].zName) ) continue; - p = sqliteHashFind(&db->aDb[i].tblHash, zName, strlen(zName)+1); + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[j].zName) ) continue; + p = sqliteHashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1); if( p ) break; } return p; @@ -133,8 +134,9 @@ Index *sqliteFindIndex(sqlite *db, const char *zName, const char *zDb){ Index *p = 0; int i; for(i=0; inDb; i++){ - if( zDb && sqliteStrICmp(zDb, db->aDb[i].zName) ) continue; - p = sqliteHashFind(&db->aDb[i].idxHash, zName, strlen(zName)+1); + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDb && sqliteStrICmp(zDb, db->aDb[j].zName) ) continue; + p = sqliteHashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1); if( p ) break; } return p; @@ -1444,8 +1446,7 @@ void sqliteCreateIndex( if( pTable!=0 ){ assert( pName!=0 ); assert( pTable->nSrc==1 ); - pTab = sqliteTableNameToTable(pParse, - pTable->a[0].zName, pTable->a[0].zDatabase); + pTab = sqliteSrcListLookup(pParse, pTable); }else{ assert( pName==0 ); pTab = pParse->pNewTable; @@ -1985,9 +1986,8 @@ void sqliteCopy( if( sqlite_malloc_failed ) goto copy_cleanup; assert( pTableName->nSrc==1 ); - pTab = sqliteTableNameToTable(pParse, pTableName->a[0].zName, - pTableName->a[0].zDatabase); - if( pTab==0 ) goto copy_cleanup; + pTab = sqliteSrcListLookup(pParse, pTableName); + if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto copy_cleanup; zFile = sqliteStrNDup(pFilename->z, pFilename->n); sqliteDequote(zFile); if( sqliteAuthCheck(pParse, SQLITE_INSERT, pTab->zName, zFile) diff --git a/src/delete.c b/src/delete.c index 770a400826..7fc2ddf911 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,39 +12,52 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.48 2003/03/27 12:51:24 drh Exp $ +** $Id: delete.c,v 1.49 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" - /* -** Given a table name, find the corresponding table and make sure the -** table is writeable. Generate an error and return NULL if not. If -** everything checks out, return a pointer to the Table structure. +** Look up every table that is named in pSrc. If any table is not found, +** add an error message to pParse->zErrMsg and return NULL. If all tables +** are found, return a pointer to the last table. */ -Table *sqliteTableNameToTable(Parse *pParse, const char *zTab, const char *zDb){ - Table *pTab; - pTab = sqliteFindTable(pParse->db, zTab, zDb); - if( pTab==0 ){ - if( zDb==0 || zDb[0]==0 ){ - sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0); - }else{ - sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0); +Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){ + Table *pTab = 0; + int i; + for(i=0; inSrc; i++){ + const char *zTab = pSrc->a[i].zName; + const char *zDb = pSrc->a[i].zDatabase; + pTab = sqliteFindTable(pParse->db, zTab, zDb); + if( pTab==0 ){ + if( zDb==0 || zDb[0]==0 ){ + sqliteSetString(&pParse->zErrMsg, "no such table: ", zTab, 0); + }else{ + sqliteSetString(&pParse->zErrMsg, "no such table: ", zDb, ".", zTab, 0); + } + pParse->nErr++; + break; } - pParse->nErr++; - return 0; - } - if( pTab->readOnly || pTab->pSelect ){ - sqliteSetString(&pParse->zErrMsg, - pTab->pSelect ? "view " : "table ", - zTab, - " may not be modified", 0); - pParse->nErr++; - return 0; + pSrc->a[i].pTab = pTab; } return pTab; } +/* +** Check to make sure the given table is writable. If it is not +** writable, generate an error message and return 1. If it is +** writable return 0; +*/ +int sqliteIsReadOnly(Parse *pParse, Table *pTab){ + if( pTab->readOnly || pTab->pSelect ){ + sqliteSetString(&pParse->zErrMsg, + pTab->pSelect ? "view " : "table ", pTab->zName, + " may not be modified", 0); + pParse->nErr++; + return 1; + } + return 0; +} + /* ** Process a DELETE FROM statement. */ @@ -101,8 +114,8 @@ void sqliteDeleteFrom( ** will be calling are designed to work with multiple tables and expect ** an SrcList* parameter instead of just a Table* parameter. */ - pTab = pTabList->a[0].pTab = sqliteTableNameToTable(pParse, zTab, zDb); - if( pTab==0 ){ + pTab = sqliteSrcListLookup(pParse, pTabList); + if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ){ goto delete_from_cleanup; } assert( pTab->pSelect==0 ); /* This table is not a view */ diff --git a/src/insert.c b/src/insert.c index 14f7824b03..f9f72f8c40 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.75 2003/03/27 12:51:25 drh Exp $ +** $Id: insert.c,v 1.76 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" @@ -93,7 +93,6 @@ void sqliteInsert( ){ Table *pTab; /* The table to insert into */ char *zTab; /* Name of the table into which we are inserting */ - char *zDb; /* Name of the database holding zTab */ int i, j, idx; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ Index *pIdx; /* For looping over indices of the table */ @@ -121,8 +120,7 @@ void sqliteInsert( assert( pTabList->nSrc==1 ); zTab = pTabList->a[0].zName; if( zTab==0 ) goto insert_cleanup; - zDb = pTabList->a[0].zDatabase; - pTab = sqliteTableNameToTable(pParse, zTab, zDb); + pTab = sqliteSrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 854e255ea6..dcc325f755 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.165 2003/03/27 12:51:25 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.166 2003/03/27 13:50:00 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -253,6 +253,13 @@ struct sqlite { #endif }; +/* +** The following are the indices of in sqlite.aDb[] of the main database +** file and the file used to store TEMP tables. +*/ +#define DB_TMP 0 +#define DB_MAIN 1 + /* ** Possible values for the sqlite.flags. */ @@ -1001,7 +1008,8 @@ Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*, int,int,int); void sqliteSelectDelete(Select*); void sqliteSelectUnbind(Select*); -Table *sqliteTableNameToTable(Parse*, const char*, const char*); +Table *sqliteSrcListLookup(Parse*, SrcList*); +int sqliteIsReadOnly(Parse*, Table*); void sqliteDeleteFrom(Parse*, SrcList*, Expr*); void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqliteWhereBegin(Parse*, int, SrcList*, Expr*, int, ExprList**); diff --git a/src/trigger.c b/src/trigger.c index c0f0e6c260..2b7d35a245 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -61,8 +61,7 @@ void sqliteCreateTrigger( */ if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); - tab = sqliteTableNameToTable(pParse, pTableName->a[0].zName, - pTableName->a[0].zDatabase); + tab = sqliteSrcListLookup(pParse, pTableName); if( !tab ){ goto trigger_cleanup; } @@ -356,8 +355,9 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){ zName = pName->a[0].zName; nName = strlen(zName); for(i=0; inDb; i++){ - if( zDb && sqliteStrICmp(db->aDb[i].zName, zDb) ) continue; - pTrigger = sqliteHashFind(&(db->aDb[i].trigHash), zName, nName+1); + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue; + pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1); if( pTrigger ) break; } if( !pTrigger ){ diff --git a/src/update.c b/src/update.c index f76686d53d..fb06030612 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.56 2003/03/27 12:51:25 drh Exp $ +** $Id: update.c,v 1.57 2003/03/27 13:50:00 drh Exp $ */ #include "sqliteInt.h" @@ -84,8 +84,8 @@ void sqliteUpdate( ** will be calling are designed to work with multiple tables and expect ** an SrcList* parameter instead of just a Table* parameter. */ - pTab = pTabList->a[0].pTab = sqliteTableNameToTable(pParse, zTab, zDb); - if( pTab==0 ) goto update_cleanup; + pTab = sqliteSrcListLookup(pParse, pTabList); + if( pTab==0 || sqliteIsReadOnly(pParse, pTab) ) goto update_cleanup; assert( pTab->pSelect==0 ); /* This table is not a VIEW */ aXRef = sqliteMalloc( sizeof(int) * pTab->nCol ); if( aXRef==0 ) goto update_cleanup;