Hello here is patch with fault tolerant drop trigger and drop rule support
drop trigger [if exists] trgname on [if exists] tablename; drop rule [if exists] trgname on [if exists] tablename; Regards Pavel 2013/11/11 Pavel Stehule <pavel.steh...@gmail.com> > > > > 2013/11/11 Tom Lane <t...@sss.pgh.pa.us> > >> Andres Freund <and...@2ndquadrant.com> writes: >> > Turns out that's bogus - ALTER TABLE has two levels of NOT EXISTS. >> >> > Maybe we should just do the same for DROP TRIGGER? >> >> > DROP TRIGGER [ IF EXISTS ] name ON table_name [ IF EXISTS ] [ CASCADE | >> RESTRICT ] >> >> Works for me. >> > > for me too > > tomorrow I'll prepare patch > > Regards > > Pavel > > >> >> regards, tom lane >> >> >> -- >> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) >> To make changes to your subscription: >> http://www.postgresql.org/mailpref/pgsql-hackers >> > >
diff --git a/doc/src/sgml/ref/drop_rule.sgml b/doc/src/sgml/ref/drop_rule.sgml index c845872..585f67b 100644 --- a/doc/src/sgml/ref/drop_rule.sgml +++ b/doc/src/sgml/ref/drop_rule.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -DROP RULE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> [ CASCADE | RESTRICT ] +DROP RULE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON [ IF EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> [ CASCADE | RESTRICT ] </synopsis> </refsynopsisdiv> @@ -42,8 +42,8 @@ DROP RULE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON <re <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the rule does not exist. A notice is issued - in this case. + Do not throw an error if the rule does not exist (or if a parent table + does not exist). A notice is issued in this case. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/drop_trigger.sgml b/doc/src/sgml/ref/drop_trigger.sgml index 3ec6cc7..1f46eff 100644 --- a/doc/src/sgml/ref/drop_trigger.sgml +++ b/doc/src/sgml/ref/drop_trigger.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -DROP TRIGGER [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> [ CASCADE | RESTRICT ] +DROP TRIGGER [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON [ IF EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> [ CASCADE | RESTRICT ] </synopsis> </refsynopsisdiv> @@ -44,8 +44,8 @@ DROP TRIGGER [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> ON <term><literal>IF EXISTS</literal></term> <listitem> <para> - Do not throw an error if the trigger does not exist. A notice is issued - in this case. + Do not throw an error if the trigger does not exist (or parent table + does not exist). A notice is issued in this case. </para> </listitem> </varlistentry> diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index cecddf1..36ef9ae 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -423,7 +423,8 @@ static ObjectAddress get_relation_by_qualified_name(ObjectType objtype, List *objname, Relation *relp, LOCKMODE lockmode, bool missing_ok); static ObjectAddress get_object_address_relobject(ObjectType objtype, - List *objname, Relation *relp, bool missing_ok); + List *objname, Relation *relp, + bool missing_ok, bool missing_parent_ok); static ObjectAddress get_object_address_attribute(ObjectType objtype, List *objname, Relation *relp, LOCKMODE lockmode, bool missing_ok); @@ -464,7 +465,8 @@ static void getRelationIdentity(StringInfo buffer, Oid relid); */ ObjectAddress get_object_address(ObjectType objtype, List *objname, List *objargs, - Relation *relp, LOCKMODE lockmode, bool missing_ok) + Relation *relp, LOCKMODE lockmode, + bool missing_ok, bool missing_parent_ok) { ObjectAddress address; ObjectAddress old_address = {InvalidOid, InvalidOid, 0}; @@ -507,7 +509,9 @@ get_object_address(ObjectType objtype, List *objname, List *objargs, case OBJECT_TRIGGER: case OBJECT_CONSTRAINT: address = get_object_address_relobject(objtype, objname, - &relation, missing_ok); + &relation, + missing_ok, + missing_parent_ok); break; case OBJECT_DATABASE: case OBJECT_EXTENSION: @@ -622,7 +626,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs, */ if (!OidIsValid(address.objectId)) { - Assert(missing_ok); + Assert(missing_ok || missing_parent_ok); return address; } @@ -898,7 +902,9 @@ get_relation_by_qualified_name(ObjectType objtype, List *objname, */ static ObjectAddress get_object_address_relobject(ObjectType objtype, List *objname, - Relation *relp, bool missing_ok) + Relation *relp, + bool missing_ok, + bool missing_parent_ok) { ObjectAddress address; Relation relation = NULL; @@ -942,42 +948,55 @@ get_object_address_relobject(ObjectType objtype, List *objname, /* Extract relation name and open relation. */ relname = list_truncate(list_copy(objname), nnames - 1); - relation = heap_openrv(makeRangeVarFromNameList(relname), - AccessShareLock); - reloid = RelationGetRelid(relation); + relation = heap_openrv_extended(makeRangeVarFromNameList(relname), + AccessShareLock, + missing_parent_ok); - switch (objtype) + if (relation != NULL) { - case OBJECT_RULE: - address.classId = RewriteRelationId; - address.objectId = get_rewrite_oid(reloid, depname, missing_ok); - address.objectSubId = 0; - break; - case OBJECT_TRIGGER: - address.classId = TriggerRelationId; - address.objectId = get_trigger_oid(reloid, depname, missing_ok); - address.objectSubId = 0; - break; - case OBJECT_CONSTRAINT: - address.classId = ConstraintRelationId; - address.objectId = - get_relation_constraint_oid(reloid, depname, missing_ok); - address.objectSubId = 0; - break; - default: - elog(ERROR, "unrecognized objtype: %d", (int) objtype); - /* placate compiler, which doesn't know elog won't return */ - address.classId = InvalidOid; - address.objectId = InvalidOid; - address.objectSubId = 0; - } + reloid = RelationGetRelid(relation); - /* Avoid relcache leak when object not found. */ - if (!OidIsValid(address.objectId)) + switch (objtype) + { + case OBJECT_RULE: + address.classId = RewriteRelationId; + address.objectId = get_rewrite_oid(reloid, depname, missing_ok); + address.objectSubId = 0; + break; + case OBJECT_TRIGGER: + address.classId = TriggerRelationId; + address.objectId = get_trigger_oid(reloid, depname, missing_ok); + address.objectSubId = 0; + break; + case OBJECT_CONSTRAINT: + address.classId = ConstraintRelationId; + address.objectId = + get_relation_constraint_oid(reloid, depname, missing_ok); + address.objectSubId = 0; + break; + default: + elog(ERROR, "unrecognized objtype: %d", (int) objtype); + /* placate compiler, which doesn't know elog won't return */ + address.classId = InvalidOid; + address.objectId = InvalidOid; + address.objectSubId = 0; + } + + /* Avoid relcache leak when object not found. */ + if (!OidIsValid(address.objectId)) + { + heap_close(relation, AccessShareLock); + relation = NULL; /* department of accident prevention */ + return address; + } + } + else { - heap_close(relation, AccessShareLock); - relation = NULL; /* department of accident prevention */ - return address; + Assert(missing_parent_ok); + + address.classId = InvalidOid; + address.objectId = InvalidOid; + address.objectSubId = 0; } } diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index b62ec70..04e1481 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -364,7 +364,8 @@ ExecRenameStmt(RenameStmt *stmt) address = get_object_address(stmt->renameType, stmt->object, stmt->objarg, &relation, - AccessExclusiveLock, false); + AccessExclusiveLock, + false, false); Assert(relation == NULL); catalog = heap_open(address.classId, RowExclusiveLock); @@ -431,6 +432,7 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) stmt->objarg, &relation, AccessExclusiveLock, + false, false); Assert(relation == NULL); classId = address.classId; @@ -725,6 +727,7 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) stmt->objarg, &relation, AccessExclusiveLock, + false, false); Assert(relation == NULL); classId = address.classId; diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 5ecc92a..5b77e87 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -71,7 +71,8 @@ CommentObject(CommentStmt *stmt) * against concurrent DROP operations. */ address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, - &relation, ShareUpdateExclusiveLock, false); + &relation, ShareUpdateExclusiveLock, + false, false); /* Require ownership of the target object. */ check_object_ownership(GetUserId(), stmt->objtype, address, diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index b32ad3a..4529727 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -31,6 +31,8 @@ static void does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs); +static void parent_not_exists_skipping(ObjectType objtype, + List *objname); /* * Drop one or more objects. @@ -71,12 +73,17 @@ RemoveObjects(DropStmt *stmt) objname, objargs, &relation, AccessExclusiveLock, - stmt->missing_ok); + stmt->missing_ok, + stmt->missing_parent_ok); /* Issue NOTICE if supplied object was not found. */ if (!OidIsValid(address.objectId)) { - does_not_exist_skipping(stmt->removeType, objname, objargs); + /* ObjectId can be invalid due missing parent relation */ + if (stmt->missing_parent_ok && !OidIsValid(address.classId)) + parent_not_exists_skipping(stmt->removeType, objname); + else + does_not_exist_skipping(stmt->removeType, objname, objargs); continue; } @@ -244,3 +251,25 @@ does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs) else ereport(NOTICE, (errmsg(msg, name, args))); } + +/* + * Generate a NOTICE "table does not exists, skipping". It is used when + * clause IF EXISTS is twice used. + */ +static void +parent_not_exists_skipping(ObjectType objtype, List *objname) +{ + switch (objtype) + { + case OBJECT_RULE: + case OBJECT_TRIGGER: + ereport(NOTICE, + (errmsg("table \%s\" does not exists, skipping", + NameListToString(list_truncate(list_copy(objname), + list_length(objname) - 1))))); + break; + default: + elog(ERROR, "unexpected object type (%d)", (int) objtype); + break; + } +} diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 798c92a..83a6d92 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2908,7 +2908,8 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) * against concurrent DROP and ALTER EXTENSION ADD/DROP operations. */ object = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, - &relation, ShareUpdateExclusiveLock, false); + &relation, ShareUpdateExclusiveLock, + false, false); /* Permission check: must own target object, too */ check_object_ownership(GetUserId(), stmt->objtype, object, diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index eaf0d0d..115c395 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -88,7 +88,8 @@ ExecSecLabelStmt(SecLabelStmt *stmt) * guard against concurrent modifications. */ address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, - &relation, ShareUpdateExclusiveLock, false); + &relation, ShareUpdateExclusiveLock, + false, false); /* Require ownership of the target object. */ check_object_ownership(GetUserId(), stmt->objtype, address, diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 1733da6..a8c5b85 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2798,6 +2798,7 @@ _copyDropStmt(const DropStmt *from) COPY_SCALAR_FIELD(removeType); COPY_SCALAR_FIELD(behavior); COPY_SCALAR_FIELD(missing_ok); + COPY_SCALAR_FIELD(missing_parent_ok); COPY_SCALAR_FIELD(concurrent); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7b29812..7fe85fb 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1137,6 +1137,7 @@ _equalDropStmt(const DropStmt *a, const DropStmt *b) COMPARE_SCALAR_FIELD(removeType); COMPARE_SCALAR_FIELD(behavior); COMPARE_SCALAR_FIELD(missing_ok); + COMPARE_SCALAR_FIELD(missing_parent_ok); COMPARE_SCALAR_FIELD(concurrent); return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8dc4b1c..2fb9388 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3546,6 +3546,7 @@ DropPLangStmt: n->arguments = NIL; n->behavior = $5; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -3556,6 +3557,7 @@ DropPLangStmt: n->objects = list_make1(list_make1(makeString($6))); n->behavior = $7; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -3969,6 +3971,7 @@ DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior n->objects = list_make1(list_make1(makeString($5))); n->arguments = NIL; n->missing_ok = false; + n->missing_parent_ok = false; n->behavior = $6; n->concurrent = false; $$ = (Node *) n; @@ -3980,6 +3983,7 @@ DropFdwStmt: DROP FOREIGN DATA_P WRAPPER name opt_drop_behavior n->objects = list_make1(list_make1(makeString($7))); n->arguments = NIL; n->missing_ok = true; + n->missing_parent_ok = false; n->behavior = $8; n->concurrent = false; $$ = (Node *) n; @@ -4131,6 +4135,7 @@ DropForeignServerStmt: DROP SERVER name opt_drop_behavior n->objects = list_make1(list_make1(makeString($3))); n->arguments = NIL; n->missing_ok = false; + n->missing_parent_ok = false; n->behavior = $4; n->concurrent = false; $$ = (Node *) n; @@ -4142,6 +4147,7 @@ DropForeignServerStmt: DROP SERVER name opt_drop_behavior n->objects = list_make1(list_make1(makeString($5))); n->arguments = NIL; n->missing_ok = true; + n->missing_parent_ok = false; n->behavior = $6; n->concurrent = false; $$ = (Node *) n; @@ -4512,6 +4518,7 @@ DropTrigStmt: n->arguments = NIL; n->behavior = $6; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -4523,6 +4530,31 @@ DropTrigStmt: n->arguments = NIL; n->behavior = $8; n->missing_ok = true; + n->missing_parent_ok = false; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP TRIGGER name ON IF_P EXISTS any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TRIGGER; + n->objects = list_make1(lappend($7, makeString($3))); + n->arguments = NIL; + n->behavior = $8; + n->missing_ok = false; + n->missing_parent_ok = true; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP TRIGGER IF_P EXISTS name ON IF_P EXISTS any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_TRIGGER; + n->objects = list_make1(lappend($9, makeString($5))); + n->arguments = NIL; + n->behavior = $10; + n->missing_ok = true; + n->missing_parent_ok = true; n->concurrent = false; $$ = (Node *) n; } @@ -5055,6 +5087,7 @@ DropOpClassStmt: n->removeType = OBJECT_OPCLASS; n->behavior = $7; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -5066,6 +5099,7 @@ DropOpClassStmt: n->removeType = OBJECT_OPCLASS; n->behavior = $9; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -5080,6 +5114,7 @@ DropOpFamilyStmt: n->removeType = OBJECT_OPFAMILY; n->behavior = $7; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -5091,6 +5126,7 @@ DropOpFamilyStmt: n->removeType = OBJECT_OPFAMILY; n->behavior = $9; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -5139,6 +5175,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior DropStmt *n = makeNode(DropStmt); n->removeType = $2; n->missing_ok = TRUE; + n->missing_parent_ok = false; n->objects = $5; n->arguments = NIL; n->behavior = $6; @@ -5150,6 +5187,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior DropStmt *n = makeNode(DropStmt); n->removeType = $2; n->missing_ok = FALSE; + n->missing_parent_ok = false; n->objects = $3; n->arguments = NIL; n->behavior = $4; @@ -5161,6 +5199,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_INDEX; n->missing_ok = FALSE; + n->missing_parent_ok = false; n->objects = $4; n->arguments = NIL; n->behavior = $5; @@ -5172,6 +5211,7 @@ DropStmt: DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_INDEX; n->missing_ok = TRUE; + n->missing_parent_ok = false; n->objects = $6; n->arguments = NIL; n->behavior = $7; @@ -6635,6 +6675,7 @@ RemoveFuncStmt: n->arguments = list_make1(extractArgTypes($4)); n->behavior = $5; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6646,6 +6687,7 @@ RemoveFuncStmt: n->arguments = list_make1(extractArgTypes($6)); n->behavior = $7; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6660,6 +6702,7 @@ RemoveAggrStmt: n->arguments = list_make1(extractArgTypes($4)); n->behavior = $5; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6671,6 +6714,7 @@ RemoveAggrStmt: n->arguments = list_make1(extractArgTypes($6)); n->behavior = $7; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6685,6 +6729,7 @@ RemoveOperStmt: n->arguments = list_make1($4); n->behavior = $5; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6696,6 +6741,7 @@ RemoveOperStmt: n->arguments = list_make1($6); n->behavior = $7; n->missing_ok = true; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -6813,6 +6859,7 @@ DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_beha n->arguments = list_make1(list_make1($7)); n->behavior = $9; n->missing_ok = $3; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *)n; } @@ -7821,6 +7868,7 @@ DropRuleStmt: n->arguments = NIL; n->behavior = $6; n->missing_ok = false; + n->missing_parent_ok = false; n->concurrent = false; $$ = (Node *) n; } @@ -7832,6 +7880,31 @@ DropRuleStmt: n->arguments = NIL; n->behavior = $8; n->missing_ok = true; + n->missing_parent_ok = false; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP RULE name ON IF_P EXISTS any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_RULE; + n->objects = list_make1(lappend($7, makeString($3))); + n->arguments = NIL; + n->behavior = $8; + n->missing_ok = false; + n->missing_parent_ok = true; + n->concurrent = false; + $$ = (Node *) n; + } + | DROP RULE IF_P EXISTS name ON IF_P EXISTS any_name opt_drop_behavior + { + DropStmt *n = makeNode(DropStmt); + n->removeType = OBJECT_RULE; + n->objects = list_make1(lappend($9, makeString($5))); + n->arguments = NIL; + n->behavior = $10; + n->missing_ok = true; + n->missing_parent_ok = true; n->concurrent = false; $$ = (Node *) n; } diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h index e2a5b0d..05f20ff 100644 --- a/src/include/catalog/objectaddress.h +++ b/src/include/catalog/objectaddress.h @@ -30,7 +30,8 @@ typedef struct ObjectAddress extern ObjectAddress get_object_address(ObjectType objtype, List *objname, List *objargs, Relation *relp, - LOCKMODE lockmode, bool missing_ok); + LOCKMODE lockmode, + bool missing_ok, bool missing_parent_ok); extern void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 952fbb3..57178bd 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2003,6 +2003,7 @@ typedef struct DropStmt ObjectType removeType; /* object type */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ bool missing_ok; /* skip error if object is missing? */ + bool missing_parent_ok; /* skip error if parent is missing? */ bool concurrent; /* drop index concurrently? */ } DropStmt; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 62fc7c5..c688999 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2630,3 +2630,10 @@ ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renam ERROR: renaming an ON SELECT rule is not allowed DROP VIEW rule_v1; DROP TABLE rule_t1; +-- +-- fault tolerant drop rule +-- +DROP RULE IF EXISTS noexistname ON IF EXISTS noexistname; +NOTICE: table noexistname" does not exists, skipping +DROP RULE noexistname ON IF EXISTS noexistname; +NOTICE: table noexistname" does not exists, skipping diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index 6a6ecf7..35622cc 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -1731,3 +1731,8 @@ select * from self_ref_trigger; drop table self_ref_trigger; drop function self_ref_trigger_ins_func(); drop function self_ref_trigger_del_func(); +-- fault tolerant trigger +drop trigger not_exists_trigger on if exists not_exists_table; +NOTICE: table not_exists_table" does not exists, skipping +drop trigger if exists not_exists_trigger on if exists not_exists_table; +NOTICE: table not_exists_table" does not exists, skipping diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index 1e15f84..23e9423 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -1007,3 +1007,9 @@ ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renam DROP VIEW rule_v1; DROP TABLE rule_t1; + +-- +-- fault tolerant drop rule +-- +DROP RULE IF EXISTS noexistname ON IF EXISTS noexistname; +DROP RULE noexistname ON IF EXISTS noexistname; diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql index 0ea2c31..6174f95 100644 --- a/src/test/regress/sql/triggers.sql +++ b/src/test/regress/sql/triggers.sql @@ -1173,3 +1173,7 @@ select * from self_ref_trigger; drop table self_ref_trigger; drop function self_ref_trigger_ins_func(); drop function self_ref_trigger_del_func(); + +-- fault tolerant trigger +drop trigger not_exists_trigger on if exists not_exists_table; +drop trigger if exists not_exists_trigger on if exists not_exists_table;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers