Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fb1227a

Browse files
committed
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
1 parent f47b602 commit fb1227a

File tree

3 files changed

+201
-60
lines changed

3 files changed

+201
-60
lines changed

src/backend/utils/adt/regproc.c

+40-8
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,7 @@ format_operator_internal(Oid operator_oid, bool force_qualify)
855855

856856
/*
857857
* Would this oper be found (given the right args) by regoperatorin?
858-
* If not, or if caller explicitly requests it, we need to qualify
859-
* it.
858+
* If not, or if caller explicitly requests it, we need to qualify it.
860859
*/
861860
if (force_qualify || !OperatorIsVisible(operator_oid))
862861
{
@@ -1570,6 +1569,7 @@ regrolein(PG_FUNCTION_ARGS)
15701569
{
15711570
char *role_name_or_oid = PG_GETARG_CSTRING(0);
15721571
Oid result;
1572+
List *names;
15731573

15741574
/* '-' ? */
15751575
if (strcmp(role_name_or_oid, "-") == 0)
@@ -1586,7 +1586,14 @@ regrolein(PG_FUNCTION_ARGS)
15861586
}
15871587

15881588
/* Normal case: see if the name matches any pg_authid entry. */
1589-
result = get_role_oid(role_name_or_oid, false);
1589+
names = stringToQualifiedNameList(role_name_or_oid);
1590+
1591+
if (list_length(names) != 1)
1592+
ereport(ERROR,
1593+
(errcode(ERRCODE_INVALID_NAME),
1594+
errmsg("invalid name syntax")));
1595+
1596+
result = get_role_oid(strVal(linitial(names)), false);
15901597

15911598
PG_RETURN_OID(result);
15921599
}
@@ -1601,8 +1608,16 @@ to_regrole(PG_FUNCTION_ARGS)
16011608
{
16021609
char *role_name = PG_GETARG_CSTRING(0);
16031610
Oid result;
1611+
List *names;
16041612

1605-
result = get_role_oid(role_name, true);
1613+
names = stringToQualifiedNameList(role_name);
1614+
1615+
if (list_length(names) != 1)
1616+
ereport(ERROR,
1617+
(errcode(ERRCODE_INVALID_NAME),
1618+
errmsg("invalid name syntax")));
1619+
1620+
result = get_role_oid(strVal(linitial(names)), true);
16061621

16071622
if (OidIsValid(result))
16081623
PG_RETURN_OID(result);
@@ -1619,14 +1634,14 @@ regroleout(PG_FUNCTION_ARGS)
16191634
Oid roleoid = PG_GETARG_OID(0);
16201635
char *result;
16211636

1622-
16231637
if (roleoid == InvalidOid)
16241638
{
16251639
result = pstrdup("-");
16261640
PG_RETURN_CSTRING(result);
16271641
}
16281642

16291643
result = GetUserNameFromId(roleoid, true);
1644+
16301645
if (!result)
16311646
{
16321647
/* If OID doesn't match any role, return it numerically */
@@ -1668,7 +1683,8 @@ Datum
16681683
regnamespacein(PG_FUNCTION_ARGS)
16691684
{
16701685
char *nsp_name_or_oid = PG_GETARG_CSTRING(0);
1671-
Oid result = InvalidOid;
1686+
Oid result;
1687+
List *names;
16721688

16731689
/* '-' ? */
16741690
if (strcmp(nsp_name_or_oid, "-") == 0)
@@ -1685,7 +1701,14 @@ regnamespacein(PG_FUNCTION_ARGS)
16851701
}
16861702

16871703
/* Normal case: see if the name matches any pg_namespace entry. */
1688-
result = get_namespace_oid(nsp_name_or_oid, false);
1704+
names = stringToQualifiedNameList(nsp_name_or_oid);
1705+
1706+
if (list_length(names) != 1)
1707+
ereport(ERROR,
1708+
(errcode(ERRCODE_INVALID_NAME),
1709+
errmsg("invalid name syntax")));
1710+
1711+
result = get_namespace_oid(strVal(linitial(names)), false);
16891712

16901713
PG_RETURN_OID(result);
16911714
}
@@ -1700,8 +1723,16 @@ to_regnamespace(PG_FUNCTION_ARGS)
17001723
{
17011724
char *nsp_name = PG_GETARG_CSTRING(0);
17021725
Oid result;
1726+
List *names;
17031727

1704-
result = get_namespace_oid(nsp_name, true);
1728+
names = stringToQualifiedNameList(nsp_name);
1729+
1730+
if (list_length(names) != 1)
1731+
ereport(ERROR,
1732+
(errcode(ERRCODE_INVALID_NAME),
1733+
errmsg("invalid name syntax")));
1734+
1735+
result = get_namespace_oid(strVal(linitial(names)), true);
17051736

17061737
if (OidIsValid(result))
17071738
PG_RETURN_OID(result);
@@ -1725,6 +1756,7 @@ regnamespaceout(PG_FUNCTION_ARGS)
17251756
}
17261757

17271758
result = get_namespace_name(nspid);
1759+
17281760
if (!result)
17291761
{
17301762
/* If OID doesn't match any namespace, return it numerically */

src/test/regress/expected/regproc.out

+125-44
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,6 @@ SELECT regtype('int4');
4040
integer
4141
(1 row)
4242

43-
SELECT regrole('regtestrole');
44-
regrole
45-
-------------
46-
regtestrole
47-
(1 row)
48-
49-
SELECT regnamespace('pg_catalog');
50-
regnamespace
51-
--------------
52-
pg_catalog
53-
(1 row)
54-
5543
SELECT to_regoper('||/');
5644
to_regoper
5745
------------
@@ -88,18 +76,6 @@ SELECT to_regtype('int4');
8876
integer
8977
(1 row)
9078

91-
SELECT to_regrole('regtestrole');
92-
to_regrole
93-
-------------
94-
regtestrole
95-
(1 row)
96-
97-
SELECT to_regnamespace('pg_catalog');
98-
to_regnamespace
99-
-----------------
100-
pg_catalog
101-
(1 row)
102-
10379
-- with schemaname
10480
SELECT regoper('pg_catalog.||/');
10581
regoper
@@ -167,6 +143,55 @@ SELECT to_regtype('pg_catalog.int4');
167143
integer
168144
(1 row)
169145

146+
-- schemaname not applicable
147+
SELECT regrole('regtestrole');
148+
regrole
149+
-------------
150+
regtestrole
151+
(1 row)
152+
153+
SELECT regrole('"regtestrole"');
154+
regrole
155+
-------------
156+
regtestrole
157+
(1 row)
158+
159+
SELECT regnamespace('pg_catalog');
160+
regnamespace
161+
--------------
162+
pg_catalog
163+
(1 row)
164+
165+
SELECT regnamespace('"pg_catalog"');
166+
regnamespace
167+
--------------
168+
pg_catalog
169+
(1 row)
170+
171+
SELECT to_regrole('regtestrole');
172+
to_regrole
173+
-------------
174+
regtestrole
175+
(1 row)
176+
177+
SELECT to_regrole('"regtestrole"');
178+
to_regrole
179+
-------------
180+
regtestrole
181+
(1 row)
182+
183+
SELECT to_regnamespace('pg_catalog');
184+
to_regnamespace
185+
-----------------
186+
pg_catalog
187+
(1 row)
188+
189+
SELECT to_regnamespace('"pg_catalog"');
190+
to_regnamespace
191+
-----------------
192+
pg_catalog
193+
(1 row)
194+
170195
/* If objects don't exist, raise errors. */
171196
DROP ROLE regtestrole;
172197
-- without schemaname
@@ -194,14 +219,6 @@ SELECT regtype('int3');
194219
ERROR: type "int3" does not exist
195220
LINE 1: SELECT regtype('int3');
196221
^
197-
SELECT regrole('regtestrole');
198-
ERROR: role "regtestrole" does not exist
199-
LINE 1: SELECT regrole('regtestrole');
200-
^
201-
SELECT regnamespace('nonexistent');
202-
ERROR: schema "nonexistent" does not exist
203-
LINE 1: SELECT regnamespace('nonexistent');
204-
^
205222
-- with schemaname
206223
SELECT regoper('ng_catalog.||/');
207224
ERROR: schema "ng_catalog" does not exist
@@ -227,6 +244,39 @@ SELECT regtype('ng_catalog.int4');
227244
ERROR: schema "ng_catalog" does not exist
228245
LINE 1: SELECT regtype('ng_catalog.int4');
229246
^
247+
-- schemaname not applicable
248+
SELECT regrole('regtestrole');
249+
ERROR: role "regtestrole" does not exist
250+
LINE 1: SELECT regrole('regtestrole');
251+
^
252+
SELECT regrole('"regtestrole"');
253+
ERROR: role "regtestrole" does not exist
254+
LINE 1: SELECT regrole('"regtestrole"');
255+
^
256+
SELECT regrole('Nonexistent');
257+
ERROR: role "nonexistent" does not exist
258+
LINE 1: SELECT regrole('Nonexistent');
259+
^
260+
SELECT regrole('"Nonexistent"');
261+
ERROR: role "Nonexistent" does not exist
262+
LINE 1: SELECT regrole('"Nonexistent"');
263+
^
264+
SELECT regrole('foo.bar');
265+
ERROR: invalid name syntax
266+
LINE 1: SELECT regrole('foo.bar');
267+
^
268+
SELECT regnamespace('Nonexistent');
269+
ERROR: schema "nonexistent" does not exist
270+
LINE 1: SELECT regnamespace('Nonexistent');
271+
^
272+
SELECT regnamespace('"Nonexistent"');
273+
ERROR: schema "Nonexistent" does not exist
274+
LINE 1: SELECT regnamespace('"Nonexistent"');
275+
^
276+
SELECT regnamespace('foo.bar');
277+
ERROR: invalid name syntax
278+
LINE 1: SELECT regnamespace('foo.bar');
279+
^
230280
/* If objects don't exist, return NULL with no error. */
231281
-- without schemaname
232282
SELECT to_regoper('||//');
@@ -265,18 +315,6 @@ SELECT to_regtype('int3');
265315

266316
(1 row)
267317

268-
SELECT to_regrole('regtestrole');
269-
to_regrole
270-
------------
271-
272-
(1 row)
273-
274-
SELECT to_regnamespace('nonexistent');
275-
to_regnamespace
276-
-----------------
277-
278-
(1 row)
279-
280318
-- with schemaname
281319
SELECT to_regoper('ng_catalog.||/');
282320
to_regoper
@@ -314,3 +352,46 @@ SELECT to_regtype('ng_catalog.int4');
314352

315353
(1 row)
316354

355+
-- schemaname not applicable
356+
SELECT to_regrole('regtestrole');
357+
to_regrole
358+
------------
359+
360+
(1 row)
361+
362+
SELECT to_regrole('"regtestrole"');
363+
to_regrole
364+
------------
365+
366+
(1 row)
367+
368+
SELECT to_regrole('foo.bar');
369+
ERROR: invalid name syntax
370+
SELECT to_regrole('Nonexistent');
371+
to_regrole
372+
------------
373+
374+
(1 row)
375+
376+
SELECT to_regrole('"Nonexistent"');
377+
to_regrole
378+
------------
379+
380+
(1 row)
381+
382+
SELECT to_regrole('foo.bar');
383+
ERROR: invalid name syntax
384+
SELECT to_regnamespace('Nonexistent');
385+
to_regnamespace
386+
-----------------
387+
388+
(1 row)
389+
390+
SELECT to_regnamespace('"Nonexistent"');
391+
to_regnamespace
392+
-----------------
393+
394+
(1 row)
395+
396+
SELECT to_regnamespace('foo.bar');
397+
ERROR: invalid name syntax

0 commit comments

Comments
 (0)