aboutsummaryrefslogtreecommitdiff
path: root/src/trigger.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2003-03-27 12:51:24 +0000
committerdrh <drh@noemail.net>2003-03-27 12:51:24 +0000
commitd24cc427b7f83ca65aefbb6cf1831d0461f16357 (patch)
treee8c0700ba474499cd46b5f6cc49c3bd1a4b607c0 /src/trigger.c
parent84e6335c0c244dfde752ee4e166b6770dd9d2e10 (diff)
downloadsqlite-d24cc427b7f83ca65aefbb6cf1831d0461f16357.tar.gz
sqlite-d24cc427b7f83ca65aefbb6cf1831d0461f16357.zip
Changes to the "sqlite" structure that allow simultaneous operations on
multiple database files. Many regession tests pass - but not all of them. Do not use this version except for debugging SQLite itself. (CVS 883) FossilOrigin-Name: d2fb2bb50cf1e13feb90995079f291384abd6ba9
Diffstat (limited to 'src/trigger.c')
-rw-r--r--src/trigger.c152
1 files changed, 83 insertions, 69 deletions
diff --git a/src/trigger.c b/src/trigger.c
index 76bdc77ba..4c0c00740 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -41,7 +41,7 @@ void sqliteCreateTrigger(
int tr_tm, /* One of TK_BEFORE, TK_AFTER , TK_INSTEAD */
int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
IdList *pColumns, /* column list if this is an UPDATE OF trigger */
- Token *pTableName, /* The name of the table/view the trigger applies to */
+ SrcList *pTableName,/* The name of the table/view the trigger applies to */
int foreach, /* One of TK_ROW or TK_STATEMENT */
Expr *pWhen, /* WHEN clause */
TriggerStep *pStepList, /* The triggered program */
@@ -50,6 +50,7 @@ void sqliteCreateTrigger(
Trigger *nt;
Table *tab;
char *zName = 0; /* Name of the trigger */
+ sqlite *db = pParse->db;
/* Check that:
** 1. the trigger name does not already exist.
@@ -58,60 +59,55 @@ void sqliteCreateTrigger(
** 4. That we are not trying to create an INSTEAD OF trigger on a table.
** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
*/
+ if( sqlite_malloc_failed ) goto trigger_cleanup;
+ assert( pTableName->nSrc==1 );
+ tab = sqliteTableNameToTable(pParse, pTableName->a[0].zName,
+ pTableName->a[0].zDatabase);
+ if( !tab ){
+ goto trigger_cleanup;
+ }
+ if( tab->iDb>=2 ){
+ sqliteSetString(&pParse->zErrMsg, "triggers may not be added to "
+ "auxiliary database \"", db->aDb[tab->iDb].zName, "\"", 0);
+ pParse->nErr++;
+ goto trigger_cleanup;
+ }
+
zName = sqliteStrNDup(pName->z, pName->n);
- if( sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1) ){
+ if( sqliteHashFind(&(db->aDb[tab->iDb].trigHash), zName,pName->n+1) ){
sqliteSetNString(&pParse->zErrMsg, "trigger ", -1,
pName->z, pName->n, " already exists", -1, 0);
pParse->nErr++;
goto trigger_cleanup;
}
+ if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
+ sqliteSetString(&pParse->zErrMsg,"cannot create trigger on system table",0);
+ pParse->nErr++;
+ goto trigger_cleanup;
+ }
+ if( tab->pSelect && tr_tm != TK_INSTEAD ){
+ sqliteSetNString(&pParse->zErrMsg, "cannot create ",
+ (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", " trigger on view: ",
+ pTableName->a[0].zName, 0);
+ goto trigger_cleanup;
+ }
+ if( !tab->pSelect && tr_tm == TK_INSTEAD ){
+ sqliteSetNString(&pParse->zErrMsg, "cannot create INSTEAD OF",
+ " trigger on table: ", pTableName->a[0].zName);
+ goto trigger_cleanup;
+ }
+#ifndef SQLITE_OMIT_AUTHORIZATION
{
- char *tmp_str = sqliteStrNDup(pTableName->z, pTableName->n);
- if( tmp_str==0 ) goto trigger_cleanup;
- tab = sqliteFindTable(pParse->db, tmp_str);
- sqliteFree(tmp_str);
- if( !tab ){
- sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1,
- pTableName->z, pTableName->n, 0);
- pParse->nErr++;
- goto trigger_cleanup;
- }
- if( sqliteStrICmp(tab->zName, MASTER_NAME)==0 ){
- sqliteSetString(&pParse->zErrMsg, "cannot create trigger on system "
- "table: " MASTER_NAME, 0);
- pParse->nErr++;
- goto trigger_cleanup;
- }
- if( sqliteStrICmp(tab->zName, TEMP_MASTER_NAME)==0 ){
- sqliteSetString(&pParse->zErrMsg, "cannot create trigger on system "
- "table: " TEMP_MASTER_NAME, 0);
- pParse->nErr++;
+ int code = SQLITE_CREATE_TRIGGER;
+ if( tab->iDb==1 ) code = SQLITE_CREATE_TEMP_TRIGGER;
+ if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
goto trigger_cleanup;
}
- if( tab->pSelect && tr_tm != TK_INSTEAD ){
- sqliteSetNString(&pParse->zErrMsg, "cannot create ", -1,
- (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", -1, " trigger on view: ", -1
- , pTableName->z, pTableName->n, 0);
+ if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0)){
goto trigger_cleanup;
}
- if( !tab->pSelect && tr_tm == TK_INSTEAD ){
- sqliteSetNString(&pParse->zErrMsg, "cannot create INSTEAD OF", -1,
- " trigger on table: ", -1, pTableName->z, pTableName->n, 0);
- goto trigger_cleanup;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_CREATE_TRIGGER;
- if( tab->isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
- if( sqliteAuthCheck(pParse, code, zName, tab->zName) ){
- goto trigger_cleanup;
- }
- if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->isTemp), 0)){
- goto trigger_cleanup;
- }
- }
-#endif
}
+#endif
if (tr_tm == TK_INSTEAD){
tr_tm = TK_BEFORE;
@@ -122,8 +118,9 @@ void sqliteCreateTrigger(
if( nt==0 ) goto trigger_cleanup;
nt->name = zName;
zName = 0;
- nt->table = sqliteStrNDup(pTableName->z, pTableName->n);
+ nt->table = sqliteStrDup(pTableName->a[0].zName);
if( sqlite_malloc_failed ) goto trigger_cleanup;
+ nt->iDb = tab->iDb;
nt->op = op;
nt->tr_tm = tr_tm;
nt->pWhen = sqliteExprDup(pWhen);
@@ -154,15 +151,15 @@ void sqliteCreateTrigger(
v = sqliteGetVdbe(pParse);
if( v==0 ) goto trigger_cleanup;
sqliteBeginWriteOperation(pParse, 0, 0);
- sqliteOpenMasterTable(v, tab->isTemp);
+ sqliteOpenMasterTable(v, tab->iDb);
addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
- sqliteVdbeChangeP3(v, addr, tab->isTemp ? TEMP_MASTER_NAME : MASTER_NAME,
+ sqliteVdbeChangeP3(v, addr, tab->iDb ? TEMP_MASTER_NAME : MASTER_NAME,
P3_STATIC);
sqliteVdbeChangeP3(v, addr+2, nt->name, 0);
sqliteVdbeChangeP3(v, addr+3, nt->table, 0);
sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
- if( !tab->isTemp ){
- sqliteChangeCookie(pParse->db, v);
+ if( tab->iDb==0 ){
+ sqliteChangeCookie(db, v);
}
sqliteVdbeAddOp(v, OP_Close, 0, 0);
sqliteEndWriteOperation(pParse);
@@ -170,7 +167,7 @@ void sqliteCreateTrigger(
if( !pParse->explain ){
/* Stick it in the hash-table */
- sqliteHashInsert(&(pParse->db->trigHash), nt->name, pName->n + 1, nt);
+ sqliteHashInsert(&(db->aDb[nt->iDb].trigHash), nt->name, pName->n + 1, nt);
/* Attach it to the table object */
nt->pNext = tab->pTrigger;
@@ -185,6 +182,7 @@ void sqliteCreateTrigger(
trigger_cleanup:
sqliteFree(zName);
+ sqliteSrcListDelete(pTableName);
sqliteIdListDelete(pColumns);
sqliteExprDelete(pWhen);
sqliteDeleteTriggerStep(pStepList);
@@ -342,31 +340,46 @@ void sqliteDeleteTrigger(Trigger *pTrigger){
* table. This is so that the trigger can be restored into the database schema
* if the transaction is rolled back.
*/
-void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
- char *zName;
+void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
Trigger *pTrigger;
Table *pTable;
Vdbe *v;
-
- zName = sqliteStrNDup(pName->z, pName->n);
-
- /* ensure that the trigger being dropped exists */
- pTrigger = sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1);
+ int i;
+ const char *zDb;
+ const char *zName;
+ int nName;
+ sqlite *db = pParse->db;
+
+ if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
+ assert( pName->nSrc==1 );
+ zDb = pName->a[0].zDatabase;
+ 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);
+ if( pTrigger ) break;
+ }
if( !pTrigger ){
- sqliteSetNString(&pParse->zErrMsg, "no such trigger: ", -1,
- zName, -1, 0);
- sqliteFree(zName);
- return;
+ sqliteSetString(&pParse->zErrMsg, "no such trigger: ", zName, 0);
+ goto drop_trigger_cleanup;
+ }
+ assert( pTrigger->iDb>=0 && pTrigger->iDb<db->nDb );
+ if( pTrigger->iDb>=2 ){
+ sqliteSetString(&pParse->zErrMsg, "triggers may not be removed from "
+ "auxiliary database \"", db->aDb[pTrigger->iDb].zName, "\"", 0);
+ pParse->nErr++;
+ goto drop_trigger_cleanup;
}
- pTable = sqliteFindTable(pParse->db, pTrigger->table);
+ pTable = sqliteFindTable(db, pTrigger->table, db->aDb[pTrigger->iDb].zName);
assert(pTable);
+ assert( pTable->iDb==pTrigger->iDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_TRIGGER;
- if( pTable->isTemp ) code = SQLITE_DROP_TEMP_TRIGGER;
+ if( pTable->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName) ||
- sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->isTemp),0) ){
- sqliteFree(zName);
+ sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->iDb),0) ){
return;
}
}
@@ -389,7 +402,7 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
}
assert(cc);
}
- sqliteHashInsert(&(pParse->db->trigHash), zName, pName->n + 1, NULL);
+ sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
sqliteDeleteTrigger(pTrigger);
}
@@ -409,17 +422,18 @@ void sqliteDropTrigger(Parse *pParse, Token *pName, int nested){
};
sqliteBeginWriteOperation(pParse, 0, 0);
- sqliteOpenMasterTable(v, pTable->isTemp);
+ sqliteOpenMasterTable(v, pTable->iDb);
base = sqliteVdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
sqliteVdbeChangeP3(v, base+1, zName, 0);
- if( !pTable->isTemp ){
- sqliteChangeCookie(pParse->db, v);
+ if( pTable->iDb==0 ){
+ sqliteChangeCookie(db, v);
}
sqliteVdbeAddOp(v, OP_Close, 0, 0);
sqliteEndWriteOperation(pParse);
}
- sqliteFree(zName);
+drop_trigger_cleanup:
+ sqliteSrcListDelete(pName);
}
/*