From: Alvaro Herrera Date: Mon, 2 Feb 2009 19:31:40 +0000 (+0000) Subject: Allow reloption names to have qualifiers, initially supporting a TOAST X-Git-Tag: REL8_4_BETA1~317 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a5b77371522b64feda006a7aed2a0e57bfb2b22;p=postgresql 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. --- diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index b387da49f0..3596b5df28 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -1,5 +1,5 @@ @@ -231,7 +231,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name The name of an index-method-specific storage parameter. See - below for details. + + for details. @@ -265,7 +266,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name The WITH clause can specify storage parameters for indexes. Each index method can have its own set of allowed storage - parameters. The built-in index methods all accept a single parameter: + parameters. The B-tree, hash and + GiST built-in index methods all accept a single parameter: diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e7d14a53ce..285ed5bd2e 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1,5 +1,5 @@ @@ -690,8 +690,8 @@ and table_constraint is: for tables, and for indexes associated with a UNIQUE or PRIMARY KEY constraint. Storage parameters for indexes are documented in . The only storage parameter currently - available for tables is: + endterm="sql-createindex-title">. The storage parameters currently + available for tables are: @@ -714,6 +714,16 @@ and table_constraint is: + + TOAST.FILLFACTOR + + + Same as above, for the supplementary storage table, if any; see + . + + + + diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 105514be9d..e566a13644 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -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) diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 3809c0f1b8..7510f96b47 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.12 2009/01/01 17:23:37 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.13 2009/02/02 19:31:38 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,8 @@ #include "utils/syscache.h" -static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid); +static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, + Datum reloptions); static bool needs_toast_table(Relation rel); @@ -46,7 +47,7 @@ static bool needs_toast_table(Relation rel); * to end with CommandCounterIncrement if it makes any changes. */ void -AlterTableCreateToastTable(Oid relOid) +AlterTableCreateToastTable(Oid relOid, Datum reloptions) { Relation rel; @@ -58,7 +59,7 @@ AlterTableCreateToastTable(Oid relOid) rel = heap_open(relOid, AccessExclusiveLock); /* create_toast_table does all the work */ - (void) create_toast_table(rel, InvalidOid, InvalidOid); + (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions); heap_close(rel, NoLock); } @@ -84,7 +85,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) relName))); /* create_toast_table does all the work */ - if (!create_toast_table(rel, toastOid, toastIndexOid)) + if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0)) elog(ERROR, "\"%s\" does not require a toast table", relName); @@ -100,7 +101,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) * bootstrap they can be nonzero to specify hand-assigned OIDs */ static bool -create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid) +create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptions) { Oid relOid = RelationGetRelid(rel); HeapTuple reltup; @@ -183,10 +184,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid) else namespaceid = PG_TOAST_NAMESPACE; - /* - * XXX would it make sense to apply the master's reloptions to the toast - * table? Or maybe some toast-specific reloptions? - */ toast_relid = heap_create_with_catalog(toast_relname, namespaceid, rel->rd_rel->reltablespace, @@ -199,7 +196,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid) true, 0, ONCOMMIT_NOOP, - (Datum) 0, + reloptions, true); /* make the toast relation visible, else index creation will fail */ diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index e5bff5cb3e..6f578440da 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -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); diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 77f7d8bfdb..c5e2a13d95 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -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 */ } + +/* + * 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 DefElem setting "oids" to the specified value. + * Create a ReloptElem setting "oids" to the specified value. */ -DefElem * -defWithOids(bool value) +ReloptElem * +reloptWithOids(bool value) { - DefElem *f = makeNode(DefElem); + ReloptElem *f = makeNode(ReloptElem); - f->defname = "oids"; + f->optname = "oids"; + f->nmspc = NULL; f->arg = (Node *) makeInteger(value); return f; } diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 55422e8b31..b0cd2ef0d1 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -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); diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index d68f525ba0..deeed23078 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -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; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 397e010aca..cda87e28b3 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -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); } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 1bd0ef2cd1..ca87b15068 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -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; diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 909c6a8865..4d8717d251 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -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; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 0352d9a5e4..41b6737049 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.321 2009/01/22 20:16:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.322 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -2832,6 +2832,7 @@ OpenIntoRel(QueryDesc *queryDesc) Oid intoRelationId; TupleDesc tupdesc; DR_intorel *myState; + static char *validnsps[] = HEAP_RELOPT_NAMESPACES; Assert(into); @@ -2890,6 +2891,8 @@ OpenIntoRel(QueryDesc *queryDesc) /* Parse and validate any reloptions */ reloptions = transformRelOptions((Datum) 0, into->options, + NULL, + validnsps, true, false); (void) heap_reloptions(RELKIND_RELATION, reloptions, true); @@ -2926,7 +2929,16 @@ OpenIntoRel(QueryDesc *queryDesc) * AlterTableCreateToastTable ends with CommandCounterIncrement(), so that * the TOAST table will be visible for insertion. */ - AlterTableCreateToastTable(intoRelationId); + reloptions = transformRelOptions((Datum) 0, + into->options, + "toast", + validnsps, + true, + false); + + (void) heap_reloptions(RELKIND_TOASTVALUE, reloptions, true); + + AlterTableCreateToastTable(intoRelationId, reloptions); /* * And open the constructed table for writing. diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 06f89b16a3..de57c874e9 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.421 2009/01/22 20:16:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.422 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -2125,6 +2125,18 @@ _copyOptionDefElem(OptionDefElem *from) return newnode; } +static ReloptElem * +_copyReloptElem(ReloptElem *from) +{ + ReloptElem *newnode = makeNode(ReloptElem); + + COPY_STRING_FIELD(optname); + COPY_STRING_FIELD(nmspc); + COPY_NODE_FIELD(arg); + + return newnode; +} + static LockingClause * _copyLockingClause(LockingClause *from) { @@ -4079,6 +4091,9 @@ copyObject(void *from) case T_OptionDefElem: retval = _copyOptionDefElem(from); break; + case T_ReloptElem: + retval = _copyReloptElem(from); + break; case T_LockingClause: retval = _copyLockingClause(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 4e101dd23b..2b8b542e74 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -22,7 +22,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.346 2009/01/22 20:16:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.347 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -2098,6 +2098,16 @@ _equalOptionDefElem(OptionDefElem *a, OptionDefElem *b) return true; } +static bool +_equalReloptElem(ReloptElem *a, ReloptElem *b) +{ + COMPARE_STRING_FIELD(nmspc); + COMPARE_STRING_FIELD(optname); + COMPARE_NODE_FIELD(arg); + + return true; +} + static bool _equalLockingClause(LockingClause *a, LockingClause *b) { @@ -2855,6 +2865,9 @@ equal(void *a, void *b) case T_OptionDefElem: retval = _equalOptionDefElem(a, b); break; + case T_ReloptElem: + retval = _equalReloptElem(a, b); + break; case T_LockingClause: retval = _equalLockingClause(a, b); break; diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 3bbb2a38a8..39d7e20f83 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.62 2009/01/01 17:23:43 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.63 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -374,3 +374,14 @@ makeOptionDefElem(int op, DefElem *def) res->def = def; return res; } + +ReloptElem * +makeReloptElem(char *name, char *nmspc, Node *arg) +{ + ReloptElem *res = makeNode(ReloptElem); + + res->optname = name; + res->nmspc = nmspc; + res->arg = arg; + return res; +} diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 0efd84dae8..74df2f3061 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.350 2009/01/22 20:16:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.351 2009/02/02 19:31:39 alvherre Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -1804,6 +1804,16 @@ _outDefElem(StringInfo str, DefElem *node) WRITE_NODE_FIELD(arg); } +static void +_outReloptElem(StringInfo str, ReloptElem *node) +{ + WRITE_NODE_TYPE("RELOPTELEM"); + + WRITE_STRING_FIELD(nmspc); + WRITE_STRING_FIELD(optname); + WRITE_NODE_FIELD(arg); +} + static void _outLockingClause(StringInfo str, LockingClause *node) { @@ -2770,6 +2780,9 @@ _outNode(StringInfo str, void *obj) case T_DefElem: _outDefElem(str, obj); break; + case T_ReloptElem: + _outReloptElem(str, obj); + break; case T_LockingClause: _outLockingClause(str, obj); break; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7f9e5e5b98..1bf99765f8 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.656 2009/01/22 20:16:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.657 2009/02/02 19:31:39 alvherre Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -164,6 +164,7 @@ static TypeName *TableFuncTypeName(List *columns); FuncWithArgs *funwithargs; DefElem *defelt; OptionDefElem *optdef; + ReloptElem *reloptel; SortBy *sortby; WindowDef *windef; JoinExpr *jexpr; @@ -271,6 +272,7 @@ static TypeName *TableFuncTypeName(List *columns); %type stmtblock stmtmulti OptTableElementList TableElementList OptInherit definition + reloptions opt_reloptions OptWith opt_distinct opt_definition func_args func_args_list func_args_with_defaults func_args_with_defaults_list func_as createfunc_opt_list alterfunc_opt_list @@ -284,7 +286,7 @@ static TypeName *TableFuncTypeName(List *columns); target_list insert_column_list set_target_list set_clause_list set_clause multiple_set_clause ctext_expr_list ctext_row def_list indirection opt_indirection - group_clause TriggerFuncArgs select_limit + reloption_list group_clause TriggerFuncArgs select_limit opt_select_limit opclass_item_list opclass_drop_list opt_opfamily transaction_mode_list_or_empty TableFuncElementList opt_type_modifiers @@ -342,6 +344,7 @@ static TypeName *TableFuncTypeName(List *columns); %type TableElement ConstraintElem TableFuncElement %type columnDef %type def_elem old_aggr_elem +%type reloption_elem %type def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr func_expr AexprConst indirection_el columnref in_expr having_clause func_table array_expr @@ -1781,7 +1784,7 @@ alter_table_cmd: $$ = (Node *)n; } /* ALTER TABLE SET (...) */ - | SET definition + | SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetRelOptions; @@ -1789,7 +1792,7 @@ alter_table_cmd: $$ = (Node *)n; } /* ALTER TABLE RESET (...) */ - | RESET definition + | RESET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ResetRelOptions; @@ -1814,6 +1817,37 @@ alter_using: | /* EMPTY */ { $$ = NULL; } ; +reloptions: + '(' reloption_list ')' { $$ = $2; } + ; + +opt_reloptions: WITH reloptions { $$ = $2; } + | /* EMPTY */ { $$ = NIL; } + ; + +reloption_list: + reloption_elem { $$ = list_make1($1); } + | reloption_list ',' reloption_elem { $$ = lappend($1, $3); } + ; + +reloption_elem: + ColLabel '=' def_arg + { + $$ = makeReloptElem($1, NULL, (Node *) $3); + } + | ColLabel + { + $$ = makeReloptElem($1, NULL, NULL); + } + | ColLabel '.' ColLabel '=' def_arg + { + $$ = makeReloptElem($3, $1, (Node *) $5); + } + | ColLabel '.' ColLabel + { + $$ = makeReloptElem($3, $1, NULL); + } + ; /***************************************************************************** @@ -2440,9 +2474,9 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; } /* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */ OptWith: - WITH definition { $$ = $2; } - | WITH OIDS { $$ = list_make1(defWithOids(true)); } - | WITHOUT OIDS { $$ = list_make1(defWithOids(false)); } + WITH reloptions { $$ = $2; } + | WITH OIDS { $$ = list_make1(reloptWithOids(true)); } + | WITHOUT OIDS { $$ = list_make1(reloptWithOids(false)); } | /*EMPTY*/ { $$ = NIL; } ; @@ -4473,7 +4507,7 @@ opt_granted_by: GRANTED BY RoleId { $$ = $3; } IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name access_method_clause '(' index_params ')' - opt_definition OptTableSpace where_clause + opt_reloptions OptTableSpace where_clause { IndexStmt *n = makeNode(IndexStmt); n->unique = $2; @@ -4489,7 +4523,7 @@ IndexStmt: CREATE index_opt_unique INDEX index_name } | CREATE index_opt_unique INDEX CONCURRENTLY index_name ON qualified_name access_method_clause '(' index_params ')' - opt_definition OptTableSpace where_clause + opt_reloptions OptTableSpace where_clause { IndexStmt *n = makeNode(IndexStmt); n->unique = $2; diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 7e9fb9c071..24b9ee22c7 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.186 2009/01/22 20:16:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.187 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -233,7 +233,7 @@ interpretInhOption(InhOption inhOpt) } /* - * Given a relation-options list (of DefElems), return true iff the specified + * Given a relation-options list (of ReloptElems), return true iff the specified * table/result set should be created with OIDs. This needs to be done after * parsing the query string because the return value can depend upon the * default_with_oids GUC var. @@ -246,10 +246,10 @@ interpretOidsOption(List *defList) /* Scan list to see if OIDS was included */ foreach(cell, defList) { - DefElem *def = (DefElem *) lfirst(cell); + ReloptElem *def = (ReloptElem *) lfirst(cell); - if (pg_strcasecmp(def->defname, "oids") == 0) - return defGetBoolean(def); + if (pg_strcasecmp(def->optname, "oids") == 0) + return reloptGetBoolean(def); } /* OIDS option was not specified, so use default. */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 7e7d07e4f0..6c6b13e17e 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,12 +10,13 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.305 2009/01/22 20:16:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.306 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/reloptions.h" #include "access/twophase.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -422,6 +423,9 @@ ProcessUtility(Node *parsetree, if (IsA(stmt, CreateStmt)) { + Datum toast_options; + static char *validnsps[] = HEAP_RELOPT_NAMESPACES; + /* Create the table itself */ relOid = DefineRelation((CreateStmt *) stmt, RELKIND_RELATION); @@ -431,7 +435,17 @@ ProcessUtility(Node *parsetree, * needs a secondary relation too. */ CommandCounterIncrement(); - AlterTableCreateToastTable(relOid); + + /* parse and validate reloptions for the toast table */ + toast_options = transformRelOptions((Datum) 0, + ((CreateStmt *)stmt)->options, + "toast", + validnsps, + true, false); + (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, + true); + + AlterTableCreateToastTable(relOid, toast_options); } else { diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index cb6ae92a38..6f057f2a33 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.517 2009/01/27 12:40:15 petere Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.518 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -3100,6 +3100,7 @@ getTables(int *numTables) int i_owning_col; int i_reltablespace; int i_reloptions; + int i_toastreloptions; /* Make sure we are in proper schema */ selectSourceSchema("pg_catalog"); @@ -3131,22 +3132,24 @@ getTables(int *numTables) * owning column, if any (note this dependency is AUTO as of 8.2) */ appendPQExpBuffer(query, - "SELECT c.tableoid, c.oid, relname, " - "relacl, relkind, relnamespace, " - "(%s relowner) as rolname, " - "relchecks, relhastriggers, " - "relhasindex, relhasrules, relhasoids, " + "SELECT c.tableoid, c.oid, c.relname, " + "c.relacl, c.relkind, c.relnamespace, " + "(%s c.relowner) as rolname, " + "c.relchecks, c.relhastriggers, " + "c.relhasindex, c.relhasrules, c.relhasoids, " "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " - "array_to_string(c.reloptions, ', ') as reloptions " + "array_to_string(c.reloptions, ', ') as reloptions, " + "array_to_string(array(select 'toast.' || x from unnest(tc.reloptions) x), ', ') as toast_reloptions " "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " "d.classid = c.tableoid and d.objid = c.oid and " "d.objsubid = 0 and " "d.refclassid = c.tableoid and d.deptype = 'a') " - "where relkind in ('%c', '%c', '%c', '%c') " + "left join pg_class tc on (c.reltoastrelid = tc.oid) " + "where c.relkind in ('%c', '%c', '%c', '%c') " "order by c.oid", username_subquery, RELKIND_SEQUENCE, @@ -3168,7 +3171,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " - "array_to_string(c.reloptions, ', ') as reloptions " + "array_to_string(c.reloptions, ', ') as reloptions, " + "NULL as toast_reloptions " "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " @@ -3197,7 +3201,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, " - "NULL as reloptions " + "NULL as reloptions, " + "NULL as toast_reloptions " "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " @@ -3226,7 +3231,8 @@ getTables(int *numTables) "d.refobjid as owning_tab, " "d.refobjsubid as owning_col, " "NULL as reltablespace, " - "NULL as reloptions " + "NULL as reloptions, " + "NULL as toast_reloptions " "from pg_class c " "left join pg_depend d on " "(c.relkind = '%c' and " @@ -3251,7 +3257,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " - "NULL as reloptions " + "NULL as reloptions, " + "NULL as toast_reloptions " "from pg_class " "where relkind in ('%c', '%c', '%c') " "order by oid", @@ -3271,7 +3278,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " - "NULL as reloptions " + "NULL as reloptions, " + "NULL as toast_reloptions " "from pg_class " "where relkind in ('%c', '%c', '%c') " "order by oid", @@ -3301,7 +3309,8 @@ getTables(int *numTables) "NULL::oid as owning_tab, " "NULL::int4 as owning_col, " "NULL as reltablespace, " - "NULL as reloptions " + "NULL as reloptions, " + "NULL as toast_reloptions " "from pg_class c " "where relkind in ('%c', '%c') " "order by oid", @@ -3344,6 +3353,7 @@ getTables(int *numTables) i_owning_col = PQfnumber(res, "owning_col"); i_reltablespace = PQfnumber(res, "reltablespace"); i_reloptions = PQfnumber(res, "reloptions"); + i_toastreloptions = PQfnumber(res, "toast_reloptions"); if (lockWaitTimeout && g_fout->remoteVersion >= 70300) { @@ -3389,6 +3399,7 @@ getTables(int *numTables) } tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace)); tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions)); + tblinfo[i].toast_reloptions = strdup(PQgetvalue(res, i, i_toastreloptions)); /* other fields were zeroed above */ @@ -9700,8 +9711,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) appendPQExpBuffer(q, ")"); } - if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) - appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions); + if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) || + (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)) + { + bool addcomma = false; + + appendPQExpBuffer(q, "\nWITH ("); + if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) + { + addcomma = true; + appendPQExpBuffer(q, "%s", tbinfo->reloptions); + } + if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0) + { + appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "", + tbinfo->toast_reloptions); + } + appendPQExpBuffer(q, ")"); + } appendPQExpBuffer(q, ";\n"); diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 2f70c70428..f18703ca85 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.149 2009/01/27 12:40:15 petere Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.150 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -221,6 +221,7 @@ typedef struct _tableInfo char relkind; char *reltablespace; /* relation tablespace */ char *reloptions; /* options specified by WITH (...) */ + char *toast_reloptions; /* ditto, for the TOAST table */ bool hasindex; /* does it have any indexes? */ bool hasrules; /* does it have any rules? */ bool hastriggers; /* does it have any triggers? */ diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index 1c23b3f004..7c02f3b12b 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -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.11 2009/01/26 19:41:06 alvherre Exp $ + * $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.12 2009/02/02 19:31:39 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -44,6 +44,9 @@ typedef enum relopt_kind RELOPT_KIND_MAX = 255 } relopt_kind; +/* reloption namespaces allowed for heaps -- currently only TOAST */ +#define HEAP_RELOPT_NAMESPACES { "toast", NULL } + /* generic struct to hold shared data */ typedef struct relopt_gen { @@ -240,6 +243,7 @@ extern void add_string_reloption(int kind, char *name, char *desc, char *default_val, validate_string_relopt validator); extern Datum transformRelOptions(Datum oldOptions, List *defList, + char *namspace, char *validnsps[], bool ignoreOids, bool isReset); extern List *untransformRelOptions(Datum options); extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 541bfb7dbc..2d5eb61d29 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.5 2009/01/01 17:23:58 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.6 2009/02/02 19:31:40 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ /* * toasting.c prototypes */ -extern void AlterTableCreateToastTable(Oid relOid); +extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index c8701402ca..7fba58bef8 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.92 2009/01/01 17:23:58 momjian Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.93 2009/02/02 19:31:40 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -145,6 +145,8 @@ extern int64 defGetInt64(DefElem *def); extern List *defGetQualifiedName(DefElem *def); extern TypeName *defGetTypeName(DefElem *def); extern int defGetTypeLength(DefElem *def); -extern DefElem *defWithOids(bool value); +extern char *reloptGetString(ReloptElem *relopt); +extern bool reloptGetBoolean(ReloptElem *relopt); +extern ReloptElem *reloptWithOids(bool value); #endif /* DEFREM_H */ diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index e497953d4c..64c3c739f0 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.65 2009/01/01 17:24:00 momjian Exp $ + * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.66 2009/02/02 19:31:40 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -69,4 +69,6 @@ extern DefElem *makeDefElem(char *name, Node *arg); extern OptionDefElem *makeOptionDefElem(int op, DefElem *def); +extern ReloptElem *makeReloptElem(char *name, char *namspc, Node *arg); + #endif /* MAKEFUNC_H */ diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 91efce9462..31881976bd 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.219 2009/01/22 20:16:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.220 2009/02/02 19:31:40 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -363,6 +363,7 @@ typedef enum NodeTag T_Constraint, T_DefElem, T_OptionDefElem, + T_ReloptElem, T_RangeTblEntry, T_SortGroupClause, T_WindowClause, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b73e9f2cda..7523982662 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.389 2009/01/22 20:16:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.390 2009/02/02 19:31:40 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -532,6 +532,17 @@ typedef struct OptionDefElem DefElem *def; /* The actual definition */ } OptionDefElem; +/* + * Reloption definition. As DefElem, with optional option namespace. + */ +typedef struct ReloptElem +{ + NodeTag type; + char *nmspc; + char *optname; + Node *arg; +} ReloptElem; + /* * LockingClause - raw representation of FOR UPDATE/SHARE options *