Here is an updated patch for the remaining cases of DROP objtype IF
EXISTS ... as recently discussed on -hackers.
The cases are:
language, tablespace, trigger, rule, opclass, function, aggregate.
operator, and cast.
Regression tests and docs still to come.
I wasn't quite sure how to format the message in the case of aggregate -
the change in calls there seems to have made it somewhat harder, so some
advice would be appreciated.
cheers
andrew
Index: src/backend/commands/aggregatecmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v
retrieving revision 1.34
diff -c -r1.34 aggregatecmds.c
*** src/backend/commands/aggregatecmds.c 15 Apr 2006 17:45:33 -0000 1.34
--- src/backend/commands/aggregatecmds.c 10 Jun 2006 14:04:54 -0000
***************
*** 211,217 ****
ObjectAddress object;
/* Look up function and make sure it's an aggregate */
! procOid = LookupAggNameTypeNames(aggName, aggArgs, false);
/*
* Find the function tuple, do permissions and validity checks
--- 211,231 ----
ObjectAddress object;
/* Look up function and make sure it's an aggregate */
! 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
Index: src/backend/commands/functioncmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v
retrieving revision 1.74
diff -c -r1.74 functioncmds.c
*** src/backend/commands/functioncmds.c 15 Apr 2006 17:45:34 -0000 1.74
--- src/backend/commands/functioncmds.c 10 Jun 2006 14:04:56 -0000
***************
*** 687,693 ****
/*
* Find the function, do permissions and validity checks
*/
! funcOid = LookupFuncNameTypeNames(functionName, argTypes, false);
tup = SearchSysCache(PROCOID,
ObjectIdGetDatum(funcOid),
--- 687,702 ----
/*
* Find the function, do permissions and validity checks
*/
! 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,1382 ****
--- 1386,1392 ----
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,1395 ****
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))));
/* Permission check */
if (!pg_type_ownercheck(sourcetypeid, GetUserId())
--- 1395,1417 ----
ObjectIdGetDatum(targettypeid),
0, 0);
if (!HeapTupleIsValid(tuple))
! {
! 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())
Index: src/backend/commands/opclasscmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v
retrieving revision 1.45
diff -c -r1.45 opclasscmds.c
*** src/backend/commands/opclasscmds.c 2 May 2006 22:25:10 -0000 1.45
--- src/backend/commands/opclasscmds.c 10 Jun 2006 14:04:56 -0000
***************
*** 700,720 ****
/* 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)));
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)));
!
opcID = HeapTupleGetOid(tuple);
/* Permission check: must own opclass or its namespace */
--- 700,739 ----
/* Unqualified opclass name, so search the search path */
opcID = OpclassnameGetOpcid(amID, opcname);
if (!OidIsValid(opcID))
! {
! 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))
! {
!
! 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 */
Index: src/backend/commands/operatorcmds.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v
retrieving revision 1.30
diff -c -r1.30 operatorcmds.c
*** src/backend/commands/operatorcmds.c 15 Apr 2006 17:45:34 -0000 1.30
--- src/backend/commands/operatorcmds.c 10 Jun 2006 14:04:56 -0000
***************
*** 213,219 ****
Assert(list_length(stmt->args) == 2);
operOid = LookupOperNameTypeNames(NULL, operatorName,
typeName1, typeName2,
! false, -1);
tup = SearchSysCache(OPEROID,
ObjectIdGetDatum(operOid),
--- 213,227 ----
Assert(list_length(stmt->args) == 2);
operOid = LookupOperNameTypeNames(NULL, operatorName,
typeName1, typeName2,
! 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),
Index: src/backend/commands/proclang.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/proclang.c,v
retrieving revision 1.64
diff -c -r1.64 proclang.c
*** src/backend/commands/proclang.c 5 Mar 2006 15:58:24 -0000 1.64
--- src/backend/commands/proclang.c 10 Jun 2006 14:04:56 -0000
***************
*** 396,404 ****
CStringGetDatum(languageName),
0, 0, 0);
if (!HeapTupleIsValid(langTup))
! ereport(ERROR,
! (errcode(ERRCODE_UNDEFINED_OBJECT),
! errmsg("language \"%s\" does not exist", languageName)));
object.classId = LanguageRelationId;
object.objectId = HeapTupleGetOid(langTup);
--- 396,413 ----
CStringGetDatum(languageName),
0, 0, 0);
if (!HeapTupleIsValid(langTup))
! {
! 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);
Index: src/backend/commands/tablespace.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/tablespace.c,v
retrieving revision 1.34
diff -c -r1.34 tablespace.c
*** src/backend/commands/tablespace.c 29 Mar 2006 21:17:38 -0000 1.34
--- src/backend/commands/tablespace.c 10 Jun 2006 14:04:57 -0000
***************
*** 403,412 ****
tuple = heap_getnext(scandesc, ForwardScanDirection);
if (!HeapTupleIsValid(tuple))
! ereport(ERROR,
! (errcode(ERRCODE_UNDEFINED_OBJECT),
! errmsg("tablespace \"%s\" does not exist",
! tablespacename)));
tablespaceoid = HeapTupleGetOid(tuple);
--- 403,427 ----
tuple = heap_getnext(scandesc, ForwardScanDirection);
if (!HeapTupleIsValid(tuple))
! {
! 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);
Index: src/backend/commands/trigger.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.202
diff -c -r1.202 trigger.c
*** src/backend/commands/trigger.c 30 May 2006 14:01:57 -0000 1.202
--- src/backend/commands/trigger.c 10 Jun 2006 14:05:01 -0000
***************
*** 452,458 ****
* DropTrigger - drop an individual trigger by name
*/
void
! DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
{
Relation tgrel;
ScanKeyData skey[2];
--- 452,459 ----
* DropTrigger - drop an individual trigger by name
*/
void
! DropTrigger(Oid relid, const char *trigname, DropBehavior behavior,
! bool missing_ok)
{
Relation tgrel;
ScanKeyData skey[2];
***************
*** 481,490 ****
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 (!pg_class_ownercheck(relid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
--- 482,502 ----
tup = systable_getnext(tgscan);
if (!HeapTupleIsValid(tup))
! {
! 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,
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.335
diff -c -r1.335 copyfuncs.c
*** src/backend/nodes/copyfuncs.c 30 Apr 2006 18:30:38 -0000 1.335
--- src/backend/nodes/copyfuncs.c 10 Jun 2006 14:05:02 -0000
***************
*** 2075,2080 ****
--- 2075,2081 ----
COPY_NODE_FIELD(name);
COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(behavior);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
***************
*** 2087,2092 ****
--- 2088,2094 ----
COPY_NODE_FIELD(opclassname);
COPY_STRING_FIELD(amname);
COPY_SCALAR_FIELD(behavior);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
***************
*** 2414,2419 ****
--- 2416,2422 ----
DropTableSpaceStmt *newnode = makeNode(DropTableSpaceStmt);
COPY_STRING_FIELD(tablespacename);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
***************
*** 2447,2452 ****
--- 2450,2456 ----
COPY_STRING_FIELD(property);
COPY_SCALAR_FIELD(removeType);
COPY_SCALAR_FIELD(behavior);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
***************
*** 2471,2476 ****
--- 2475,2481 ----
COPY_STRING_FIELD(plname);
COPY_SCALAR_FIELD(behavior);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
***************
*** 2606,2611 ****
--- 2611,2617 ----
COPY_NODE_FIELD(sourcetype);
COPY_NODE_FIELD(targettype);
COPY_SCALAR_FIELD(behavior);
+ COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.271
diff -c -r1.271 equalfuncs.c
*** src/backend/nodes/equalfuncs.c 30 Apr 2006 18:30:38 -0000 1.271
--- src/backend/nodes/equalfuncs.c 10 Jun 2006 14:05:04 -0000
***************
*** 999,1004 ****
--- 999,1005 ----
COMPARE_NODE_FIELD(name);
COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
***************
*** 1009,1014 ****
--- 1010,1016 ----
COMPARE_NODE_FIELD(opclassname);
COMPARE_STRING_FIELD(amname);
COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
***************
*** 1282,1287 ****
--- 1284,1290 ----
_equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
{
COMPARE_STRING_FIELD(tablespacename);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
***************
*** 1312,1317 ****
--- 1315,1321 ----
COMPARE_STRING_FIELD(property);
COMPARE_SCALAR_FIELD(removeType);
COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
***************
*** 1332,1337 ****
--- 1336,1342 ----
{
COMPARE_STRING_FIELD(plname);
COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
***************
*** 1445,1450 ****
--- 1450,1456 ----
COMPARE_NODE_FIELD(sourcetype);
COMPARE_NODE_FIELD(targettype);
COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.545
diff -c -r2.545 gram.y
*** src/backend/parser/gram.y 27 May 2006 17:38:45 -0000 2.545
--- src/backend/parser/gram.y 10 Jun 2006 14:05:13 -0000
***************
*** 191,197 ****
%type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace
opt_grant_grant_option opt_grant_admin_option
! opt_nowait
%type <boolean> like_including_defaults
--- 191,197 ----
%type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace
opt_grant_grant_option opt_grant_admin_option
! opt_nowait opt_if_exists
%type <boolean> like_including_defaults
***************
*** 2401,2406 ****
--- 2401,2415 ----
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,2450 ****
--- 2454,2467 ----
{
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,2635 ****
--- 2647,2663 ----
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,2908 ****
--- 2931,2946 ----
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,3917 ****
--- 3950,3966 ----
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,3929 ****
--- 3973,3989 ----
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,3941 ****
--- 3996,4012 ----
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,4013 ****
;
! DropCastStmt: DROP CAST '(' Typename AS Typename ')' opt_drop_behavior
{
DropCastStmt *n = makeNode(DropCastStmt);
! n->sourcetype = $4;
! n->targettype = $6;
! n->behavior = $8;
$$ = (Node *)n;
}
;
/*****************************************************************************
--- 4069,4089 ----
;
! DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior
{
DropCastStmt *n = makeNode(DropCastStmt);
! n->sourcetype = $5;
! n->targettype = $7;
! n->behavior = $9;
! n->missing_ok =
$$ = (Node *)n;
}
;
+ opt_if_exists: IF_P EXISTS { $$ = true; }
+ | /* empty */ { $$ = false; }
+ ;
+
/*****************************************************************************
***************
*** 4432,4437 ****
--- 4508,4524 ----
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;
}
;
Index: src/backend/rewrite/rewriteRemove.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v
retrieving revision 1.64
diff -c -r1.64 rewriteRemove.c
*** src/backend/rewrite/rewriteRemove.c 5 Mar 2006 15:58:36 -0000 1.64
--- src/backend/rewrite/rewriteRemove.c 10 Jun 2006 14:05:13 -0000
***************
*** 34,40 ****
* Delete a rule given its name.
*/
void
! RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior)
{
HeapTuple tuple;
Oid eventRelationOid;
--- 34,41 ----
* Delete a rule given its name.
*/
void
! RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior,
! bool missing_ok)
{
HeapTuple tuple;
Oid eventRelationOid;
***************
*** 53,62 ****
* 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))));
/*
* Verify user has appropriate permissions.
--- 54,71 ----
* complain if no rule with such name exists
*/
if (!HeapTupleIsValid(tuple))
! {
! 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.
Index: src/backend/tcop/utility.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.257
diff -c -r1.257 utility.c
*** src/backend/tcop/utility.c 30 Apr 2006 18:30:40 -0000 1.257
--- src/backend/tcop/utility.c 10 Jun 2006 14:05:14 -0000
***************
*** 986,997 ****
case OBJECT_RULE:
/* RemoveRewriteRule checks permissions */
RemoveRewriteRule(relId, stmt->property,
! stmt->behavior);
break;
case OBJECT_TRIGGER:
/* DropTrigger checks permissions */
DropTrigger(relId, stmt->property,
! stmt->behavior);
break;
default:
elog(ERROR, "unrecognized object type: %d",
--- 986,997 ----
case OBJECT_RULE:
/* RemoveRewriteRule checks permissions */
RemoveRewriteRule(relId, stmt->property,
! stmt->behavior, stmt->missing_ok);
break;
case OBJECT_TRIGGER:
/* DropTrigger checks permissions */
DropTrigger(relId, stmt->property,
! stmt->behavior, stmt->missing_ok);
break;
default:
elog(ERROR, "unrecognized object type: %d",
Index: src/include/commands/trigger.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/commands/trigger.h,v
retrieving revision 1.57
diff -c -r1.57 trigger.h
*** src/include/commands/trigger.h 5 Mar 2006 15:58:55 -0000 1.57
--- src/include/commands/trigger.h 10 Jun 2006 14:05:16 -0000
***************
*** 108,114 ****
extern Oid CreateTrigger(CreateTrigStmt *stmt, bool forConstraint);
extern void DropTrigger(Oid relid, const char *trigname,
! DropBehavior behavior);
extern void RemoveTriggerById(Oid trigOid);
extern void renametrig(Oid relid, const char *oldname, const char *newname);
--- 108,114 ----
extern Oid CreateTrigger(CreateTrigStmt *stmt, bool forConstraint);
extern void DropTrigger(Oid relid, const char *trigname,
! DropBehavior behavior, bool missing_ok);
extern void RemoveTriggerById(Oid trigOid);
extern void renametrig(Oid relid, const char *oldname, const char *newname);
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.310
diff -c -r1.310 parsenodes.h
*** src/include/nodes/parsenodes.h 30 Apr 2006 18:30:40 -0000 1.310
--- src/include/nodes/parsenodes.h 10 Jun 2006 14:05:17 -0000
***************
*** 1131,1136 ****
--- 1131,1137 ----
{
NodeTag type;
char *tablespacename;
+ bool missing_ok; /* skip error if a missing? */
} DropTableSpaceStmt;
/* ----------------------
***************
*** 1175,1180 ****
--- 1176,1182 ----
NodeTag type;
char *plname; /* PL name */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
+ bool missing_ok; /* skip error if missing? */
} DropPLangStmt;
/* ----------------------
***************
*** 1329,1334 ****
--- 1331,1337 ----
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,1482 ****
--- 1480,1486 ----
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,1494 ****
--- 1493,1499 ----
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,1851 ****
--- 1851,1857 ----
TypeName *sourcetype;
TypeName *targettype;
DropBehavior behavior;
+ bool missing_ok; /* skip error if a missing? */
} DropCastStmt;
Index: src/include/rewrite/rewriteRemove.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/rewrite/rewriteRemove.h,v
retrieving revision 1.21
diff -c -r1.21 rewriteRemove.h
*** src/include/rewrite/rewriteRemove.h 5 Mar 2006 15:58:58 -0000 1.21
--- src/include/rewrite/rewriteRemove.h 10 Jun 2006 14:05:18 -0000
***************
*** 18,24 ****
extern void RemoveRewriteRule(Oid owningRel, const char *ruleName,
! DropBehavior behavior);
extern void RemoveRewriteRuleById(Oid ruleOid);
#endif /* REWRITEREMOVE_H */
--- 18,24 ----
extern void RemoveRewriteRule(Oid owningRel, const char *ruleName,
! DropBehavior behavior, bool missing_ok);
extern void RemoveRewriteRuleById(Oid ruleOid);
#endif /* REWRITEREMOVE_H */