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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy