diff options
author | drh <drh@noemail.net> | 2003-03-27 13:50:00 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2003-03-27 13:50:00 +0000 |
commit | 812d7a21dd30c9ed9aebdb063a3efedede092d63 (patch) | |
tree | 40176d47b4cc2c517ba9dd0d0cef845861ae3cad /src | |
parent | 0951d703f2dcd3f096f1cdec7a2c3c304956f5fe (diff) | |
download | sqlite-812d7a21dd30c9ed9aebdb063a3efedede092d63.tar.gz sqlite-812d7a21dd30c9ed9aebdb063a3efedede092d63.zip |
Regression tests now work - except for some changes in error message
text. The library is now safe to use for experimental work. (CVS 885)
FossilOrigin-Name: 8a593e9c2d57e758739a7ef54fa40ca6a0071a9a
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 20 | ||||
-rw-r--r-- | src/delete.c | 55 | ||||
-rw-r--r-- | src/insert.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 12 | ||||
-rw-r--r-- | src/trigger.c | 8 | ||||
-rw-r--r-- | src/update.c | 6 |
6 files changed, 63 insertions, 44 deletions
diff --git a/src/build.c b/src/build.c index 4900e9231..12f54a59b 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 <ctype.h> @@ -117,8 +117,9 @@ Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; for(i=0; i<db->nDb; 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; i<db->nDb; 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 770a40082..7fc2ddf91 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,37 +12,50 @@ ** 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; i<pSrc->nSrc; 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; + 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 ", - zTab, + pTab->pSelect ? "view " : "table ", pTab->zName, " may not be modified", 0); pParse->nErr++; - return 0; + return 1; } - return pTab; + return 0; } /* @@ -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 14f7824b0..f9f72f8c4 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 854e255ea..dcc325f75 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" @@ -254,6 +254,13 @@ struct sqlite { }; /* +** 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. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ @@ -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 c0f0e6c26..2b7d35a24 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; i<db->nDb; 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 f76686d53..fb0603061 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; |