Add new OID alias type regnamespace
authorAndrew Dunstan <andrew@dunslane.net>
Sat, 9 May 2015 17:36:52 +0000 (13:36 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Sat, 9 May 2015 17:36:52 +0000 (13:36 -0400)
Catalog version bumped

Kyotaro HORIGUCHI

13 files changed:
doc/src/sgml/datatype.sgml
src/backend/bootstrap/bootstrap.c
src/backend/catalog/dependency.c
src/backend/utils/adt/regproc.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/cache/catcache.c
src/include/catalog/catversion.h
src/include/catalog/pg_cast.h
src/include/catalog/pg_proc.h
src/include/catalog/pg_type.h
src/include/utils/builtins.h
src/test/regress/expected/regproc.out
src/test/regress/sql/regproc.sql

index 0cac9935d2d85a11c6c2b39d51a2fadc90528c73..9d5ce953f1728343f664699c5fab65ef31aa1ed6 100644 (file)
@@ -4321,9 +4321,9 @@ 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>regrole</>, <type>regconfig</>, and
-    <type>regdictionary</>.  <xref linkend="datatype-oid-table"> shows
-    an overview.
+    <type>regtype</>, <type>regrole</>, <type>regnamespace</>, 
+    <type>regconfig</>, and <type>regdictionary</>.
+    <xref linkend="datatype-oid-table"> shows an overview.
    </para>
 
    <para>
@@ -4438,6 +4438,13 @@ SELECT * FROM pg_attribute
         <entry><literal>smithee</></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>
index 66028d5877e07fa35f3b0a2bd8803c703f1b4caa..e42187a7d5da76babf397d8030c73c1f8150fad8 100644 (file)
@@ -115,6 +115,8 @@ static const struct typinfo TypInfo[] = {
    F_REGTYPEIN, F_REGTYPEOUT},
    {"regrole", REGROLEOID, 0, 4, true, 'i', 'p', InvalidOid,
    F_REGROLEIN, F_REGROLEOUT},
+   {"regnamespace", REGNAMESPACEOID, 0, 4, true, 'i', 'p', InvalidOid,
+   F_REGNAMESPACEIN, F_REGNAMESPACEOUT},
    {"text", TEXTOID, 0, -1, false, 'i', 'x', DEFAULT_COLLATION_OID,
    F_TEXTIN, F_TEXTOUT},
    {"oid", OIDOID, 0, 4, true, 'i', 'p', InvalidOid,
index 0ab57322f35e312f5228c9be4c1aacdd4747956b..ec4ba397c71ad4bc39270cffd2f2b23d318b3646 100644 (file)
@@ -1603,6 +1603,14 @@ 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 should be shared among all
                 * databases, so explicitly inhibit to have dependencies.
index 8b5672875c244a6befed2b084b2ed1778aba577c..7e5598d53cc917bff029d9cc3903574a7adef5a8 100644 (file)
@@ -1656,7 +1656,103 @@ regrolesend(PG_FUNCTION_ARGS)
    return oidsend(fcinfo);
 }
 
+/*
+ * regnamespacein      - converts "nspname" to namespace 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_namespace 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);
+   }
+
+   /* Normal case: see if the name matches any pg_namespace entry. */
+   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 "nsp_name"
+ */
+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)
+   {
+       /* If OID doesn't match any namespace, return it numerically */
+       result = (char *) palloc(NAMEDATALEN);
+       snprintf(result, NAMEDATALEN, "%u", nspid);
+   }
+   PG_RETURN_CSTRING(result);
+}
+
+/*
+ *     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);
+}
 
 /*
  * text_regclass: convert text to regclass
index a28868c3130263d709e8631fd33eec602ae0590c..91399f79fc80273c4978f4520abe566fa5dd8ed3 100644 (file)
@@ -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);
    }
index 9b7cc5eb76464b241a0475e66df35c8d938e1e7a..5bb03dd0b1ed306437b13330a6c256f5c56e2693 100644 (file)
@@ -151,6 +151,7 @@ GetCCHashEqFuncs(Oid keytype, PGFunction *hashfunc, RegProcedure *eqfunc)
        case REGCONFIGOID:
        case REGDICTIONARYOID:
        case REGROLEOID:
+       case REGNAMESPACEOID:
            *hashfunc = hashoid;
 
            *eqfunc = F_OIDEQ;
index c2e6dbf57bfa42f1a8431b22c8f02935d1e1f8b8..662ba27a414095f0231cdac955cd2120d47144af 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201505083
+#define CATALOG_VERSION_NO 201505091
 
 #endif
index 4eba2ebbec581215e7e42392d35e7fb920abd3ff..bf6ef10821165fc31061886b84913337487aca68 100644 (file)
@@ -217,6 +217,13 @@ 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 ));
+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 ));
 
 /*
  * String category
index 5452d10e8a8986618b212bd212803f17f42a3029..5fa65d63a87ec5267b405ff93713bab120e2f00c 100644 (file)
@@ -3488,6 +3488,13 @@ 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_ _null_ to_regrole _null_ _null_ _null_ ));
 DESCR("convert role name to regrole");
 
+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_ _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_ _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_ _null_ to_regnamespace _null_ _null_ _null_ ));
+DESCR("convert namespace name to regnamespace");
+
 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_ _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_ _null_ fmgr_c_validator _null_ _null_ _null_ ));
@@ -3888,6 +3895,10 @@ DATA(insert OID = 4094 (  regrolerecv           PGNSP PGUID 12 1 0 0 0 f f f f t f i
 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_ _null_    regrolesend _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_ _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_ _null_    regnamespacesend _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_  _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_ _null_    bit_send _null_ _null_ _null_ ));
index 1430bc15b7447d2caecda5abe45f5b1c1494571f..24933539aabe384f893f115f368d54c273a094a0 100644 (file)
@@ -568,6 +568,10 @@ DATA(insert OID = 4096 ( regrole       PGNSP PGUID 4 t b N f t \054 0   0 4097 re
 DESCR("registered role");
 #define REGROLEOID     4096
 
+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 = 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_ ));
@@ -575,6 +579,7 @@ DATA(insert OID = 2210 ( _regclass     PGNSP PGUID -1 f b A f t \054 0 2205 0 arr
 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_ ));
+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_ ));
 
 /* 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_ ));
index 654ae1b305e36878d21cff526a6ea5a54ac3f925..a90bfe29e9f5c93fd19419f4ddca3950332c567e 100644 (file)
@@ -635,6 +635,11 @@ 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 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 regconfigin(PG_FUNCTION_ARGS);
 extern Datum regconfigout(PG_FUNCTION_ARGS);
 extern Datum regconfigrecv(PG_FUNCTION_ARGS);
index beda8ecabce7a0dbfbf25f9e944d0631d175b431..8c734f413ce6468c30f50c961892a86c4d7178bf 100644 (file)
@@ -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 
index bc77c67cb8f8484667ddc9e8f6502d6aab04d07b..8edaf15f75fcec041be474c93a6a3abafd02b4f6 100644 (file)
@@ -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