Commit fb1227af authored by Tom Lane's avatar Tom Lane

Fix regrole and regnamespace types to honor quoting like other reg* types.

Aside from any consistency arguments, this is logically necessary because
the I/O functions for these types also handle numeric OID values.  Without
a quoting rule it is impossible to distinguish numeric OIDs from role or
namespace names that happen to contain only digits.

Also change the to_regrole and to_regnamespace functions to dequote their
arguments.  While not logically essential, this seems like a good idea
since the other to_reg* functions do it.  Anyone who really wants raw
lookup of an uninterpreted name can fall back on the time-honored solution
of (SELECT oid FROM pg_namespace WHERE nspname = whatever).

Report and patch by Jim Nasby, reviewed by Michael Paquier
parent f47b602d
...@@ -855,8 +855,7 @@ format_operator_internal(Oid operator_oid, bool force_qualify) ...@@ -855,8 +855,7 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
/* /*
* Would this oper be found (given the right args) by regoperatorin? * Would this oper be found (given the right args) by regoperatorin?
* If not, or if caller explicitly requests it, we need to qualify * If not, or if caller explicitly requests it, we need to qualify it.
* it.
*/ */
if (force_qualify || !OperatorIsVisible(operator_oid)) if (force_qualify || !OperatorIsVisible(operator_oid))
{ {
...@@ -1570,6 +1569,7 @@ regrolein(PG_FUNCTION_ARGS) ...@@ -1570,6 +1569,7 @@ regrolein(PG_FUNCTION_ARGS)
{ {
char *role_name_or_oid = PG_GETARG_CSTRING(0); char *role_name_or_oid = PG_GETARG_CSTRING(0);
Oid result; Oid result;
List *names;
/* '-' ? */ /* '-' ? */
if (strcmp(role_name_or_oid, "-") == 0) if (strcmp(role_name_or_oid, "-") == 0)
...@@ -1586,7 +1586,14 @@ regrolein(PG_FUNCTION_ARGS) ...@@ -1586,7 +1586,14 @@ regrolein(PG_FUNCTION_ARGS)
} }
/* Normal case: see if the name matches any pg_authid entry. */ /* Normal case: see if the name matches any pg_authid entry. */
result = get_role_oid(role_name_or_oid, false); names = stringToQualifiedNameList(role_name_or_oid);
if (list_length(names) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid name syntax")));
result = get_role_oid(strVal(linitial(names)), false);
PG_RETURN_OID(result); PG_RETURN_OID(result);
} }
...@@ -1601,8 +1608,16 @@ to_regrole(PG_FUNCTION_ARGS) ...@@ -1601,8 +1608,16 @@ to_regrole(PG_FUNCTION_ARGS)
{ {
char *role_name = PG_GETARG_CSTRING(0); char *role_name = PG_GETARG_CSTRING(0);
Oid result; Oid result;
List *names;
result = get_role_oid(role_name, true); names = stringToQualifiedNameList(role_name);
if (list_length(names) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid name syntax")));
result = get_role_oid(strVal(linitial(names)), true);
if (OidIsValid(result)) if (OidIsValid(result))
PG_RETURN_OID(result); PG_RETURN_OID(result);
...@@ -1619,7 +1634,6 @@ regroleout(PG_FUNCTION_ARGS) ...@@ -1619,7 +1634,6 @@ regroleout(PG_FUNCTION_ARGS)
Oid roleoid = PG_GETARG_OID(0); Oid roleoid = PG_GETARG_OID(0);
char *result; char *result;
if (roleoid == InvalidOid) if (roleoid == InvalidOid)
{ {
result = pstrdup("-"); result = pstrdup("-");
...@@ -1627,6 +1641,7 @@ regroleout(PG_FUNCTION_ARGS) ...@@ -1627,6 +1641,7 @@ regroleout(PG_FUNCTION_ARGS)
} }
result = GetUserNameFromId(roleoid, true); result = GetUserNameFromId(roleoid, true);
if (!result) if (!result)
{ {
/* If OID doesn't match any role, return it numerically */ /* If OID doesn't match any role, return it numerically */
...@@ -1668,7 +1683,8 @@ Datum ...@@ -1668,7 +1683,8 @@ Datum
regnamespacein(PG_FUNCTION_ARGS) regnamespacein(PG_FUNCTION_ARGS)
{ {
char *nsp_name_or_oid = PG_GETARG_CSTRING(0); char *nsp_name_or_oid = PG_GETARG_CSTRING(0);
Oid result = InvalidOid; Oid result;
List *names;
/* '-' ? */ /* '-' ? */
if (strcmp(nsp_name_or_oid, "-") == 0) if (strcmp(nsp_name_or_oid, "-") == 0)
...@@ -1685,7 +1701,14 @@ regnamespacein(PG_FUNCTION_ARGS) ...@@ -1685,7 +1701,14 @@ regnamespacein(PG_FUNCTION_ARGS)
} }
/* Normal case: see if the name matches any pg_namespace entry. */ /* Normal case: see if the name matches any pg_namespace entry. */
result = get_namespace_oid(nsp_name_or_oid, false); names = stringToQualifiedNameList(nsp_name_or_oid);
if (list_length(names) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid name syntax")));
result = get_namespace_oid(strVal(linitial(names)), false);
PG_RETURN_OID(result); PG_RETURN_OID(result);
} }
...@@ -1700,8 +1723,16 @@ to_regnamespace(PG_FUNCTION_ARGS) ...@@ -1700,8 +1723,16 @@ to_regnamespace(PG_FUNCTION_ARGS)
{ {
char *nsp_name = PG_GETARG_CSTRING(0); char *nsp_name = PG_GETARG_CSTRING(0);
Oid result; Oid result;
List *names;
result = get_namespace_oid(nsp_name, true); names = stringToQualifiedNameList(nsp_name);
if (list_length(names) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid name syntax")));
result = get_namespace_oid(strVal(linitial(names)), true);
if (OidIsValid(result)) if (OidIsValid(result))
PG_RETURN_OID(result); PG_RETURN_OID(result);
...@@ -1725,6 +1756,7 @@ regnamespaceout(PG_FUNCTION_ARGS) ...@@ -1725,6 +1756,7 @@ regnamespaceout(PG_FUNCTION_ARGS)
} }
result = get_namespace_name(nspid); result = get_namespace_name(nspid);
if (!result) if (!result)
{ {
/* If OID doesn't match any namespace, return it numerically */ /* If OID doesn't match any namespace, return it numerically */
......
...@@ -40,18 +40,6 @@ SELECT regtype('int4'); ...@@ -40,18 +40,6 @@ SELECT regtype('int4');
integer integer
(1 row) (1 row)
SELECT regrole('regtestrole');
regrole
-------------
regtestrole
(1 row)
SELECT regnamespace('pg_catalog');
regnamespace
--------------
pg_catalog
(1 row)
SELECT to_regoper('||/'); SELECT to_regoper('||/');
to_regoper to_regoper
------------ ------------
...@@ -88,18 +76,6 @@ SELECT to_regtype('int4'); ...@@ -88,18 +76,6 @@ SELECT to_regtype('int4');
integer integer
(1 row) (1 row)
SELECT to_regrole('regtestrole');
to_regrole
-------------
regtestrole
(1 row)
SELECT to_regnamespace('pg_catalog');
to_regnamespace
-----------------
pg_catalog
(1 row)
-- with schemaname -- with schemaname
SELECT regoper('pg_catalog.||/'); SELECT regoper('pg_catalog.||/');
regoper regoper
...@@ -167,6 +143,55 @@ SELECT to_regtype('pg_catalog.int4'); ...@@ -167,6 +143,55 @@ SELECT to_regtype('pg_catalog.int4');
integer integer
(1 row) (1 row)
-- schemaname not applicable
SELECT regrole('regtestrole');
regrole
-------------
regtestrole
(1 row)
SELECT regrole('"regtestrole"');
regrole
-------------
regtestrole
(1 row)
SELECT regnamespace('pg_catalog');
regnamespace
--------------
pg_catalog
(1 row)
SELECT regnamespace('"pg_catalog"');
regnamespace
--------------
pg_catalog
(1 row)
SELECT to_regrole('regtestrole');
to_regrole
-------------
regtestrole
(1 row)
SELECT to_regrole('"regtestrole"');
to_regrole
-------------
regtestrole
(1 row)
SELECT to_regnamespace('pg_catalog');
to_regnamespace
-----------------
pg_catalog
(1 row)
SELECT to_regnamespace('"pg_catalog"');
to_regnamespace
-----------------
pg_catalog
(1 row)
/* If objects don't exist, raise errors. */ /* If objects don't exist, raise errors. */
DROP ROLE regtestrole; DROP ROLE regtestrole;
-- without schemaname -- without schemaname
...@@ -194,14 +219,6 @@ SELECT regtype('int3'); ...@@ -194,14 +219,6 @@ SELECT regtype('int3');
ERROR: type "int3" does not exist ERROR: type "int3" does not exist
LINE 1: SELECT regtype('int3'); LINE 1: SELECT regtype('int3');
^ ^
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 -- with schemaname
SELECT regoper('ng_catalog.||/'); SELECT regoper('ng_catalog.||/');
ERROR: schema "ng_catalog" does not exist ERROR: schema "ng_catalog" does not exist
...@@ -227,6 +244,39 @@ SELECT regtype('ng_catalog.int4'); ...@@ -227,6 +244,39 @@ SELECT regtype('ng_catalog.int4');
ERROR: schema "ng_catalog" does not exist ERROR: schema "ng_catalog" does not exist
LINE 1: SELECT regtype('ng_catalog.int4'); LINE 1: SELECT regtype('ng_catalog.int4');
^ ^
-- schemaname not applicable
SELECT regrole('regtestrole');
ERROR: role "regtestrole" does not exist
LINE 1: SELECT regrole('regtestrole');
^
SELECT regrole('"regtestrole"');
ERROR: role "regtestrole" does not exist
LINE 1: SELECT regrole('"regtestrole"');
^
SELECT regrole('Nonexistent');
ERROR: role "nonexistent" does not exist
LINE 1: SELECT regrole('Nonexistent');
^
SELECT regrole('"Nonexistent"');
ERROR: role "Nonexistent" does not exist
LINE 1: SELECT regrole('"Nonexistent"');
^
SELECT regrole('foo.bar');
ERROR: invalid name syntax
LINE 1: SELECT regrole('foo.bar');
^
SELECT regnamespace('Nonexistent');
ERROR: schema "nonexistent" does not exist
LINE 1: SELECT regnamespace('Nonexistent');
^
SELECT regnamespace('"Nonexistent"');
ERROR: schema "Nonexistent" does not exist
LINE 1: SELECT regnamespace('"Nonexistent"');
^
SELECT regnamespace('foo.bar');
ERROR: invalid name syntax
LINE 1: SELECT regnamespace('foo.bar');
^
/* If objects don't exist, return NULL with no error. */ /* If objects don't exist, return NULL with no error. */
-- without schemaname -- without schemaname
SELECT to_regoper('||//'); SELECT to_regoper('||//');
...@@ -265,18 +315,6 @@ SELECT to_regtype('int3'); ...@@ -265,18 +315,6 @@ SELECT to_regtype('int3');
(1 row) (1 row)
SELECT to_regrole('regtestrole');
to_regrole
------------
(1 row)
SELECT to_regnamespace('nonexistent');
to_regnamespace
-----------------
(1 row)
-- with schemaname -- with schemaname
SELECT to_regoper('ng_catalog.||/'); SELECT to_regoper('ng_catalog.||/');
to_regoper to_regoper
...@@ -314,3 +352,46 @@ SELECT to_regtype('ng_catalog.int4'); ...@@ -314,3 +352,46 @@ SELECT to_regtype('ng_catalog.int4');
(1 row) (1 row)
-- schemaname not applicable
SELECT to_regrole('regtestrole');
to_regrole
------------
(1 row)
SELECT to_regrole('"regtestrole"');
to_regrole
------------
(1 row)
SELECT to_regrole('foo.bar');
ERROR: invalid name syntax
SELECT to_regrole('Nonexistent');
to_regrole
------------
(1 row)
SELECT to_regrole('"Nonexistent"');
to_regrole
------------
(1 row)
SELECT to_regrole('foo.bar');
ERROR: invalid name syntax
SELECT to_regnamespace('Nonexistent');
to_regnamespace
-----------------
(1 row)
SELECT to_regnamespace('"Nonexistent"');
to_regnamespace
-----------------
(1 row)
SELECT to_regnamespace('foo.bar');
ERROR: invalid name syntax
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
/* If objects exist, return oids */ /* If objects exist, return oids */
CREATE ROLE regtestrole; CREATE ROLE regtestrole;
-- without schemaname -- without schemaname
SELECT regoper('||/'); SELECT regoper('||/');
...@@ -13,8 +14,6 @@ SELECT regproc('now'); ...@@ -13,8 +14,6 @@ SELECT regproc('now');
SELECT regprocedure('abs(numeric)'); SELECT regprocedure('abs(numeric)');
SELECT regclass('pg_class'); SELECT regclass('pg_class');
SELECT regtype('int4'); SELECT regtype('int4');
SELECT regrole('regtestrole');
SELECT regnamespace('pg_catalog');
SELECT to_regoper('||/'); SELECT to_regoper('||/');
SELECT to_regoperator('+(int4,int4)'); SELECT to_regoperator('+(int4,int4)');
...@@ -22,8 +21,6 @@ SELECT to_regproc('now'); ...@@ -22,8 +21,6 @@ SELECT to_regproc('now');
SELECT to_regprocedure('abs(numeric)'); SELECT to_regprocedure('abs(numeric)');
SELECT to_regclass('pg_class'); SELECT to_regclass('pg_class');
SELECT to_regtype('int4'); SELECT to_regtype('int4');
SELECT to_regrole('regtestrole');
SELECT to_regnamespace('pg_catalog');
-- with schemaname -- with schemaname
...@@ -40,6 +37,18 @@ SELECT to_regprocedure('pg_catalog.abs(numeric)'); ...@@ -40,6 +37,18 @@ SELECT to_regprocedure('pg_catalog.abs(numeric)');
SELECT to_regclass('pg_catalog.pg_class'); SELECT to_regclass('pg_catalog.pg_class');
SELECT to_regtype('pg_catalog.int4'); SELECT to_regtype('pg_catalog.int4');
-- schemaname not applicable
SELECT regrole('regtestrole');
SELECT regrole('"regtestrole"');
SELECT regnamespace('pg_catalog');
SELECT regnamespace('"pg_catalog"');
SELECT to_regrole('regtestrole');
SELECT to_regrole('"regtestrole"');
SELECT to_regnamespace('pg_catalog');
SELECT to_regnamespace('"pg_catalog"');
/* If objects don't exist, raise errors. */ /* If objects don't exist, raise errors. */
DROP ROLE regtestrole; DROP ROLE regtestrole;
...@@ -52,8 +61,6 @@ SELECT regproc('know'); ...@@ -52,8 +61,6 @@ SELECT regproc('know');
SELECT regprocedure('absinthe(numeric)'); SELECT regprocedure('absinthe(numeric)');
SELECT regclass('pg_classes'); SELECT regclass('pg_classes');
SELECT regtype('int3'); SELECT regtype('int3');
SELECT regrole('regtestrole');
SELECT regnamespace('nonexistent');
-- with schemaname -- with schemaname
...@@ -64,6 +71,17 @@ SELECT regprocedure('ng_catalog.abs(numeric)'); ...@@ -64,6 +71,17 @@ SELECT regprocedure('ng_catalog.abs(numeric)');
SELECT regclass('ng_catalog.pg_class'); SELECT regclass('ng_catalog.pg_class');
SELECT regtype('ng_catalog.int4'); SELECT regtype('ng_catalog.int4');
-- schemaname not applicable
SELECT regrole('regtestrole');
SELECT regrole('"regtestrole"');
SELECT regrole('Nonexistent');
SELECT regrole('"Nonexistent"');
SELECT regrole('foo.bar');
SELECT regnamespace('Nonexistent');
SELECT regnamespace('"Nonexistent"');
SELECT regnamespace('foo.bar');
/* If objects don't exist, return NULL with no error. */ /* If objects don't exist, return NULL with no error. */
-- without schemaname -- without schemaname
...@@ -74,8 +92,6 @@ SELECT to_regproc('know'); ...@@ -74,8 +92,6 @@ SELECT to_regproc('know');
SELECT to_regprocedure('absinthe(numeric)'); SELECT to_regprocedure('absinthe(numeric)');
SELECT to_regclass('pg_classes'); SELECT to_regclass('pg_classes');
SELECT to_regtype('int3'); SELECT to_regtype('int3');
SELECT to_regrole('regtestrole');
SELECT to_regnamespace('nonexistent');
-- with schemaname -- with schemaname
...@@ -85,3 +101,15 @@ SELECT to_regproc('ng_catalog.now'); ...@@ -85,3 +101,15 @@ SELECT to_regproc('ng_catalog.now');
SELECT to_regprocedure('ng_catalog.abs(numeric)'); SELECT to_regprocedure('ng_catalog.abs(numeric)');
SELECT to_regclass('ng_catalog.pg_class'); SELECT to_regclass('ng_catalog.pg_class');
SELECT to_regtype('ng_catalog.int4'); SELECT to_regtype('ng_catalog.int4');
-- schemaname not applicable
SELECT to_regrole('regtestrole');
SELECT to_regrole('"regtestrole"');
SELECT to_regrole('foo.bar');
SELECT to_regrole('Nonexistent');
SELECT to_regrole('"Nonexistent"');
SELECT to_regrole('foo.bar');
SELECT to_regnamespace('Nonexistent');
SELECT to_regnamespace('"Nonexistent"');
SELECT to_regnamespace('foo.bar');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment