mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
Move scanint8() to numutils.c
Move scanint8() to numutils.c and rename to pg_strtoint64(). We already have a "16" and "32" version of that, and the code inside the functions was aligned, so this move makes all three versions consistent. The API is also changed to no longer provide the errorOK case. Users that need the error checking can use strtoi64(). Reviewed-by: John Naylor <john.naylor@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/b239564c-cad0-b23e-c57e-166d883cb97d@enterprisedb.com
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
#include "nodes/supportnodes.h"
|
||||
#include "optimizer/optimizer.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/int8.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
@@ -45,99 +44,14 @@ typedef struct
|
||||
* Formatting and conversion routines.
|
||||
*---------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* scanint8 --- try to parse a string into an int8.
|
||||
*
|
||||
* If errorOK is false, ereport a useful error message if the string is bad.
|
||||
* If errorOK is true, just return "false" for bad input.
|
||||
*/
|
||||
bool
|
||||
scanint8(const char *str, bool errorOK, int64 *result)
|
||||
{
|
||||
const char *ptr = str;
|
||||
int64 tmp = 0;
|
||||
bool neg = false;
|
||||
|
||||
/*
|
||||
* Do our own scan, rather than relying on sscanf which might be broken
|
||||
* for long long.
|
||||
*
|
||||
* As INT64_MIN can't be stored as a positive 64 bit integer, accumulate
|
||||
* value as a negative number.
|
||||
*/
|
||||
|
||||
/* skip leading spaces */
|
||||
while (*ptr && isspace((unsigned char) *ptr))
|
||||
ptr++;
|
||||
|
||||
/* handle sign */
|
||||
if (*ptr == '-')
|
||||
{
|
||||
ptr++;
|
||||
neg = true;
|
||||
}
|
||||
else if (*ptr == '+')
|
||||
ptr++;
|
||||
|
||||
/* require at least one digit */
|
||||
if (unlikely(!isdigit((unsigned char) *ptr)))
|
||||
goto invalid_syntax;
|
||||
|
||||
/* process digits */
|
||||
while (*ptr && isdigit((unsigned char) *ptr))
|
||||
{
|
||||
int8 digit = (*ptr++ - '0');
|
||||
|
||||
if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) ||
|
||||
unlikely(pg_sub_s64_overflow(tmp, digit, &tmp)))
|
||||
goto out_of_range;
|
||||
}
|
||||
|
||||
/* allow trailing whitespace, but not other trailing chars */
|
||||
while (*ptr != '\0' && isspace((unsigned char) *ptr))
|
||||
ptr++;
|
||||
|
||||
if (unlikely(*ptr != '\0'))
|
||||
goto invalid_syntax;
|
||||
|
||||
if (!neg)
|
||||
{
|
||||
/* could fail if input is most negative number */
|
||||
if (unlikely(tmp == PG_INT64_MIN))
|
||||
goto out_of_range;
|
||||
tmp = -tmp;
|
||||
}
|
||||
|
||||
*result = tmp;
|
||||
return true;
|
||||
|
||||
out_of_range:
|
||||
if (!errorOK)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("value \"%s\" is out of range for type %s",
|
||||
str, "bigint")));
|
||||
return false;
|
||||
|
||||
invalid_syntax:
|
||||
if (!errorOK)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"",
|
||||
"bigint", str)));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* int8in()
|
||||
*/
|
||||
Datum
|
||||
int8in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *str = PG_GETARG_CSTRING(0);
|
||||
int64 result;
|
||||
char *num = PG_GETARG_CSTRING(0);
|
||||
|
||||
(void) scanint8(str, false, &result);
|
||||
PG_RETURN_INT64(result);
|
||||
PG_RETURN_INT64(pg_strtoint64(num));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user