From cb9fa802b32b222b43e28866c20ebb7125779ec3 Mon Sep 17 00:00:00 2001 From: Andrew Dunstan Date: Sat, 9 May 2015 13:36:52 -0400 Subject: [PATCH] Add new OID alias type regnamespace Catalog version bumped Kyotaro HORIGUCHI --- doc/src/sgml/datatype.sgml | 13 +++- src/backend/bootstrap/bootstrap.c | 2 + src/backend/catalog/dependency.c | 8 +++ src/backend/utils/adt/regproc.c | 96 +++++++++++++++++++++++++++ src/backend/utils/adt/selfuncs.c | 2 + src/backend/utils/cache/catcache.c | 1 + src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_cast.h | 7 ++ src/include/catalog/pg_proc.h | 11 +++ 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 ++ 13 files changed, 174 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 0cac9935d2..9d5ce953f1 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -4321,9 +4321,9 @@ SET xmloption TO { DOCUMENT | CONTENT }; an object identifier. There are also several alias types for oid: regproc, regprocedure, regoper, regoperator, regclass, - regtype, regrole, regconfig, and - regdictionary. shows - an overview. + regtype, regrole, regnamespace, + regconfig, and regdictionary. + shows an overview. @@ -4438,6 +4438,13 @@ SELECT * FROM pg_attribute smithee + + regnamespace + pg_namespace + namespace name + pg_catalog + + regconfig pg_ts_config diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 66028d5877..e42187a7d5 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -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, diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 0ab57322f3..ec4ba397c7 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -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. diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 8b5672875c..7e5598d53c 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -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 diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index a28868c313..91399f79fc 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 9b7cc5eb76..5bb03dd0b1 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/catversion.h b/src/include/catalog/catversion.h index c2e6dbf57b..662ba27a41 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201505083 +#define CATALOG_VERSION_NO 201505091 #endif diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index 4eba2ebbec..bf6ef10821 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -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 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 5452d10e8a..5fa65d63a8 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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_ )); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 1430bc15b7..24933539aa 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -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_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 654ae1b305..a90bfe29e9 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -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); diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out index beda8ecabc..8c734f413c 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 bc77c67cb8..8edaf15f75 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