aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2003-03-27 13:50:00 +0000
committerdrh <drh@noemail.net>2003-03-27 13:50:00 +0000
commit812d7a21dd30c9ed9aebdb063a3efedede092d63 (patch)
tree40176d47b4cc2c517ba9dd0d0cef845861ae3cad /src
parent0951d703f2dcd3f096f1cdec7a2c3c304956f5fe (diff)
downloadsqlite-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.c20
-rw-r--r--src/delete.c55
-rw-r--r--src/insert.c6
-rw-r--r--src/sqliteInt.h12
-rw-r--r--src/trigger.c8
-rw-r--r--src/update.c6
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;