1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-31 17:02:12 +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:
Alvaro Herrera
2009-02-02 19:31:40 +00:00
parent 80f95a6500
commit 3a5b773715
27 changed files with 455 additions and 130 deletions

View File

@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.181 2009/01/16 13:27:23 heikki Exp $
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.182 2009/02/02 19:31:38 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -668,6 +668,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
TupleDesc OldHeapDesc,
tupdesc;
Oid OIDNewHeap;
Oid toastid;
Relation OldHeap;
HeapTuple tuple;
Datum reloptions;
@@ -726,7 +727,24 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
* the TOAST table will be visible for insertion.
*/
AlterTableCreateToastTable(OIDNewHeap);
toastid = OldHeap->rd_rel->reltoastrelid;
reloptions = (Datum) 0;
if (OidIsValid(toastid))
{
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(toastid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", toastid);
reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
&isNull);
if (isNull)
reloptions = (Datum) 0;
}
AlterTableCreateToastTable(OIDNewHeap, reloptions);
if (OidIsValid(toastid))
ReleaseSysCache(tuple);
heap_close(OldHeap, NoLock);

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.102 2009/01/01 17:23:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.103 2009/02/02 19:31:38 alvherre Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -55,24 +55,20 @@ case_translate_language_name(const char *input)
}
/*
* Extract a string value (otherwise uninterpreted) from a DefElem.
*/
char *
defGetString(DefElem *def)
static char *
nodeGetString(Node *value, char *name)
{
if (def->arg == NULL)
if (value == NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s requires a parameter",
def->defname)));
switch (nodeTag(def->arg))
errmsg("%s requires a parameter", name)));
switch (nodeTag(value))
{
case T_Integer:
{
char *str = palloc(32);
snprintf(str, 32, "%ld", (long) intVal(def->arg));
snprintf(str, 32, "%ld", (long) intVal(value));
return str;
}
case T_Float:
@@ -81,19 +77,28 @@ defGetString(DefElem *def)
* T_Float values are kept in string form, so this type cheat
* works (and doesn't risk losing precision)
*/
return strVal(def->arg);
return strVal(value);
case T_String:
return strVal(def->arg);
return strVal(value);
case T_TypeName:
return TypeNameToString((TypeName *) def->arg);
return TypeNameToString((TypeName *) value);
case T_List:
return NameListToString((List *) def->arg);
return NameListToString((List *) value);
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
}
return NULL; /* keep compiler quiet */
}
/*
* Extract a string value (otherwise uninterpreted) from a DefElem.
*/
char *
defGetString(DefElem *def)
{
return nodeGetString(def->arg, def->defname);
}
/*
* Extract a numeric value (actually double) from a DefElem.
*/
@@ -120,25 +125,22 @@ defGetNumeric(DefElem *def)
return 0; /* keep compiler quiet */
}
/*
* Extract a boolean value from a DefElem.
*/
bool
defGetBoolean(DefElem *def)
static bool
nodeGetBoolean(Node *value, char *name)
{
/*
* If no parameter given, assume "true" is meant.
*/
if (def->arg == NULL)
if (value == NULL)
return true;
/*
* Allow 0, 1, "true", "false"
*/
switch (nodeTag(def->arg))
switch (nodeTag(value))
{
case T_Integer:
switch (intVal(def->arg))
switch (intVal(value))
{
case 0:
return false;
@@ -151,7 +153,7 @@ defGetBoolean(DefElem *def)
break;
default:
{
char *sval = defGetString(def);
char *sval = nodeGetString(value, name);
if (pg_strcasecmp(sval, "true") == 0)
return true;
@@ -163,11 +165,19 @@ defGetBoolean(DefElem *def)
}
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("%s requires a Boolean value",
def->defname)));
errmsg("%s requires a Boolean value", name)));
return false; /* keep compiler quiet */
}
/*
* Extract a boolean value from a DefElem.
*/
bool
defGetBoolean(DefElem *def)
{
return nodeGetBoolean(def->arg, def->defname);
}
/*
* Extract an int64 value from a DefElem.
*/
@@ -305,15 +315,35 @@ defGetTypeLength(DefElem *def)
return 0; /* keep compiler quiet */
}
/*
* Create a DefElem setting "oids" to the specified value.
*/
DefElem *
defWithOids(bool value)
{
DefElem *f = makeNode(DefElem);
f->defname = "oids";
/*
* Extract a string value (otherwise uninterpreted) from a ReloptElem.
*/
char *
reloptGetString(ReloptElem *relopt)
{
return nodeGetString(relopt->arg, relopt->optname);
}
/*
* Extract a boolean value from a ReloptElem.
*/
bool
reloptGetBoolean(ReloptElem *relopt)
{
return nodeGetBoolean(relopt->arg, relopt->optname);
}
/*
* Create a ReloptElem setting "oids" to the specified value.
*/
ReloptElem *
reloptWithOids(bool value)
{
ReloptElem *f = makeNode(ReloptElem);
f->optname = "oids";
f->nmspc = NULL;
f->arg = (Node *) makeInteger(value);
return f;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.181 2009/01/01 17:23:38 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.182 2009/02/02 19:31:38 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -398,7 +398,7 @@ DefineIndex(RangeVar *heapRelation,
/*
* Parse AM-specific options, convert to text array form, validate.
*/
reloptions = transformRelOptions((Datum) 0, options, false, false);
reloptions = transformRelOptions((Datum) 0, options, NULL, NULL, false, false);
(void) index_reloptions(amoptions, reloptions, true);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.157 2009/01/20 18:59:37 heikki Exp $
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.158 2009/02/02 19:31:38 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,7 +198,7 @@ DefineSequence(CreateSeqStmt *seq)
stmt->relation = seq->sequence;
stmt->inhRelations = NIL;
stmt->constraints = NIL;
stmt->options = list_make1(defWithOids(false));
stmt->options = list_make1(reloptWithOids(false));
stmt->oncommit = ONCOMMIT_NOOP;
stmt->tablespacename = NULL;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.278 2009/01/22 20:16:02 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.279 2009/02/02 19:31:38 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -351,6 +351,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
Datum reloptions;
ListCell *listptr;
AttrNumber attnum;
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
/*
* Truncate relname to appropriate length (probably a waste of time, as
@@ -418,7 +419,8 @@ DefineRelation(CreateStmt *stmt, char relkind)
/*
* Parse and validate reloptions, if any.
*/
reloptions = transformRelOptions((Datum) 0, stmt->options, true, false);
reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
true, false);
(void) heap_reloptions(relkind, reloptions, true);
@@ -2572,7 +2574,7 @@ ATRewriteCatalogs(List **wqueue)
(tab->subcmds[AT_PASS_ADD_COL] ||
tab->subcmds[AT_PASS_ALTER_TYPE] ||
tab->subcmds[AT_PASS_COL_ATTRS]))
AlterTableCreateToastTable(tab->relid);
AlterTableCreateToastTable(tab->relid, (Datum) 0);
}
}
@@ -6457,6 +6459,7 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
Datum repl_val[Natts_pg_class];
bool repl_null[Natts_pg_class];
bool repl_repl[Natts_pg_class];
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
if (defList == NIL)
return; /* nothing to do */
@@ -6475,7 +6478,7 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
/* Generate new proposed reloptions (text array) */
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
defList, false, isReset);
defList, NULL, validnsps, false, isReset);
/* Validate */
switch (rel->rd_rel->relkind)
@@ -6521,6 +6524,53 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
ReleaseSysCache(tuple);
/* repeat the whole exercise for the toast table, if there's one */
if (OidIsValid(rel->rd_rel->reltoastrelid))
{
Relation toastrel;
Oid toastid = rel->rd_rel->reltoastrelid;
toastrel = heap_open(toastid, AccessExclusiveLock);
/* Get the old reloptions */
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(toastid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", toastid);
datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
defList, "toast", validnsps, false, isReset);
(void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
memset(repl_val, 0, sizeof(repl_val));
memset(repl_null, false, sizeof(repl_null));
memset(repl_repl, false, sizeof(repl_repl));
if (newOptions != (Datum) 0)
repl_val[Anum_pg_class_reloptions - 1] = newOptions;
else
repl_null[Anum_pg_class_reloptions - 1] = true;
repl_repl[Anum_pg_class_reloptions - 1] = true;
newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
repl_val, repl_null, repl_repl);
simple_heap_update(pgclass, &newtuple->t_self, newtuple);
CatalogUpdateIndexes(pgclass, newtuple);
heap_freetuple(newtuple);
ReleaseSysCache(tuple);
heap_close(toastrel, NoLock);
}
heap_close(pgclass, RowExclusiveLock);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.130 2009/01/09 15:46:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.131 2009/02/02 19:31:39 alvherre Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1491,7 +1491,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->tableElts = coldeflist;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
createStmt->options = list_make1(defWithOids(false));
createStmt->options = list_make1(reloptWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.113 2009/01/27 12:40:15 petere Exp $
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.114 2009/02/02 19:31:39 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
@@ -229,7 +229,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->tableElts = attrList;
createStmt->inhRelations = NIL;
createStmt->constraints = NIL;
createStmt->options = list_make1(defWithOids(false));
createStmt->options = list_make1(reloptWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL;