diff options
author | Alvaro Herrera | 2009-02-02 19:31:40 +0000 |
---|---|---|
committer | Alvaro Herrera | 2009-02-02 19:31:40 +0000 |
commit | 3a5b77371522b64feda006a7aed2a0e57bfb2b22 (patch) | |
tree | 2a3660571ea184c8e40a78608839914af4f2bb27 | |
parent | 80f95a6500d7f5762e4701c80eb202c3fce9095f (diff) |
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.
27 files changed, 452 insertions, 127 deletions
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 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.69 2008/11/14 10:22:46 petere Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.70 2009/02/02 19:31:38 alvherre Exp $ PostgreSQL documentation --> @@ -231,7 +231,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re <listitem> <para> The name of an index-method-specific storage parameter. See - below for details. + <xref linkend="sql-createindex-storage-parameters" endterm="sql-createindex-storage-parameters-title"> + for details. </para> </listitem> </varlistentry> @@ -265,7 +266,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re <para> The <literal>WITH</> clause can specify <firstterm>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 <literal>B-tree</literal>, <literal>hash</literal> and + <literal>GiST</literal> built-in index methods all accept a single parameter: </para> <variablelist> 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 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.111 2008/11/14 10:22:46 petere Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.112 2009/02/02 19:31:38 alvherre Exp $ PostgreSQL documentation --> @@ -690,8 +690,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: for tables, and for indexes associated with a <literal>UNIQUE</literal> or <literal>PRIMARY KEY</literal> constraint. Storage parameters for indexes are documented in <xref linkend="SQL-CREATEINDEX" - endterm="sql-createindex-title">. The only storage parameter currently - available for tables is: + endterm="sql-createindex-title">. The storage parameters currently + available for tables are: </para> <variablelist> @@ -714,6 +714,16 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is: </listitem> </varlistentry> + <varlistentry> + <term><literal>TOAST.FILLFACTOR</literal></term> + <listitem> + <para> + Same as above, for the supplementary storage table, if any; see + <xref linkend="storage-toast">. + </para> + </listitem> + </varlistentry> + </variablelist> </refsect2> 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,20 +77,29 @@ 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. */ double @@ -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,12 +165,20 @@ 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. */ int64 @@ -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 $ * *------------------------------------------------------------------------- */ @@ -2099,6 +2099,16 @@ _equalOptionDefElem(OptionDefElem *a, OptionDefElem *b) } 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) { COMPARE_NODE_FIELD(lockedRels); @@ -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* @@ -1805,6 +1805,16 @@ _outDefElem(StringInfo str, DefElem *node) } 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) { WRITE_NODE_TYPE("LOCKINGCLAUSE"); @@ -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 <list> 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 <node> TableElement ConstraintElem TableFuncElement %type <node> columnDef %type <defelt> def_elem old_aggr_elem +%type <reloptel> reloption_elem %type <node> 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 <name> SET (...) */ - | SET definition + | SET reloptions { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetRelOptions; @@ -1789,7 +1792,7 @@ alter_table_cmd: $$ = (Node *)n; } /* ALTER TABLE <name> 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 $ * *------------------------------------------------------------------------- */ @@ -533,6 +533,17 @@ typedef struct OptionDefElem } 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 * * Note: lockedRels == NIL means "all relations in query". Otherwise it |