From bbcd01692bff099117f5afb0fe2d1ad182621766 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Fri, 16 Jun 2006 20:23:45 +0000 Subject: [PATCH] DROP ... IF EXISTS for the following cases: language, tablespace, trigger, rule, opclass, function, aggregate. operator, and cast. --- src/backend/commands/aggregatecmds.c | 18 ++++- src/backend/commands/functioncmds.c | 36 ++++++++-- src/backend/commands/opclasscmds.c | 39 ++++++++--- src/backend/commands/operatorcmds.c | 12 +++- src/backend/commands/proclang.c | 17 +++-- src/backend/commands/tablespace.c | 25 +++++-- src/backend/commands/trigger.c | 24 +++++-- src/backend/nodes/copyfuncs.c | 8 ++- src/backend/nodes/equalfuncs.c | 8 ++- src/backend/parser/gram.y | 99 ++++++++++++++++++++++++++-- src/backend/rewrite/rewriteRemove.c | 21 ++++-- src/backend/tcop/utility.c | 6 +- src/include/commands/trigger.h | 4 +- src/include/nodes/parsenodes.h | 8 ++- src/include/rewrite/rewriteRemove.h | 4 +- 15 files changed, 271 insertions(+), 58 deletions(-) diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 7b954edd38..7fb323a8b8 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.34 2006/04/15 17:45:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.35 2006/06/16 20:23:44 adunstan Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -211,7 +211,21 @@ RemoveAggregate(RemoveFuncStmt *stmt) ObjectAddress object; /* Look up function and make sure it's an aggregate */ - procOid = LookupAggNameTypeNames(aggName, aggArgs, false); + procOid = LookupAggNameTypeNames(aggName, aggArgs, stmt->missing_ok); + + if (!OidIsValid(procOid)) + { + /* we only get here if stmt->missing_ok is true */ + + /* XXX might need better message here */ + + ereport(NOTICE, + (errmsg("aggregate %s does not exist ... skipping", + stmt->name))); + + + return; + } /* * Find the function tuple, do permissions and validity checks diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 96929a0d6c..b37e2e8632 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.74 2006/04/15 17:45:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.75 2006/06/16 20:23:44 adunstan Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -687,7 +687,16 @@ RemoveFunction(RemoveFuncStmt *stmt) /* * Find the function, do permissions and validity checks */ - funcOid = LookupFuncNameTypeNames(functionName, argTypes, false); + funcOid = LookupFuncNameTypeNames(functionName, argTypes, stmt->missing_ok); + if (stmt->missing_ok &&!OidIsValid(funcOid)) + { + ereport(NOTICE, + (errmsg("function %s(%s) does not exist ... skipping", + NameListToString(functionName), + NameListToString(argTypes)))); + return; + } + tup = SearchSysCache(PROCOID, ObjectIdGetDatum(funcOid), @@ -1377,6 +1386,7 @@ DropCast(DropCastStmt *stmt) HeapTuple tuple; ObjectAddress object; + /* when dropping a cast, the types must exist even if you use IF EXISTS */ sourcetypeid = typenameTypeId(NULL, stmt->sourcetype); targettypeid = typenameTypeId(NULL, stmt->targettype); @@ -1385,11 +1395,23 @@ DropCast(DropCastStmt *stmt) ObjectIdGetDatum(targettypeid), 0, 0); if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("cast from type %s to type %s does not exist", - TypeNameToString(stmt->sourcetype), - TypeNameToString(stmt->targettype)))); + { + if (! stmt->missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("cast from type %s to type %s does not exist", + TypeNameToString(stmt->sourcetype), + TypeNameToString(stmt->targettype)))); + else + ereport(NOTICE, + (errmsg("cast from type %s to type %s does not exist ... skipping", + TypeNameToString(stmt->sourcetype), + TypeNameToString(stmt->targettype)))); + + return; + } + + /* Permission check */ if (!pg_type_ownercheck(sourcetypeid, GetUserId()) diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 8e67219cc0..343f5a70cf 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.45 2006/05/02 22:25:10 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.46 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -700,21 +700,40 @@ RemoveOpClass(RemoveOpClassStmt *stmt) /* Unqualified opclass name, so search the search path */ opcID = OpclassnameGetOpcid(amID, opcname); if (!OidIsValid(opcID)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("operator class \"%s\" does not exist for access method \"%s\"", - opcname, stmt->amname))); + { + if (! stmt -> missing_ok ) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("operator class \"%s\" does not exist for access method \"%s\"", + opcname, stmt->amname))); + else + ereport(NOTICE, + (errmsg("operator class \"%s\" does not exist for access method \"%s\"", + opcname, stmt->amname))); + + return; + } + tuple = SearchSysCache(CLAOID, ObjectIdGetDatum(opcID), 0, 0, 0); } if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("operator class \"%s\" does not exist for access method \"%s\"", - NameListToString(stmt->opclassname), stmt->amname))); - + { + + if (! stmt->missing_ok ) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("operator class \"%s\" does not exist for access method \"%s\"", + NameListToString(stmt->opclassname), stmt->amname))); + else + ereport(NOTICE, + (errmsg("operator class \"%s\" does not exist for access method \"%s\"", + NameListToString(stmt->opclassname), stmt->amname))); + return; + } + opcID = HeapTupleGetOid(tuple); /* Permission check: must own opclass or its namespace */ diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 54f50a8477..04c91f4509 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.30 2006/04/15 17:45:34 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.31 2006/06/16 20:23:44 adunstan Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -213,7 +213,15 @@ RemoveOperator(RemoveFuncStmt *stmt) Assert(list_length(stmt->args) == 2); operOid = LookupOperNameTypeNames(NULL, operatorName, typeName1, typeName2, - false, -1); + stmt->missing_ok, -1); + + if (stmt->missing_ok &&!OidIsValid(operOid) ) + { + ereport(NOTICE, + (errmsg("operator %s does not exist ... skipping", + NameListToString(operatorName)))); + return; + } tup = SearchSysCache(OPEROID, ObjectIdGetDatum(operOid), diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 801ccb13ec..e661d45239 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.64 2006/03/05 15:58:24 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.65 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -396,9 +396,18 @@ DropProceduralLanguage(DropPLangStmt *stmt) CStringGetDatum(languageName), 0, 0, 0); if (!HeapTupleIsValid(langTup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("language \"%s\" does not exist", languageName))); + { + if (! stmt->missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("language \"%s\" does not exist", languageName))); + else + ereport(NOTICE, + (errmsg("language \"%s\" does not exist ... skipping", + languageName))); + + return; + } object.classId = LanguageRelationId; object.objectId = HeapTupleGetOid(langTup); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index bafea91dfc..17dcf9f3a5 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.34 2006/03/29 21:17:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.35 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -403,10 +403,25 @@ DropTableSpace(DropTableSpaceStmt *stmt) tuple = heap_getnext(scandesc, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("tablespace \"%s\" does not exist", - tablespacename))); + { + if ( ! stmt->missing_ok ) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace \"%s\" does not exist", + tablespacename))); + } + else + { + ereport(NOTICE, + (errmsg("tablespace \"%s\" does not exist ... skipping", + tablespacename))); + /* XXX I assume I need one or both of these next two calls */ + heap_endscan(scandesc); + heap_close(rel, NoLock); + } + return; + } tablespaceoid = HeapTupleGetOid(tuple); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 04cd75e99f..2de7456827 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.202 2006/05/30 14:01:57 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.203 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -452,7 +452,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) * DropTrigger - drop an individual trigger by name */ void -DropTrigger(Oid relid, const char *trigname, DropBehavior behavior) +DropTrigger(Oid relid, const char *trigname, DropBehavior behavior, + bool missing_ok) { Relation tgrel; ScanKeyData skey[2]; @@ -481,10 +482,21 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior) tup = systable_getnext(tgscan); if (!HeapTupleIsValid(tup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("trigger \"%s\" for table \"%s\" does not exist", - trigname, get_rel_name(relid)))); + { + if (! missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("trigger \"%s\" for table \"%s\" does not exist", + trigname, get_rel_name(relid)))); + else + ereport(NOTICE, + (errmsg("trigger \"%s\" for table \"%s\" does not exist ...skipping", + trigname, get_rel_name(relid)))); + /* cleanup */ + systable_endscan(tgscan); + heap_close(tgrel, AccessShareLock); + return; + } if (!pg_class_ownercheck(relid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 6bf342ab92..e213df5b21 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.335 2006/04/30 18:30:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.336 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -2075,6 +2075,7 @@ _copyRemoveFuncStmt(RemoveFuncStmt *from) COPY_NODE_FIELD(name); COPY_NODE_FIELD(args); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } @@ -2087,6 +2088,7 @@ _copyRemoveOpClassStmt(RemoveOpClassStmt *from) COPY_NODE_FIELD(opclassname); COPY_STRING_FIELD(amname); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } @@ -2414,6 +2416,7 @@ _copyDropTableSpaceStmt(DropTableSpaceStmt *from) DropTableSpaceStmt *newnode = makeNode(DropTableSpaceStmt); COPY_STRING_FIELD(tablespacename); + COPY_SCALAR_FIELD(missing_ok); return newnode; } @@ -2447,6 +2450,7 @@ _copyDropPropertyStmt(DropPropertyStmt *from) COPY_STRING_FIELD(property); COPY_SCALAR_FIELD(removeType); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } @@ -2471,6 +2475,7 @@ _copyDropPLangStmt(DropPLangStmt *from) COPY_STRING_FIELD(plname); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } @@ -2606,6 +2611,7 @@ _copyDropCastStmt(DropCastStmt *from) COPY_NODE_FIELD(sourcetype); COPY_NODE_FIELD(targettype); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7f7eb06fbc..cc60fdd8dd 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.271 2006/04/30 18:30:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.272 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -999,6 +999,7 @@ _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b) COMPARE_NODE_FIELD(name); COMPARE_NODE_FIELD(args); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } @@ -1009,6 +1010,7 @@ _equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b) COMPARE_NODE_FIELD(opclassname); COMPARE_STRING_FIELD(amname); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } @@ -1282,6 +1284,7 @@ static bool _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b) { COMPARE_STRING_FIELD(tablespacename); + COMPARE_SCALAR_FIELD(missing_ok); return true; } @@ -1312,6 +1315,7 @@ _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b) COMPARE_STRING_FIELD(property); COMPARE_SCALAR_FIELD(removeType); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } @@ -1332,6 +1336,7 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b) { COMPARE_STRING_FIELD(plname); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } @@ -1445,6 +1450,7 @@ _equalDropCastStmt(DropCastStmt *a, DropCastStmt *b) COMPARE_NODE_FIELD(sourcetype); COMPARE_NODE_FIELD(targettype); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d84f4034ab..f95a6b74cd 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.545 2006/05/27 17:38:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.546 2006/06/16 20:23:44 adunstan Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -191,7 +191,7 @@ static void doNegateFloat(Value *v); %type opt_lock lock_type cast_context %type opt_force opt_or_replace opt_grant_grant_option opt_grant_admin_option - opt_nowait + opt_nowait opt_if_exists %type like_including_defaults @@ -2401,6 +2401,15 @@ DropPLangStmt: DropPLangStmt *n = makeNode(DropPLangStmt); n->plname = $4; n->behavior = $5; + n->missing_ok = false; + $$ = (Node *)n; + } + | DROP opt_procedural LANGUAGE IF_P EXISTS ColId_or_Sconst opt_drop_behavior + { + DropPLangStmt *n = makeNode(DropPLangStmt); + n->plname = $6; + n->behavior = $7; + n->missing_ok = true; $$ = (Node *)n; } ; @@ -2445,6 +2454,14 @@ DropTableSpaceStmt: DROP TABLESPACE name { DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); n->tablespacename = $3; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP TABLESPACE IF_P EXISTS name + { + DropTableSpaceStmt *n = makeNode(DropTableSpaceStmt); + n->tablespacename = $5; + n->missing_ok = true; $$ = (Node *) n; } ; @@ -2630,6 +2647,17 @@ DropTrigStmt: n->property = $3; n->behavior = $6; n->removeType = OBJECT_TRIGGER; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior + { + DropPropertyStmt *n = makeNode(DropPropertyStmt); + n->relation = $7; + n->property = $5; + n->behavior = $8; + n->removeType = OBJECT_TRIGGER; + n->missing_ok = true; $$ = (Node *) n; } ; @@ -2903,6 +2931,16 @@ DropOpClassStmt: n->opclassname = $4; n->amname = $6; n->behavior = $7; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior + { + RemoveOpClassStmt *n = makeNode(RemoveOpClassStmt); + n->opclassname = $6; + n->amname = $8; + n->behavior = $9; + n->missing_ok = true; $$ = (Node *) n; } ; @@ -3912,6 +3950,17 @@ RemoveFuncStmt: n->name = $3; n->args = extractArgTypes($4); n->behavior = $5; + n->missing_ok = false; + $$ = (Node *)n; + } + | DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior + { + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->kind = OBJECT_FUNCTION; + n->name = $5; + n->args = extractArgTypes($6); + n->behavior = $7; + n->missing_ok = true; $$ = (Node *)n; } ; @@ -3924,6 +3973,17 @@ RemoveAggrStmt: n->name = $3; n->args = $4; n->behavior = $5; + n->missing_ok = false; + $$ = (Node *)n; + } + | DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior + { + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->kind = OBJECT_AGGREGATE; + n->name = $5; + n->args = $6; + n->behavior = $7; + n->missing_ok = true; $$ = (Node *)n; } ; @@ -3936,6 +3996,17 @@ RemoveOperStmt: n->name = $3; n->args = $5; n->behavior = $7; + n->missing_ok = false; + $$ = (Node *)n; + } + | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior + { + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->kind = OBJECT_OPERATOR; + n->name = $5; + n->args = $7; + n->behavior = $9; + n->missing_ok = true; $$ = (Node *)n; } ; @@ -3998,16 +4069,21 @@ cast_context: AS IMPLICIT_P { $$ = COERCION_IMPLICIT; } ; -DropCastStmt: DROP CAST '(' Typename AS Typename ')' opt_drop_behavior +DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior { DropCastStmt *n = makeNode(DropCastStmt); - n->sourcetype = $4; - n->targettype = $6; - n->behavior = $8; + n->sourcetype = $5; + n->targettype = $7; + n->behavior = $9; + n->missing_ok = $$ = (Node *)n; } ; +opt_if_exists: IF_P EXISTS { $$ = true; } + | /* empty */ { $$ = false; } + ; + /***************************************************************************** @@ -4432,6 +4508,17 @@ DropRuleStmt: n->property = $3; n->behavior = $6; n->removeType = OBJECT_RULE; + n->missing_ok = false; + $$ = (Node *) n; + } + | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior + { + DropPropertyStmt *n = makeNode(DropPropertyStmt); + n->relation = $7; + n->property = $5; + n->behavior = $8; + n->removeType = OBJECT_RULE; + n->missing_ok = true; $$ = (Node *) n; } ; diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index 97a4a3247d..b0acc01f82 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.64 2006/03/05 15:58:36 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.65 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,8 @@ * Delete a rule given its name. */ void -RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior) +RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior, + bool missing_ok) { HeapTuple tuple; Oid eventRelationOid; @@ -53,10 +54,18 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior) * complain if no rule with such name exists */ if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("rule \"%s\" for relation \"%s\" does not exist", - ruleName, get_rel_name(owningRel)))); + { + if (! missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("rule \"%s\" for relation \"%s\" does not exist", + ruleName, get_rel_name(owningRel)))); + else + ereport(NOTICE, + (errmsg("rule \"%s\" for relation \"%s\" does not exist ... skipping", + ruleName, get_rel_name(owningRel)))); + return; + } /* * Verify user has appropriate permissions. diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 5729b58450..749b96cb45 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.257 2006/04/30 18:30:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.258 2006/06/16 20:23:44 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -986,12 +986,12 @@ ProcessUtility(Node *parsetree, case OBJECT_RULE: /* RemoveRewriteRule checks permissions */ RemoveRewriteRule(relId, stmt->property, - stmt->behavior); + stmt->behavior, stmt->missing_ok); break; case OBJECT_TRIGGER: /* DropTrigger checks permissions */ DropTrigger(relId, stmt->property, - stmt->behavior); + stmt->behavior, stmt->missing_ok); break; default: elog(ERROR, "unrecognized object type: %d", diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 7f83f8e4bb..0cb4df7c4f 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.57 2006/03/05 15:58:55 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/trigger.h,v 1.58 2006/06/16 20:23:45 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -108,7 +108,7 @@ typedef struct TriggerData extern Oid CreateTrigger(CreateTrigStmt *stmt, bool forConstraint); extern void DropTrigger(Oid relid, const char *trigname, - DropBehavior behavior); + DropBehavior behavior, bool missing_ok); extern void RemoveTriggerById(Oid trigOid); extern void renametrig(Oid relid, const char *oldname, const char *newname); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 896b426370..56d41a2fd8 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.310 2006/04/30 18:30:40 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.311 2006/06/16 20:23:45 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -1131,6 +1131,7 @@ typedef struct DropTableSpaceStmt { NodeTag type; char *tablespacename; + bool missing_ok; /* skip error if a missing? */ } DropTableSpaceStmt; /* ---------------------- @@ -1175,6 +1176,7 @@ typedef struct DropPLangStmt NodeTag type; char *plname; /* PL name */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if missing? */ } DropPLangStmt; /* ---------------------- @@ -1329,6 +1331,7 @@ typedef struct DropPropertyStmt char *property; /* name of rule, trigger, etc */ ObjectType removeType; /* OBJECT_RULE or OBJECT_TRIGGER */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if a missing? */ } DropPropertyStmt; /* ---------------------- @@ -1477,6 +1480,7 @@ typedef struct RemoveFuncStmt List *name; /* qualified name of object to drop */ List *args; /* types of the arguments */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if a missing? */ } RemoveFuncStmt; /* ---------------------- @@ -1489,6 +1493,7 @@ typedef struct RemoveOpClassStmt List *opclassname; /* qualified name (list of Value strings) */ char *amname; /* name of index AM opclass is for */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ + bool missing_ok; /* skip error if a missing? */ } RemoveOpClassStmt; /* ---------------------- @@ -1846,6 +1851,7 @@ typedef struct DropCastStmt TypeName *sourcetype; TypeName *targettype; DropBehavior behavior; + bool missing_ok; /* skip error if a missing? */ } DropCastStmt; diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h index d08501cfbe..76b003985d 100644 --- a/src/include/rewrite/rewriteRemove.h +++ b/src/include/rewrite/rewriteRemove.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/rewrite/rewriteRemove.h,v 1.21 2006/03/05 15:58:58 momjian Exp $ + * $PostgreSQL: pgsql/src/include/rewrite/rewriteRemove.h,v 1.22 2006/06/16 20:23:45 adunstan Exp $ * *------------------------------------------------------------------------- */ @@ -18,7 +18,7 @@ extern void RemoveRewriteRule(Oid owningRel, const char *ruleName, - DropBehavior behavior); + DropBehavior behavior, bool missing_ok); extern void RemoveRewriteRuleById(Oid ruleOid); #endif /* REWRITEREMOVE_H */ -- 2.40.0