mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Allow reloption names to have qualifiers, initially supporting a TOAST
qualifier, and add support for this in pg_dump. This allows TOAST tables to have user-defined fillfactor, and will also enable us to move the autovacuum parameters to reloptions without taking away the possibility of setting values for TOAST tables.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.19 2009/01/26 19:41:06 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.20 2009/02/02 19:31:38 alvherre Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -390,8 +390,10 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
|
||||
}
|
||||
|
||||
/*
|
||||
* Transform a relation options list (list of DefElem) into the text array
|
||||
* format that is kept in pg_class.reloptions.
|
||||
* Transform a relation options list (list of ReloptElem) into the text array
|
||||
* format that is kept in pg_class.reloptions, including only those options
|
||||
* that are in the passed namespace. The output values do not include the
|
||||
* namespace.
|
||||
*
|
||||
* This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and
|
||||
* ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing
|
||||
@ -402,14 +404,17 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
|
||||
* in the list (it will be or has been handled by interpretOidsOption()).
|
||||
*
|
||||
* Note that this is not responsible for determining whether the options
|
||||
* are valid.
|
||||
* are valid, but it does check that namespaces for all the options given are
|
||||
* listed in validnsps. The NULL namespace is always valid and needs not be
|
||||
* explicitely listed. Passing a NULL pointer means that only the NULL
|
||||
* namespace is valid.
|
||||
*
|
||||
* Both oldOptions and the result are text arrays (or NULL for "default"),
|
||||
* but we declare them as Datums to avoid including array.h in reloptions.h.
|
||||
*/
|
||||
Datum
|
||||
transformRelOptions(Datum oldOptions, List *defList,
|
||||
bool ignoreOids, bool isReset)
|
||||
transformRelOptions(Datum oldOptions, List *defList, char *namspace,
|
||||
char *validnsps[], bool ignoreOids, bool isReset)
|
||||
{
|
||||
Datum result;
|
||||
ArrayBuildState *astate;
|
||||
@ -444,11 +449,23 @@ transformRelOptions(Datum oldOptions, List *defList,
|
||||
/* Search for a match in defList */
|
||||
foreach(cell, defList)
|
||||
{
|
||||
DefElem *def = lfirst(cell);
|
||||
int kw_len = strlen(def->defname);
|
||||
ReloptElem *def = lfirst(cell);
|
||||
int kw_len;
|
||||
|
||||
/* ignore if not in the same namespace */
|
||||
if (namspace == NULL)
|
||||
{
|
||||
if (def->nmspc != NULL)
|
||||
continue;
|
||||
}
|
||||
else if (def->nmspc == NULL)
|
||||
continue;
|
||||
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
|
||||
continue;
|
||||
|
||||
kw_len = strlen(def->optname);
|
||||
if (text_len > kw_len && text_str[kw_len] == '=' &&
|
||||
pg_strncasecmp(text_str, def->defname, kw_len) == 0)
|
||||
pg_strncasecmp(text_str, def->optname, kw_len) == 0)
|
||||
break;
|
||||
}
|
||||
if (!cell)
|
||||
@ -468,7 +485,8 @@ transformRelOptions(Datum oldOptions, List *defList,
|
||||
*/
|
||||
foreach(cell, defList)
|
||||
{
|
||||
DefElem *def = lfirst(cell);
|
||||
ReloptElem *def = lfirst(cell);
|
||||
|
||||
|
||||
if (isReset)
|
||||
{
|
||||
@ -483,22 +501,62 @@ transformRelOptions(Datum oldOptions, List *defList,
|
||||
const char *value;
|
||||
Size len;
|
||||
|
||||
if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
|
||||
/*
|
||||
* Error out if the namespace is not valid. A NULL namespace
|
||||
* is always valid.
|
||||
*/
|
||||
if (def->nmspc != NULL)
|
||||
{
|
||||
bool valid = false;
|
||||
int i;
|
||||
|
||||
if (validnsps)
|
||||
{
|
||||
for (i = 0; validnsps[i]; i++)
|
||||
{
|
||||
if (pg_strcasecmp(def->nmspc, validnsps[i]) == 0)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("unrecognized parameter namespace \"%s\"",
|
||||
def->nmspc)));
|
||||
}
|
||||
|
||||
if (ignoreOids && pg_strcasecmp(def->optname, "oids") == 0)
|
||||
continue;
|
||||
|
||||
/* ignore if not in the same namespace */
|
||||
if (namspace == NULL)
|
||||
{
|
||||
if (def->nmspc != NULL)
|
||||
continue;
|
||||
}
|
||||
else if (def->nmspc == NULL)
|
||||
continue;
|
||||
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Flatten the DefElem into a text string like "name=arg". If we
|
||||
* have just "name", assume "name=true" is meant.
|
||||
* Flatten the ReloptElem into a text string like "name=arg". If we
|
||||
* have just "name", assume "name=true" is meant. Note: the
|
||||
* namespace is not output.
|
||||
*/
|
||||
if (def->arg != NULL)
|
||||
value = defGetString(def);
|
||||
value = reloptGetString(def);
|
||||
else
|
||||
value = "true";
|
||||
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
|
||||
len = VARHDRSZ + strlen(def->optname) + 1 + strlen(value);
|
||||
/* +1 leaves room for sprintf's trailing null */
|
||||
t = (text *) palloc(len + 1);
|
||||
SET_VARSIZE(t, len);
|
||||
sprintf(VARDATA(t), "%s=%s", def->defname, value);
|
||||
sprintf(VARDATA(t), "%s=%s", def->optname, value);
|
||||
|
||||
astate = accumArrayResult(astate, PointerGetDatum(t),
|
||||
false, TEXTOID,
|
||||
@ -944,7 +1002,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse options for heaps (and perhaps someday toast tables).
|
||||
* Parse options for heaps and toast tables.
|
||||
*/
|
||||
bytea *
|
||||
heap_reloptions(char relkind, Datum reloptions, bool validate)
|
||||
|
Reference in New Issue
Block a user