diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
new file mode 100644
index c76d357..61daf55
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
*************** SELECT pg_type_is_visible('myschema.widg
*** 14831,14836 ****
--- 14831,14852 ----
      <primary>collation for</primary>
     </indexterm>
  
+    <indexterm>
+     <primary>to_regclass</primary>
+    </indexterm>
+ 
+    <indexterm>
+     <primary>to_regproc</primary>
+    </indexterm>
+ 
+    <indexterm>
+     <primary>to_regoper</primary>
+    </indexterm>
+ 
+    <indexterm>
+     <primary>to_regtype</primary>
+    </indexterm>
+ 
    <para>
     <xref linkend="functions-info-catalog-table"> lists functions that
     extract information from the system catalogs.
*************** SELECT pg_type_is_visible('myschema.widg
*** 15001,15006 ****
--- 15017,15042 ----
         <entry><type>text</type></entry>
         <entry>get the collation of the argument</entry>
        </row>
+       <row>
+        <entry><literal><function>to_regclass(<parameter>table_name</parameter>)</function></literal></entry>
+        <entry><type>regclass</type></entry>
+        <entry>get the table oid</entry>
+       </row>
+       <row>
+        <entry><literal><function>to_regproc(<parameter>func_name</parameter>)</function></literal></entry>
+        <entry><type>regproc</type></entry>
+        <entry>get the function oid</entry>
+       </row>
+       <row>
+        <entry><literal><function>to_regoper(<parameter>operator_name</parameter>)</function></literal></entry>
+        <entry><type>regoper</type></entry>
+        <entry>get the operator oid</entry>
+       </row>
+       <row>
+        <entry><literal><function>to_regtype(<parameter>type_name</parameter>)</function></literal></entry>
+        <entry><type>regtype</type></entry>
+        <entry>get the type oid</entry>
+       </row>
       </tbody>
      </tgroup>
     </table>
*************** SELECT collation for ('foo' COLLATE "de_
*** 15166,15171 ****
--- 15202,15213 ----
    is not of a collatable data type, then an error is raised.
    </para>
  
+   <para>
+     to_regclass, to_regproc, to_regoper and to_regtype are similar to
+     regclass, regproc, regoper and regtype except that if the requested object
+     is not found, returns InvalidOid, rather than raises an error.
+   </para>
+ 
     <indexterm>
      <primary>col_description</primary>
     </indexterm>
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
new file mode 100644
index 635aa1d..0612e53
*** a/src/backend/parser/parse_type.c
--- b/src/backend/parser/parse_type.c
***************
*** 30,35 ****
--- 30,38 ----
  
  static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName,
  				Type typ);
+ static void typenameTypeIdAndMod_guts(ParseState *pstate, const TypeName *typeName,
+ 				Oid *typeid_p, int32 *typmod_p, bool missing_ok);
+ static void parseTypeString_guts(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok);
  
  
  /*
*************** void
*** 241,251 ****
  typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
  					 Oid *typeid_p, int32 *typmod_p)
  {
  	Type		tup;
  
! 	tup = typenameType(pstate, typeName, typmod_p);
! 	*typeid_p = HeapTupleGetOid(tup);
! 	ReleaseSysCache(tup);
  }
  
  /*
--- 244,293 ----
  typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
  					 Oid *typeid_p, int32 *typmod_p)
  {
+ 	typenameTypeIdAndMod_guts(pstate, typeName, typeid_p, typmod_p, false);
+ }
+ 
+ /*
+  * typenameTypeIdAndModMissingOk - given a TypeName, return the type's OID and typmod
+  *
+  * Diffrence from typenameTypeIdMod is, this does not throw an error if the typeName
+  * does not exist.
+  */
+ void
+ typenameTypeIdAndModMissingOk(ParseState *pstate, const TypeName *typeName,
+ 					 Oid *typeid_p, int32 *typmod_p)
+ {
+ 	typenameTypeIdAndMod_guts(pstate, typeName, typeid_p, typmod_p, true);
+ }
+ 
+ /*
+  * Guts of typenameTypeIdAndMod and typenameTypeIdAndModMissingOk.
+  * If missing_ok is true, returns InvalidOid upon error.
+  */
+ static void
+ typenameTypeIdAndMod_guts(ParseState *pstate, const TypeName *typeName,
+ 					 Oid *typeid_p, int32 *typmod_p,
+ 					 bool missing_ok)
+ {
  	Type		tup;
  
! 	if (missing_ok)
! 	{
! 		tup = LookupTypeName(pstate, typeName, typmod_p);
! 		if (tup == NULL || !((Form_pg_type) GETSTRUCT(tup))->typisdefined)
! 			*typeid_p = InvalidOid;
! 		else
! 			*typeid_p = HeapTupleGetOid(tup);
! 
! 		if (tup)
! 			ReleaseSysCache(tup);
! 	}
! 	else
! 	{
! 		tup = typenameType(pstate, typeName, typmod_p);
! 		*typeid_p = HeapTupleGetOid(tup);
! 		ReleaseSysCache(tup);
! 	}
  }
  
  /*
*************** pts_error_callback(void *arg)
*** 662,667 ****
--- 704,729 ----
  void
  parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p)
  {
+ 	parseTypeString_guts(str, typeid_p, typmod_p, false);
+ }
+ 
+ /*
+  * This is equivalent to parseTyepString, except that this does not throw an
+  * error if the type does not exist.
+  */
+ void
+ parseTypeStringMissingOk(const char *str, Oid *typeid_p, int32 *typmod_p)
+ {
+ 	parseTypeString_guts(str, typeid_p, typmod_p, true);
+ }
+ 
+ /*
+  * Guts of parseTypeString and parseTypeStringMissingOk.
+  * If missing_ok is true, returns InvalidOid upon error.
+  */
+ static void
+ parseTypeString_guts(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok)
+ {
  	StringInfoData buf;
  	List	   *raw_parsetree_list;
  	SelectStmt *stmt;
*************** parseTypeString(const char *str, Oid *ty
*** 734,740 ****
  	if (typeName->setof)
  		goto fail;
  
! 	typenameTypeIdAndMod(NULL, typeName, typeid_p, typmod_p);
  
  	pfree(buf.data);
  
--- 796,805 ----
  	if (typeName->setof)
  		goto fail;
  
! 	if (missing_ok)
! 		typenameTypeIdAndModMissingOk(NULL, typeName, typeid_p, typmod_p);
! 	else
! 		typenameTypeIdAndMod(NULL, typeName, typeid_p, typmod_p);
  
  	pfree(buf.data);
  
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
new file mode 100644
index 5023d16..0194187
*** a/src/backend/utils/adt/regproc.c
--- b/src/backend/utils/adt/regproc.c
*************** static char *format_operator_internal(Oi
*** 45,50 ****
--- 45,54 ----
  static char *format_procedure_internal(Oid procedure_oid, bool force_qualify);
  static void parseNameAndArgTypes(const char *string, bool allowNone,
  					 List **names, int *nargs, Oid *argtypes);
+ static Datum regoper_guts(char *opr_name_or_oid, bool raiseError);
+ static Datum regproc_guts(char *pro_name_or_oid, bool raiseError);
+ static Datum regclass_guts(char *class_name_or_oid, bool raiseError);
+ static Datum regtype_guts(char *typ_name_or_oid, bool raiseError);
  
  
  /*****************************************************************************
*************** Datum
*** 63,68 ****
--- 67,98 ----
  regprocin(PG_FUNCTION_ARGS)
  {
  	char	   *pro_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regproc_guts(pro_name_or_oid, true);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * to_regproc	- converts "proname" to proc OID
+  *
+  * Diffrence from regprocin is, this does not throw an error if the proname
+  * does not exist.
+  * Note: this is not an I/O function.
+  */
+ Datum
+ to_regproc(PG_FUNCTION_ARGS)
+ {
+ 	char	   *pro_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regproc_guts(pro_name_or_oid, false);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ Datum
+ regproc_guts(char *pro_name_or_oid, bool raiseError)
+ {
  	RegProcedure result = InvalidOid;
  	List	   *names;
  	FuncCandidateList clist;
*************** regprocin(PG_FUNCTION_ARGS)
*** 117,133 ****
  		heap_close(hdesc, AccessShareLock);
  
  		if (matches == 0)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 				 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
! 
  		else if (matches > 1)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 					 errmsg("more than one function named \"%s\"",
! 							pro_name_or_oid)));
  
! 		PG_RETURN_OID(result);
  	}
  
  	/*
--- 147,172 ----
  		heap_close(hdesc, AccessShareLock);
  
  		if (matches == 0)
! 		{
! 			if (raiseError)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 					 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
! 			else
! 				return InvalidOid;
! 		}
  		else if (matches > 1)
! 		{
! 			if (raiseError)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 						 errmsg("more than one function named \"%s\"",
! 								pro_name_or_oid)));
! 			else
! 				return InvalidOid;
! 		}
  
! 		return result;
  	}
  
  	/*
*************** regprocin(PG_FUNCTION_ARGS)
*** 138,155 ****
  	clist = FuncnameGetCandidates(names, -1, NIL, false, false);
  
  	if (clist == NULL)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 				 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
  	else if (clist->next != NULL)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 				 errmsg("more than one function named \"%s\"",
  						pro_name_or_oid)));
  
  	result = clist->oid;
  
! 	PG_RETURN_OID(result);
  }
  
  /*
--- 177,204 ----
  	clist = FuncnameGetCandidates(names, -1, NIL, false, false);
  
  	if (clist == NULL)
! 	{
! 		if (raiseError)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 					 errmsg("function \"%s\" does not exist", pro_name_or_oid)));
! 		else
! 			return InvalidOid;
! 	}
  	else if (clist->next != NULL)
! 	{
! 		if (raiseError)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 					 errmsg("more than one function named \"%s\"",
  						pro_name_or_oid)));
+ 		else
+ 			return InvalidOid;
+ 	}
  
  	result = clist->oid;
  
! 	return result;
  }
  
  /*
*************** Datum
*** 431,443 ****
  regoperin(PG_FUNCTION_ARGS)
  {
  	char	   *opr_name_or_oid = PG_GETARG_CSTRING(0);
  	Oid			result = InvalidOid;
  	List	   *names;
  	FuncCandidateList clist;
  
  	/* '0' ? */
  	if (strcmp(opr_name_or_oid, "0") == 0)
! 		PG_RETURN_OID(InvalidOid);
  
  	/* Numeric OID? */
  	if (opr_name_or_oid[0] >= '0' &&
--- 480,521 ----
  regoperin(PG_FUNCTION_ARGS)
  {
  	char	   *opr_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regoper_guts(opr_name_or_oid, true);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * to_regoper		- converts "oprname" to operator OID
+  *
+  * Diffrence from regoper is, this does not throw an error if the operator
+  * does not exist.
+  * Note: this is not an I/O function.
+  */
+ Datum
+ to_regoper(PG_FUNCTION_ARGS)
+ {
+ 	char	   *opr_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regoper_guts(opr_name_or_oid, false);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * Guts of regoperin and to_regoper.
+  * If raiseError is false, returns InvalidOid upon error.
+  */
+ static Datum regoper_guts(char *opr_name_or_oid, bool raiseError)
+ {
  	Oid			result = InvalidOid;
  	List	   *names;
  	FuncCandidateList clist;
  
  	/* '0' ? */
  	if (strcmp(opr_name_or_oid, "0") == 0)
! 		return InvalidOid;
  
  	/* Numeric OID? */
  	if (opr_name_or_oid[0] >= '0' &&
*************** regoperin(PG_FUNCTION_ARGS)
*** 446,452 ****
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										  CStringGetDatum(opr_name_or_oid)));
! 		PG_RETURN_OID(result);
  	}
  
  	/* Else it's a name, possibly schema-qualified */
--- 524,530 ----
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										  CStringGetDatum(opr_name_or_oid)));
! 		return result;
  	}
  
  	/* Else it's a name, possibly schema-qualified */
*************** regoperin(PG_FUNCTION_ARGS)
*** 485,500 ****
  		heap_close(hdesc, AccessShareLock);
  
  		if (matches == 0)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 					 errmsg("operator does not exist: %s", opr_name_or_oid)));
  		else if (matches > 1)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 					 errmsg("more than one operator named %s",
! 							opr_name_or_oid)));
  
! 		PG_RETURN_OID(result);
  	}
  
  	/*
--- 563,588 ----
  		heap_close(hdesc, AccessShareLock);
  
  		if (matches == 0)
! 		{
! 			if (raiseError)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 						 errmsg("operator does not exist: %s", opr_name_or_oid)));
! 			else
! 				return InvalidOid;
! 		}
  		else if (matches > 1)
! 		{
! 			if (raiseError)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 						 errmsg("more than one operator named %s",
! 								opr_name_or_oid)));
! 			else
! 				return InvalidOid;
! 		}
  
! 		return result;
  	}
  
  	/*
*************** regoperin(PG_FUNCTION_ARGS)
*** 505,522 ****
  	clist = OpernameGetCandidates(names, '\0');
  
  	if (clist == NULL)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 				 errmsg("operator does not exist: %s", opr_name_or_oid)));
  	else if (clist->next != NULL)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 				 errmsg("more than one operator named %s",
! 						opr_name_or_oid)));
  
  	result = clist->oid;
  
! 	PG_RETURN_OID(result);
  }
  
  /*
--- 593,620 ----
  	clist = OpernameGetCandidates(names, '\0');
  
  	if (clist == NULL)
! 	{
! 		if (raiseError)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
! 					 errmsg("operator does not exist: %s", opr_name_or_oid)));
! 		else
! 			return InvalidOid;
! 	}
  	else if (clist->next != NULL)
! 	{
! 		if (raiseError)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_AMBIGUOUS_FUNCTION),
! 					 errmsg("more than one operator named %s",
! 							opr_name_or_oid)));
! 		else
! 			return InvalidOid;
! 	}
  
  	result = clist->oid;
  
! 	return result;
  }
  
  /*
*************** Datum
*** 804,815 ****
  regclassin(PG_FUNCTION_ARGS)
  {
  	char	   *class_name_or_oid = PG_GETARG_CSTRING(0);
  	Oid			result = InvalidOid;
  	List	   *names;
  
  	/* '-' ? */
  	if (strcmp(class_name_or_oid, "-") == 0)
! 		PG_RETURN_OID(InvalidOid);
  
  	/* Numeric OID? */
  	if (class_name_or_oid[0] >= '0' &&
--- 902,942 ----
  regclassin(PG_FUNCTION_ARGS)
  {
  	char	   *class_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regclass_guts(class_name_or_oid, true);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * to_regclass		- converts "classname" to class OID
+  *
+  * Diffrence from regclassin is, this does not throw an error if the classname
+  * does not exist.
+  * Note: this is not an I/O function.
+  */
+ Datum
+ to_regclass(PG_FUNCTION_ARGS)
+ {
+ 	char	   *class_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regclass_guts(class_name_or_oid, false);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * Guts of regclassin and to_regclass.
+  * If raiseError is false, returns InvalidOid upon error.
+  */
+ static Datum regclass_guts(char *class_name_or_oid, bool raiseError)
+ {
  	Oid			result = InvalidOid;
  	List	   *names;
  
  	/* '-' ? */
  	if (strcmp(class_name_or_oid, "-") == 0)
! 		return result;
  
  	/* Numeric OID? */
  	if (class_name_or_oid[0] >= '0' &&
*************** regclassin(PG_FUNCTION_ARGS)
*** 818,824 ****
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										CStringGetDatum(class_name_or_oid)));
! 		PG_RETURN_OID(result);
  	}
  
  	/* Else it's a name, possibly schema-qualified */
--- 945,951 ----
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										CStringGetDatum(class_name_or_oid)));
! 		return result;
  	}
  
  	/* Else it's a name, possibly schema-qualified */
*************** regclassin(PG_FUNCTION_ARGS)
*** 848,863 ****
  		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
  			result = HeapTupleGetOid(tuple);
  		else
! 			ereport(ERROR,
! 					(errcode(ERRCODE_UNDEFINED_TABLE),
! 			   errmsg("relation \"%s\" does not exist", class_name_or_oid)));
  
  		/* We assume there can be only one match */
  
  		systable_endscan(sysscan);
  		heap_close(hdesc, AccessShareLock);
  
! 		PG_RETURN_OID(result);
  	}
  
  	/*
--- 975,993 ----
  		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
  			result = HeapTupleGetOid(tuple);
  		else
! 			if (raiseError)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_UNDEFINED_TABLE),
! 						 errmsg("relation \"%s\" does not exist", class_name_or_oid)));
! 			else
! 				return InvalidOid;
  
  		/* We assume there can be only one match */
  
  		systable_endscan(sysscan);
  		heap_close(hdesc, AccessShareLock);
  
! 		return result;
  	}
  
  	/*
*************** regclassin(PG_FUNCTION_ARGS)
*** 865,875 ****
  	 * pg_class entries in the current search path.
  	 */
  	names = stringToQualifiedNameList(class_name_or_oid);
  
  	/* We might not even have permissions on this relation; don't lock it. */
! 	result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
  
! 	PG_RETURN_OID(result);
  }
  
  /*
--- 995,1010 ----
  	 * pg_class entries in the current search path.
  	 */
  	names = stringToQualifiedNameList(class_name_or_oid);
+ 	if (names == NIL)
+ 		return InvalidOid;
  
  	/* We might not even have permissions on this relation; don't lock it. */
! 	if (raiseError)
! 		result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
! 	else
! 		result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);
  
! 	return result;
  }
  
  /*
*************** Datum
*** 968,973 ****
--- 1103,1137 ----
  regtypein(PG_FUNCTION_ARGS)
  {
  	char	   *typ_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regtype_guts(typ_name_or_oid, true);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * to_regtype		- converts "typename" to type OID
+  *
+  * Diffrence from regtypein is, this does not throw an error if the typename
+  * does not exist.
+  * Note: this is not an I/O function.
+  */
+ Datum
+ to_regtype(PG_FUNCTION_ARGS)
+ {
+ 	char	   *typ_name_or_oid = PG_GETARG_CSTRING(0);
+ 	Oid			result;
+ 
+ 	result = regtype_guts(typ_name_or_oid, false);
+ 	PG_RETURN_OID(result);
+ }
+ 
+ /*
+  * Guts of regtypein and to_regtype.
+  * If raiseError is false, returns InvalidOid upon error.
+  */
+ static Datum regtype_guts(char *typ_name_or_oid, bool raiseError)
+ {
  	Oid			result = InvalidOid;
  	int32		typmod;
  
*************** regtypein(PG_FUNCTION_ARGS)
*** 982,988 ****
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										  CStringGetDatum(typ_name_or_oid)));
! 		PG_RETURN_OID(result);
  	}
  
  	/* Else it's a type name, possibly schema-qualified or decorated */
--- 1146,1152 ----
  	{
  		result = DatumGetObjectId(DirectFunctionCall1(oidin,
  										  CStringGetDatum(typ_name_or_oid)));
! 		return result;
  	}
  
  	/* Else it's a type name, possibly schema-qualified or decorated */
*************** regtypein(PG_FUNCTION_ARGS)
*** 1011,1017 ****
  
  		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
  			result = HeapTupleGetOid(tuple);
! 		else
  			ereport(ERROR,
  					(errcode(ERRCODE_UNDEFINED_OBJECT),
  					 errmsg("type \"%s\" does not exist", typ_name_or_oid)));
--- 1175,1181 ----
  
  		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
  			result = HeapTupleGetOid(tuple);
! 		else if (raiseError)
  			ereport(ERROR,
  					(errcode(ERRCODE_UNDEFINED_OBJECT),
  					 errmsg("type \"%s\" does not exist", typ_name_or_oid)));
*************** regtypein(PG_FUNCTION_ARGS)
*** 1021,1036 ****
  		systable_endscan(sysscan);
  		heap_close(hdesc, AccessShareLock);
  
! 		PG_RETURN_OID(result);
  	}
  
  	/*
  	 * Normal case: invoke the full parser to deal with special cases such as
  	 * array syntax.
  	 */
! 	parseTypeString(typ_name_or_oid, &result, &typmod);
  
! 	PG_RETURN_OID(result);
  }
  
  /*
--- 1185,1203 ----
  		systable_endscan(sysscan);
  		heap_close(hdesc, AccessShareLock);
  
! 		return result;
  	}
  
  	/*
  	 * Normal case: invoke the full parser to deal with special cases such as
  	 * array syntax.
  	 */
! 	if (raiseError)
! 		parseTypeString(typ_name_or_oid, &result, &typmod);
! 	else
! 		parseTypeStringMissingOk(typ_name_or_oid, &result, &typmod);
  
! 	return result;
  }
  
  /*
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
new file mode 100644
index ab05c46..74f8bf9
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
*************** DATA(insert OID =  44 (  regprocin		   P
*** 173,178 ****
--- 173,180 ----
  DESCR("I/O");
  DATA(insert OID =  45 (  regprocout		   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "24" _null_ _null_ _null_ _null_ regprocout _null_ _null_ _null_ ));
  DESCR("I/O");
+ DATA(insert OID = 3196 (  to_regproc		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "2275" _null_ _null_ _null_ _null_ to_regproc _null_ _null_ _null_ ));
+ DESCR("convert proname to regproc");
  DATA(insert OID =  46 (  textin			   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "2275" _null_ _null_ _null_ _null_ textin _null_ _null_ _null_ ));
  DESCR("I/O");
  DATA(insert OID =  47 (  textout		   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "25" _null_ _null_ _null_ _null_ textout _null_ _null_ _null_ ));
*************** DATA(insert OID = 2214 (  regoperin			PG
*** 3296,3301 ****
--- 3298,3305 ----
  DESCR("I/O");
  DATA(insert OID = 2215 (  regoperout		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2203" _null_ _null_ _null_ _null_ regoperout _null_ _null_ _null_ ));
  DESCR("I/O");
+ DATA(insert OID = 3180 (  to_regoper		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2203 "2275" _null_ _null_ _null_ _null_ to_regoper _null_ _null_ _null_ ));
+ DESCR("convert operator name to regoper");
  DATA(insert OID = 2216 (  regoperatorin		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2204 "2275" _null_ _null_ _null_ _null_ regoperatorin _null_ _null_ _null_ ));
  DESCR("I/O");
  DATA(insert OID = 2217 (  regoperatorout	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2204" _null_ _null_ _null_ _null_ regoperatorout _null_ _null_ _null_ ));
*************** DATA(insert OID = 2218 (  regclassin		PG
*** 3304,3313 ****
--- 3308,3321 ----
  DESCR("I/O");
  DATA(insert OID = 2219 (  regclassout		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2205" _null_ _null_ _null_ _null_ regclassout _null_ _null_ _null_ ));
  DESCR("I/O");
+ DATA(insert OID = 3179 (  to_regclass		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "2275" _null_ _null_ _null_ _null_ to_regclass _null_ _null_ _null_ ));
+ DESCR("convert classname to regclass");
  DATA(insert OID = 2220 (  regtypein			PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2206 "2275" _null_ _null_ _null_ _null_ regtypein _null_ _null_ _null_ ));
  DESCR("I/O");
  DATA(insert OID = 2221 (  regtypeout		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2206" _null_ _null_ _null_ _null_ regtypeout _null_ _null_ _null_ ));
  DESCR("I/O");
+ DATA(insert OID = 3195 (  to_regtype		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2206 "2275" _null_ _null_ _null_ _null_ to_regtype _null_ _null_ _null_ ));
+ DESCR("convert type name to regtype");
  DATA(insert OID = 1079 (  regclass			PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "25" _null_ _null_ _null_ _null_	text_regclass _null_ _null_ _null_ ));
  DESCR("convert text to regclass");
  
diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h
new file mode 100644
index 9208bad..470e2a6
*** a/src/include/parser/parse_type.h
--- b/src/include/parser/parse_type.h
*************** extern Type typenameType(ParseState *pst
*** 26,31 ****
--- 26,33 ----
  extern Oid	typenameTypeId(ParseState *pstate, const TypeName *typeName);
  extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
  					 Oid *typeid_p, int32 *typmod_p);
+ extern void typenameTypeIdAndModMissingOk(ParseState *pstate, const TypeName *typeName,
+ 					 Oid *typeid_p, int32 *typmod_p);
  
  extern char *TypeNameToString(const TypeName *typeName);
  extern char *TypeNameListToString(List *typenames);
*************** extern Datum stringTypeDatum(Type tp, ch
*** 46,51 ****
--- 48,54 ----
  extern Oid	typeidTypeRelid(Oid type_id);
  
  extern void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p);
+ extern void parseTypeStringMissingOk(const char *str, Oid *typeid_p, int32 *typmod_p);
  
  #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid)
  
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
new file mode 100644
index b90d88d..85dee8a
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
*************** extern char *regexp_fixed_prefix(text *t
*** 597,602 ****
--- 597,603 ----
  /* regproc.c */
  extern Datum regprocin(PG_FUNCTION_ARGS);
  extern Datum regprocout(PG_FUNCTION_ARGS);
+ extern Datum to_regproc(PG_FUNCTION_ARGS);
  extern Datum regprocrecv(PG_FUNCTION_ARGS);
  extern Datum regprocsend(PG_FUNCTION_ARGS);
  extern Datum regprocedurein(PG_FUNCTION_ARGS);
*************** extern Datum regoperin(PG_FUNCTION_ARGS)
*** 607,612 ****
--- 608,614 ----
  extern Datum regoperout(PG_FUNCTION_ARGS);
  extern Datum regoperrecv(PG_FUNCTION_ARGS);
  extern Datum regopersend(PG_FUNCTION_ARGS);
+ extern Datum to_regoper(PG_FUNCTION_ARGS);
  extern Datum regoperatorin(PG_FUNCTION_ARGS);
  extern Datum regoperatorout(PG_FUNCTION_ARGS);
  extern Datum regoperatorrecv(PG_FUNCTION_ARGS);
*************** extern Datum regclassin(PG_FUNCTION_ARGS
*** 615,624 ****
--- 617,628 ----
  extern Datum regclassout(PG_FUNCTION_ARGS);
  extern Datum regclassrecv(PG_FUNCTION_ARGS);
  extern Datum regclasssend(PG_FUNCTION_ARGS);
+ extern Datum to_regclass(PG_FUNCTION_ARGS);
  extern Datum regtypein(PG_FUNCTION_ARGS);
  extern Datum regtypeout(PG_FUNCTION_ARGS);
  extern Datum regtyperecv(PG_FUNCTION_ARGS);
  extern Datum regtypesend(PG_FUNCTION_ARGS);
+ extern Datum to_regtype(PG_FUNCTION_ARGS);
  extern Datum regconfigin(PG_FUNCTION_ARGS);
  extern Datum regconfigout(PG_FUNCTION_ARGS);
  extern Datum regconfigrecv(PG_FUNCTION_ARGS);
