On 08.08.2011 22:11, Alvaro Herrera wrote:
Perhaps the easiest way to fix it is as you suggest, by declaring the
struct to take a pointer rather than the value directly.  Not sure how
to make both cases work sanely; the add_string_reloption path will need
updates.

Agreed, I propose the attached patch to do that. Are there any extensions out there that use add_string_relopt(), that I could use for testing?

--
  Heikki Linnakangas
  EnterpriseDB   http://www.enterprisedb.com
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 4657425..900b222 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -371,8 +371,6 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
 	size_t		size;
 	relopt_gen *newoption;
 
-	Assert(type != RELOPT_TYPE_STRING);
-
 	oldcxt = MemoryContextSwitchTo(TopMemoryContext);
 
 	switch (type)
@@ -386,6 +384,9 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
 		case RELOPT_TYPE_REAL:
 			size = sizeof(relopt_real);
 			break;
+		case RELOPT_TYPE_STRING:
+			size = sizeof(relopt_string);
+			break;
 		default:
 			elog(ERROR, "unsupported option type");
 			return NULL;		/* keep compiler quiet */
@@ -474,45 +475,29 @@ void
 add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
 					 validate_string_relopt validator)
 {
-	MemoryContext oldcxt;
 	relopt_string *newoption;
-	int			default_len = 0;
-
-	oldcxt = MemoryContextSwitchTo(TopMemoryContext);
-
-	if (default_val)
-		default_len = strlen(default_val);
 
-	newoption = palloc0(sizeof(relopt_string) + default_len);
+	/* make sure the validator/default combination is sane */
+	if (validator)
+		(validator) (default_val);
 
-	newoption->gen.name = pstrdup(name);
-	if (desc)
-		newoption->gen.desc = pstrdup(desc);
-	else
-		newoption->gen.desc = NULL;
-	newoption->gen.kinds = kinds;
-	newoption->gen.namelen = strlen(name);
-	newoption->gen.type = RELOPT_TYPE_STRING;
+	newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING,
+													 name, desc);
 	newoption->validate_cb = validator;
 	if (default_val)
 	{
-		strcpy(newoption->default_val, default_val);
-		newoption->default_len = default_len;
+		newoption->default_val = MemoryContextStrdup(TopMemoryContext,
+													 default_val);
+		newoption->default_len = strlen(default_val);
 		newoption->default_isnull = false;
 	}
 	else
 	{
-		newoption->default_val[0] = '\0';
+		newoption->default_val = "";
 		newoption->default_len = 0;
 		newoption->default_isnull = true;
 	}
 
-	/* make sure the validator/default combination is sane */
-	if (newoption->validate_cb)
-		(newoption->validate_cb) (newoption->default_val);
-
-	MemoryContextSwitchTo(oldcxt);
-
 	add_reloption((relopt_gen *) newoption);
 }
 
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index c7709cc..14f5034 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -108,7 +108,7 @@ typedef struct relopt_string
 	int			default_len;
 	bool		default_isnull;
 	validate_string_relopt validate_cb;
-	char		default_val[1]; /* variable length, zero-terminated */
+	char	   *default_val;
 } relopt_string;
 
 /* This is the table datatype for fillRelOptions */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to