Commit 77949a29 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Change the way string relopts are allocated.

Don't try to allocate the default value for a string relopt in the same
palloc chunk as the relopt_string struct. That didn't work too well if you
added a built-in string relopt in the stringRelOpts array, as it's not
possible to have an initializer for a variable length struct in C. This
makes the code slightly simpler too.

While we're at it, move the call to validator function in
add_string_reloption to before the allocation, so that if someone does pass
a bogus default value, we don't leak memory.
parent 5b6c8436
...@@ -371,8 +371,6 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc) ...@@ -371,8 +371,6 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
size_t size; size_t size;
relopt_gen *newoption; relopt_gen *newoption;
Assert(type != RELOPT_TYPE_STRING);
oldcxt = MemoryContextSwitchTo(TopMemoryContext); oldcxt = MemoryContextSwitchTo(TopMemoryContext);
switch (type) switch (type)
...@@ -386,6 +384,9 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc) ...@@ -386,6 +384,9 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
case RELOPT_TYPE_REAL: case RELOPT_TYPE_REAL:
size = sizeof(relopt_real); size = sizeof(relopt_real);
break; break;
case RELOPT_TYPE_STRING:
size = sizeof(relopt_string);
break;
default: default:
elog(ERROR, "unsupported option type"); elog(ERROR, "unsupported option type");
return NULL; /* keep compiler quiet */ return NULL; /* keep compiler quiet */
...@@ -474,45 +475,29 @@ void ...@@ -474,45 +475,29 @@ void
add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val, add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
validate_string_relopt validator) validate_string_relopt validator)
{ {
MemoryContext oldcxt;
relopt_string *newoption; 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); newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING,
if (desc) name, 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->validate_cb = validator; newoption->validate_cb = validator;
if (default_val) if (default_val)
{ {
strcpy(newoption->default_val, default_val); newoption->default_val = MemoryContextStrdup(TopMemoryContext,
newoption->default_len = default_len; default_val);
newoption->default_len = strlen(default_val);
newoption->default_isnull = false; newoption->default_isnull = false;
} }
else else
{ {
newoption->default_val[0] = '\0'; newoption->default_val = "";
newoption->default_len = 0; newoption->default_len = 0;
newoption->default_isnull = true; 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); add_reloption((relopt_gen *) newoption);
} }
......
...@@ -108,7 +108,7 @@ typedef struct relopt_string ...@@ -108,7 +108,7 @@ typedef struct relopt_string
int default_len; int default_len;
bool default_isnull; bool default_isnull;
validate_string_relopt validate_cb; validate_string_relopt validate_cb;
char default_val[1]; /* variable length, zero-terminated */ char *default_val;
} relopt_string; } relopt_string;
/* This is the table datatype for fillRelOptions */ /* This is the table datatype for fillRelOptions */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment