diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml
index d5e4e27..dcd809a 100644
--- a/doc/src/sgml/ref/create_aggregate.sgml
+++ b/doc/src/sgml/ref/create_aggregate.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">input_data_type</replaceable> [ , ... ] ) (
+CREATE AGGREGATE [ IF NOT EXISTS ] <replaceable class="PARAMETER">name</replaceable> ( <replaceable class="PARAMETER">input_data_type</replaceable> [ , ... ] ) (
     SFUNC = <replaceable class="PARAMETER">sfunc</replaceable>,
     STYPE = <replaceable class="PARAMETER">state_data_type</replaceable>
     [ , FINALFUNC = <replaceable class="PARAMETER">ffunc</replaceable> ]
@@ -31,7 +31,7 @@ CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> ( <replaceabl
 
 <phrase>or the old syntax</phrase>
 
-CREATE AGGREGATE <replaceable class="PARAMETER">name</replaceable> (
+CREATE AGGREGATE [ IF NOT EXISTS ] <replaceable class="PARAMETER">name</replaceable> (
     BASETYPE = <replaceable class="PARAMETER">base_type</replaceable>,
     SFUNC = <replaceable class="PARAMETER">sfunc</replaceable>,
     STYPE = <replaceable class="PARAMETER">state_data_type</replaceable>
@@ -177,6 +177,16 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if an aggregate function with
+      the same argument types already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="PARAMETER">name</replaceable></term>
     <listitem>
      <para>
diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml
index 29ea298..1c4c1df 100644
--- a/doc/src/sgml/ref/create_cast.sgml
+++ b/doc/src/sgml/ref/create_cast.sgml
@@ -18,15 +18,15 @@
 
  <refsynopsisdiv>
 <synopsis>
-CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+CREATE CAST [ IF NOT EXISTS ] (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
     WITH FUNCTION <replaceable>function_name</replaceable> (<replaceable>argument_type</replaceable> [, ...])
     [ AS ASSIGNMENT | AS IMPLICIT ]
 
-CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+CREATE CAST [ IF NOT EXISTS ] (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
     WITHOUT FUNCTION
     [ AS ASSIGNMENT | AS IMPLICIT ]
 
-CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+CREATE CAST [ IF NOT EXISTS ] (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
     WITH INOUT
     [ AS ASSIGNMENT | AS IMPLICIT ]
 </synopsis>
@@ -171,6 +171,16 @@ SELECT CAST ( 2 AS numeric ) + 4.0;
   <title>Parameters</title>
 
    <variablelist>
+     <varlistentry>
+      <term><literal>IF NOT EXISTS</literal></term>
+      <listitem>
+       <para>
+        Do nothing (except issuing a notice) if a cast with the same
+        from and to type already exists.
+       </para>
+      </listitem>
+     </varlistentry>
+
     <varlistentry>
      <term><replaceable>source_type</replaceable></term>
 
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
index c853576..f93d87e 100644
--- a/doc/src/sgml/ref/create_collation.sgml
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -18,12 +18,12 @@
 
  <refsynopsisdiv>
 <synopsis>
-CREATE COLLATION <replaceable>name</replaceable> (
+CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> (
     [ LOCALE = <replaceable>locale</replaceable>, ]
     [ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
     [ LC_CTYPE = <replaceable>lc_ctype</replaceable> ]
 )
-CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
+CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
 </synopsis>
  </refsynopsisdiv>
 
@@ -47,6 +47,16 @@ CREATE COLLATION <replaceable>name</replaceable> FROM <replaceable>existing_coll
   <title>Parameters</title>
 
    <variablelist>
+   <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if an collation with the same
+      name already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
     <varlistentry>
      <term><replaceable>name</replaceable></term>
 
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
index dd33f06..80a6bf6 100644
--- a/doc/src/sgml/ref/create_operator.sgml
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE OPERATOR <replaceable>name</replaceable> (
+CREATE OPERATOR [ IF NOT EXISTS ] <replaceable>name</replaceable> (
     PROCEDURE = <replaceable class="parameter">function_name</replaceable>
     [, LEFTARG = <replaceable class="parameter">left_type</replaceable> ] [, RIGHTARG = <replaceable class="parameter">right_type</replaceable> ]
     [, COMMUTATOR = <replaceable class="parameter">com_op</replaceable> ] [, NEGATOR = <replaceable class="parameter">neg_op</replaceable> ]
@@ -117,6 +117,16 @@ CREATE OPERATOR <replaceable>name</replaceable> (
 
     <variablelist>
      <varlistentry>
+      <term><literal>IF NOT EXISTS</literal></term>
+      <listitem>
+       <para>
+        Do nothing (except issuing a notice) if an operator with the same
+        name already exists.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><replaceable class="parameter">name</replaceable></term>
       <listitem>
        <para>
diff --git a/doc/src/sgml/ref/create_tsconfig.sgml b/doc/src/sgml/ref/create_tsconfig.sgml
index c34d1c0..2cc7c1f 100644
--- a/doc/src/sgml/ref/create_tsconfig.sgml
+++ b/doc/src/sgml/ref/create_tsconfig.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TEXT SEARCH CONFIGURATION <replaceable class="parameter">name</replaceable> (
+CREATE TEXT SEARCH CONFIGURATION [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> (
     PARSER = <replaceable class="parameter">parser_name</replaceable> |
     COPY = <replaceable class="parameter">source_config</replaceable>
 )
@@ -66,6 +66,16 @@ CREATE TEXT SEARCH CONFIGURATION <replaceable class="parameter">name</replaceabl
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if a text search configuration
+      with the same name already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
      <para>
diff --git a/doc/src/sgml/ref/create_tsdictionary.sgml b/doc/src/sgml/ref/create_tsdictionary.sgml
index 2673bc5..4ffd408 100644
--- a/doc/src/sgml/ref/create_tsdictionary.sgml
+++ b/doc/src/sgml/ref/create_tsdictionary.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TEXT SEARCH DICTIONARY <replaceable class="parameter">name</replaceable> (
+CREATE TEXT SEARCH DICTIONARY [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> (
     TEMPLATE = <replaceable class="parameter">template</replaceable>
     [, <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ]]
 )
@@ -59,6 +59,16 @@ CREATE TEXT SEARCH DICTIONARY <replaceable class="parameter">name</replaceable>
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if a text search dictionary
+      with the same name already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
      <para>
diff --git a/doc/src/sgml/ref/create_tsparser.sgml b/doc/src/sgml/ref/create_tsparser.sgml
index 7643f08..1631af4 100644
--- a/doc/src/sgml/ref/create_tsparser.sgml
+++ b/doc/src/sgml/ref/create_tsparser.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TEXT SEARCH PARSER <replaceable class="parameter">name</replaceable> (
+CREATE TEXT SEARCH PARSER [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> (
     START = <replaceable class="parameter">start_function</replaceable> ,
     GETTOKEN = <replaceable class="parameter">gettoken_function</replaceable> ,
     END = <replaceable class="parameter">end_function</replaceable> ,
@@ -64,6 +64,16 @@ CREATE TEXT SEARCH PARSER <replaceable class="parameter">name</replaceable> (
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if a text search parser
+      with the same name already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
      <para>
diff --git a/doc/src/sgml/ref/create_tstemplate.sgml b/doc/src/sgml/ref/create_tstemplate.sgml
index 532419c..ac65baf 100644
--- a/doc/src/sgml/ref/create_tstemplate.sgml
+++ b/doc/src/sgml/ref/create_tstemplate.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TEXT SEARCH TEMPLATE <replaceable class="parameter">name</replaceable> (
+CREATE TEXT SEARCH TEMPLATE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> (
     [ INIT = <replaceable class="parameter">init_function</replaceable> , ]
     LEXIZE = <replaceable class="parameter">lexize_function</replaceable>
 )
@@ -65,6 +65,16 @@ CREATE TEXT SEARCH TEMPLATE <replaceable class="parameter">name</replaceable> (
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if a text search template with
+      the same name already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
      <para>
diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index 606efee..0919da7 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -21,13 +21,13 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE TYPE <replaceable class="parameter">name</replaceable> AS
+CREATE TYPE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> AS
     ( [ <replaceable class="PARAMETER">attribute_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ COLLATE <replaceable>collation</replaceable> ] [, ... ] ] )
 
-CREATE TYPE <replaceable class="parameter">name</replaceable> AS ENUM
+CREATE TYPE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> AS ENUM
     ( [ '<replaceable class="parameter">label</replaceable>' [, ... ] ] )
 
-CREATE TYPE <replaceable class="parameter">name</replaceable> AS RANGE (
+CREATE TYPE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> AS RANGE (
     SUBTYPE = <replaceable class="parameter">subtype</replaceable>
     [ , SUBTYPE_OPCLASS = <replaceable class="parameter">subtype_operator_class</replaceable> ]
     [ , COLLATION = <replaceable class="parameter">collation</replaceable> ]
@@ -35,7 +35,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> AS RANGE (
     [ , SUBTYPE_DIFF = <replaceable class="parameter">subtype_diff_function</replaceable> ]
 )
 
-CREATE TYPE <replaceable class="parameter">name</replaceable> (
+CREATE TYPE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> (
     INPUT = <replaceable class="parameter">input_function</replaceable>,
     OUTPUT = <replaceable class="parameter">output_function</replaceable>
     [ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ]
@@ -56,7 +56,7 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
     [ , COLLATABLE = <replaceable class="parameter">collatable</replaceable> ]
 )
 
-CREATE TYPE <replaceable class="parameter">name</replaceable>
+CREATE TYPE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable>
 </synopsis>
  </refsynopsisdiv>
 
@@ -484,6 +484,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable>
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF NOT EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do nothing (except issuing a notice) if a type with the same name
+      already exists.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="parameter">name</replaceable></term>
     <listitem>
      <para>
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 64ca312..a4277e8 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -963,7 +963,8 @@ AddNewRelationType(const char *typeName,
 				   -1,			/* typmod */
 				   0,			/* array dimensions for typBaseType */
 				   false,		/* Type NOT NULL */
-				   InvalidOid); /* rowtypes never have a collation */
+				   InvalidOid,	/* rowtypes never have a collation */
+				   false);		/* if not exists */
 }
 
 /* --------------------------------
@@ -1219,7 +1220,8 @@ heap_create_with_catalog(const char *relname,
 				   -1,			/* typmod */
 				   0,			/* array dimensions for typBaseType */
 				   false,		/* Type NOT NULL */
-				   InvalidOid); /* rowtypes never have a collation */
+				   InvalidOid,	/* rowtypes never have a collation */
+				   false);		/* if not exists */
 
 		pfree(relarrayname);
 	}
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 480c17c..fecc994 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -51,7 +51,8 @@ AggregateCreate(const char *aggName,
 				List *aggfinalfnName,
 				List *aggsortopName,
 				Oid aggTransType,
-				const char *agginitval)
+				const char *agginitval,
+				bool aggIfNotExists)
 {
 	Relation	aggdesc;
 	HeapTuple	tup;
@@ -252,7 +253,11 @@ AggregateCreate(const char *aggName,
 							  NIL,		/* parameterDefaults */
 							  PointerGetDatum(NULL),	/* proconfig */
 							  1,	/* procost */
-							  0);		/* prorows */
+							  0,		/* prorows */
+							  aggIfNotExists);	/* if not exists */
+
+	if (!OidIsValid(procOid))
+		return InvalidOid;
 
 	/*
 	 * Okay to create the pg_aggregate entry.
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 3c4fedb..d87c32c 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -336,7 +336,8 @@ OperatorCreate(const char *operatorName,
 			   Oid restrictionId,
 			   Oid joinId,
 			   bool canMerge,
-			   bool canHash)
+			   bool canHash,
+			   bool ifNotExists)
 {
 	Relation	pg_operator_desc;
 	HeapTuple	tup;
@@ -417,10 +418,21 @@ OperatorCreate(const char *operatorName,
 								   &operatorAlreadyDefined);
 
 	if (operatorAlreadyDefined)
+	{
+		if (ifNotExists)
+		{
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_FUNCTION),
+					 errmsg("operator %s already exists, skipping",
+							operatorName)));
+			return InvalidOid;
+		}
+
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_FUNCTION),
 				 errmsg("operator %s already exists",
 						operatorName)));
+	}
 
 	/*
 	 * At this point, if operatorObjectId is not InvalidOid then we are
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 2a98ca9..fd3b655 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -88,7 +88,8 @@ ProcedureCreate(const char *procedureName,
 				List *parameterDefaults,
 				Datum proconfig,
 				float4 procost,
-				float4 prorows)
+				float4 prorows,
+				bool ifNotExists)
 {
 	Oid			retval;
 	int			parameterCount;
@@ -388,10 +389,23 @@ ProcedureCreate(const char *procedureName,
 		bool		isnull;
 
 		if (!replace)
+		{
+			if (ifNotExists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_FUNCTION),
+						 errmsg("function \"%s\" already exists with same argument types, skipping",
+								procedureName)));
+				ReleaseSysCache(oldtup);
+				heap_close(rel, RowExclusiveLock);
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_FUNCTION),
-			errmsg("function \"%s\" already exists with same argument types",
-				   procedureName)));
+					 errmsg("function \"%s\" already exists with same argument types",
+							procedureName)));
+		}
 		if (!pg_proc_ownercheck(HeapTupleGetOid(oldtup), proowner))
 			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
 						   procedureName);
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 23ac3dd..03d8216 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -215,7 +215,8 @@ TypeCreate(Oid newTypeOid,
 		   int32 typeMod,
 		   int32 typNDims,		/* Array dimensions for baseType */
 		   bool typeNotNull,
-		   Oid typeCollation)
+		   Oid typeCollation,
+		   bool ifNotExists)
 {
 	Relation	pg_type_desc;
 	Oid			typeObjectId;
@@ -397,9 +398,21 @@ TypeCreate(Oid newTypeOid,
 		 * shell type, however.
 		 */
 		if (((Form_pg_type) GETSTRUCT(tup))->typisdefined)
+		{
+			/* skip if already exists */
+			if (ifNotExists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_OBJECT),
+						 errmsg("type \"%s\" already exists, skipping", typeName)));
+				heap_close(pg_type_desc, RowExclusiveLock);
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", typeName)));
+		}
 
 		/*
 		 * shell type must have been created by same owner
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 4a03786..8d89380 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -48,7 +48,7 @@
  * "args" defines the input type(s).
  */
 Oid
-DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
+DefineAggregate(List *name, List *args, bool oldstyle, List *parameters, bool ifNotExists)
 {
 	char	   *aggName;
 	Oid			aggNamespace;
@@ -224,6 +224,7 @@ DefineAggregate(List *name, List *args, bool oldstyle, List *parameters)
 						   transfuncName,		/* step function name */
 						   finalfuncName,		/* final function name */
 						   sortoperatorName,	/* sort operator name */
-						   transTypeId, /* transition data type */
-						   initval);	/* initial condition */
+						   transTypeId,	/* transition data type */
+						   initval,		/* initial condition */
+						   ifNotExists);	/* if not exists */
 }
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 0a9facf..4fa42e2 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -983,7 +983,8 @@ CreateFunction(CreateFunctionStmt *stmt, const char *queryString)
 						   parameterDefaults,
 						   PointerGetDatum(proconfig),
 						   procost,
-						   prorows);
+						   prorows,
+						   false);
 }
 
 
@@ -1498,8 +1499,6 @@ CreateCast(CreateCastStmt *stmt)
 			break;
 	}
 
-	relation = heap_open(CastRelationId, RowExclusiveLock);
-
 	/*
 	 * Check for duplicate.  This is just to give a friendly error message,
 	 * the unique index would catch it anyway (so no need to sweat about race
@@ -1509,11 +1508,26 @@ CreateCast(CreateCastStmt *stmt)
 							ObjectIdGetDatum(sourcetypeid),
 							ObjectIdGetDatum(targettypeid));
 	if (HeapTupleIsValid(tuple))
+	{
+		if (stmt->if_not_exists)
+               {
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("cast from type %s to type %s already exists, skipping",
+							format_type_be(sourcetypeid),
+							format_type_be(targettypeid))));
+			ReleaseSysCache(tuple);
+			return InvalidOid;
+               }
+
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("cast from type %s to type %s already exists",
 						format_type_be(sourcetypeid),
 						format_type_be(targettypeid))));
+	}
+
+	relation = heap_open(CastRelationId, RowExclusiveLock);
 
 	/* ready to go */
 	values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 4692b08..6c230b4 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -60,7 +60,7 @@
  * 'parameters' is a list of DefElem
  */
 Oid
-DefineOperator(List *names, List *parameters)
+DefineOperator(List *names, List *parameters, bool ifNotExists)
 {
 	char	   *oprName;
 	Oid			oprNamespace;
@@ -306,7 +306,8 @@ DefineOperator(List *names, List *parameters)
 					   restrictionOid,	/* optional restrict. sel. procedure */
 					   joinOid, /* optional join sel. procedure name */
 					   canMerge,	/* operator merges */
-					   canHash);	/* operator hashes */
+					   canHash,		/* operator hashes */
+					   ifNotExists);	/* if not exists */
 }
 
 /*
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index b7be1f7..28f22fc 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -141,7 +141,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 										 NIL,
 										 PointerGetDatum(NULL),
 										 1,
-										 0);
+										 0,
+										 false);
 		}
 
 		/*
@@ -178,7 +179,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 											NIL,
 											PointerGetDatum(NULL),
 											1,
-											0);
+											0,
+											false);
 			}
 		}
 		else
@@ -218,7 +220,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 										 NIL,
 										 PointerGetDatum(NULL),
 										 1,
-										 0);
+										 0,
+										 false);
 			}
 		}
 		else
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 61ebc2e..cb6ace2 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -168,7 +168,7 @@ makeParserDependencies(HeapTuple tuple)
  * CREATE TEXT SEARCH PARSER
  */
 Oid
-DefineTSParser(List *names, List *parameters)
+DefineTSParser(List *names, List *parameters, bool ifNotExists)
 {
 	char	   *prsname;
 	ListCell   *pl;
@@ -188,6 +188,30 @@ DefineTSParser(List *names, List *parameters)
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
+	/* Check if text search parser already exists */
+	prsOid = GetSysCacheOid2(TSPARSERNAMENSP,
+							 CStringGetDatum(prsname),
+							 ObjectIdGetDatum(namespaceoid));
+
+	if (OidIsValid(prsOid))
+	{
+		if (ifNotExists)
+		{
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("text search parser \"%s\".\"%s\" already exists, skipping",
+							get_namespace_name(namespaceoid),
+							prsname)));
+			return InvalidOid;
+		}
+
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("text search parser \"%s\".\"%s\" already exists",
+						get_namespace_name(namespaceoid),
+						prsname)));
+	}
+
 	/* initialize tuple fields with name/namespace */
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
@@ -398,7 +422,7 @@ verify_dictoptions(Oid tmplId, List *dictoptions)
  * CREATE TEXT SEARCH DICTIONARY
  */
 Oid
-DefineTSDictionary(List *names, List *parameters)
+DefineTSDictionary(List *names, List *parameters, bool ifNotExists)
 {
 	ListCell   *pl;
 	Relation	dictRel;
@@ -412,15 +436,43 @@ DefineTSDictionary(List *names, List *parameters)
 	Oid			namespaceoid;
 	AclResult	aclresult;
 	char	   *dictname;
+	char	   *dictnamespace;
 
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
 
+	/* Get namespace name */
+	dictnamespace = get_namespace_name(namespaceoid);
+
 	/* Check we have creation rights in target namespace */
 	aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
 	if (aclresult != ACLCHECK_OK)
 		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
-					   get_namespace_name(namespaceoid));
+					   dictnamespace);
+
+	/* Check if text search dictionary already exists */
+	dictOid = GetSysCacheOid2(TSDICTNAMENSP,
+							  CStringGetDatum(dictname),
+							  ObjectIdGetDatum(namespaceoid));
+
+	if (OidIsValid(dictOid))
+	{
+		if (ifNotExists)
+		{
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("text search dictionary \"%s\".\"%s\" already exists, skipping",
+							dictnamespace,
+							dictname)));
+			return InvalidOid;
+		}
+
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("text search dictionary \"%s\".\"%s\" already exists",
+						dictnamespace,
+						dictname)));
+	}
 
 	/*
 	 * loop over the definition list and extract the information we need.
@@ -716,7 +768,7 @@ makeTSTemplateDependencies(HeapTuple tuple)
  * CREATE TEXT SEARCH TEMPLATE
  */
 Oid
-DefineTSTemplate(List *names, List *parameters)
+DefineTSTemplate(List *names, List *parameters, bool ifNotExists)
 {
 	ListCell   *pl;
 	Relation	tmplRel;
@@ -737,6 +789,30 @@ DefineTSTemplate(List *names, List *parameters)
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
 
+	/* Check if text search template already exists */
+	tmplOid = GetSysCacheOid2(TSTEMPLATENAMENSP,
+							  CStringGetDatum(tmplname),
+							  ObjectIdGetDatum(namespaceoid));
+
+	if (OidIsValid(tmplOid))
+	{
+		if (ifNotExists)
+		{
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("text search template \"%s\".\"%s\" already exists, skipping",
+							get_namespace_name(namespaceoid),
+							tmplname)));
+			return InvalidOid;
+		}
+
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("text search template \"%s\".\"%s\" already exists",
+						get_namespace_name(namespaceoid),
+						tmplname)));
+	}
+
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
 		nulls[i] = false;
@@ -946,7 +1022,7 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld,
  * CREATE TEXT SEARCH CONFIGURATION
  */
 Oid
-DefineTSConfiguration(List *names, List *parameters)
+DefineTSConfiguration(List *names, List *parameters, bool ifNotExists)
 {
 	Relation	cfgRel;
 	Relation	mapRel = NULL;
@@ -956,6 +1032,7 @@ DefineTSConfiguration(List *names, List *parameters)
 	AclResult	aclresult;
 	Oid			namespaceoid;
 	char	   *cfgname;
+	char	   *cfgnamespace;
 	NameData	cname;
 	Oid			sourceOid = InvalidOid;
 	Oid			prsOid = InvalidOid;
@@ -965,11 +1042,38 @@ DefineTSConfiguration(List *names, List *parameters)
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
 
+	/* Get namespace name */
+	cfgnamespace = get_namespace_name(namespaceoid);
+
 	/* Check we have creation rights in target namespace */
 	aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
 	if (aclresult != ACLCHECK_OK)
 		aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
-					   get_namespace_name(namespaceoid));
+					   cfgnamespace);
+
+	/* Check if text search configuration already exists */
+	cfgOid = GetSysCacheOid2(TSCONFIGNAMENSP,
+							 CStringGetDatum(cfgname),
+							 ObjectIdGetDatum(namespaceoid));
+
+	if (OidIsValid(cfgOid))
+	{
+		if (ifNotExists)
+		{
+			ereport(NOTICE,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("text search configuration \"%s\".\"%s\" already exists, skipping",
+							cfgnamespace,
+							cfgname)));
+			return InvalidOid;
+		}
+
+		ereport(ERROR,
+				(errcode(ERRCODE_DUPLICATE_OBJECT),
+				 errmsg("text search configuration \"%s\".\"%s\" already exists",
+						cfgnamespace,
+						cfgname)));
+	}
 
 	/*
 	 * loop over the definition list and extract the information we need.
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index d4a14ca..6641635 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -114,7 +114,7 @@ static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
  *		Registers a new base type.
  */
 Oid
-DefineType(List *names, List *parameters)
+DefineType(List *names, List *parameters, bool ifNotExists)
 {
 	char	   *typeName;
 	Oid			typeNamespace;
@@ -233,9 +233,19 @@ DefineType(List *names, List *parameters)
 	{
 		/* Complain if dummy CREATE TYPE and entry already exists */
 		if (parameters == NIL)
+		{
+			if (ifNotExists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_OBJECT),
+						 errmsg("type \"%s\" already exists, skipping", typeName)));
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", typeName)));
+		}
 	}
 
 	/* Extract the parameters from the parameter list */
@@ -585,7 +595,11 @@ DefineType(List *names, List *parameters)
 				   -1,			/* typMod (Domains only) */
 				   0,			/* Array Dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
-				   collation);	/* type's collation */
+				   collation,	/* type's collation */
+				   ifNotExists);	/* if not exists */
+
+	if (!OidIsValid(typoid))
+		return typoid;
 
 	/*
 	 * Create the array type that goes with it.
@@ -621,11 +635,12 @@ DefineType(List *names, List *parameters)
 						NULL,	/* binary default isn't sent either */
 						false,	/* never passed by value */
 						alignment,		/* see above */
-						'x',	/* ARRAY is always toastable */
-						-1,		/* typMod (Domains only) */
-						0,		/* Array dimensions of typbasetype */
-						false,	/* Type NOT NULL */
-						collation);		/* type's collation */
+						'x',				/* ARRAY is always toastable */
+						-1,				/* typMod (Domains only) */
+						0,				/* Array dimensions of typbasetype */
+						false,			/* Type NOT NULL */
+						collation,		/* type's collation */
+						ifNotExists);	/* if not exists */
 
 	pfree(array_type);
 
@@ -1011,7 +1026,8 @@ DefineDomain(CreateDomainStmt *stmt)
 				   basetypeMod, /* typeMod value */
 				   typNDims,	/* Array dimensions for base type */
 				   typNotNull,	/* Type NOT NULL */
-				   domaincoll); /* type's collation */
+				   domaincoll,	/* type's collation */
+				   false);		/* if not exists */
 
 	/*
 	 * Process constraints which refer to the domain ID returned by TypeCreate
@@ -1084,9 +1100,19 @@ DefineEnum(CreateEnumStmt *stmt)
 	if (OidIsValid(old_type_oid))
 	{
 		if (!moveArrayTypeName(old_type_oid, enumName, enumNamespace))
+		{
+			if (stmt->if_not_exists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_OBJECT),
+						 errmsg("type \"%s\" already exists, skipping", enumName)));
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", enumName)));
+		}
 	}
 
 	enumArrayOid = AssignTypeArrayOid();
@@ -1123,7 +1149,11 @@ DefineEnum(CreateEnumStmt *stmt)
 				   -1,			/* typMod (Domains only) */
 				   0,			/* Array dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
-				   InvalidOid); /* type's collation */
+				   InvalidOid,	/* type's collation */
+				   stmt->if_not_exists);		/* if not exists */
+
+	if (!OidIsValid(enumTypeOid))
+		return enumTypeOid;
 
 	/* Enter the enum's values into pg_enum */
 	EnumValuesCreate(enumTypeOid, stmt->vals);
@@ -1163,7 +1193,8 @@ DefineEnum(CreateEnumStmt *stmt)
 			   -1,				/* typMod (Domains only) */
 			   0,				/* Array dimensions of typbasetype */
 			   false,			/* Type NOT NULL */
-			   InvalidOid);		/* type's collation */
+			   InvalidOid,		/* type's collation */
+			   stmt->if_not_exists);			/* if not exists */
 
 	pfree(enumArrayName);
 
@@ -1302,9 +1333,19 @@ DefineRange(CreateRangeStmt *stmt)
 		if (moveArrayTypeName(typoid, typeName, typeNamespace))
 			typoid = InvalidOid;
 		else
+		{
+			if (stmt->if_not_exists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_OBJECT),
+						 errmsg("type \"%s\" already exists, skipping", typeName)));
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", typeName)));
+		}
 	}
 
 	/*
@@ -1457,7 +1498,11 @@ DefineRange(CreateRangeStmt *stmt)
 				   -1,			/* typMod (Domains only) */
 				   0,			/* Array dimensions of typbasetype */
 				   false,		/* Type NOT NULL */
-				   InvalidOid); /* type's collation (ranges never have one) */
+				   InvalidOid,	/* type's collation (ranges never have one) */
+				   stmt->if_not_exists);		/* if not exists */
+
+	if (!OidIsValid(typoid))
+		return typoid;
 
 	/* Create the entry in pg_range */
 	RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass,
@@ -1498,7 +1543,8 @@ DefineRange(CreateRangeStmt *stmt)
 			   -1,				/* typMod (Domains only) */
 			   0,				/* Array dimensions of typbasetype */
 			   false,			/* Type NOT NULL */
-			   InvalidOid);		/* typcollation */
+			   InvalidOid,		/* typcollation */
+			   stmt->if_not_exists);			/* if not exists */
 
 	pfree(rangeArrayName);
 
@@ -1569,7 +1615,8 @@ makeRangeConstructors(const char *name, Oid namespace,
 								  NIL,	/* parameterDefaults */
 								  PointerGetDatum(NULL),		/* proconfig */
 								  1.0,	/* procost */
-								  0.0); /* prorows */
+								  0.0,	/* prorows */
+								  false);	/* if not exists */
 
 		/*
 		 * Make the constructors internally-dependent on the range type so
@@ -2018,7 +2065,7 @@ AssignTypeArrayOid(void)
  *-------------------------------------------------------------------
  */
 Oid
-DefineCompositeType(RangeVar *typevar, List *coldeflist)
+DefineCompositeType(RangeVar *typevar, List *coldeflist, bool ifNotExists)
 {
 	CreateStmt *createStmt = makeNode(CreateStmt);
 	Oid			old_type_oid;
@@ -2054,9 +2101,19 @@ DefineCompositeType(RangeVar *typevar, List *coldeflist)
 	if (OidIsValid(old_type_oid))
 	{
 		if (!moveArrayTypeName(old_type_oid, createStmt->relation->relname, typeNamespace))
+		{
+			if (ifNotExists)
+			{
+				ereport(NOTICE,
+						(errcode(ERRCODE_DUPLICATE_OBJECT),
+						 errmsg("type \"%s\" already exists, skipping", createStmt->relation->relname)));
+				return InvalidOid;
+			}
+
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", createStmt->relation->relname)));
+		}
 	}
 
 	/*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index bcc6496..bdf3325 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2780,6 +2780,7 @@ _copyDefineStmt(const DefineStmt *from)
 	COPY_NODE_FIELD(defnames);
 	COPY_NODE_FIELD(args);
 	COPY_NODE_FIELD(definition);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
@@ -3039,6 +3040,7 @@ _copyCompositeTypeStmt(const CompositeTypeStmt *from)
 
 	COPY_NODE_FIELD(typevar);
 	COPY_NODE_FIELD(coldeflist);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
@@ -3050,6 +3052,7 @@ _copyCreateEnumStmt(const CreateEnumStmt *from)
 
 	COPY_NODE_FIELD(typeName);
 	COPY_NODE_FIELD(vals);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
@@ -3061,6 +3064,7 @@ _copyCreateRangeStmt(const CreateRangeStmt *from)
 
 	COPY_NODE_FIELD(typeName);
 	COPY_NODE_FIELD(params);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
@@ -3677,6 +3681,7 @@ _copyCreateCastStmt(const CreateCastStmt *from)
 	COPY_NODE_FIELD(func);
 	COPY_SCALAR_FIELD(context);
 	COPY_SCALAR_FIELD(inout);
+	COPY_SCALAR_FIELD(if_not_exists);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 7f9737e..c2acfe5 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1120,6 +1120,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b)
 	COMPARE_NODE_FIELD(defnames);
 	COMPARE_NODE_FIELD(args);
 	COMPARE_NODE_FIELD(definition);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
@@ -1341,6 +1342,7 @@ _equalCompositeTypeStmt(const CompositeTypeStmt *a, const CompositeTypeStmt *b)
 {
 	COMPARE_NODE_FIELD(typevar);
 	COMPARE_NODE_FIELD(coldeflist);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
@@ -1350,6 +1352,7 @@ _equalCreateEnumStmt(const CreateEnumStmt *a, const CreateEnumStmt *b)
 {
 	COMPARE_NODE_FIELD(typeName);
 	COMPARE_NODE_FIELD(vals);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
@@ -1359,6 +1362,7 @@ _equalCreateRangeStmt(const CreateRangeStmt *a, const CreateRangeStmt *b)
 {
 	COMPARE_NODE_FIELD(typeName);
 	COMPARE_NODE_FIELD(params);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
@@ -1879,6 +1883,7 @@ _equalCreateCastStmt(const CreateCastStmt *a, const CreateCastStmt *b)
 	COMPARE_NODE_FIELD(func);
 	COMPARE_SCALAR_FIELD(context);
 	COMPARE_SCALAR_FIELD(inout);
+	COMPARE_SCALAR_FIELD(if_not_exists);
 
 	return true;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index d8d2bdf..7fa9dea 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4613,6 +4613,18 @@ DefineStmt:
 					n->defnames = $3;
 					n->args = $4;
 					n->definition = $5;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE AGGREGATE IF_P NOT EXISTS func_name aggr_args definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_AGGREGATE;
+					n->oldstyle = false;
+					n->defnames = $6;
+					n->args = $7;
+					n->definition = $8;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE AGGREGATE func_name old_aggr_definition
@@ -4624,6 +4636,19 @@ DefineStmt:
 					n->defnames = $3;
 					n->args = NIL;
 					n->definition = $4;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE AGGREGATE IF_P NOT EXISTS func_name old_aggr_definition
+				{
+					/* old-style (pre-8.2) syntax for CREATE AGGREGATE */
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_AGGREGATE;
+					n->oldstyle = true;
+					n->defnames = $6;
+					n->args = NIL;
+					n->definition = $7;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE OPERATOR any_operator definition
@@ -4634,6 +4659,18 @@ DefineStmt:
 					n->defnames = $3;
 					n->args = NIL;
 					n->definition = $4;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE OPERATOR IF_P NOT EXISTS any_operator definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_OPERATOR;
+					n->oldstyle = false;
+					n->defnames = $6;
+					n->args = NIL;
+					n->definition = $7;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TYPE_P any_name definition
@@ -4644,6 +4681,18 @@ DefineStmt:
 					n->defnames = $3;
 					n->args = NIL;
 					n->definition = $4;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TYPE_P IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TYPE;
+					n->oldstyle = false;
+					n->defnames = $6;
+					n->args = NIL;
+					n->definition = $7;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TYPE_P any_name
@@ -4655,6 +4704,19 @@ DefineStmt:
 					n->defnames = $3;
 					n->args = NIL;
 					n->definition = NIL;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TYPE_P IF_P NOT EXISTS any_name
+				{
+					/* Shell type (identified by lack of definition) */
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TYPE;
+					n->oldstyle = false;
+					n->defnames = $6;
+					n->args = NIL;
+					n->definition = NIL;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')'
@@ -4664,6 +4726,17 @@ DefineStmt:
 					/* can't use qualified_name, sigh */
 					n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner);
 					n->coldeflist = $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TYPE_P IF_P NOT EXISTS any_name AS '(' OptTableFuncElementList ')'
+				{
+					CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
+
+					/* can't use qualified_name, sigh */
+					n->typevar = makeRangeVarFromAnyName($6, @6, yyscanner);
+					n->coldeflist = $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')'
@@ -4671,6 +4744,15 @@ DefineStmt:
 					CreateEnumStmt *n = makeNode(CreateEnumStmt);
 					n->typeName = $3;
 					n->vals = $7;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TYPE_P IF_P NOT EXISTS any_name AS ENUM_P '(' opt_enum_val_list ')'
+				{
+					CreateEnumStmt *n = makeNode(CreateEnumStmt);
+					n->typeName = $6;
+					n->vals = $10;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TYPE_P any_name AS RANGE definition
@@ -4678,6 +4760,15 @@ DefineStmt:
 					CreateRangeStmt *n = makeNode(CreateRangeStmt);
 					n->typeName = $3;
 					n->params	= $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TYPE_P IF_P NOT EXISTS any_name AS RANGE definition
+				{
+					CreateRangeStmt *n = makeNode(CreateRangeStmt);
+					n->typeName = $6;
+					n->params	= $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TEXT_P SEARCH PARSER any_name definition
@@ -4687,6 +4778,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $5;
 					n->definition = $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TEXT_P SEARCH PARSER IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TSPARSER;
+					n->args = NIL;
+					n->defnames = $8;
+					n->definition = $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TEXT_P SEARCH DICTIONARY any_name definition
@@ -4696,6 +4798,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $5;
 					n->definition = $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TEXT_P SEARCH DICTIONARY IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TSDICTIONARY;
+					n->args = NIL;
+					n->defnames = $8;
+					n->definition = $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TEXT_P SEARCH TEMPLATE any_name definition
@@ -4705,6 +4818,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $5;
 					n->definition = $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TEXT_P SEARCH TEMPLATE IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TSTEMPLATE;
+					n->args = NIL;
+					n->defnames = $8;
+					n->definition = $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE TEXT_P SEARCH CONFIGURATION any_name definition
@@ -4714,6 +4838,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $5;
 					n->definition = $6;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE TEXT_P SEARCH CONFIGURATION IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_TSCONFIGURATION;
+					n->args = NIL;
+					n->defnames = $8;
+					n->definition = $9;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE COLLATION any_name definition
@@ -4723,6 +4858,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $3;
 					n->definition = $4;
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE COLLATION IF_P NOT EXISTS any_name definition
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_COLLATION;
+					n->args = NIL;
+					n->defnames = $6;
+					n->definition = $7;
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 			| CREATE COLLATION any_name FROM any_name
@@ -4732,6 +4878,17 @@ DefineStmt:
 					n->args = NIL;
 					n->defnames = $3;
 					n->definition = list_make1(makeDefElem("from", (Node *) $5));
+					n->if_not_exists = false;
+					$$ = (Node *)n;
+				}
+			| CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name
+				{
+					DefineStmt *n = makeNode(DefineStmt);
+					n->kind = OBJECT_COLLATION;
+					n->args = NIL;
+					n->defnames = $6;
+					n->definition = list_make1(makeDefElem("from", (Node *) $8));
+					n->if_not_exists = true;
 					$$ = (Node *)n;
 				}
 		;
@@ -4833,8 +4990,8 @@ AlterEnumStmt:
 			}
 		 ;
 
-opt_if_not_exists: IF_P NOT EXISTS              { $$ = true; }
-         | /* empty */                          { $$ = false; }
+opt_if_not_exists: IF_P NOT EXISTS              { $$ = TRUE; }
+         | /* empty */                          { $$ = FALSE; }
          ;
 
 
@@ -6702,37 +6859,40 @@ dostmt_opt_item:
  *
  *****************************************************************************/
 
-CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
+CreateCastStmt: CREATE CAST opt_if_not_exists '(' Typename AS Typename ')'
 					WITH FUNCTION function_with_argtypes cast_context
 				{
 					CreateCastStmt *n = makeNode(CreateCastStmt);
-					n->sourcetype = $4;
-					n->targettype = $6;
-					n->func = $10;
-					n->context = (CoercionContext) $11;
+					n->sourcetype = $5;
+					n->targettype = $7;
+					n->func = $11;
+					n->context = (CoercionContext) $12;
 					n->inout = false;
+					n->if_not_exists = $3;
 					$$ = (Node *)n;
 				}
-			| CREATE CAST '(' Typename AS Typename ')'
+			| CREATE CAST opt_if_not_exists '(' Typename AS Typename ')'
 					WITHOUT FUNCTION cast_context
 				{
 					CreateCastStmt *n = makeNode(CreateCastStmt);
-					n->sourcetype = $4;
-					n->targettype = $6;
+					n->sourcetype = $5;
+					n->targettype = $7;
 					n->func = NULL;
-					n->context = (CoercionContext) $10;
+					n->context = (CoercionContext) $11;
 					n->inout = false;
+					n->if_not_exists = $3;
 					$$ = (Node *)n;
 				}
-			| CREATE CAST '(' Typename AS Typename ')'
+			| CREATE CAST opt_if_not_exists '(' Typename AS Typename ')'
 					WITH INOUT cast_context
 				{
 					CreateCastStmt *n = makeNode(CreateCastStmt);
-					n->sourcetype = $4;
-					n->targettype = $6;
+					n->sourcetype = $5;
+					n->targettype = $7;
 					n->func = NULL;
-					n->context = (CoercionContext) $10;
+					n->context = (CoercionContext) $11;
 					n->inout = true;
+					n->if_not_exists = $3;
 					$$ = (Node *)n;
 				}
 		;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index c940897..d33f67e 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1103,34 +1103,41 @@ ProcessUtilitySlow(Node *parsetree,
 					{
 						case OBJECT_AGGREGATE:
 							DefineAggregate(stmt->defnames, stmt->args,
-											stmt->oldstyle, stmt->definition);
+											stmt->oldstyle, stmt->definition,
+											stmt->if_not_exists);
 							break;
 						case OBJECT_OPERATOR:
 							Assert(stmt->args == NIL);
-							DefineOperator(stmt->defnames, stmt->definition);
+							DefineOperator(stmt->defnames, stmt->definition,
+										   stmt->if_not_exists);
 							break;
 						case OBJECT_TYPE:
 							Assert(stmt->args == NIL);
-							DefineType(stmt->defnames, stmt->definition);
+							DefineType(stmt->defnames, stmt->definition,
+									   stmt->if_not_exists);
 							break;
 						case OBJECT_TSPARSER:
 							Assert(stmt->args == NIL);
-							DefineTSParser(stmt->defnames, stmt->definition);
+							DefineTSParser(stmt->defnames, stmt->definition,
+										   stmt->if_not_exists);
 							break;
 						case OBJECT_TSDICTIONARY:
 							Assert(stmt->args == NIL);
 							DefineTSDictionary(stmt->defnames,
-											   stmt->definition);
+											   stmt->definition,
+											   stmt->if_not_exists);
 							break;
 						case OBJECT_TSTEMPLATE:
 							Assert(stmt->args == NIL);
 							DefineTSTemplate(stmt->defnames,
-											 stmt->definition);
+											 stmt->definition,
+											 stmt->if_not_exists);
 							break;
 						case OBJECT_TSCONFIGURATION:
 							Assert(stmt->args == NIL);
 							DefineTSConfiguration(stmt->defnames,
-												  stmt->definition);
+												  stmt->definition,
+												  stmt->if_not_exists);
 							break;
 						case OBJECT_COLLATION:
 							Assert(stmt->args == NIL);
@@ -1211,7 +1218,7 @@ ProcessUtilitySlow(Node *parsetree,
 				{
 					CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
 
-					DefineCompositeType(stmt->typevar, stmt->coldeflist);
+					DefineCompositeType(stmt->typevar, stmt->coldeflist, stmt->if_not_exists);
 				}
 				break;
 
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 6fb10a9..65c8616 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -246,6 +246,7 @@ extern Oid AggregateCreate(const char *aggName,
 				List *aggfinalfnName,
 				List *aggsortopName,
 				Oid aggTransType,
-				const char *agginitval);
+				const char *agginitval,
+				bool aggIfNotExists);
 
 #endif   /* PG_AGGREGATE_H */
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 5f28fc3..18f3897 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1752,6 +1752,7 @@ extern Oid OperatorCreate(const char *operatorName,
 			   Oid restrictionId,
 			   Oid joinId,
 			   bool canMerge,
-			   bool canHash);
+			   bool canHash,
+			   bool ifNotExists);
 
 #endif   /* PG_OPERATOR_H */
diff --git a/src/include/catalog/pg_proc_fn.h b/src/include/catalog/pg_proc_fn.h
index 3b04301..d920c0b 100644
--- a/src/include/catalog/pg_proc_fn.h
+++ b/src/include/catalog/pg_proc_fn.h
@@ -39,7 +39,8 @@ extern Oid ProcedureCreate(const char *procedureName,
 				List *parameterDefaults,
 				Datum proconfig,
 				float4 procost,
-				float4 prorows);
+				float4 prorows,
+				bool ifNotExists);
 
 extern bool function_parse_error_transpose(const char *prosrc);
 
diff --git a/src/include/catalog/pg_type_fn.h b/src/include/catalog/pg_type_fn.h
index b12d58a..e21a817 100644
--- a/src/include/catalog/pg_type_fn.h
+++ b/src/include/catalog/pg_type_fn.h
@@ -51,7 +51,8 @@ extern Oid TypeCreate(Oid newTypeOid,
 		   int32 typeMod,
 		   int32 typNDims,
 		   bool typeNotNull,
-		   Oid typeCollation);
+		   Oid typeCollation,
+		   bool ifNotExists);
 
 extern void GenerateTypeDependencies(Oid typeNamespace,
 						 Oid typeObjectId,
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index fa9f41f..34baf01 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -55,12 +55,12 @@ extern void ExecuteDoStmt(DoStmt *stmt);
 extern Oid	get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
 /* commands/operatorcmds.c */
-extern Oid	DefineOperator(List *names, List *parameters);
+extern Oid DefineOperator(List *names, List *parameters, bool ifNotExists);
 extern void RemoveOperatorById(Oid operOid);
 
 /* commands/aggregatecmds.c */
 extern Oid DefineAggregate(List *name, List *args, bool oldstyle,
-				List *parameters);
+				List *parameters, bool ifNotExists);
 
 /* commands/opclasscmds.c */
 extern Oid	DefineOpClass(CreateOpClassStmt *stmt);
@@ -79,17 +79,17 @@ extern Oid	get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
 extern Oid	get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
 
 /* commands/tsearchcmds.c */
-extern Oid	DefineTSParser(List *names, List *parameters);
+extern Oid DefineTSParser(List *names, List *parameters, bool ifNotExists);
 extern void RemoveTSParserById(Oid prsId);
 
-extern Oid	DefineTSDictionary(List *names, List *parameters);
+extern Oid DefineTSDictionary(List *names, List *parameters, bool ifNotExists);
 extern void RemoveTSDictionaryById(Oid dictId);
 extern Oid	AlterTSDictionary(AlterTSDictionaryStmt *stmt);
 
-extern Oid	DefineTSTemplate(List *names, List *parameters);
+extern Oid DefineTSTemplate(List *names, List *parameters, bool ifNotExists);
 extern void RemoveTSTemplateById(Oid tmplId);
 
-extern Oid	DefineTSConfiguration(List *names, List *parameters);
+extern Oid DefineTSConfiguration(List *names, List *parameters, bool ifNotExists);
 extern void RemoveTSConfigurationById(Oid cfgId);
 extern Oid	AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
 
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index f45fde7..dbd4e32 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -21,13 +21,13 @@
 
 #define DEFAULT_TYPDELIM		','
 
-extern Oid	DefineType(List *names, List *parameters);
+extern Oid DefineType(List *names, List *parameters, bool ifNotExists);
 extern void RemoveTypeById(Oid typeOid);
 extern Oid	DefineDomain(CreateDomainStmt *stmt);
 extern Oid	DefineEnum(CreateEnumStmt *stmt);
 extern Oid	DefineRange(CreateRangeStmt *stmt);
 extern Oid	AlterEnum(AlterEnumStmt *stmt, bool isTopLevel);
-extern Oid	DefineCompositeType(RangeVar *typevar, List *coldeflist);
+extern Oid	DefineCompositeType(RangeVar *typevar, List *coldeflist, bool ifNotExists);
 extern Oid	AssignTypeArrayOid(void);
 
 extern Oid	AlterDomainDefault(List *names, Node *defaultRaw);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index b4013e8..aa3bed5 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1898,6 +1898,7 @@ typedef struct DefineStmt
 	List	   *defnames;		/* qualified name (list of Value strings) */
 	List	   *args;			/* a list of TypeName (if needed) */
 	List	   *definition;		/* a list of DefElem */
+	bool		if_not_exists;	/* just do nothing if {aggregate|operator|type} already exists? */
 } DefineStmt;
 
 /* ----------------------
@@ -2312,6 +2313,7 @@ typedef struct CompositeTypeStmt
 	NodeTag		type;
 	RangeVar   *typevar;		/* the composite type to be created */
 	List	   *coldeflist;		/* list of ColumnDef nodes */
+	bool		if_not_exists;	/* just do nothing if type already exists? */
 } CompositeTypeStmt;
 
 /* ----------------------
@@ -2323,6 +2325,7 @@ typedef struct CreateEnumStmt
 	NodeTag		type;
 	List	   *typeName;		/* qualified name (list of Value strings) */
 	List	   *vals;			/* enum values (list of Value strings) */
+	bool		if_not_exists;	/* just do nothing if type already exists? */
 } CreateEnumStmt;
 
 /* ----------------------
@@ -2334,6 +2337,7 @@ typedef struct CreateRangeStmt
 	NodeTag		type;
 	List	   *typeName;		/* qualified name (list of Value strings) */
 	List	   *params;			/* range parameters (list of DefElem) */
+	bool		if_not_exists;	/* just do nothing if type already exists? */
 } CreateRangeStmt;
 
 /* ----------------------
@@ -2603,6 +2607,7 @@ typedef struct CreateCastStmt
 	FuncWithArgs *func;
 	CoercionContext context;
 	bool		inout;
+	bool		if_not_exists;	/* just do nothing if cast already exists? */
 } CreateCastStmt;
 
 /* ----------------------
diff --git a/src/test/regress/expected/alter_generic.out b/src/test/regress/expected/alter_generic.out
index 4e4df0c..6f2becf 100644
--- a/src/test/regress/expected/alter_generic.out
+++ b/src/test/regress/expected/alter_generic.out
@@ -581,6 +581,10 @@ SELECT nspname, cfgname, rolname
 -- Text Search Template
 --
 CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+ERROR:  text search template "alt_nsp1"."alt_ts_temp1" already exists
+CREATE TEXT SEARCH TEMPLATE IF NOT EXISTS alt_ts_temp1 (lexize=dsimple_lexize);
+NOTICE:  text search template "alt_nsp1"."alt_ts_temp1" already exists, skipping
 CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
 ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2; -- failed (name conflict)
 ERROR:  text search template "alt_ts_temp2" already exists in schema "alt_nsp1"
@@ -605,6 +609,12 @@ SELECT nspname, tmplname
 --
 CREATE TEXT SEARCH PARSER alt_ts_prs1
     (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+CREATE TEXT SEARCH PARSER alt_ts_prs1
+    (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ERROR:  text search parser "alt_nsp1"."alt_ts_prs1" already exists
+CREATE TEXT SEARCH PARSER IF NOT EXISTS alt_ts_prs1
+    (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+NOTICE:  text search parser "alt_nsp1"."alt_ts_prs1" already exists, skipping
 CREATE TEXT SEARCH PARSER alt_ts_prs2
     (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
 ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2; -- failed (name conflict)
diff --git a/src/test/regress/expected/create_aggregate.out b/src/test/regress/expected/create_aggregate.out
index ad14594..e294d06 100644
--- a/src/test/regress/expected/create_aggregate.out
+++ b/src/test/regress/expected/create_aggregate.out
@@ -12,6 +12,19 @@ COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment';
 ERROR:  aggregate newavg_wrong(integer) does not exist
 COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment';
 COMMENT ON AGGREGATE newavg (int4) IS NULL;
+-- test IF NOT EXISTS
+CREATE AGGREGATE newavg (
+   sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+   finalfunc = int8_avg,
+   initcond1 = '{0,0}'
+);
+ERROR:  function "newavg" already exists with same argument types
+CREATE AGGREGATE IF NOT EXISTS newavg (
+   sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+   finalfunc = int8_avg,
+   initcond1 = '{0,0}'
+);
+NOTICE:  function "newavg" already exists with same argument types, skipping
 -- without finalfunc; test obsolete spellings 'sfunc1' etc
 CREATE AGGREGATE newsum (
    sfunc1 = int4pl, basetype = int4, stype1 = int4,
diff --git a/src/test/regress/expected/create_cast.out b/src/test/regress/expected/create_cast.out
index 56cd86e..1c3e6f0 100644
--- a/src/test/regress/expected/create_cast.out
+++ b/src/test/regress/expected/create_cast.out
@@ -29,6 +29,10 @@ LINE 1: SELECT casttestfunc('foo'::text);
 HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
 -- Try binary coercion cast
 CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+ERROR:  cast from type text to type casttesttype already exists
+CREATE CAST IF NOT EXISTS (text AS casttesttype) WITHOUT FUNCTION;
+NOTICE:  cast from type text to type casttesttype already exists, skipping
 SELECT casttestfunc('foo'::text); -- doesn't work, as the cast is explicit
 ERROR:  function casttestfunc(text) does not exist
 LINE 1: SELECT casttestfunc('foo'::text);
@@ -43,6 +47,10 @@ SELECT casttestfunc('foo'::text::casttesttype); -- should work
 DROP CAST (text AS casttesttype); -- cleanup
 -- Try IMPLICIT binary coercion cast
 CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
+ERROR:  cast from type text to type casttesttype already exists
+CREATE CAST IF NOT EXISTS (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
+NOTICE:  cast from type text to type casttesttype already exists, skipping
 SELECT casttestfunc('foo'::text); -- Should work now
  casttestfunc 
 --------------
@@ -55,6 +63,10 @@ ERROR:  cannot cast type integer to casttesttype
 LINE 1: SELECT 1234::int4::casttesttype;
                          ^
 CREATE CAST (int4 AS casttesttype) WITH INOUT;
+CREATE CAST (int4 AS casttesttype) WITH INOUT;
+ERROR:  cast from type integer to type casttesttype already exists
+CREATE CAST IF NOT EXISTS (int4 AS casttesttype) WITH INOUT;
+NOTICE:  cast from type integer to type casttesttype already exists, skipping
 SELECT 1234::int4::casttesttype; -- Should work now
  casttesttype 
 --------------
@@ -66,6 +78,10 @@ DROP CAST (int4 AS casttesttype);
 CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE SQL AS
 $$ SELECT ('foo'::text || $1::text)::casttesttype; $$;
 CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
+CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
+ERROR:  cast from type integer to type casttesttype already exists
+CREATE CAST IF NOT EXISTS (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
+NOTICE:  cast from type integer to type casttesttype already exists, skipping
 SELECT 1234::int4::casttesttype; -- Should work now
  casttesttype 
 --------------
diff --git a/src/test/regress/expected/create_operator.out b/src/test/regress/expected/create_operator.out
index 2e6c764..3e5a2f7 100644
--- a/src/test/regress/expected/create_operator.out
+++ b/src/test/regress/expected/create_operator.out
@@ -7,6 +7,20 @@ CREATE OPERATOR ## (
    procedure = path_inter,
    commutator = ##
 );
+CREATE OPERATOR ## (
+   leftarg = path,
+   rightarg = path,
+   procedure = path_inter,
+   commutator = ##
+);
+ERROR:  operator ## already exists
+CREATE OPERATOR IF NOT EXISTS ## (
+   leftarg = path,
+   rightarg = path,
+   procedure = path_inter,
+   commutator = ##
+);
+NOTICE:  operator ## already exists, skipping
 CREATE OPERATOR <% (
    leftarg = point,
    rightarg = widget,
diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out
index 6dfe916..666a7c1 100644
--- a/src/test/regress/expected/create_type.out
+++ b/src/test/regress/expected/create_type.out
@@ -14,6 +14,24 @@ CREATE TYPE widget (
    typmod_out = numerictypmodout,
    alignment = double
 );
+CREATE TYPE widget (
+   internallength = 24,
+   input = widget_in,
+   output = widget_out,
+   typmod_in = numerictypmodin,
+   typmod_out = numerictypmodout,
+   alignment = double
+);
+ERROR:  type "widget" already exists
+CREATE TYPE IF NOT EXISTS widget (
+   internallength = 24,
+   input = widget_in,
+   output = widget_out,
+   typmod_in = numerictypmodin,
+   typmod_out = numerictypmodout,
+   alignment = double
+);
+NOTICE:  type "widget" already exists, skipping
 CREATE TYPE city_budget (
    internallength = 16,
    input = int44in,
@@ -26,6 +44,8 @@ CREATE TYPE city_budget (
 CREATE TYPE shell;
 CREATE TYPE shell;   -- fail, type already present
 ERROR:  type "shell" already exists
+CREATE TYPE IF NOT EXISTS shell;   -- do not fail, just skip
+NOTICE:  type "shell" already exists, skipping
 DROP TYPE shell;
 DROP TYPE shell;     -- fail, type not exist
 ERROR:  type "shell" does not exist
@@ -83,6 +103,10 @@ SELECT * FROM default_test;
 
 -- Test stand-alone composite type
 CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42);
+CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42);
+ERROR:  type "default_test_row" already exists
+CREATE TYPE IF NOT EXISTS default_test_row AS (f1 text_w_default, f2 int42);
+NOTICE:  type "default_test_row" already exists, skipping
 CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS '
   SELECT * FROM default_test;
 ' LANGUAGE SQL;
diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out
index 3682642..b95e6a5 100644
--- a/src/test/regress/expected/enum.out
+++ b/src/test/regress/expected/enum.out
@@ -2,6 +2,10 @@
 -- Enum tests
 --
 CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+ERROR:  type "rainbow" already exists
+CREATE TYPE IF NOT EXISTS rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+NOTICE:  type "rainbow" already exists, skipping
 --
 -- Did it create the right number of rows?
 --
diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out
index 39db992..7397498 100644
--- a/src/test/regress/expected/rangetypes.out
+++ b/src/test/regress/expected/rangetypes.out
@@ -1,5 +1,9 @@
 -- Tests for range data types.
 create type textrange as range (subtype=text, collation="C");
+create type textrange as range (subtype=text, collation="C");
+ERROR:  type "textrange" already exists
+create type if not exists textrange as range (subtype=text, collation="C");
+NOTICE:  type "textrange" already exists, skipping
 --
 -- test input parser
 --
diff --git a/src/test/regress/expected/tsdicts.out b/src/test/regress/expected/tsdicts.out
index 9df1434..3214609 100644
--- a/src/test/regress/expected/tsdicts.out
+++ b/src/test/regress/expected/tsdicts.out
@@ -5,6 +5,18 @@ CREATE TEXT SEARCH DICTIONARY ispell (
                         DictFile=ispell_sample,
                         AffFile=ispell_sample
 );
+CREATE TEXT SEARCH DICTIONARY ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
+ERROR:  text search dictionary "public"."ispell" already exists
+CREATE TEXT SEARCH DICTIONARY IF NOT EXISTS ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
+NOTICE:  text search dictionary "public"."ispell" already exists, skipping
 SELECT ts_lexize('ispell', 'skies');
  ts_lexize 
 -----------
@@ -232,6 +244,14 @@ SELECT ts_lexize('thesaurus', 'one');
 CREATE TEXT SEARCH CONFIGURATION ispell_tst (
 						COPY=english
 );
+CREATE TEXT SEARCH CONFIGURATION ispell_tst (
+						COPY=english
+);
+ERROR:  text search configuration "public"."ispell_tst" already exists
+CREATE TEXT SEARCH CONFIGURATION IF NOT EXISTS ispell_tst (
+						COPY=english
+);
+NOTICE:  text search configuration "public"."ispell_tst" already exists, skipping
 ALTER TEXT SEARCH CONFIGURATION ispell_tst ALTER MAPPING FOR
 	word, numword, asciiword, hword, numhword, asciihword, hword_part, hword_numpart, hword_asciipart
 	WITH ispell, english_stem;
diff --git a/src/test/regress/sql/alter_generic.sql b/src/test/regress/sql/alter_generic.sql
index d62f64f..f225ade 100644
--- a/src/test/regress/sql/alter_generic.sql
+++ b/src/test/regress/sql/alter_generic.sql
@@ -501,6 +501,8 @@ SELECT nspname, cfgname, rolname
 -- Text Search Template
 --
 CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize);
+CREATE TEXT SEARCH TEMPLATE IF NOT EXISTS alt_ts_temp1 (lexize=dsimple_lexize);
 CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
 
 ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2; -- failed (name conflict)
@@ -521,6 +523,10 @@ SELECT nspname, tmplname
 
 CREATE TEXT SEARCH PARSER alt_ts_prs1
     (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+CREATE TEXT SEARCH PARSER alt_ts_prs1
+    (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+CREATE TEXT SEARCH PARSER IF NOT EXISTS alt_ts_prs1
+    (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
 CREATE TEXT SEARCH PARSER alt_ts_prs2
     (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
 
diff --git a/src/test/regress/sql/create_aggregate.sql b/src/test/regress/sql/create_aggregate.sql
index 84f9a4f..2d58c85 100644
--- a/src/test/regress/sql/create_aggregate.sql
+++ b/src/test/regress/sql/create_aggregate.sql
@@ -14,6 +14,18 @@ COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment';
 COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment';
 COMMENT ON AGGREGATE newavg (int4) IS NULL;
 
+-- test IF NOT EXISTS
+CREATE AGGREGATE newavg (
+   sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+   finalfunc = int8_avg,
+   initcond1 = '{0,0}'
+);
+CREATE AGGREGATE IF NOT EXISTS newavg (
+   sfunc = int4_avg_accum, basetype = int4, stype = _int8,
+   finalfunc = int8_avg,
+   initcond1 = '{0,0}'
+);
+
 -- without finalfunc; test obsolete spellings 'sfunc1' etc
 CREATE AGGREGATE newsum (
    sfunc1 = int4pl, basetype = int4, stype1 = int4,
diff --git a/src/test/regress/sql/create_cast.sql b/src/test/regress/sql/create_cast.sql
index ad348da..ec9e266 100644
--- a/src/test/regress/sql/create_cast.sql
+++ b/src/test/regress/sql/create_cast.sql
@@ -29,18 +29,24 @@ SELECT casttestfunc('foo'::text); -- fails, as there's no cast
 
 -- Try binary coercion cast
 CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION;
+CREATE CAST IF NOT EXISTS (text AS casttesttype) WITHOUT FUNCTION;
 SELECT casttestfunc('foo'::text); -- doesn't work, as the cast is explicit
 SELECT casttestfunc('foo'::text::casttesttype); -- should work
 DROP CAST (text AS casttesttype); -- cleanup
 
 -- Try IMPLICIT binary coercion cast
 CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
+CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
+CREATE CAST IF NOT EXISTS (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT;
 SELECT casttestfunc('foo'::text); -- Should work now
 
 -- Try I/O conversion cast.
 SELECT 1234::int4::casttesttype; -- No cast yet, should fail
 
 CREATE CAST (int4 AS casttesttype) WITH INOUT;
+CREATE CAST (int4 AS casttesttype) WITH INOUT;
+CREATE CAST IF NOT EXISTS (int4 AS casttesttype) WITH INOUT;
 SELECT 1234::int4::casttesttype; -- Should work now
 
 DROP CAST (int4 AS casttesttype);
@@ -51,4 +57,6 @@ CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE SQL AS
 $$ SELECT ('foo'::text || $1::text)::casttesttype; $$;
 
 CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
+CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
+CREATE CAST IF NOT EXISTS (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT;
 SELECT 1234::int4::casttesttype; -- Should work now
diff --git a/src/test/regress/sql/create_operator.sql b/src/test/regress/sql/create_operator.sql
index f7a372a..8278f88 100644
--- a/src/test/regress/sql/create_operator.sql
+++ b/src/test/regress/sql/create_operator.sql
@@ -1,14 +1,24 @@
 --
 -- CREATE_OPERATOR
 --
-
 CREATE OPERATOR ## (
    leftarg = path,
    rightarg = path,
    procedure = path_inter,
    commutator = ##
 );
-
+CREATE OPERATOR ## (
+   leftarg = path,
+   rightarg = path,
+   procedure = path_inter,
+   commutator = ##
+);
+CREATE OPERATOR IF NOT EXISTS ## (
+   leftarg = path,
+   rightarg = path,
+   procedure = path_inter,
+   commutator = ##
+);
 CREATE OPERATOR <% (
    leftarg = point,
    rightarg = widget,
@@ -16,22 +26,18 @@ CREATE OPERATOR <% (
    commutator = >% ,
    negator = >=%
 );
-
 CREATE OPERATOR @#@ (
    rightarg = int8,		-- left unary
    procedure = numeric_fac
 );
-
 CREATE OPERATOR #@# (
    leftarg = int8,		-- right unary
    procedure = numeric_fac
 );
-
 CREATE OPERATOR #%# (
    leftarg = int8,		-- right unary
    procedure = numeric_fac
 );
-
 -- Test comments
 COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
 
diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql
index a4906b6..79e0181 100644
--- a/src/test/regress/sql/create_type.sql
+++ b/src/test/regress/sql/create_type.sql
@@ -16,6 +16,24 @@ CREATE TYPE widget (
    alignment = double
 );
 
+CREATE TYPE widget (
+   internallength = 24,
+   input = widget_in,
+   output = widget_out,
+   typmod_in = numerictypmodin,
+   typmod_out = numerictypmodout,
+   alignment = double
+);
+
+CREATE TYPE IF NOT EXISTS widget (
+   internallength = 24,
+   input = widget_in,
+   output = widget_out,
+   typmod_in = numerictypmodin,
+   typmod_out = numerictypmodout,
+   alignment = double
+);
+
 CREATE TYPE city_budget (
    internallength = 16,
    input = int44in,
@@ -28,6 +46,7 @@ CREATE TYPE city_budget (
 -- Test creation and destruction of shell types
 CREATE TYPE shell;
 CREATE TYPE shell;   -- fail, type already present
+CREATE TYPE IF NOT EXISTS shell;   -- do not fail, just skip
 DROP TYPE shell;
 DROP TYPE shell;     -- fail, type not exist
 
@@ -85,6 +104,10 @@ SELECT * FROM default_test;
 
 CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42);
 
+CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42);
+
+CREATE TYPE IF NOT EXISTS default_test_row AS (f1 text_w_default, f2 int42);
+
 CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS '
   SELECT * FROM default_test;
 ' LANGUAGE SQL;
diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql
index 88a835e..4f9ebb7 100644
--- a/src/test/regress/sql/enum.sql
+++ b/src/test/regress/sql/enum.sql
@@ -4,6 +4,10 @@
 
 CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
 
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+
+CREATE TYPE IF NOT EXISTS rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+
 --
 -- Did it create the right number of rows?
 --
diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql
index fad843a..32d5b95 100644
--- a/src/test/regress/sql/rangetypes.sql
+++ b/src/test/regress/sql/rangetypes.sql
@@ -1,6 +1,8 @@
 -- Tests for range data types.
 
 create type textrange as range (subtype=text, collation="C");
+create type textrange as range (subtype=text, collation="C");
+create type if not exists textrange as range (subtype=text, collation="C");
 
 --
 -- test input parser
diff --git a/src/test/regress/sql/tsdicts.sql b/src/test/regress/sql/tsdicts.sql
index 55afcec..2f66006 100644
--- a/src/test/regress/sql/tsdicts.sql
+++ b/src/test/regress/sql/tsdicts.sql
@@ -6,6 +6,16 @@ CREATE TEXT SEARCH DICTIONARY ispell (
                         DictFile=ispell_sample,
                         AffFile=ispell_sample
 );
+CREATE TEXT SEARCH DICTIONARY ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
+CREATE TEXT SEARCH DICTIONARY IF NOT EXISTS ispell (
+                        Template=ispell,
+                        DictFile=ispell_sample,
+                        AffFile=ispell_sample
+);
 
 SELECT ts_lexize('ispell', 'skies');
 SELECT ts_lexize('ispell', 'bookings');
@@ -73,6 +83,12 @@ SELECT ts_lexize('thesaurus', 'one');
 CREATE TEXT SEARCH CONFIGURATION ispell_tst (
 						COPY=english
 );
+CREATE TEXT SEARCH CONFIGURATION ispell_tst (
+						COPY=english
+);
+CREATE TEXT SEARCH CONFIGURATION IF NOT EXISTS ispell_tst (
+						COPY=english
+);
 
 ALTER TEXT SEARCH CONFIGURATION ispell_tst ALTER MAPPING FOR
 	word, numword, asciiword, hword, numhword, asciihword, hword_part, hword_numpart, hword_asciipart
