diff options
author | drh <drh@noemail.net> | 2006-09-11 23:45:48 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2006-09-11 23:45:48 +0000 |
commit | fdd48a76a6446da07aa5b9471485211ae87f1a1f (patch) | |
tree | 03fceb758bd53c7b20086ed8ed7d9b8f8568383a | |
parent | 4240240f1218a304ddc14e76d321ff0529a9491e (diff) | |
download | sqlite-fdd48a76a6446da07aa5b9471485211ae87f1a1f.tar.gz sqlite-fdd48a76a6446da07aa5b9471485211ae87f1a1f.zip |
Add support for IF EXISTS on CREATE/DROP TRIGGER/VIEW. Ticket #1899. (CVS 3406)
FossilOrigin-Name: e4fe736cfbbdc081581911a01690576034877b72
-rw-r--r-- | manifest | 28 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/build.c | 7 | ||||
-rw-r--r-- | src/parse.y | 16 | ||||
-rw-r--r-- | src/sqliteInt.h | 8 | ||||
-rw-r--r-- | src/trigger.c | 13 | ||||
-rw-r--r-- | src/vacuum.c | 34 | ||||
-rw-r--r-- | test/trigger1.test | 17 | ||||
-rw-r--r-- | test/view.test | 21 | ||||
-rw-r--r-- | www/lang.tcl | 12 |
10 files changed, 91 insertions, 67 deletions
@@ -1,5 +1,5 @@ -C Re-use\sdeleted\srowids\sfor\snew\ssegments.\s\sThis\shas\sa\ssomewhat\nsurprising\simpact\son\sperformance,\sI\sbelieve\sbecause\sit\skeeps\sthe\sindex\nsmaller\s(by\skeeping\srowids\ssmaller),\sand\salso\sbecause\sit\simproves\nlocality\sin\sthe\stable\s(deleting\sa\srow\smeans\swe've\salready\stouched\sthe\npages\sleading\sto\sthat\srowid).\s(CVS\s3405) -D 2006-09-11T21:39:22 +C Add\ssupport\sfor\sIF\sEXISTS\son\sCREATE/DROP\sTRIGGER/VIEW.\s\sTicket\s#1899.\s(CVS\s3406) +D 2006-09-11T23:45:49 F Makefile.in cabd42d34340f49260bc2a7668c38eba8d4cfd99 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -50,7 +50,7 @@ F src/attach.c b11eb4d5d3fb99a10a626956bccc7215f6b68b16 F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f F src/btree.c 8f18bb08f84d6a12104fd0f01255febe6289a186 F src/btree.h 061c50e37de7f50b58528e352d400cf33ead7418 -F src/build.c 4359b34a36938716ed10ac037eec9dc5173b8f4b +F src/build.c 7199949a6a3449e9ec69408cc79a48ed04fd0b85 F src/callback.c fd9bb39f7ff6b52bad8365617abc61c720640429 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675 F src/date.c d5519023569adf30892ff7be6deadf25ecdf1ecd @@ -78,7 +78,7 @@ F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c e51c079b3cad8394898a6c22330150339103700a F src/pager.h 0cff9de5e9019cb695a04d18df8caaaff933a272 -F src/parse.y b26898e5270c3dc58798047e72cd57113663f761 +F src/parse.y 3279443a2b8173230dd27b9821373b681bb1f3c8 F src/pragma.c dcb79b8170231f3aed99d4004b4d0a0fc14c4b4d F src/prepare.c 84e2c855600c7bfbe2ca691b263301de525f9123 F src/printf.c b179b6ed12f793e028dd169e2e2e2b2a37eedc63 @@ -88,7 +88,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 233f7766e532a204bed465249ffc584424ed1757 F src/sqlite.h.in 19f5390cce182242b309a053aa1ee2b902bee147 F src/sqlite3ext.h 11a046b3519c4b9b7709e6d6a95c3a36366f684a -F src/sqliteInt.h 259adce944cc3b28da1fa3df9beb9ba86017a45d +F src/sqliteInt.h fc2439b695dd80a3c58c8f14759e621dbf630b03 F src/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1 F src/tclsqlite.c e029f739bed90071789fe81a226d53e97a80a4d8 F src/test1.c e8213bf8024a47b49ee8ad276ea07d8e3d4c3c26 @@ -107,11 +107,11 @@ F src/test_schema.c ced72140a3a25c148975428e170ec1850d3c3a7d F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c F src/test_tclvar.c 315e77c17f128ff8c06b38c08617fd07c825a95b F src/tokenize.c dfdff21768fbedd40e8d3ca84fc5d0d7af2b46dd -F src/trigger.c 0fc40125820409a6274834a6e04ad804d96e2793 +F src/trigger.c 74ccec784683232f89f3b4db34a089d8cace2058 F src/update.c 951f95ef044cf6d28557c48dc35cb0711a0b9129 F src/utf.c 4459801e9b00cfd69993bfca58545d3775682d6e F src/util.c 5409031819ee4672c5f9c3ac7cf517e267a25845 -F src/vacuum.c 5dac7938d70bf0cb5182a291c8605e69cde2398d +F src/vacuum.c e2cd47929d63c16d835b6052b82fd7422010b903 F src/vdbe.c a77869949ddd0afe01443611edb949e24e67c91c F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa F src/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b @@ -294,7 +294,7 @@ F test/tkt1667.test ef52c857940755ea5eab24d68f808826e7dcdc94 F test/tkt1873.test 7159a1c1bf627bbb03f11362e4ad4de11d6ff316 F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567 F test/trans.test 06bff0246886858793fca3748721936e2f65e3df -F test/trigger1.test e8c717e959c2f98c8181cd9466e140fa7aac781f +F test/trigger1.test 2c79e2bf76350811e362814e98779c120b6a9421 F test/trigger2.test 33bf8ae9b788013be194efe5f66c04a202facbb4 F test/trigger3.test 9102fd3933db294dc654b5aee9edfe9e94f2b9e2 F test/trigger4.test 4bed3705c9df4aaf7a7b164a2d573410d05ca025 @@ -312,7 +312,7 @@ F test/utf16align.test 7360e84472095518c56746f76b1f9d4dce99fb4d F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 -F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5 +F test/view.test 852bd4101e6d171c46ad682eb5c5faf662b2eba4 F test/vtab1.test c7275c6c6575dfbbd975757f646f94477a6ea5c0 F test/vtab2.test 43763026b124e68785de05d3fbf957a4b5f81a0d F test/vtab3.test f38d6d7d19f08bffdadce4d5b8cba078f8118587 @@ -375,7 +375,7 @@ F www/fullscanb.gif f7c94cb227f060511f8909e10f570157263e9a25 F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3 F www/index.tcl 7b9c5747a838501dace958131755651d6ca31adb F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1 -F www/lang.tcl 529f5f0f44b55f26cdb66c6547a86b1332e1144a +F www/lang.tcl 73ce7ce69eff7afef4d62cdeb7b050a670952acd F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf @@ -397,7 +397,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P d5ffef3870f06d2dd744ce9470d3c0e68062e804 -R 4f28d2c19780234e639fe3db42d9de5e -U shess -Z 323322cfc0451e1239808887226bd556 +P 2f5f6290c9ef99c7b060aecc4d996c976c50c9d7 +R d17bd6ef8648d9d2f3852e6272db6a75 +U drh +Z 86240886575897a77ef3f7d53b2d3c49 diff --git a/manifest.uuid b/manifest.uuid index 298e7e013..a92c67e51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f5f6290c9ef99c7b060aecc4d996c976c50c9d7
\ No newline at end of file +e4fe736cfbbdc081581911a01690576034877b72
\ No newline at end of file diff --git a/src/build.c b/src/build.c index 1f7a9267d..eeceded71 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.410 2006/08/14 14:23:42 drh Exp $ +** $Id: build.c,v 1.411 2006/09/11 23:45:49 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1590,7 +1590,8 @@ void sqlite3CreateView( Token *pName1, /* The token that holds the name of the view */ Token *pName2, /* The token that holds the name of the view */ Select *pSelect, /* A SELECT statement that will become the new view */ - int isTemp /* TRUE for a TEMPORARY view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ ){ Table *p; int n; @@ -1605,7 +1606,7 @@ void sqlite3CreateView( sqlite3SelectDelete(pSelect); return; } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0); + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); diff --git a/src/parse.y b/src/parse.y index f9445113c..122d7842c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.208 2006/08/25 23:42:53 drh Exp $ +** @(#) $Id: parse.y,v 1.209 2006/09/11 23:45:49 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -355,8 +355,8 @@ ifexists(A) ::= . {A = 0;} ///////////////////// The CREATE VIEW statement ///////////////////////////// // %ifndef SQLITE_OMIT_VIEW -cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). { - sqlite3CreateView(pParse, &X, &Y, &Z, S, T); +cmd ::= CREATE(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) AS select(S). { + sqlite3CreateView(pParse, &X, &Y, &Z, S, T, E); } cmd ::= DROP VIEW ifexists(E) fullname(X). { sqlite3DropTable(pParse, X, 1, E); @@ -931,10 +931,10 @@ cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { sqlite3FinishTrigger(pParse, S, &all); } -trigger_decl(A) ::= temp(T) TRIGGER nm(B) dbnm(Z) trigger_time(C) - trigger_event(D) +trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z) + trigger_time(C) trigger_event(D) ON fullname(E) foreach_clause(F) when_clause(G). { - sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, F, G, T); + sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, F, G, T, NOERR); A = (Z.n==0?B:Z); } @@ -1019,8 +1019,8 @@ raisetype(A) ::= FAIL. {A = OE_Fail;} //////////////////////// DROP TRIGGER statement ////////////////////////////// %ifndef SQLITE_OMIT_TRIGGER -cmd ::= DROP TRIGGER fullname(X). { - sqlite3DropTrigger(pParse,X); +cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). { + sqlite3DropTrigger(pParse,X,NOERR); } %endif // !SQLITE_OMIT_TRIGGER diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 582685414..fae55f2ec 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.525 2006/09/02 20:57:52 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.526 2006/09/11 23:45:50 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1600,7 +1600,7 @@ void sqlite3AddDefaultValue(Parse*,Expr*); void sqlite3AddCollateType(Parse*, const char*, int); void sqlite3EndTable(Parse*,Token*,Token*,Select*); -void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int); +void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) int sqlite3ViewGetColumnNames(Parse*,Table*); @@ -1691,9 +1691,9 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*, int); #ifndef SQLITE_OMIT_TRIGGER void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, - int,Expr*,int); + int,Expr*,int, int); void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); - void sqlite3DropTrigger(Parse*, SrcList*); + void sqlite3DropTrigger(Parse*, SrcList*, int); void sqlite3DropTriggerPtr(Parse*, Trigger*); int sqlite3TriggersExist(Parse*, Table*, int, ExprList*); int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, diff --git a/src/trigger.c b/src/trigger.c index 15992df38..efff8b833 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -49,7 +49,8 @@ void sqlite3BeginTrigger( 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 */ - int isTemp /* True if the TEMPORARY keyword is present */ + int isTemp, /* True if the TEMPORARY keyword is present */ + int noErr /* Suppress errors if the trigger already exists */ ){ Trigger *pTrigger = 0; Table *pTab; @@ -115,7 +116,9 @@ void sqlite3BeginTrigger( goto trigger_cleanup; } if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){ - sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + } goto trigger_cleanup; } @@ -439,7 +442,7 @@ void sqlite3DeleteTrigger(Trigger *pTrigger){ ** same job as this routine except it takes a pointer to the trigger ** instead of the trigger name. **/ -void sqlite3DropTrigger(Parse *pParse, SrcList *pName){ +void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ Trigger *pTrigger = 0; int i; const char *zDb; @@ -463,7 +466,9 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){ if( pTrigger ) break; } if( !pTrigger ){ - sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + if( !noErr ){ + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + } goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); diff --git a/src/vacuum.c b/src/vacuum.c index f15648c3d..f7737f88a 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -14,7 +14,7 @@ ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: vacuum.c,v 1.60 2006/09/11 11:13:27 drh Exp $ +** $Id: vacuum.c,v 1.61 2006/09/11 23:45:50 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -188,13 +188,6 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ - rc = execSql(db, - "INSERT INTO vacuum_db.sqlite_master " - " SELECT 'table', name, name, 0, sql" - " FROM sqlite_master" - " WHERE type='table' AND rootpage==0" - ); - if( rc ) goto end_of_vacuum; rc = execExecSql(db, "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) " " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" @@ -209,11 +202,6 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) " " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, - "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) " - " FROM sqlite_master WHERE type='view'" - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy @@ -244,17 +232,19 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ if( rc!=SQLITE_OK ) goto end_of_vacuum; - /* Copy the triggers from the main database to the temporary database. - ** This was deferred before in case the triggers interfered with copying - ** the data. It's possible the indices should be deferred until this - ** point also. + /* Copy the triggers, views, and virtual tables from the main database + ** over to the temporary database. None of these objects has any + ** associated storage, so all we have to do is copy their entries + ** from the SQLITE_MASTER table. */ - rc = execExecSql(db, - "SELECT 'CREATE TRIGGER vacuum_db.' || substr(sql, 16, 1000000) " - "FROM sqlite_master WHERE type='trigger'" + rc = execSql(db, + "INSERT INTO vacuum_db.sqlite_master " + " SELECT type, name, tbl_name, rootpage, sql" + " FROM sqlite_master" + " WHERE type='view' OR type='trigger'" + " OR (type='table' AND rootpage=0)" ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - + if( rc ) goto end_of_vacuum; /* At this point, unless the main db was completely empty, there is now a ** transaction open on the vacuum database, but not on the main database. diff --git a/test/trigger1.test b/test/trigger1.test index 3147927f8..ca2333582 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -60,6 +60,13 @@ execsql { INSERT INTO t1 values(1); END; } +do_test trigger1-1.2.0 { + catchsql { + CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN + SELECT * FROM sqlite_master; + END + } +} {0 {}} do_test trigger1-1.2.1 { catchsql { CREATE TRIGGER tr1 DELETE ON t1 BEGIN @@ -95,7 +102,7 @@ do_test trigger1-1.3 { do_test trigger1-1.4 { catchsql { - DROP TRIGGER tr1; + DROP TRIGGER IF EXISTS tr1; CREATE TRIGGER tr1 DELETE ON t1 BEGIN SELECT * FROM sqlite_master; END @@ -111,7 +118,13 @@ do_test trigger1-1.5 { } } {} -do_test trigger1-1.6 { +do_test trigger1-1.6.1 { + catchsql { + DROP TRIGGER IF EXISTS biggles; + } +} {0 {}} + +do_test trigger1-1.6.2 { catchsql { DROP TRIGGER biggles; } diff --git a/test/view.test b/test/view.test index 19c33f9d4..83ffec256 100644 --- a/test/view.test +++ b/test/view.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing VIEW statements. # -# $Id: view.test,v 1.32 2006/06/11 23:41:56 drh Exp $ +# $Id: view.test,v 1.33 2006/09/11 23:45:50 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -34,7 +34,7 @@ do_test view-1.0 { do_test view-1.1 { execsql { BEGIN; - CREATE VIEW v1 AS SELECT a,b FROM t1; + CREATE VIEW IF NOT EXISTS v1 AS SELECT a,b FROM t1; SELECT * FROM v1 ORDER BY a; } } {1 2 4 5 7 8} @@ -59,7 +59,7 @@ do_test view-1.3.1 { } {1 2 4 5 7 8} do_test view-1.4 { catchsql { - DROP VIEW v1; + DROP VIEW IF EXISTS v1; SELECT * FROM v1 ORDER BY a; } } {1 {no such table: v1}} @@ -482,5 +482,20 @@ do_test view-15.2 { } } {x 2 y 3} +do_test view-16.1 { + catchsql { + CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1; + } +} {0 {}} +do_test view-16.2 { + execsql { + SELECT sql FROM sqlite_master WHERE name='v1' + } +} {{CREATE VIEW v1 AS SELECT a AS 'xyz', b+c AS 'pqr', c-b FROM t1}} +do_test view-16.3 { + catchsql { + DROP VIEW IF EXISTS nosuchview + } +} {0 {}} finish_test diff --git a/www/lang.tcl b/www/lang.tcl index 75cda0f26..cd17ac480 100644 --- a/www/lang.tcl +++ b/www/lang.tcl @@ -1,7 +1,7 @@ # # Run this Tcl script to generate the lang-*.html files. # -set rcsid {$Id: lang.tcl,v 1.116 2006/08/29 13:08:38 drh Exp $} +set rcsid {$Id: lang.tcl,v 1.117 2006/09/11 23:45:50 drh Exp $} source common.tcl if {[llength $argv]>0} { @@ -638,13 +638,13 @@ statement. </p> Section {CREATE TRIGGER} createtrigger Syntax {sql-statement} { -CREATE [TEMP | TEMPORARY] TRIGGER <trigger-name> [ BEFORE | AFTER ] +CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] <trigger-name> [ BEFORE | AFTER ] <database-event> ON [<database-name> .] <table-name> <trigger-action> } Syntax {sql-statement} { -CREATE [TEMP | TEMPORARY] TRIGGER <trigger-name> INSTEAD OF +CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] <trigger-name> INSTEAD OF <database-event> ON [<database-name> .] <view-name> <trigger-action> } @@ -794,7 +794,7 @@ statement.</p> Section {CREATE VIEW} {createview} Syntax {sql-command} { -CREATE [TEMP | TEMPORARY] VIEW [<database-name>.] <view-name> AS <select-statement> +CREATE [TEMP | TEMPORARY] VIEW [IF NOT EXISTS] [<database-name>.] <view-name> AS <select-statement> } puts { @@ -941,7 +941,7 @@ result if the table does not exist.</p> Section {DROP TRIGGER} droptrigger Syntax {sql-statement} { -DROP TRIGGER [<database-name> .] <trigger-name> +DROP TRIGGER [IF EXISTS] [<database-name> .] <trigger-name> } puts { <p>The DROP TRIGGER statement removes a trigger created by the @@ -954,7 +954,7 @@ dropped when the associated table is dropped.</p> Section {DROP VIEW} dropview Syntax {sql-command} { -DROP VIEW <view-name> +DROP VIEW [IF EXISTS] <view-name> } puts { |