summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-07-23 17:29:53 +0000
committerTom Lane2008-07-23 17:29:53 +0000
commit3364c4afafb21d2e6cb4b77256984aad2481c9a4 (patch)
tree5bc42290c68f73c5299682adcdc64836eadd0271
parentc8b0d53c711e9ee094f2ba8b04d542021682b1b7 (diff)
Use guc.c's parse_int() instead of pg_atoi() to parse fillfactor in
default_reloptions(). The previous coding was really a bug because pg_atoi() will always throw elog on bad input data, whereas default_reloptions is not supposed to complain about bad input unless its validate parameter is true. Right now you could only expose the problem by hand-modifying pg_class.reloptions into an invalid state, so it doesn't seem worth back-patching; but we should get it right in HEAD because there might be other situations in future. Noted while studying GIN fast-update patch.
-rw-r--r--src/backend/access/common/reloptions.c14
-rw-r--r--src/backend/utils/misc/guc.c4
-rw-r--r--src/include/utils/guc.h3
3 files changed, 17 insertions, 4 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 532190abe0..db39d90d02 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -21,6 +21,7 @@
#include "nodes/makefuncs.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/guc.h"
#include "utils/rel.h"
@@ -287,7 +288,7 @@ default_reloptions(Datum reloptions, bool validate,
{
static const char *const default_keywords[1] = {"fillfactor"};
char *values[1];
- int32 fillfactor;
+ int fillfactor;
StdRdOptions *result;
parseRelOptions(reloptions, 1, default_keywords, values, validate);
@@ -300,7 +301,16 @@ default_reloptions(Datum reloptions, bool validate,
if (values[0] == NULL)
return NULL;
- fillfactor = pg_atoi(values[0], sizeof(int32), 0);
+ if (!parse_int(values[0], &fillfactor, 0, NULL))
+ {
+ if (validate)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("fillfactor must be an integer: \"%s\"",
+ values[0])));
+ return NULL;
+ }
+
if (fillfactor < minFillfactor || fillfactor > 100)
{
if (validate)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 56c42eebb2..1615119b6d 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4115,7 +4115,7 @@ parse_bool(const char *value, bool *result)
* If not okay and hintmsg is not NULL, *hintmsg is set to a suitable
* HINT message, or NULL if no hint provided.
*/
-static bool
+bool
parse_int(const char *value, int *result, int flags, const char **hintmsg)
{
int64 val;
@@ -4322,7 +4322,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
* If the string parses okay, return true, else false.
* If okay and result is not NULL, return the value in *result.
*/
-static bool
+bool
parse_real(const char *value, double *result)
{
double val;
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 004df9fdd2..5c723b2476 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -224,6 +224,9 @@ extern void AtEOXact_GUC(bool isCommit, int nestLevel);
extern void BeginReportingGUCOptions(void);
extern void ParseLongOption(const char *string, char **name, char **value);
extern bool parse_bool(const char *value, bool *result);
+extern bool parse_int(const char *value, int *result, int flags,
+ const char **hintmsg);
+extern bool parse_real(const char *value, double *result);
extern bool set_config_option(const char *name, const char *value,
GucContext context, GucSource source,
GucAction action, bool changeVal);