Sorry, I sent the previous mail without patches by accident. The
patches are attached to this mail.

====
Hello, this is the patchset v2 of this feature.

0001-Add-regrole.patch
  Adding regrole as the name says.

0002-Add-regnamespace.patch
  Adding regnamespace. This depends on 0001 patch.

0003-Check-new-reg-types-are-not-used-as-default-values.patch
  Inhibiting the new OID aliss types from being used as constants
  in default values, which make dependencies on the other
  (existing) OID alias types.

0004-Documentation-for-new-OID-alias-types.patch
  Documentation patch for this new types.

regards,

At Tue, 17 Feb 2015 20:19:11 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI 
<horiguchi.kyot...@lab.ntt.co.jp> wrote in 
<20150217.201911.239516619.horiguchi.kyot...@lab.ntt.co.jp>
> Hello, thank you for the comment.
> 
> The current patch lacks change in documentation and dependency
> stuff. Current framework doesn't consider changing pg_shdepend
> from column default expressions so the possible measures are the
> followings, I think.
> 
> 1. Make pg_shdepend to have refobjsubid and add some deptypes of
>    pg_depend, specifically DEPENDENCY_NORMAL is needed. Then,
>    change the dependency stuff.
> 
> 2. Simplly inhibit specifying them in default
>   expressions. Integer or OID can act as the replacement.
> 
>    =# create table t1 (a int, b regrole default 'horiguti'::regrole);
>    ERROR:  Type 'regrole' cannot have a default value
> 
> 1 is quite overkill but hardly seems to be usable. So I will go
> on 2 and post additional patch.
> 
> 
> At Thu, 12 Feb 2015 17:12:24 -0600, Jim Nasby <jim.na...@bluetreble.com> 
> wrote in <54dd3358.9030...@bluetreble.com>
> > On 2/12/15 5:28 AM, Kyotaro HORIGUCHI wrote:
> > > Hello, I changed the subject.
> 
> # Ouch! the subject remaines wrong..
> 
> > > 1. Expected frequency of use
> > ...
> > > For that reason, although the current policy of deciding whether
> > > to have reg* types seems to be whether they have schema-qualified
> > > names, I think regrole and regnamespace are valuable to have.
> > 
> > Perhaps schema qualification was the original intent, but I think at
> > this point everyone uses them for convenience. Why would I want to
> > type out JOIN pg_namespace n ON n.oid = blah.???namespace when I could
> > simply do ???namespace::regnamespace?
> 
> Yes, that is the most important point of this patch.
> 
> > > 2. Anticipaed un-optimizability
> > >
> > > Tom pointed that these reg* types prevents planner from
> > > optimizing the query, so we should refrain from having such
> > > machinary. It should have been a long-standing issue but reg*s
> > > sees to be rather faster than joining corresponding catalogs
> > > for moderate number of the result rows, but this raises another
> > > more annoying issue.
> > >
> > >
> > > 3. Potentially breakage of MVCC
> > >
> > > The another issue Tom pointed is potentially breakage of MVCC by
> > > using these reg* types. Syscache is invalidated on updates so
> > > this doesn't seem to be a problem on READ COMMITTED mode, but
> > > breaks SERIALIZABLE mode. But IMHO it is not so serious problem
> > > as long as such inconsistency occurs only on system catalog and
> > > it is explicitly documented togethee with the un-optimizability
> > > issue. I'll add a patch for this later.
> > 
> > The way I look at it, all these arguments went out the window when
> > regclass was introduced.
> > 
> > The reality is that reg* is *way* more convenient than manual
> > joins. The arguments about optimization and MVCC presumably apply to
> > all reg* casts, which means that ship has long since sailed.
> 
> I agree basically, but I think some caveat is needed. I'll
> include that in the coming documentation patch.
> 
> > If we offered views that made it easier to get at this data then maybe
> > this wouldn't matter so much. But DBA's don't want to join 3 catalogs
> > together to try and answer a simple question.
> 
> It has been annoying me these days.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 2a6f689afdc8197c2fe2fc235a4819ce1a5e9928 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Wed, 18 Feb 2015 14:38:32 +0900
Subject: [PATCH 1/4] Add regrole

