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 */
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to