Fix string reloption handling, per KaiGai Kohei.
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 6 Jan 2009 14:47:37 +0000 (14:47 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 6 Jan 2009 14:47:37 +0000 (14:47 +0000)
src/backend/access/common/reloptions.c
src/include/access/reloptions.h

index 01c9ab5f9093cf54bcddc0447b0add287c295c64..7690da0e671a3b98aeda539e36d2dfac1fe5a3f3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.15 2009/01/06 03:15:51 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.16 2009/01/06 14:47:37 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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);
index 8a2e2286becc0fef59988e415939a18be1addf62..5238c70904ac0c21f312cbb60b62125f6ee8d8da 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.7 2009/01/05 17:14:28 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.8 2009/01/06 14:47:37 alvherre Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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)