Add new regtype regrole. For the development reason, the system OIDs
used for the new procs, types, casts are making a gap from existing
OIDs.
---
 src/backend/bootstrap/bootstrap.c     |   2 +
 src/backend/utils/adt/regproc.c       | 101 ++++++++++++++++++++++++++++++++++
 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 |  26 ++++++++-
 src/test/regress/sql/regproc.sql      |   7 +++
 10 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index bc66eac..11e40ee 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},
+	{"regrole", REGROLEOID, 0, 4, true, 'i', 'p', InvalidOid,
+	F_REGROLEIN, F_REGROLEOUT},
 	{"text", TEXTOID, 0, -1, false, 'i', 'x', DEFAULT_COLLATION_OID,
 	F_TEXTIN, F_TEXTOUT},
 	{"oid", OIDOID, 0, 4, true, 'i', 'p', InvalidOid,
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 3d1bb32..ec4893f 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -40,6 +40,7 @@
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
 #include "utils/tqual.h"
+#include "utils/acl.h"
 
 static char *format_operator_internal(Oid operator_oid, bool force_qualify);
 static char *format_procedure_internal(Oid procedure_oid, bool force_qualify);
@@ -1553,6 +1554,106 @@ regdictionarysend(PG_FUNCTION_ARGS)
 	return oidsend(fcinfo);
 }
 
+/*
+ * regrolein	- converts "regrole" to role 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_ts_dict entry.
+ *
+ * This function is not needed in bootstrap mode, so we don't worry about
+ * making it work then.
+ */
+Datum
+regrolein(PG_FUNCTION_ARGS)
+{
+	char	   *role_or_oid = PG_GETARG_CSTRING(0);
+	Oid			result;
+
+	/* '-' ? */
+	if (strcmp(role_or_oid, "-") == 0)
+		PG_RETURN_OID(InvalidOid);
+
+	/* Numeric OID? */
+	if (role_or_oid[0] >= '0' &&
+		role_or_oid[0] <= '9' &&
+		strspn(role_or_oid, "0123456789") == strlen(role_or_oid))
+	{
+		result = DatumGetObjectId(DirectFunctionCall1(oidin,
+										 CStringGetDatum(role_or_oid)));
+		PG_RETURN_OID(result);
+	}
+
+	/*
+	 * Normal case: parse the name into components and see if it matches any
+	 * pg_role entries in the current search path.
+	 */
+	result = get_role_oid(role_or_oid, false);
+
+	PG_RETURN_OID(result);
+}
+
+/*
+ * to_regrole		- converts "role name" to role OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regrole(PG_FUNCTION_ARGS)
+{
+	char	   *role_name = PG_GETARG_CSTRING(0);
+	Oid			result;
+
+	result = get_role_oid(role_name, true);
+	
+	if (OidIsValid(result))
+		PG_RETURN_OID(result);
+	else
+		PG_RETURN_NULL();
+}
+
+/*
+ * regroleout		- converts role OID to "role_name"
+ */
+Datum
+regroleout(PG_FUNCTION_ARGS)
+{
+	Oid			roleoid = PG_GETARG_OID(0);
+	char	   *result;
+
+
+	if (roleoid == InvalidOid)
+	{
+		result = pstrdup("-");
+		PG_RETURN_CSTRING(result);
+	}
+
+	result = GetUserNameFromId(roleoid);
+	PG_RETURN_CSTRING(result);
+}
+
+/*
+ *		regrolerecv	- converts external binary format to regrole
+ */
+Datum
+regrolerecv(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidrecv, so share code */
+	return oidrecv(fcinfo);
+}
+
+/*
+ *		regrolesend	- converts regrole to binary format
+ */
+Datum
+regrolesend(PG_FUNCTION_ARGS)
+{
+	/* Exactly the same as oidsend, so share code */
+	return oidsend(fcinfo);
+}
+
+
 
 /*
  * text_regclass: convert text to regclass
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 1ba103c..529b0ed 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3619,6 +3619,7 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
 		case REGTYPEOID:
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
+		case REGROLEOID:
 			*scaledvalue = convert_numeric_to_scalar(value, valuetypid);
 			*scaledlobound = convert_numeric_to_scalar(lobound, boundstypid);
 			*scaledhibound = convert_numeric_to_scalar(hibound, boundstypid);
@@ -3724,6 +3725,7 @@ convert_numeric_to_scalar(Datum value, Oid typid)
 		case REGTYPEOID:
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
+		case REGROLEOID:
 			/* 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 2e4d0b3..51ba43d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -150,6 +150,7 @@ GetCCHashEqFuncs(Oid keytype, PGFunction *hashfunc, RegProcedure *eqfunc)
 		case REGTYPEOID:
 		case REGCONFIGOID:
 		case REGDICTIONARYOID:
+		case REGROLEOID:
 			*hashfunc = hashoid;
 
 			*eqfunc = F_OIDEQ;
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index b314369..bc0faa8 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 4096    0 i b ));
+DATA(insert ( 4096	 26    0 i b ));
+DATA(insert (	20 4096 1287 i f ));
+DATA(insert (	21 4096  313 i f ));
+DATA(insert (	23 4096    0 i b ));
+DATA(insert ( 4096	 20 1288 a f ));
+DATA(insert ( 4096	 23    0 a b ));
 
 /*
  * String category
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 9edfdb8..b2b4beb 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 = 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_ ));
+DESCR("I/O");
+DATA(insert OID = 4093 (  to_regrole		PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 4096 "2275" _null_ _null_ _null_ _null_ to_regrole _null_ _null_ _null_ ));
+DESCR("convert role name to regrole");
 DATA(insert OID = 2246 ( fmgr_internal_validator PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_ _null_ _null_ fmgr_internal_validator _null_ _null_ _null_ ));
 DESCR("(internal)");
 DATA(insert OID = 2247 ( fmgr_c_validator	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_ _null_ _null_ fmgr_c_validator _null_ _null_ _null_ ));
@@ -3831,6 +3837,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 = 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_ ));
+DESCR("I/O");
 DATA(insert OID = 2456 (  bit_recv			   PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1560 "2281 26 23" _null_ _null_ _null_ _null_  bit_recv _null_ _null_ _null_ ));
 DESCR("I/O");
 DATA(insert OID = 2457 (  bit_send			   PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "1560" _null_ _null_ _null_ _null_	bit_send _null_ _null_ _null_ ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 0a900dd..1430bc1 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -564,12 +564,17 @@ 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 = 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
+
 DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A f t \054 0 2202 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 DATA(insert OID = 2208 ( _regoper	   PGNSP PGUID -1 f b A f t \054 0 2203 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 DATA(insert OID = 2209 ( _regoperator  PGNSP PGUID -1 f b A f t \054 0 2204 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
 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 = 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 */
 DATA(insert OID = 2950 ( uuid			PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 0 _null_ _null_ _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index bc4517d..0e1e99e 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 regrolein(PG_FUNCTION_ARGS);
+extern Datum regroleout(PG_FUNCTION_ARGS);
+extern Datum regrolerecv(PG_FUNCTION_ARGS);
+extern Datum regrolesend(PG_FUNCTION_ARGS);
+extern Datum to_regrole(PG_FUNCTION_ARGS);
 extern Datum regconfigin(PG_FUNCTION_ARGS);
 extern Datum regconfigout(PG_FUNCTION_ARGS);
 extern Datum regconfigrecv(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index 3342129..beda8ec 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -2,6 +2,7 @@
 -- regproc
 --
 /* If objects exist, return oids */
+CREATE ROLE regtestrole;
 -- without schemaname
 SELECT regoper('||/');
  regoper 
@@ -39,6 +40,12 @@ SELECT regtype('int4');
  integer
 (1 row)
 
+SELECT regrole('regtestrole');
+   regrole   
+-------------
+ regtestrole
+(1 row)
+
 SELECT to_regoper('||/');
  to_regoper 
 ------------
@@ -75,6 +82,12 @@ SELECT to_regtype('int4');
  integer
 (1 row)
 
+SELECT to_regrole('regtestrole');
+ to_regrole  
+-------------
+ regtestrole
+(1 row)
+
 -- with schemaname
 SELECT regoper('pg_catalog.||/');
  regoper 
@@ -143,10 +156,11 @@ SELECT to_regtype('pg_catalog.int4');
 (1 row)
 
 /* If objects don't exist, raise errors. */
+DROP ROLE regtestrole;
 -- without schemaname
 SELECT regoper('||//');
 ERROR:  operator does not exist: ||//
-LINE 3: SELECT regoper('||//');
+LINE 1: SELECT regoper('||//');
                        ^
 SELECT regoperator('++(int4,int4)');
 ERROR:  operator does not exist: ++(int4,int4)
@@ -168,6 +182,10 @@ SELECT regtype('int3');
 ERROR:  type "int3" does not exist
 LINE 1: SELECT regtype('int3');
                        ^
+SELECT regrole('regtestrole');
+ERROR:  role "regtestrole" does not exist
+LINE 1: SELECT regrole('regtestrole');
+                       ^
 -- with schemaname
 SELECT regoper('ng_catalog.||/');
 ERROR:  schema "ng_catalog" does not exist
@@ -231,6 +249,12 @@ SELECT to_regtype('int3');
  
 (1 row)
 
+SELECT to_regrole('regtestrole');
+ to_regrole 
+------------
+ 
+(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 cc90838..bc77c67 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -4,6 +4,7 @@
 
 /* If objects exist, return oids */
 
+CREATE ROLE regtestrole;
 -- without schemaname
 
 SELECT regoper('||/');
@@ -12,6 +13,7 @@ SELECT regproc('now');
 SELECT regprocedure('abs(numeric)');
 SELECT regclass('pg_class');
 SELECT regtype('int4');
+SELECT regrole('regtestrole');
 
 SELECT to_regoper('||/');
 SELECT to_regoperator('+(int4,int4)');
@@ -19,6 +21,7 @@ SELECT to_regproc('now');
 SELECT to_regprocedure('abs(numeric)');
 SELECT to_regclass('pg_class');
 SELECT to_regtype('int4');
+SELECT to_regrole('regtestrole');
 
 -- with schemaname
 
@@ -37,6 +40,8 @@ SELECT to_regtype('pg_catalog.int4');
 
 /* If objects don't exist, raise errors. */
 
+DROP ROLE regtestrole;
+
 -- without schemaname
 
 SELECT regoper('||//');
@@ -45,6 +50,7 @@ SELECT regproc('know');
 SELECT regprocedure('absinthe(numeric)');
 SELECT regclass('pg_classes');
 SELECT regtype('int3');
+SELECT regrole('regtestrole');
 
 -- with schemaname
 
@@ -65,6 +71,7 @@ SELECT to_regproc('know');
 SELECT to_regprocedure('absinthe(numeric)');
 SELECT to_regclass('pg_classes');
 SELECT to_regtype('int3');
+SELECT to_regrole('regtestrole');
 
 -- with schemaname
 
-- 
2.1.0.GIT

>From 565565b5818575d1540dabf8c2f9e580f266d1a2 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@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

>From 648f702b90ae05564e2792277ce279047f53566c Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Mon, 16 Feb 2015 20:05:43 +0900
Subject: [PATCH 3/4] Check new reg* types are not used as default values

The new OID alias types don't behave as the same as the other OID
alias types concerning object dependency. To get rid of confusion,
inhibit constants of these types from appearing where dependencies are
registered for other types.
---
 src/backend/catalog/dependency.c | 23 +++++++++++++++++++++++
 src/backend/catalog/heap.c       |  1 +
 2 files changed, 24 insertions(+)

diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index bacb242..a59c2cd 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1597,6 +1597,29 @@ find_expr_references_walker(Node *node,
 						add_object_address(OCLASS_TSDICT, 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.
+				 */
+				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)));
+				}
+				break;
 			}
 		}
 		return false;
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 17f7266..fa5957a 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1860,6 +1860,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 	Oid			attrdefOid;
 	ObjectAddress colobject,
 				defobject;
+	Oid			exprtype;
 
 	/*
 	 * Flatten expression to string form for storage.
-- 
2.1.0.GIT

>From c5a9ca98342dd032996b1c138cf414bf1b64f460 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Wed, 18 Feb 2015 15:42:54 +0900
Subject: [PATCH 4/4] Documentation for new OID alias types.

Added description about regrole and regnamespace and modified some
existing descriptions according to the restriction of these new
types. Addition to it, put a note about MVCC violation and
optimization issues.
---
 doc/src/sgml/datatype.sgml | 54 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index edf636b..78a70ee 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4319,7 +4319,8 @@ SET xmloption TO { DOCUMENT | CONTENT };
     an object identifier.  There are also several alias types for
     <type>oid</>: <type>regproc</>, <type>regprocedure</>,
     <type>regoper</>, <type>regoperator</>, <type>regclass</>,
-    <type>regtype</>, <type>regconfig</>, and <type>regdictionary</>.
+    <type>regtype</>, <type>regrole</>, <type>regnamespace</>, 
+    <type>regconfig</>, and <type>regdictionary</>.
     <xref linkend="datatype-oid-table"> shows an overview.
    </para>
 
@@ -4429,6 +4430,20 @@ SELECT * FROM pg_attribute
        </row>
 
        <row>
+        <entry><type>regrole</></entry>
+        <entry><structname>pg_authid</></entry>
+        <entry>role name</entry>
+        <entry><literal>John</></entry>
+       </row>
+
+       <row>
+        <entry><type>regnamespace</></entry>
+        <entry><structname>pg_namespace</></entry>
+        <entry>namespace name</entry>
+        <entry><literal>pg_catalog</></entry>
+       </row>
+
+       <row>
         <entry><type>regconfig</></entry>
         <entry><structname>pg_ts_config</></entry>
         <entry>text search configuration</entry>
@@ -4446,30 +4461,41 @@ SELECT * FROM pg_attribute
     </table>
 
    <para>
-    All of the OID alias types accept schema-qualified names, and will
-    display schema-qualified names on output if the object would not
-    be found in the current search path without being qualified.
-    The <type>regproc</> and <type>regoper</> alias types will only
-    accept input names that are unique (not overloaded), so they are
-    of limited use; for most uses <type>regprocedure</> or
+    All of the OID alias types for objects grouped by namespace accept
+    schema-qualified names, and will display schema-qualified names on output
+    if the object would not be found in the current search path without being
+    qualified.  The <type>regproc</> and <type>regoper</> alias types will
+    only accept input names that are unique (not overloaded), so they are of
+    limited use; for most uses <type>regprocedure</> or
     <type>regoperator</> are more appropriate.  For <type>regoperator</>,
     unary operators are identified by writing <literal>NONE</> for the unused
     operand.
    </para>
 
    <para>
-    An additional property 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)</>,
+    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.
+    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>
 
+   <note>
+   <para>
+     The OID alias types don't sctrictly comply the transaction isolation
+     rules so do not use them where exact transaction isolation on the values
+     of theses types has a significance. Likewise, since they look as simple
+     constants to planner so you might get slower plans than the queries
+     joining the system tables correnspond to the OID types.
+   </para>
+   </note>
+
    <para>
     Another identifier type used by the system is <type>xid</>, or transaction
     (abbreviated <abbrev>xact</>) identifier.  This is the data type of the system columns
-- 
2.1.0.GIT

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to