From 0e20d90ab016b7ac926feba765f62d8b64017d50 Mon Sep 17 00:00:00 2001
From: Jeevan Ladhe
Date: Sun, 4 Aug 2019 09:08:20 +0530
Subject: [PATCH] Make have_error initialization more defensive v3
Basically get rid of the dependency to have caller
initalize the flag.
This patch addresses such occurrences in following functions:
pg_lsn_in_internal(), float8in_internal_opt_error(),
numeric_mod_opt_error(), numeric_div_opt_error() and
numeric_mod_opt_error().
Also, add have_error flag to macro RETURN_ERROR to make the
references more readable in float.c
Jeevan Ladhe
---
src/backend/utils/adt/float.c | 44 ++++++++++++++++++-----------------
src/backend/utils/adt/jsonpath_exec.c | 6 ++---
src/backend/utils/adt/numeric.c | 9 +++++++
src/backend/utils/adt/pg_lsn.c | 5 +++-
src/backend/utils/misc/guc.c | 2 +-
5 files changed, 40 insertions(+), 26 deletions(-)
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 7540ca2..219a0bb 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -337,10 +337,10 @@ float8in(PG_FUNCTION_ARGS)
}
/* Convenience macro: set *have_error flag (if provided) or throw error */
-#define RETURN_ERROR(throw_error) \
+#define RETURN_ERROR(have_error, throw_error) \
do { \
if (have_error) { \
- *have_error = true; \
+ *(have_error) = true; \
return 0.0; \
} else { \
throw_error; \
@@ -376,6 +376,9 @@ float8in_internal_opt_error(char *num, char **endptr_p,
double val;
char *endptr;
+ if (have_error)
+ *have_error = false;
+
/* skip leading whitespace */
while (*num != '\0' && isspace((unsigned char) *num))
num++;
@@ -385,10 +388,10 @@ float8in_internal_opt_error(char *num, char **endptr_p,
* strtod() on different platforms.
*/
if (*num == '\0')
- RETURN_ERROR(ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type %s: \"%s\"",
- type_name, orig_string))));
+ RETURN_ERROR(have_error, ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ type_name, orig_string))));
errno = 0;
val = strtod(num, &endptr);
@@ -461,19 +464,18 @@ float8in_internal_opt_error(char *num, char **endptr_p,
char *errnumber = pstrdup(num);
errnumber[endptr - num] = '\0';
- RETURN_ERROR(ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("\"%s\" is out of range for "
- "type double precision",
- errnumber))));
+ RETURN_ERROR(have_error, ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("\"%s\" is out of range for type double precision",
+ errnumber))));
}
}
else
- RETURN_ERROR(ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type "
- "%s: \"%s\"",
- type_name, orig_string))));
+ RETURN_ERROR(have_error, ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type "
+ "%s: \"%s\"",
+ type_name, orig_string))));
}
#ifdef HAVE_BUGGY_SOLARIS_STRTOD
else
@@ -496,11 +498,11 @@ float8in_internal_opt_error(char *num, char **endptr_p,
if (endptr_p)
*endptr_p = endptr;
else if (*endptr != '\0')
- RETURN_ERROR(ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type "
- "%s: \"%s\"",
- type_name, orig_string))));
+ RETURN_ERROR(have_error, ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type "
+ "%s: \"%s\"",
+ type_name, orig_string))));
return val;
}
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index 293d6da..a0ead39 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -976,7 +976,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
{
char *tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
NumericGetDatum(jb->val.numeric)));
- bool have_error = false;
+ bool have_error;
(void) float8in_internal_opt_error(tmp,
NULL,
@@ -997,7 +997,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp,
double val;
char *tmp = pnstrdup(jb->val.string.val,
jb->val.string.len);
- bool have_error = false;
+ bool have_error;
val = float8in_internal_opt_error(tmp,
NULL,
@@ -1521,7 +1521,7 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
}
else
{
- bool error = false;
+ bool error;
res = func(lval->val.numeric, rval->val.numeric, &error);
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 201784b..7b0874b 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -2605,6 +2605,9 @@ numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Numeric res;
int rscale;
+ if(have_error)
+ *have_error = false;
+
/*
* Handle NaN
*/
@@ -2721,6 +2724,9 @@ numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
NumericVar arg2;
NumericVar result;
+ if (have_error)
+ *have_error = false;
+
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
return make_result(&const_nan);
@@ -6249,6 +6255,9 @@ make_result_opt_error(const NumericVar *var, bool *have_error)
int n;
Size len;
+ if (have_error)
+ *have_error = false;
+
if (sign == NUMERIC_NAN)
{
result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c
index b4c6c23..90e9b8c 100644
--- a/src/backend/utils/adt/pg_lsn.c
+++ b/src/backend/utils/adt/pg_lsn.c
@@ -34,6 +34,9 @@ pg_lsn_in_internal(const char *str, bool *have_error)
off;
XLogRecPtr result;
+ Assert(have_error != NULL);
+ *have_error = false;
+
/* Sanity check input format. */
len1 = strspn(str, "0123456789abcdefABCDEF");
if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
@@ -61,7 +64,7 @@ pg_lsn_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
XLogRecPtr result;
- bool have_error = false;
+ bool have_error;
result = pg_lsn_in_internal(str, &have_error);
if (have_error)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fc46360..ce179fc 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -11677,7 +11677,7 @@ check_recovery_target_lsn(char **newval, void **extra, GucSource source)
{
XLogRecPtr lsn;
XLogRecPtr *myextra;
- bool have_error = false;
+ bool have_error;
lsn = pg_lsn_in_internal(*newval, &have_error);
if (have_error)
--
2.7.4