>From 565565b5818575d1540dabf8c2f9e580f266d1a2 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Wed, 18 Feb 2015 15:14:27 +0900
Subject: [PATCH 2/4] Add regnamespace.

Add new regtype regnamespace.
---
 src/backend/bootstrap/bootstrap.c     |  2 +
 src/backend/utils/adt/regproc.c       | 97 +++++++++++++++++++++++++++++++++++
 src/backend/utils/adt/selfuncs.c      |  2 +
 src/backend/utils/cache/catcache.c    |  1 +
 src/include/catalog/pg_cast.h         |  7 +++
 src/include/catalog/pg_proc.h         | 10 ++++
 src/include/catalog/pg_type.h         |  5 ++
 src/include/utils/builtins.h          |  5 ++
 src/test/regress/expected/regproc.out | 22 ++++++++
 src/test/regress/sql/regproc.sql      |  4 ++
 10 files changed, 155 insertions(+)

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 11e40ee..c38e1fc 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -113,6 +113,8 @@ static const struct typinfo TypInfo[] = {
 	F_REGPROCIN, F_REGPROCOUT},
 	{"regtype", REGTYPEOID, 0, 4, true, 'i', 'p', InvalidOid,
 	F_REGTYPEIN, F_REGTYPEOUT},
+	{"regnamespace", REGNAMESPACEOID, 0, 4, true, 'i', 'p', InvalidOid,
+	F_REGNAMESPACEIN, F_REGNAMESPACEOUT},
 	{"regrole", REGROLEOID, 0, 4, true, 'i', 'p', InvalidOid,
 	F_REGROLEIN, F_REGROLEOUT},
 	{"text", TEXTOID, 0, -1, false, 'i', 'x', DEFAULT_COLLATION_OID,
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index ec4893f..6155e4f 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -1160,6 +1160,103 @@ regclasssend(PG_FUNCTION_ARGS)
 
 
 /*
+ * regnamespacein		- converts "classname" to class OID
+ *
+ * We also accept a numeric OID, for symmetry with the output routine.
+ *
+ * '-' signifies unknown (OID 0).  In all other cases, the input must
+ * match an existing pg_class entry.
+ */
+Datum
+regnamespacein(PG_FUNCTION_ARGS)
+{
+	char	   *nsp_name_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result = InvalidOid;
+
+	/* '-' ? */
+	if (strcmp(nsp_name_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (nsp_name_or_oid[0] >= '0' &&
+		nsp_name_or_oid[0] <= '9' &&
+		strspn(nsp_name_or_oid, "0123456789") == strlen(nsp_name_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+										CStringGetDatum(nsp_name_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/* Else it's a name */
+
+	result = get_namespace_oid(nsp_name_or_oid, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regnamespace		- converts "nspname" to namespace OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regnamespace(PG_FUNCTION_ARGS)
+{
+	char	   *nsp_name = PG_GETARG_CSTRING(0);
+	Oid			result;
+
+	result = get_namespace_oid(nsp_name, true);
+
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regnamespaceout		- converts namespace OID to "nspname"
+ */
+Datum
+regnamespaceout(PG_FUNCTION_ARGS)
+{
+	Oid			nspid = PG_GETARG_OID(0);
+	char	   *result;
+
+	if (nspid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	result = get_namespace_name(nspid);
+	if (result)
+		PG_RETURN_CSTRING(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ *		regnamespacerecv	- converts external binary format to regnamespace
+ */
+Datum
+regnamespacerecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regnamespacesend		- converts regnamespace to binary format
+ */
+Datum
+regnamespacesend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
+/*
  * regtypein		- converts "typename" to type OID
  *
  * We also accept a numeric OID, for symmetry with the output routine.
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 529b0ed..1761729 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3620,6 +3620,7 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
 		case REGROLEOID:
+		case REGNAMESPACEOID:
 			*scaledvalue = convert_numeric_to_scalar(value, valuetypid);
 			*scaledlobound = convert_numeric_to_scalar(lobound, boundstypid);
 			*scaledhibound = convert_numeric_to_scalar(hibound, boundstypid);
@@ -3726,6 +3727,7 @@ convert_numeric_to_scalar(Datum value, Oid typid)
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
 		case REGROLEOID:
+		case REGNAMESPACEOID:
 			/* we can treat OIDs as integers... */
 			return (double) DatumGetObjectId(value);
 	}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 51ba43d..3bce4de 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -151,6 +151,7 @@ GetCCHashEqFuncs(Oid keytype, PGFunction *hashfunc, RegProcedure *eqfunc)
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
 		case REGROLEOID:
+		case REGNAMESPACEOID:
 			*hashfunc = hashoid;
 
 			*eqfunc = F_OIDEQ;
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index bc0faa8..fad168f 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -210,6 +210,13 @@ DATA(insert ( 3769	 20 1288 a f ));
 DATA(insert ( 3769	 23    0 a b ));
 DATA(insert (	25 2205 1079 i f ));
 DATA(insert ( 1043 2205 1079 i f ));
+DATA(insert (	26 4089    0 i b ));
+DATA(insert ( 4089	 26    0 i b ));
+DATA(insert (	20 4089 1287 i f ));
+DATA(insert (	21 4089  313 i f ));
+DATA(insert (	23 4089    0 i b ));
+DATA(insert ( 4089	 20 1288 a f ));
+DATA(insert ( 4089	 23    0 a b ));
 DATA(insert (	26 4096    0 i b ));
 DATA(insert ( 4096	 26    0 i b ));
 DATA(insert (	20 4096 1287 i f ));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index b2b4beb..a292394 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3436,6 +3436,12 @@ 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");
 
+DATA(insert OID = 4084 (  regnamespacein	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 4089 "2275" _null_ _null_ _null_ _null_ regnamespacein _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 4085 (  regnamespaceout	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "4089" _null_ _null_ _null_ _null_ regnamespaceout _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 4086 (  to_regnamespace	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 4089 "2275" _null_ _null_ _null_ _null_ to_regnamespace _null_ _null_ _null_ ));
+DESCR("convert namespace name to regnamespace");
 DATA(insert OID = 4091 (  regrolein			PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 4096 "2275" _null_ _null_ _null_ _null_ regrolein _null_ _null_ _null_ ));
 DESCR("I/O");
 DATA(insert OID = 4092 (  regroleout		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "4096" _null_ _null_ _null_ _null_ regroleout _null_ _null_ _null_ ));
@@ -3837,6 +3843,10 @@ DATA(insert OID = 2454 (  regtyperecv		   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1
 DESCR("I/O");
 DATA(insert OID = 2455 (  regtypesend		   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "2206" _null_ _null_ _null_ _null_	regtypesend _null_ _null_ _null_ ));
 DESCR("I/O");
+DATA(insert OID = 4087 (  regnamespacerecv	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 4089 "2281" _null_ _null_ _null_ _null_ regnamespacerecv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 4088 (  regnamespacesend	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "4089" _null_ _null_ _null_ _null_	regnamespacesend _null_ _null_ _null_ ));
+DESCR("I/O");
 DATA(insert OID = 4094 (  regrolerecv	  	   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 4096 "2281" _null_ _null_ _null_ _null_ regrolerecv _null_ _null_ _null_ ));
 DESCR("I/O");
 DATA(insert OID = 4095 (  regrolesend	       PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "4096" _null_ _null_ _null_ _null_	regrolesend _null_ _null_ _null_ ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 1430bc1..0bd3fbd 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -564,6 +564,10 @@ DATA(insert OID = 2206 ( regtype	   PGNSP PGUID	4 t b N f t \054 0	 0 2211 regty
 DESCR("registered type");
 #define REGTYPEOID		2206
 
+DATA(insert OID = 4089 ( regnamespace  PGNSP PGUID	4 t b N f t \054 0	 0 4090 regnamespacein regnamespaceout regnamespacerecv regnamespacesend - - - i p f 0 -1 0 0 _null_ _null_ _null_ ));
+DESCR("registered namespace");
+#define REGNAMESPACEOID		4089
+
 DATA(insert OID = 4096 ( regrole       PGNSP PGUID	4 t b N f t \054 0	 0 4097 regrolein regroleout regrolerecv regrolesend - - - i p f 0 -1 0 0 _null_ _null_ _null_ ));
 DESCR("registered role");
 #define REGROLEOID		4096
@@ -574,6 +578,7 @@ DATA(insert OID = 2209 ( _regoperator  PGNSP PGUID -1 f b A f t \054 0 2204 0 ar
 DATA(insert OID = 2210 ( _regclass	   PGNSP PGUID -1 f b A f t \054 0 2205 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 DATA(insert OID = 2211 ( _regtype	   PGNSP PGUID -1 f b A f t \054 0 2206 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 #define REGTYPEARRAYOID 2211
+DATA(insert OID = 4090 ( _regnamespace PGNSP PGUID -1 f b A f t \054 0 4089 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 DATA(insert OID = 4097 ( _regrole      PGNSP PGUID -1 f b A f t \054 0 4096 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 
 /* uuid */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 0e1e99e..a95ed23 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -630,6 +630,11 @@ 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 regnamespacein(PG_FUNCTION_ARGS);
+extern Datum regnamespaceout(PG_FUNCTION_ARGS);
+extern Datum regnamespacerecv(PG_FUNCTION_ARGS);
+extern Datum regnamespacesend(PG_FUNCTION_ARGS);
+extern Datum to_regnamespace(PG_FUNCTION_ARGS);
 extern Datum regrolein(PG_FUNCTION_ARGS);
 extern Datum regroleout(PG_FUNCTION_ARGS);
 extern Datum regrolerecv(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index beda8ec..8c734f4 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -46,6 +46,12 @@ SELECT regrole('regtestrole');
  regtestrole
 (1 row)
 
+SELECT regnamespace('pg_catalog');
+ regnamespace 
+--------------
+ pg_catalog
+(1 row)
+
 SELECT to_regoper('||/');
  to_regoper 
 ------------
@@ -88,6 +94,12 @@ SELECT to_regrole('regtestrole');
  regtestrole
 (1 row)
 
+SELECT to_regnamespace('pg_catalog');
+ to_regnamespace 
+-----------------
+ pg_catalog
+(1 row)
+
 -- with schemaname
 SELECT regoper('pg_catalog.||/');
  regoper 
@@ -186,6 +198,10 @@ SELECT regrole('regtestrole');
 ERROR:  role "regtestrole" does not exist
 LINE 1: SELECT regrole('regtestrole');
                        ^
+SELECT regnamespace('nonexistent');
+ERROR:  schema "nonexistent" does not exist
+LINE 1: SELECT regnamespace('nonexistent');
+                            ^
 -- with schemaname
 SELECT regoper('ng_catalog.||/');
 ERROR:  schema "ng_catalog" does not exist
@@ -255,6 +271,12 @@ SELECT to_regrole('regtestrole');
  
 (1 row)
 
+SELECT to_regnamespace('nonexistent');
+ to_regnamespace 
+-----------------
+ 
+(1 row)
+
 -- with schemaname
 SELECT to_regoper('ng_catalog.||/');
  to_regoper 
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index bc77c67..8edaf15 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -14,6 +14,7 @@ SELECT regprocedure('abs(numeric)');
 SELECT regclass('pg_class');
 SELECT regtype('int4');
 SELECT regrole('regtestrole');
+SELECT regnamespace('pg_catalog');
 
 SELECT to_regoper('||/');
 SELECT to_regoperator('+(int4,int4)');
@@ -22,6 +23,7 @@ SELECT to_regprocedure('abs(numeric)');
 SELECT to_regclass('pg_class');
 SELECT to_regtype('int4');
 SELECT to_regrole('regtestrole');
+SELECT to_regnamespace('pg_catalog');
 
 -- with schemaname
 
@@ -51,6 +53,7 @@ SELECT regprocedure('absinthe(numeric)');
 SELECT regclass('pg_classes');
 SELECT regtype('int3');
 SELECT regrole('regtestrole');
+SELECT regnamespace('nonexistent');
 
 -- with schemaname
 
@@ -72,6 +75,7 @@ SELECT to_regprocedure('absinthe(numeric)');
 SELECT to_regclass('pg_classes');
 SELECT to_regtype('int3');
 SELECT to_regrole('regtestrole');
+SELECT to_regnamespace('nonexistent');
 
 -- with schemaname
 
-- 
2.1.0.GIT

