]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Require the INSTEAD OF syntax to create triggers on database views. (CVS 591)
authordanielk1977 <danielk1977@noemail.net>
Sun, 26 May 2002 23:24:40 +0000 (23:24 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Sun, 26 May 2002 23:24:40 +0000 (23:24 +0000)
FossilOrigin-Name: d9e48cd5180e2aae7672b9d54e18c37d0fe5258a

manifest
manifest.uuid
src/trigger.c
test/trigger1.test
www/lang.tcl

index ad6cf7c78683bbe07c5c576fd9e97305ac42fee3..ecec19fcc63c9bf37b5059ec5c2c30d4e9b15a94 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sfunctions\sto\shandle\sNULLs\scorrectly.\s\sAdded\sthe\sNULLIF()\sfunction.\s(CVS\s590)
-D 2002-05-26T21:34:58
+C Require\sthe\sINSTEAD\sOF\ssyntax\sto\screate\striggers\son\sdatabase\sviews.\s(CVS\s591)
+D 2002-05-26T23:24:41
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -49,7 +49,7 @@ F src/test2.c 669cc22781c6461a273416ec1a7414d25c081730
 F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
 F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
 F src/tokenize.c facec7dc0b4a13e17ad67702f548dac2f7c6a732
-F src/trigger.c f9adb404ea355a8be2c9cd9740794a898cf1096c
+F src/trigger.c b7a93ffa7b91dafff433e6c87d603bfb1d50e3ee
 F src/update.c f68375173bf5338cae3e97012708e10f206aedd9
 F src/util.c a9f6e6f03e8b7137204ac15b35a58f321e38037e
 F src/vdbe.c caa269517b2392986c8f55401f272e76b9de82d9
@@ -100,7 +100,7 @@ F test/tclsqlite.test 79deeffd7cd637ca0f06c5dbbf2f44d272079533
 F test/temptable.test daa83489eea2e9aaeeece09675c28be84c72cb67
 F test/tester.tcl dc1b56bd628b487e4d75bfd1e7480b5ed8810ac6
 F test/trans.test ae0b9a82d5d34122c3a3108781eb8d078091ccee
-F test/trigger1.test a0550c5cce97170dbebb88eee09506d9ad1174e9
+F test/trigger1.test bb63749fa8a395a60541100607d86381604b7194
 F test/trigger2.test 7f2b0a9b20004449c78b834c2f22494db3b2e63a
 F test/unique.test 572aa791327c1e8d797932263e9d67f176cfdb44
 F test/update.test a0aa0bf83e6fad8407d0e4ad25ebb09b513f5bf4
@@ -128,14 +128,14 @@ F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
 F www/faq.tcl 45bdb18b75ac3aa1befec42985fb892413aac0bb
 F www/formatchng.tcl 2ce21ff30663fad6618198fe747ce675df577590
 F www/index.tcl d0c52fbf031d0a3ee6d9d77aa669d5a4b24b6130
-F www/lang.tcl be7a241fe3dbb145ff25fe951c3d8ad16b543a1f
+F www/lang.tcl e87aa6b305d92977a6bd84bfcddd18fa76dff60a
 F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
 F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
 F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 9051173742f1b0e15a809d12a0c9c98fd2c4614d
-R 0620e522ec88d7386c2177fd29ebfac3
-U drh
-Z 0624defcbccb679d773bc9ffe5a1ecda
+P 46ce1a9ab6e527958ebc757fa2175c488299cd84
+R 35b518a6cb0a7aed91c92408e7bd6686
+U danielk1977
+Z 9e3f1ec0355281ef07dac5144d661dfb
index 424c86b5e6a29997734e41afcc6f99020e35b734..6cf893c2460343ac6bfb6f1fa29728bf5dead098 100644 (file)
@@ -1 +1 @@
-46ce1a9ab6e527958ebc757fa2175c488299cd84
\ No newline at end of file
+d9e48cd5180e2aae7672b9d54e18c37d0fe5258a
\ No newline at end of file
index 82ba258a01fc44eb5f69e7c8dcc64a5769b8e1d2..92971b7610a8ce40b9b17fb66fc8ffdb12f6c7be 100644 (file)
@@ -20,7 +20,7 @@
 void sqliteCreateTrigger(
   Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
   Token *pName,       /* The name of the trigger */
-  int tr_tm,          /* One of TK_BEFORE, TK_AFTER */
+  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 */
@@ -38,6 +38,9 @@ void sqliteCreateTrigger(
   /* Check that: 
   ** 1. the trigger name does not already exist.
   ** 2. the table (or view) does exist.
+  ** 3. that we are not trying to create a trigger on the sqlite_master table
+  ** 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.
   */
   {
     char *tmp_str = sqliteStrNDup(pName->z, pName->n);
@@ -67,6 +70,21 @@ void sqliteCreateTrigger(
       pParse->nErr++;
       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);
+      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;
+    }
+  }
+
+  if (tr_tm == TK_INSTEAD){
+    tr_tm = TK_BEFORE;
   }
 
   /* Build the Trigger object */
index 153f71766a7dda05e8992a7994ed7a2c4afa2e03..bfd5e6e6a9ec35b9b432009cae62bcb8b1d3dd41 100644 (file)
 # trig-1.6: Error if dropped trigger doesn't exist
 # trig-1.7: Dropping the table automatically drops all triggers
 # trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
+# trig-1.9: Ensure that we cannot create a trigger on sqlite_master
+# trig-1.10:
+# trig-1.11:
+# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
+# trig-1.13: Ensure that AFTER triggers cannot be created on views
+# trig-1.14: Ensure that BEFORE triggers cannot be created on views
 #
 
 set testdir [file dirname $argv0]
@@ -145,4 +151,33 @@ do_test trig_cd-1.11 {
   }
 } {1 x-a 2 b 4 d}
 
+# Ensure that we cannot create INSTEAD OF triggers on tables
+do_test trig_cd-1.12 {
+  catchsql {
+    create table t1(a,b);
+    create trigger t1t instead of update on t1 for each row begin
+      delete from t1 WHERE a=old.a+2;
+    end;
+  }
+} {1 {cannot create INSTEAD OF trigger on table: t1}}
+# Ensure that we cannot create BEFORE triggers on views
+do_test trig_cd-1.13 {
+  catchsql {
+    create view v1 as select * from t1;
+    create trigger v1t before update on v1 for each row begin
+      delete from t1 WHERE a=old.a+2;
+    end;
+  }
+} {1 {cannot create BEFORE trigger on view: v1}}
+# Ensure that we cannot create AFTER triggers on views
+do_test trig_cd-1.14 {
+  catchsql {
+    create table t1(a,b);
+    create view v1 as select * from t1;
+    create trigger v1t AFTER update on v1 for each row begin
+      delete from t1 WHERE a=old.a+2;
+    end;
+  }
+} {1 {cannot create AFTER trigger on view: v1}}
+
 finish_test
index a99d387ae411689f3155ac14c6f9afcc3c611abb..e12fa55aa96abe645611c071c9de74d3aaf46c9b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: lang.tcl,v 1.35 2002/05/15 11:43:16 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.36 2002/05/26 23:24:41 danielk1977 Exp $}
 
 puts {<html>
 <head>
@@ -353,6 +353,12 @@ CREATE TRIGGER <trigger-name> [ BEFORE | AFTER ]
 <trigger-action>
 }
 
+Syntax {sql-statement} {
+CREATE TRIGGER <trigger-name> INSTEAD OF
+<database-event> ON <view-name>
+<trigger-action>
+}
+
 Syntax {database-event} {
 DELETE | 
 INSERT | 
@@ -425,12 +431,13 @@ policy is used instead.</p>
 <p>Triggers are automatically dropped when the table that they are 
 associated with is dropped.</p>
 
-<p>Triggers may be created on views, as well as ordinary tables. If one or
-more INSERT, DELETE or UPDATE triggers are defined on a view, then it is not
-an error to execute an INSERT, DELETE or UPDATE statement on the view, 
-respectively. Thereafter, executing an INSERT, DELETE or UPDATE on the view
-causes the associated triggers to fire. The real tables underlying the view
-are not modified (except possibly explicitly, by a trigger program).</p>
+<p>Triggers may be created on views, as well as ordinary tables, by specifying
+INSTEAD OF in the CREATE TRIGGER statement. If one or more ON INSERT, ON DELETE
+or ON UPDATE triggers are defined on a view, then it is not an error to execute
+an INSERT, DELETE or UPDATE statement on the view, respectively. Thereafter,
+executing an INSERT, DELETE or UPDATE on the view causes the associated
+  triggers to fire. The real tables underlying the view are not modified
+  (except possibly explicitly, by a trigger program).</p>
 
 <p><b>Example:</b></p>