Skip to content

Commit 780ec9f

Browse files
committed
Make the numeric-OID cases of regprocin and friends be non-throwing.
While at it, use a common subroutine already. This doesn't move the needle very far in terms of making these functions non-throwing; the only case we're now able to trap is numeric-OID-is-out-of-range. Still, it seems like a pretty non-controversial step in that direction.
1 parent b5aff92 commit 780ec9f

File tree

1 file changed

+77
-139
lines changed

1 file changed

+77
-139
lines changed

src/backend/utils/adt/regproc.c

Lines changed: 77 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
#include "utils/syscache.h"
4242
#include "utils/varlena.h"
4343

44+
static bool parseNumericOid(char *string, Oid *result, Node *escontext);
45+
static bool parseDashOrOid(char *string, Oid *result, Node *escontext);
4446
static void parseNameAndArgTypes(const char *string, bool allowNone,
4547
List **names, int *nargs, Oid *argtypes);
4648

@@ -61,23 +63,13 @@ Datum
6163
regprocin(PG_FUNCTION_ARGS)
6264
{
6365
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
64-
RegProcedure result = InvalidOid;
66+
RegProcedure result;
6567
List *names;
6668
FuncCandidateList clist;
6769

68-
/* '-' ? */
69-
if (strcmp(pro_name_or_oid, "-") == 0)
70-
PG_RETURN_OID(InvalidOid);
71-
72-
/* Numeric OID? */
73-
if (pro_name_or_oid[0] >= '0' &&
74-
pro_name_or_oid[0] <= '9' &&
75-
strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
76-
{
77-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
78-
CStringGetDatum(pro_name_or_oid)));
70+
/* Handle "-" or numeric OID */
71+
if (parseDashOrOid(pro_name_or_oid, &result, fcinfo->context))
7972
PG_RETURN_OID(result);
80-
}
8173

8274
/* Else it's a name, possibly schema-qualified */
8375

@@ -230,25 +222,15 @@ Datum
230222
regprocedurein(PG_FUNCTION_ARGS)
231223
{
232224
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
233-
RegProcedure result = InvalidOid;
225+
RegProcedure result;
234226
List *names;
235227
int nargs;
236228
Oid argtypes[FUNC_MAX_ARGS];
237229
FuncCandidateList clist;
238230

239-
/* '-' ? */
240-
if (strcmp(pro_name_or_oid, "-") == 0)
241-
PG_RETURN_OID(InvalidOid);
242-
243-
/* Numeric OID? */
244-
if (pro_name_or_oid[0] >= '0' &&
245-
pro_name_or_oid[0] <= '9' &&
246-
strspn(pro_name_or_oid, "0123456789") == strlen(pro_name_or_oid))
247-
{
248-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
249-
CStringGetDatum(pro_name_or_oid)));
231+
/* Handle "-" or numeric OID */
232+
if (parseDashOrOid(pro_name_or_oid, &result, fcinfo->context))
250233
PG_RETURN_OID(result);
251-
}
252234

253235
/* The rest of this wouldn't work in bootstrap mode */
254236
if (IsBootstrapProcessingMode())
@@ -502,23 +484,13 @@ Datum
502484
regoperin(PG_FUNCTION_ARGS)
503485
{
504486
char *opr_name_or_oid = PG_GETARG_CSTRING(0);
505-
Oid result = InvalidOid;
487+
Oid result;
506488
List *names;
507489
FuncCandidateList clist;
508490

509-
/* '0' ? */
510-
if (strcmp(opr_name_or_oid, "0") == 0)
511-
PG_RETURN_OID(InvalidOid);
512-
513-
/* Numeric OID? */
514-
if (opr_name_or_oid[0] >= '0' &&
515-
opr_name_or_oid[0] <= '9' &&
516-
strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
517-
{
518-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
519-
CStringGetDatum(opr_name_or_oid)));
491+
/* Handle "0" or numeric OID */
492+
if (parseNumericOid(opr_name_or_oid, &result, fcinfo->context))
520493
PG_RETURN_OID(result);
521-
}
522494

523495
/* Else it's a name, possibly schema-qualified */
524496

@@ -679,19 +651,9 @@ regoperatorin(PG_FUNCTION_ARGS)
679651
int nargs;
680652
Oid argtypes[FUNC_MAX_ARGS];
681653

682-
/* '0' ? */
683-
if (strcmp(opr_name_or_oid, "0") == 0)
684-
PG_RETURN_OID(InvalidOid);
685-
686-
/* Numeric OID? */
687-
if (opr_name_or_oid[0] >= '0' &&
688-
opr_name_or_oid[0] <= '9' &&
689-
strspn(opr_name_or_oid, "0123456789") == strlen(opr_name_or_oid))
690-
{
691-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
692-
CStringGetDatum(opr_name_or_oid)));
654+
/* Handle "0" or numeric OID */
655+
if (parseNumericOid(opr_name_or_oid, &result, fcinfo->context))
693656
PG_RETURN_OID(result);
694-
}
695657

696658
/* The rest of this wouldn't work in bootstrap mode */
697659
if (IsBootstrapProcessingMode())
@@ -941,22 +903,12 @@ Datum
941903
regclassin(PG_FUNCTION_ARGS)
942904
{
943905
char *class_name_or_oid = PG_GETARG_CSTRING(0);
944-
Oid result = InvalidOid;
906+
Oid result;
945907
List *names;
946908

947-
/* '-' ? */
948-
if (strcmp(class_name_or_oid, "-") == 0)
949-
PG_RETURN_OID(InvalidOid);
950-
951-
/* Numeric OID? */
952-
if (class_name_or_oid[0] >= '0' &&
953-
class_name_or_oid[0] <= '9' &&
954-
strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid))
955-
{
956-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
957-
CStringGetDatum(class_name_or_oid)));
909+
/* Handle "-" or numeric OID */
910+
if (parseDashOrOid(class_name_or_oid, &result, fcinfo->context))
958911
PG_RETURN_OID(result);
959-
}
960912

961913
/* Else it's a name, possibly schema-qualified */
962914

@@ -1093,22 +1045,12 @@ Datum
10931045
regcollationin(PG_FUNCTION_ARGS)
10941046
{
10951047
char *collation_name_or_oid = PG_GETARG_CSTRING(0);
1096-
Oid result = InvalidOid;
1048+
Oid result;
10971049
List *names;
10981050

1099-
/* '-' ? */
1100-
if (strcmp(collation_name_or_oid, "-") == 0)
1101-
PG_RETURN_OID(InvalidOid);
1102-
1103-
/* Numeric OID? */
1104-
if (collation_name_or_oid[0] >= '0' &&
1105-
collation_name_or_oid[0] <= '9' &&
1106-
strspn(collation_name_or_oid, "0123456789") == strlen(collation_name_or_oid))
1107-
{
1108-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1109-
CStringGetDatum(collation_name_or_oid)));
1051+
/* Handle "-" or numeric OID */
1052+
if (parseDashOrOid(collation_name_or_oid, &result, fcinfo->context))
11101053
PG_RETURN_OID(result);
1111-
}
11121054

11131055
/* Else it's a name, possibly schema-qualified */
11141056

@@ -1145,7 +1087,6 @@ to_regcollation(PG_FUNCTION_ARGS)
11451087
*/
11461088
names = stringToQualifiedNameList(collation_name);
11471089

1148-
/* We might not even have permissions on this relation; don't lock it. */
11491090
result = get_collation_oid(names, true);
11501091

11511092
if (OidIsValid(result))
@@ -1251,22 +1192,12 @@ Datum
12511192
regtypein(PG_FUNCTION_ARGS)
12521193
{
12531194
char *typ_name_or_oid = PG_GETARG_CSTRING(0);
1254-
Oid result = InvalidOid;
1195+
Oid result;
12551196
int32 typmod;
12561197

1257-
/* '-' ? */
1258-
if (strcmp(typ_name_or_oid, "-") == 0)
1259-
PG_RETURN_OID(InvalidOid);
1260-
1261-
/* Numeric OID? */
1262-
if (typ_name_or_oid[0] >= '0' &&
1263-
typ_name_or_oid[0] <= '9' &&
1264-
strspn(typ_name_or_oid, "0123456789") == strlen(typ_name_or_oid))
1265-
{
1266-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1267-
CStringGetDatum(typ_name_or_oid)));
1198+
/* Handle "-" or numeric OID */
1199+
if (parseDashOrOid(typ_name_or_oid, &result, fcinfo->context))
12681200
PG_RETURN_OID(result);
1269-
}
12701201

12711202
/* Else it's a type name, possibly schema-qualified or decorated */
12721203

@@ -1390,19 +1321,9 @@ regconfigin(PG_FUNCTION_ARGS)
13901321
Oid result;
13911322
List *names;
13921323

1393-
/* '-' ? */
1394-
if (strcmp(cfg_name_or_oid, "-") == 0)
1395-
PG_RETURN_OID(InvalidOid);
1396-
1397-
/* Numeric OID? */
1398-
if (cfg_name_or_oid[0] >= '0' &&
1399-
cfg_name_or_oid[0] <= '9' &&
1400-
strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid))
1401-
{
1402-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1403-
CStringGetDatum(cfg_name_or_oid)));
1324+
/* Handle "-" or numeric OID */
1325+
if (parseDashOrOid(cfg_name_or_oid, &result, fcinfo->context))
14041326
PG_RETURN_OID(result);
1405-
}
14061327

14071328
/* The rest of this wouldn't work in bootstrap mode */
14081329
if (IsBootstrapProcessingMode())
@@ -1501,19 +1422,9 @@ regdictionaryin(PG_FUNCTION_ARGS)
15011422
Oid result;
15021423
List *names;
15031424

1504-
/* '-' ? */
1505-
if (strcmp(dict_name_or_oid, "-") == 0)
1506-
PG_RETURN_OID(InvalidOid);
1507-
1508-
/* Numeric OID? */
1509-
if (dict_name_or_oid[0] >= '0' &&
1510-
dict_name_or_oid[0] <= '9' &&
1511-
strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid))
1512-
{
1513-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1514-
CStringGetDatum(dict_name_or_oid)));
1425+
/* Handle "-" or numeric OID */
1426+
if (parseDashOrOid(dict_name_or_oid, &result, fcinfo->context))
15151427
PG_RETURN_OID(result);
1516-
}
15171428

15181429
/* The rest of this wouldn't work in bootstrap mode */
15191430
if (IsBootstrapProcessingMode())
@@ -1612,19 +1523,9 @@ regrolein(PG_FUNCTION_ARGS)
16121523
Oid result;
16131524
List *names;
16141525

1615-
/* '-' ? */
1616-
if (strcmp(role_name_or_oid, "-") == 0)
1617-
PG_RETURN_OID(InvalidOid);
1618-
1619-
/* Numeric OID? */
1620-
if (role_name_or_oid[0] >= '0' &&
1621-
role_name_or_oid[0] <= '9' &&
1622-
strspn(role_name_or_oid, "0123456789") == strlen(role_name_or_oid))
1623-
{
1624-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1625-
CStringGetDatum(role_name_or_oid)));
1526+
/* Handle "-" or numeric OID */
1527+
if (parseDashOrOid(role_name_or_oid, &result, fcinfo->context))
16261528
PG_RETURN_OID(result);
1627-
}
16281529

16291530
/* The rest of this wouldn't work in bootstrap mode */
16301531
if (IsBootstrapProcessingMode())
@@ -1737,19 +1638,9 @@ regnamespacein(PG_FUNCTION_ARGS)
17371638
Oid result;
17381639
List *names;
17391640

1740-
/* '-' ? */
1741-
if (strcmp(nsp_name_or_oid, "-") == 0)
1742-
PG_RETURN_OID(InvalidOid);
1743-
1744-
/* Numeric OID? */
1745-
if (nsp_name_or_oid[0] >= '0' &&
1746-
nsp_name_or_oid[0] <= '9' &&
1747-
strspn(nsp_name_or_oid, "0123456789") == strlen(nsp_name_or_oid))
1748-
{
1749-
result = DatumGetObjectId(DirectFunctionCall1(oidin,
1750-
CStringGetDatum(nsp_name_or_oid)));
1641+
/* Handle "-" or numeric OID */
1642+
if (parseDashOrOid(nsp_name_or_oid, &result, fcinfo->context))
17511643
PG_RETURN_OID(result);
1752-
}
17531644

17541645
/* The rest of this wouldn't work in bootstrap mode */
17551646
if (IsBootstrapProcessingMode())
@@ -1911,6 +1802,53 @@ stringToQualifiedNameList(const char *string)
19111802
* SUPPORT ROUTINES *
19121803
*****************************************************************************/
19131804

1805+
/*
1806+
* Given a C string, see if it is all-digits (and not empty).
1807+
* If so, convert directly to OID and return true.
1808+
* If it is not all-digits, return false.
1809+
*
1810+
* If escontext is an ErrorSaveContext node, any error in oidin() will be
1811+
* reported there instead of being thrown (but we still return true).
1812+
*/
1813+
static bool
1814+
parseNumericOid(char *string, Oid *result, Node *escontext)
1815+
{
1816+
if (string[0] >= '0' && string[0] <= '9' &&
1817+
strspn(string, "0123456789") == strlen(string))
1818+
{
1819+
Datum oid_datum;
1820+
1821+
/* We need not care here whether oidin() fails or not. */
1822+
(void) DirectInputFunctionCallSafe(oidin, string,
1823+
InvalidOid, -1,
1824+
escontext,
1825+
&oid_datum);
1826+
*result = DatumGetObjectId(oid_datum);
1827+
return true;
1828+
}
1829+
1830+
/* Prevent uninitialized-variable warnings from stupider compilers. */
1831+
*result = InvalidOid;
1832+
return false;
1833+
}
1834+
1835+
/*
1836+
* As above, but also accept "-" as meaning 0 (InvalidOid).
1837+
*/
1838+
static bool
1839+
parseDashOrOid(char *string, Oid *result, Node *escontext)
1840+
{
1841+
/* '-' ? */
1842+
if (strcmp(string, "-") == 0)
1843+
{
1844+
*result = InvalidOid;
1845+
return true;
1846+
}
1847+
1848+
/* Numeric OID? */
1849+
return parseNumericOid(string, result, escontext);
1850+
}
1851+
19141852
/*
19151853
* Given a C string, parse it into a qualified function or operator name
19161854
* followed by a parenthesized list of type names. Reduce the

0 commit comments

Comments
 (0)