Hello, I fonund that pg_proc.h got modified so rebased and rearranged the patchset merging the recent fixes.
regards, > I sent the previous mail unfinished. > > At Thu, 09 Apr 2015 17:25:10 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI > <horiguchi.kyot...@lab.ntt.co.jp> wrote in > <20150409.172510.29010318.horiguchi.kyot...@lab.ntt.co.jp> > > Hello, sorry for the absence. I changed the regnamespace's > > behavior as the same as the other reg* types. And I attached a > > patch as separate one that fixes regroleout to do the same as the > > other reg* types, because I have > > because, I doubt that it is appropriate way to do so. > > > 0001-Add-regrole_v6.patch : fix regnamespace to behave as the > > same as the other reg* types. > > > > 0001-Make-regnamespace-behave-as-the-same-as-other-reg-ty.patch: > > Diff from v5 to v6, only for convinience. > > > > 0001-Fix-regroleout-s-behavior-following-other-out-functi.patch: > > Fixes regroleout so as to behave as the same as other reg* > > types, but might be a bit too large. -- Kyotaro Horiguchi NTT Open Source Software Center
>From 2210bc524906ec1c9fdf4649260568b0ba807c30 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/2] Add regrole-v7 Add new OID aliass type regrole. The new type has the scope of whole the database cluster so it doesn't behave as the same as the existing OID alias types which have database scope, concerning object dependency. To get rid of confusion, inhibit constants of the new type from appearing where dependencies are made involving it. Documentation about this new type is added and some existing descriptions are modified according to the restriction of the type. Addition to it, put a note about possible MVCC violation and optimization issues, which are general over the all reg* types. --- contrib/spi/insert_username.c | 2 +- contrib/spi/timetravel.c | 2 +- doc/src/sgml/datatype.sgml | 27 +++++++-- src/backend/bootstrap/bootstrap.c | 2 + src/backend/catalog/dependency.c | 10 ++++ src/backend/catalog/objectaddress.c | 20 +++---- src/backend/utils/adt/acl.c | 2 +- src/backend/utils/adt/name.c | 4 +- src/backend/utils/adt/regproc.c | 104 ++++++++++++++++++++++++++++++++++ src/backend/utils/adt/selfuncs.c | 2 + src/backend/utils/cache/catcache.c | 1 + src/backend/utils/init/miscinit.c | 24 +++++--- src/include/catalog/pg_cast.h | 7 +++ src/include/catalog/pg_proc.h | 12 ++++ src/include/catalog/pg_type.h | 5 ++ src/include/foreign/foreign.h | 2 +- src/include/miscadmin.h | 2 +- src/include/utils/builtins.h | 5 ++ src/test/regress/expected/regproc.out | 26 ++++++++- src/test/regress/sql/regproc.sql | 7 +++ 20 files changed, 235 insertions(+), 31 deletions(-) diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c index 8752078..3812525 100644 --- a/contrib/spi/insert_username.c +++ b/contrib/spi/insert_username.c @@ -79,7 +79,7 @@ insert_username(PG_FUNCTION_ARGS) args[0], relname))); /* create fields containing name */ - newval = CStringGetTextDatum(GetUserNameFromId(GetUserId())); + newval = CStringGetTextDatum(GetUserNameFromId(GetUserId(), false)); /* construct new tuple */ rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL); diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c index 0699438..e125986 100644 --- a/contrib/spi/timetravel.c +++ b/contrib/spi/timetravel.c @@ -174,7 +174,7 @@ timetravel(PG_FUNCTION_ARGS) } /* create fields containing name */ - newuser = CStringGetTextDatum(GetUserNameFromId(GetUserId())); + newuser = CStringGetTextDatum(GetUserNameFromId(GetUserId(), false)); nulltext = (Datum) NULL; diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index da1f25f..0cac993 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -4321,8 +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>regconfig</>, and <type>regdictionary</>. - <xref linkend="datatype-oid-table"> shows an overview. + <type>regtype</>, <type>regrole</>, <type>regconfig</>, and + <type>regdictionary</>. <xref linkend="datatype-oid-table"> shows + an overview. </para> <para> @@ -4431,6 +4432,13 @@ SELECT * FROM pg_attribute </row> <row> + <entry><type>regrole</></entry> + <entry><structname>pg_authid</></entry> + <entry>role name</entry> + <entry><literal>smithee</></entry> + </row> + + <row> <entry><type>regconfig</></entry> <entry><structname>pg_ts_config</></entry> <entry>text search configuration</entry> @@ -4448,7 +4456,8 @@ SELECT * FROM pg_attribute </table> <para> - All of the OID alias types accept schema-qualified names, and will + 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 @@ -4460,7 +4469,7 @@ SELECT * FROM pg_attribute </para> <para> - An additional property of the OID alias types is the creation of + 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 @@ -4470,7 +4479,17 @@ SELECT * FROM pg_attribute 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</> is the only exception for the property. Constants of this + type are not allowed in such expressions. + </para> + + <note> + <para> + The OID alias types do not completely follow transaction isolation + rules. The planner also treats them as simple constants, which may + result in sub-optimal planning. </para> + </note> <para> Another identifier type used by the system is <type>xid</>, or transaction diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 6866d92..66028d5 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/catalog/dependency.c b/src/backend/catalog/dependency.c index 6271f8f..0ab5732 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1602,6 +1602,16 @@ find_expr_references_walker(Node *node, add_object_address(OCLASS_TSDICT, objoid, 0, context->addrs); break; + + /* + * Dependencies for regrole should be shared among all + * databases, so explicitly inhibit to have dependencies. + */ + case REGROLEOID: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("constant of the type \'regrole\' cannot be used here"))); + break; } } return false; diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 10f0396..a1f8ada 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -2818,7 +2818,7 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_ROLE: { appendStringInfo(&buffer, _("role %s"), - GetUserNameFromId(object->objectId)); + GetUserNameFromId(object->objectId, false)); break; } @@ -2884,7 +2884,7 @@ getObjectDescription(const ObjectAddress *object) ReleaseSysCache(tup); if (OidIsValid(useid)) - usename = GetUserNameFromId(useid); + usename = GetUserNameFromId(useid, false); else usename = "public"; @@ -2924,28 +2924,28 @@ getObjectDescription(const ObjectAddress *object) case DEFACLOBJ_RELATION: appendStringInfo(&buffer, _("default privileges on new relations belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_SEQUENCE: appendStringInfo(&buffer, _("default privileges on new sequences belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_FUNCTION: appendStringInfo(&buffer, _("default privileges on new functions belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; case DEFACLOBJ_TYPE: appendStringInfo(&buffer, _("default privileges on new types belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; default: /* shouldn't get here */ appendStringInfo(&buffer, _("default privileges belonging to role %s"), - GetUserNameFromId(defacl->defaclrole)); + GetUserNameFromId(defacl->defaclrole, false)); break; } @@ -4214,7 +4214,7 @@ getObjectIdentityParts(const ObjectAddress *object, { char *username; - username = GetUserNameFromId(object->objectId); + username = GetUserNameFromId(object->objectId, false); if (objname) *objname = list_make1(username); appendStringInfoString(&buffer, @@ -4295,7 +4295,7 @@ getObjectIdentityParts(const ObjectAddress *object, ReleaseSysCache(tup); if (OidIsValid(useid)) - usename = GetUserNameFromId(useid); + usename = GetUserNameFromId(useid, false); else usename = "public"; @@ -4339,7 +4339,7 @@ getObjectIdentityParts(const ObjectAddress *object, defacl = (Form_pg_default_acl) GETSTRUCT(tup); - username = GetUserNameFromId(defacl->defaclrole); + username = GetUserNameFromId(defacl->defaclrole, false); appendStringInfo(&buffer, "for role %s", quote_identifier(username)); diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 7701fc5..e7aecc9 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -4878,7 +4878,7 @@ check_is_member_of_role(Oid member, Oid role) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be member of role \"%s\"", - GetUserNameFromId(role)))); + GetUserNameFromId(role, false)))); } /* diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index b6c6e39..5826127 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -263,13 +263,13 @@ namestrcmp(Name name, const char *str) Datum current_user(PG_FUNCTION_ARGS) { - PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId())))); + PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetUserId(), false)))); } Datum session_user(PG_FUNCTION_ARGS) { - PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId())))); + PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(GetUserNameFromId(GetSessionUserId(), false)))); } diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 11d663b..8b56728 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,109 @@ regdictionarysend(PG_FUNCTION_ARGS) return oidsend(fcinfo); } +/* + * regrolein - converts "rolename" 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_authid 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_name_or_oid = PG_GETARG_CSTRING(0); + Oid result; + + /* '-' ? */ + if (strcmp(role_name_or_oid, "-") == 0) + PG_RETURN_OID(InvalidOid); + + /* Numeric OID? */ + if (role_name_or_oid[0] >= '0' && + role_name_or_oid[0] <= '9' && + strspn(role_name_or_oid, "0123456789") == strlen(role_name_or_oid)) + { + result = DatumGetObjectId(DirectFunctionCall1(oidin, + CStringGetDatum(role_name_or_oid))); + PG_RETURN_OID(result); + } + + /* Normal case: see if the name matches any pg_authid entry. */ + result = get_role_oid(role_name_or_oid, false); + + PG_RETURN_OID(result); +} + +/* + * to_regrole - converts "rolename" 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, true); + if (!result) + { + /* If OID doesn't match any role, return it numerically */ + result = (char *) palloc(NAMEDATALEN); + snprintf(result, NAMEDATALEN, "%u", 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 4dd3f9f..a28868c 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 1af43c6..9b7cc5e 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/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 1dc3153..b0d85af 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -648,23 +648,29 @@ SetCurrentRoleId(Oid roleid, bool is_superuser) /* - * Get user name from user oid + * Get user name from user oid, returns NULL for nonexistent roleid if noerr + * is true. */ char * -GetUserNameFromId(Oid roleid) +GetUserNameFromId(Oid roleid, bool noerr) { HeapTuple tuple; char *result; tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("invalid role OID: %u", roleid))); - - result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); - - ReleaseSysCache(tuple); + { + if (!noerr) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("invalid role OID: %u", roleid))); + result = NULL; + } + else + { + result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); + ReleaseSysCache(tuple); + } return result; } diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index c49fe26..9e8cb1c 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 55c246e..d0f3818 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3471,6 +3471,13 @@ 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_ _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_ _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_ _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_ _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_ _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_ )); @@ -3866,6 +3873,11 @@ 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_ _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_ _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_ _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_ _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 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/foreign/foreign.h b/src/include/foreign/foreign.h index 9c737b4..c820e09 100644 --- a/src/include/foreign/foreign.h +++ b/src/include/foreign/foreign.h @@ -18,7 +18,7 @@ /* Helper for obtaining username for user mapping */ #define MappingUserName(userid) \ - (OidIsValid(userid) ? GetUserNameFromId(userid) : "public") + (OidIsValid(userid) ? GetUserNameFromId(userid, false) : "public") /* diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index eacfccb..56ae545 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -295,7 +295,7 @@ extern void InitStandaloneProcess(const char *argv0); extern void SetDatabasePath(const char *path); -extern char *GetUserNameFromId(Oid roleid); +extern char *GetUserNameFromId(Oid roleid, bool noerr); extern Oid GetUserId(void); extern Oid GetOuterUserId(void); extern Oid GetSessionUserId(void); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 33a453f..62af523 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 -- 1.8.3.1
>From 5e0131076afcbe6ede724238f1be84864df80623 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp> Date: Thu, 30 Apr 2015 16:44:19 +0900 Subject: [PATCH 2/2] Add regnamespace-v7 Added new OID alias type regnamespace, and edited related documents. --- 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/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 ++ 12 files changed, 173 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 0cac993..9d5ce95 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 <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> @@ -4439,6 +4439,13 @@ SELECT * FROM pg_attribute </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> diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 66028d5..e42187a 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 0ab5732..ec4ba39 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 8b56728..7e5598d 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 a28868c..91399f7 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 9b7cc5e..5bb03dd 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 9e8cb1c..d1e303f 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 d0f3818..9ee71fc 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3478,6 +3478,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_ )); @@ -3878,6 +3885,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 1430bc1..2493353 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 62af523..9e2ee82 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 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 -- 1.8.3.1
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers