Skip to content

Commit 3c6f8c0

Browse files
committed
Simplify the general-purpose 64-bit integer parsing APIs
pg_strtouint64() is a wrapper around strtoull/strtoul/_strtoui64, but it seems no longer necessary to have this indirection. msvc/Solution.pm claims HAVE_STRTOULL, so the "MSVC only" part seems unnecessary. Also, we have code in c.h to substitute alternatives for strtoull() if not found, and that would appear to cover all currently supported platforms, so having a further fallback in pg_strtouint64() seems unnecessary. Therefore, we could remove pg_strtouint64(), and use strtoull() directly in all call sites. However, it seems useful to keep a separate notation for parsing exactly 64-bit integers, matching the type definition int64/uint64. For that, add new macros strtoi64() and strtou64() in c.h as thin wrappers around strtol()/strtoul() or strtoll()/stroull(). This makes these functions available everywhere instead of just in the server code, and it makes the function naming notably different from the pg_strtointNN() functions in numutils.c, which have a different API. Discussion: https://www.postgresql.org/message-id/flat/a3df47c9-b1b4-29f2-7e91-427baf8b75a3%40enterprisedb.com
1 parent 9c356f4 commit 3c6f8c0

File tree

7 files changed

+19
-29
lines changed

7 files changed

+19
-29
lines changed

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
#define READ_UINT64_FIELD(fldname) \
8181
token = pg_strtok(&length); /* skip :fldname */ \
8282
token = pg_strtok(&length); /* get field value */ \
83-
local_node->fldname = pg_strtouint64(token, NULL, 10)
83+
local_node->fldname = strtou64(token, NULL, 10)
8484

8585
/* Read a long integer field (anything written as ":fldname %ld") */
8686
#define READ_LONG_FIELD(fldname) \

src/backend/utils/adt/numutils.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -606,25 +606,3 @@ pg_ultostr(char *str, uint32 value)
606606

607607
return str + len;
608608
}
609-
610-
/*
611-
* pg_strtouint64
612-
* Converts 'str' into an unsigned 64-bit integer.
613-
*
614-
* This has the identical API to strtoul(3), except that it will handle
615-
* 64-bit ints even where "long" is narrower than that.
616-
*
617-
* For the moment it seems sufficient to assume that the platform has
618-
* such a function somewhere; let's not roll our own.
619-
*/
620-
uint64
621-
pg_strtouint64(const char *str, char **endptr, int base)
622-
{
623-
#ifdef _MSC_VER /* MSVC only */
624-
return _strtoui64(str, endptr, base);
625-
#elif defined(HAVE_STRTOULL) && SIZEOF_LONG < 8
626-
return strtoull(str, endptr, base);
627-
#else
628-
return strtoul(str, endptr, base);
629-
#endif
630-
}

src/backend/utils/adt/xid.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ xid8in(PG_FUNCTION_ARGS)
158158
{
159159
char *str = PG_GETARG_CSTRING(0);
160160

161-
PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(pg_strtouint64(str, NULL, 0)));
161+
PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(strtou64(str, NULL, 0)));
162162
}
163163

164164
Datum

src/backend/utils/adt/xid8funcs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,12 @@ parse_snapshot(const char *str)
295295
char *endp;
296296
StringInfo buf;
297297

298-
xmin = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
298+
xmin = FullTransactionIdFromU64(strtou64(str, &endp, 10));
299299
if (*endp != ':')
300300
goto bad_format;
301301
str = endp + 1;
302302

303-
xmax = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
303+
xmax = FullTransactionIdFromU64(strtou64(str, &endp, 10));
304304
if (*endp != ':')
305305
goto bad_format;
306306
str = endp + 1;
@@ -318,7 +318,7 @@ parse_snapshot(const char *str)
318318
while (*str != '\0')
319319
{
320320
/* read next value */
321-
val = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
321+
val = FullTransactionIdFromU64(strtou64(str, &endp, 10));
322322
str = endp;
323323

324324
/* require the input to be in order */

src/backend/utils/misc/guc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12438,7 +12438,7 @@ check_recovery_target_xid(char **newval, void **extra, GucSource source)
1243812438
TransactionId *myextra;
1243912439

1244012440
errno = 0;
12441-
xid = (TransactionId) pg_strtouint64(*newval, NULL, 0);
12441+
xid = (TransactionId) strtou64(*newval, NULL, 0);
1244212442
if (errno == EINVAL || errno == ERANGE)
1244312443
return false;
1244412444

src/include/c.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,19 @@ extern long long strtoll(const char *str, char **endptr, int base);
13121312
extern unsigned long long strtoull(const char *str, char **endptr, int base);
13131313
#endif
13141314

1315+
/*
1316+
* Thin wrappers that convert strings to exactly 64-bit integers, matching our
1317+
* definition of int64. (For the naming, compare that POSIX has
1318+
* strtoimax()/strtoumax() which return intmax_t/uintmax_t.)
1319+
*/
1320+
#ifdef HAVE_LONG_INT_64
1321+
#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base))
1322+
#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base))
1323+
#else
1324+
#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base))
1325+
#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base))
1326+
#endif
1327+
13151328
/*
13161329
* Use "extern PGDLLIMPORT ..." to declare variables that are defined
13171330
* in the core backend and need to be accessible by loadable modules.

src/include/utils/builtins.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ extern int pg_ltoa(int32 l, char *a);
5353
extern int pg_lltoa(int64 ll, char *a);
5454
extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth);
5555
extern char *pg_ultostr(char *str, uint32 value);
56-
extern uint64 pg_strtouint64(const char *str, char **endptr, int base);
5756

5857
/* oid.c */
5958
extern oidvector *buildoidvector(const Oid *oids, int n);

0 commit comments

Comments
 (0)