Skip to content

Commit 3a5b773

Browse files
committed
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.
1 parent 80f95a6 commit 3a5b773

File tree

27 files changed

+452
-127
lines changed

27 files changed

+452
-127
lines changed

doc/src/sgml/ref/create_index.sgml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.69 2008/11/14 10:22:46 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.70 2009/02/02 19:31:38 alvherre Exp $
33
PostgreSQL documentation
44
-->
55

@@ -231,7 +231,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
231231
<listitem>
232232
<para>
233233
The name of an index-method-specific storage parameter. See
234-
below for details.
234+
<xref linkend="sql-createindex-storage-parameters" endterm="sql-createindex-storage-parameters-title">
235+
for details.
235236
</para>
236237
</listitem>
237238
</varlistentry>
@@ -265,7 +266,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
265266
<para>
266267
The <literal>WITH</> clause can specify <firstterm>storage parameters</>
267268
for indexes. Each index method can have its own set of allowed storage
268-
parameters. The built-in index methods all accept a single parameter:
269+
parameters. The <literal>B-tree</literal>, <literal>hash</literal> and
270+
<literal>GiST</literal> built-in index methods all accept a single parameter:
269271
</para>
270272

271273
<variablelist>

doc/src/sgml/ref/create_table.sgml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.111 2008/11/14 10:22:46 petere Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.112 2009/02/02 19:31:38 alvherre Exp $
33
PostgreSQL documentation
44
-->
55

@@ -690,8 +690,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
690690
for tables, and for indexes associated with a <literal>UNIQUE</literal> or
691691
<literal>PRIMARY KEY</literal> constraint. Storage parameters for
692692
indexes are documented in <xref linkend="SQL-CREATEINDEX"
693-
endterm="sql-createindex-title">. The only storage parameter currently
694-
available for tables is:
693+
endterm="sql-createindex-title">. The storage parameters currently
694+
available for tables are:
695695
</para>
696696

697697
<variablelist>
@@ -714,6 +714,16 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
714714
</listitem>
715715
</varlistentry>
716716

717+
<varlistentry>
718+
<term><literal>TOAST.FILLFACTOR</literal></term>
719+
<listitem>
720+
<para>
721+
Same as above, for the supplementary storage table, if any; see
722+
<xref linkend="storage-toast">.
723+
</para>
724+
</listitem>
725+
</varlistentry>
726+
717727
</variablelist>
718728

719729
</refsect2>

src/backend/access/common/reloptions.c

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.19 2009/01/26 19:41:06 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.20 2009/02/02 19:31:38 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -390,8 +390,10 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
390390
}
391391

392392
/*
393-
* Transform a relation options list (list of DefElem) into the text array
394-
* format that is kept in pg_class.reloptions.
393+
* Transform a relation options list (list of ReloptElem) into the text array
394+
* format that is kept in pg_class.reloptions, including only those options
395+
* that are in the passed namespace. The output values do not include the
396+
* namespace.
395397
*
396398
* This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and
397399
* 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,
402404
* in the list (it will be or has been handled by interpretOidsOption()).
403405
*
404406
* Note that this is not responsible for determining whether the options
405-
* are valid.
407+
* are valid, but it does check that namespaces for all the options given are
408+
* listed in validnsps. The NULL namespace is always valid and needs not be
409+
* explicitely listed. Passing a NULL pointer means that only the NULL
410+
* namespace is valid.
406411
*
407412
* Both oldOptions and the result are text arrays (or NULL for "default"),
408413
* but we declare them as Datums to avoid including array.h in reloptions.h.
409414
*/
410415
Datum
411-
transformRelOptions(Datum oldOptions, List *defList,
412-
bool ignoreOids, bool isReset)
416+
transformRelOptions(Datum oldOptions, List *defList, char *namspace,
417+
char *validnsps[], bool ignoreOids, bool isReset)
413418
{
414419
Datum result;
415420
ArrayBuildState *astate;
@@ -444,11 +449,23 @@ transformRelOptions(Datum oldOptions, List *defList,
444449
/* Search for a match in defList */
445450
foreach(cell, defList)
446451
{
447-
DefElem *def = lfirst(cell);
448-
int kw_len = strlen(def->defname);
452+
ReloptElem *def = lfirst(cell);
453+
int kw_len;
449454

455+
/* ignore if not in the same namespace */
456+
if (namspace == NULL)
457+
{
458+
if (def->nmspc != NULL)
459+
continue;
460+
}
461+
else if (def->nmspc == NULL)
462+
continue;
463+
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
464+
continue;
465+
466+
kw_len = strlen(def->optname);
450467
if (text_len > kw_len && text_str[kw_len] == '=' &&
451-
pg_strncasecmp(text_str, def->defname, kw_len) == 0)
468+
pg_strncasecmp(text_str, def->optname, kw_len) == 0)
452469
break;
453470
}
454471
if (!cell)
@@ -468,7 +485,8 @@ transformRelOptions(Datum oldOptions, List *defList,
468485
*/
469486
foreach(cell, defList)
470487
{
471-
DefElem *def = lfirst(cell);
488+
ReloptElem *def = lfirst(cell);
489+
472490

473491
if (isReset)
474492
{
@@ -483,22 +501,62 @@ transformRelOptions(Datum oldOptions, List *defList,
483501
const char *value;
484502
Size len;
485503

486-
if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
504+
/*
505+
* Error out if the namespace is not valid. A NULL namespace
506+
* is always valid.
507+
*/
508+
if (def->nmspc != NULL)
509+
{
510+
bool valid = false;
511+
int i;
512+
513+
if (validnsps)
514+
{
515+
for (i = 0; validnsps[i]; i++)
516+
{
517+
if (pg_strcasecmp(def->nmspc, validnsps[i]) == 0)
518+
{
519+
valid = true;
520+
break;
521+
}
522+
}
523+
}
524+
525+
if (!valid)
526+
ereport(ERROR,
527+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
528+
errmsg("unrecognized parameter namespace \"%s\"",
529+
def->nmspc)));
530+
}
531+
532+
if (ignoreOids && pg_strcasecmp(def->optname, "oids") == 0)
533+
continue;
534+
535+
/* ignore if not in the same namespace */
536+
if (namspace == NULL)
537+
{
538+
if (def->nmspc != NULL)
539+
continue;
540+
}
541+
else if (def->nmspc == NULL)
542+
continue;
543+
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
487544
continue;
488545

489546
/*
490-
* Flatten the DefElem into a text string like "name=arg". If we
491-
* have just "name", assume "name=true" is meant.
547+
* Flatten the ReloptElem into a text string like "name=arg". If we
548+
* have just "name", assume "name=true" is meant. Note: the
549+
* namespace is not output.
492550
*/
493551
if (def->arg != NULL)
494-
value = defGetString(def);
552+
value = reloptGetString(def);
495553
else
496554
value = "true";
497-
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
555+
len = VARHDRSZ + strlen(def->optname) + 1 + strlen(value);
498556
/* +1 leaves room for sprintf's trailing null */
499557
t = (text *) palloc(len + 1);
500558
SET_VARSIZE(t, len);
501-
sprintf(VARDATA(t), "%s=%s", def->defname, value);
559+
sprintf(VARDATA(t), "%s=%s", def->optname, value);
502560

503561
astate = accumArrayResult(astate, PointerGetDatum(t),
504562
false, TEXTOID,
@@ -944,7 +1002,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
9441002
}
9451003

9461004
/*
947-
* Parse options for heaps (and perhaps someday toast tables).
1005+
* Parse options for heaps and toast tables.
9481006
*/
9491007
bytea *
9501008
heap_reloptions(char relkind, Datum reloptions, bool validate)

src/backend/catalog/toasting.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.12 2009/01/01 17:23:37 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.13 2009/02/02 19:31:38 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -32,7 +32,8 @@
3232
#include "utils/syscache.h"
3333

3434

35-
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid);
35+
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
36+
Datum reloptions);
3637
static bool needs_toast_table(Relation rel);
3738

3839

@@ -46,7 +47,7 @@ static bool needs_toast_table(Relation rel);
4647
* to end with CommandCounterIncrement if it makes any changes.
4748
*/
4849
void
49-
AlterTableCreateToastTable(Oid relOid)
50+
AlterTableCreateToastTable(Oid relOid, Datum reloptions)
5051
{
5152
Relation rel;
5253

@@ -58,7 +59,7 @@ AlterTableCreateToastTable(Oid relOid)
5859
rel = heap_open(relOid, AccessExclusiveLock);
5960

6061
/* create_toast_table does all the work */
61-
(void) create_toast_table(rel, InvalidOid, InvalidOid);
62+
(void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions);
6263

6364
heap_close(rel, NoLock);
6465
}
@@ -84,7 +85,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
8485
relName)));
8586

8687
/* create_toast_table does all the work */
87-
if (!create_toast_table(rel, toastOid, toastIndexOid))
88+
if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0))
8889
elog(ERROR, "\"%s\" does not require a toast table",
8990
relName);
9091

@@ -100,7 +101,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
100101
* bootstrap they can be nonzero to specify hand-assigned OIDs
101102
*/
102103
static bool
103-
create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
104+
create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptions)
104105
{
105106
Oid relOid = RelationGetRelid(rel);
106107
HeapTuple reltup;
@@ -183,10 +184,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
183184
else
184185
namespaceid = PG_TOAST_NAMESPACE;
185186

186-
/*
187-
* XXX would it make sense to apply the master's reloptions to the toast
188-
* table? Or maybe some toast-specific reloptions?
189-
*/
190187
toast_relid = heap_create_with_catalog(toast_relname,
191188
namespaceid,
192189
rel->rd_rel->reltablespace,
@@ -199,7 +196,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
199196
true,
200197
0,
201198
ONCOMMIT_NOOP,
202-
(Datum) 0,
199+
reloptions,
203200
true);
204201

205202
/* make the toast relation visible, else index creation will fail */

src/backend/commands/cluster.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.181 2009/01/16 13:27:23 heikki Exp $
14+
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.182 2009/02/02 19:31:38 alvherre Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -668,6 +668,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
668668
TupleDesc OldHeapDesc,
669669
tupdesc;
670670
Oid OIDNewHeap;
671+
Oid toastid;
671672
Relation OldHeap;
672673
HeapTuple tuple;
673674
Datum reloptions;
@@ -726,7 +727,24 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
726727
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
727728
* the TOAST table will be visible for insertion.
728729
*/
729-
AlterTableCreateToastTable(OIDNewHeap);
730+
toastid = OldHeap->rd_rel->reltoastrelid;
731+
reloptions = (Datum) 0;
732+
if (OidIsValid(toastid))
733+
{
734+
tuple = SearchSysCache(RELOID,
735+
ObjectIdGetDatum(toastid),
736+
0, 0, 0);
737+
if (!HeapTupleIsValid(tuple))
738+
elog(ERROR, "cache lookup failed for relation %u", toastid);
739+
reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
740+
&isNull);
741+
if (isNull)
742+
reloptions = (Datum) 0;
743+
}
744+
AlterTableCreateToastTable(OIDNewHeap, reloptions);
745+
746+
if (OidIsValid(toastid))
747+
ReleaseSysCache(tuple);
730748

731749
heap_close(OldHeap, NoLock);
732750

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy