>From c1958171f91866bacbaa39f797b3746f1e1c72d0 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Thu, 9 Apr 2015 16:57:38 +0900
Subject: [PATCH] Make regnamespace behave as the same as other reg* types.

regrole has the reason should not to be used as default vaues, but
regnamespace is not so. Fix regnamespace to behave as the same as the
other reg* types. Addition to that, fixed regnamespace to return the
given value numerically if nonexistent.
---
 doc/src/sgml/datatype.sgml       | 19 +++++++++----------
 src/backend/catalog/dependency.c | 27 +++++++++++----------------
 src/backend/utils/adt/regproc.c  | 11 +++++++----
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index bde159f..6d1f02d 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4474,19 +4474,18 @@ SELECT * FROM pg_attribute
     operand.
    </para>
 
-   <para>
-    An additional property of most of the OID alias types is the creation of
-    dependencies.  If a constant of one of these types appears in a stored
-    expression (such as a column default expression or view), it creates a
-    dependency on the referenced object.  For example, if a column has
-    a default expression <literal>nextval('my_seq'::regclass)</>,
+   <para> An additional property of most of the OID alias types is the
+    creation of dependencies.  If a constant of one of these types
+    appears in a stored expression (such as a column default
+    expression or view), it creates a dependency on the referenced
+    object.  For example, if a column has a default expression
+    <literal>nextval('my_seq'::regclass)</>,
     <productname>PostgreSQL</productname> understands that the default
     expression depends on the sequence <literal>my_seq</>; the system
     will not let the sequence be dropped without first removing the
-    default expression. <type>regrole</> and <type>regnamespace</> are
-    the exceptions for the property. Constants of these types are not
-    allowed in such expressions.
-   </para>
+    default expression. <type>regrole</> is the only exception for the
+    property. Constants of this type is not allowed in such
+    expressions.  </para>
 
    <note>
    <para>
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index a59c2cd..858d52f 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1598,27 +1598,22 @@ find_expr_references_walker(Node *node,
 										   context->addrs);
 					break;
 
+				case REGNAMESPACEOID:
+					objoid = DatumGetObjectId(con->constvalue);
+					if (SearchSysCacheExists1(NAMESPACEOID,
+											  ObjectIdGetDatum(objoid)))
+						add_object_address(OCLASS_SCHEMA, objoid, 0,
+										   context->addrs);
+					break;
+
 				/*
-				 * Dependencies for regrole and regnamespace in expressions
-				 * are not handled as same as other reg* types. So explicitly
-				 * inhibit the usage to get rid of confusions.
+				 * Dependencies for regrole is shared among all databases, so
+				 * explicitly inhibit to have dependencies.
 				 */
 				case REGROLEOID:
-				case REGNAMESPACEOID:
-				{
-					HeapTuple tt;
-					char *typename = "<unknown>";
-
-					tt = SearchSysCache1(TYPEOID, con->consttype);
-					if (HeapTupleIsValid(tt))
-						typename = pstrdup(NameStr(((Form_pg_type)
-													GETSTRUCT(tt))->typname));
-					ReleaseSysCache(tt);
 					ereport(ERROR,
 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							 errmsg("constant of the type \'%s\' cannot be used here",
-									typename)));
-				}
+							 errmsg("constant of the type \'regrole\' cannot be used here")));
 				break;
 			}
 		}
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index aeb7929..a41f577 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1719,10 +1719,13 @@ regnamespaceout(PG_FUNCTION_ARGS)
 	}
 
 	result = get_namespace_name(nspid);
-	if (result)
-		PG_RETURN_CSTRING(result);
-	else
-		PG_RETURN_NULL();
+	if (!result)
+	{
+		/* If OID doesn't match any namespace, return it numerically */
+		result = (char *) palloc(NAMEDATALEN);
+		snprintf(result, NAMEDATALEN, "%u", nspid);
+	}
+	PG_RETURN_CSTRING(result);
 }
 
 /*
-- 
1.8.3.1

