summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera2009-01-06 14:47:37 +0000
committerAlvaro Herrera2009-01-06 14:47:37 +0000
commit1b826c270f2710b0da968a9a33d30fb5907565a6 (patch)
treef1e96695bc883e61fd4dbdd7111987854952df2a
parent6e807875e02ef6e35f03c3b16c7991d259458ca6 (diff)
Fix string reloption handling, per KaiGai Kohei.
-rw-r--r--src/backend/access/common/reloptions.c3
-rw-r--r--src/include/access/reloptions.h48
2 files changed, 40 insertions, 11 deletions
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 6d571351c8..7ce2792170 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -769,7 +769,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
for (i = 0; i < numoptions; i++)
{
- HANDLE_INT_RELOPTION("fillfactor", lopts.fillfactor, options[i]);
+ HANDLE_INT_RELOPTION("fillfactor", lopts.fillfactor, options[i],
+ (char *) NULL);
}
pfree(options);
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 6a5b1b54a7..cd6029145c 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -106,11 +106,16 @@ typedef struct relopt_string
* Most of the time there's no need to call HAVE_RELOPTION manually, but it's
* possible that an amoptions routine needs to walk the array with a different
* purpose (say, to compute the size of a struct to allocate beforehand.)
+ *
+ * The last argument in the HANDLE_*_RELOPTION macros allows the caller to
+ * determine whether the option was set (true), or its value acquired from
+ * defaults (false); it can be passed as (char *) NULL if the caller does not
+ * need this information.
*/
#define HAVE_RELOPTION(optname, option) \
(pg_strncasecmp(option.gen->name, optname, option.gen->namelen) == 0)
-#define HANDLE_INT_RELOPTION(optname, var, option) \
+#define HANDLE_INT_RELOPTION(optname, var, option, wasset) \
do { \
if (HAVE_RELOPTION(optname, option)) \
{ \
@@ -118,11 +123,12 @@ typedef struct relopt_string
var = option.values.int_val; \
else \
var = ((relopt_int *) option.gen)->default_val; \
+ (wasset) != NULL ? *(wasset) = option.isset : (dummyret)NULL; \
continue; \
} \
} while (0)
-#define HANDLE_BOOL_RELOPTION(optname, var, option) \
+#define HANDLE_BOOL_RELOPTION(optname, var, option, wasset) \
do { \
if (HAVE_RELOPTION(optname, option)) \
{ \
@@ -130,11 +136,12 @@ typedef struct relopt_string
var = option.values.bool_val; \
else \
var = ((relopt_bool *) option.gen)->default_val; \
+ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
continue; \
} \
} while (0)
-#define HANDLE_REAL_RELOPTION(optname, var, option) \
+#define HANDLE_REAL_RELOPTION(optname, var, option, wasset) \
do { \
if (HAVE_RELOPTION(optname, option)) \
{ \
@@ -142,22 +149,43 @@ typedef struct relopt_string
var = option.values.real_val; \
else \
var = ((relopt_real *) option.gen)->default_val; \
+ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
continue; \
} \
} while (0)
-/* Note that this assumes that the variable is already allocated! */
-#define HANDLE_STRING_RELOPTION(optname, var, option) \
+/*
+ * Note that this assumes that the variable is already allocated at the tail of
+ * reloptions structure (StdRdOptions or other).
+ *
+ * "base" is a pointer to the reloptions structure, and "offset" is an integer
+ * variable that must be initialized to sizeof(reloptions structure). This
+ * struct must have been allocated with enough space to hold any string option
+ * present, including terminating \0 for every option. SET_VARSIZE() must be
+ * called on the struct with this offset as the second argument, after all the
+ * string options have been processed.
+ */
+#define HANDLE_STRING_RELOPTION(optname, var, option, base, offset, wasset) \
do { \
if (HAVE_RELOPTION(optname, option)) \
{ \
relopt_string *optstring = (relopt_string *) option.gen;\
- if (optstring->default_isnull) \
- var[0] = '\0'; \
+ char *string_val = NULL; \
+ \
+ if (option.isset) \
+ string_val = option.values.string_val; \
+ else if (!optstring->default_isnull) \
+ string_val = optstring->default_val; \
+ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
+ \
+ if (!string_val) \
+ var = 0; \
else \
- strcpy(var, \
- option.isset ? option.values.string_val : \
- optstring->default_val); \
+ { \
+ strcpy((char *)(base) + (offset), string_val); \
+ var = (offset); \
+ (offset) += strlen(string_val) + 1; \
+ } \
continue; \
} \
} while (0)