Skip to content
Snippets Groups Projects
Commit 1c855f01 authored by Alvaro Herrera's avatar Alvaro Herrera
Browse files

Disallow setting fillfactor for TOAST tables.

To implement this without almost duplicating the reloption table, treat
relopt_kind as a bitmask instead of an integer value.  This decreases the
range of allowed values, but it's not clear that there's need for that much
values anyway.

This patch also makes heap_reloptions explicitly a no-op for relation kinds
other than heap and TOAST tables.

Patch by ITAGAKI Takahiro with minor edits from me.  (In particular I removed
the bit about adding relation kind to an error message, which I intend to
commit separately.)
parent 591f2944
No related branches found
No related tags found
No related merge requests found
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.24 2009/03/24 20:17:09 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.25 2009/04/04 00:45:02 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -52,7 +52,7 @@ static relopt_bool boolRelOpts[] =
{
"autovacuum_enabled",
"Enables autovacuum in this relation",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
true
},
......@@ -106,7 +106,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_vacuum_threshold",
"Minimum number of tuple updates or deletes prior to vacuum",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
50, 0, INT_MAX
},
......@@ -114,7 +114,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_analyze_threshold",
"Minimum number of tuple inserts, updates or deletes prior to analyze",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
50, 0, INT_MAX
},
......@@ -122,7 +122,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_vacuum_cost_delay",
"Vacuum cost delay in milliseconds, for autovacuum",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
20, 0, 100
},
......@@ -130,7 +130,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_vacuum_cost_limit",
"Vacuum cost amount available before napping, for autovacuum",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
200, 1, 10000
},
......@@ -138,7 +138,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_freeze_min_age",
"Minimum age at which VACUUM should freeze a table row, for autovacuum",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
100000000, 0, 1000000000
},
......@@ -146,7 +146,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_freeze_max_age",
"Age at which to autovacuum a table to prevent transaction ID wraparound",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
200000000, 100000000, 2000000000
},
......@@ -154,7 +154,7 @@ static relopt_int intRelOpts[] =
{
"autovacuum_freeze_table_age",
"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
}, 150000000, 0, 2000000000
},
/* list terminator */
......@@ -167,7 +167,7 @@ static relopt_real realRelOpts[] =
{
"autovacuum_vacuum_scale_factor",
"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
0.2, 0.0, 100.0
},
......@@ -175,7 +175,7 @@ static relopt_real realRelOpts[] =
{
"autovacuum_analyze_scale_factor",
"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
RELOPT_KIND_HEAP
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
0.1, 0.0, 100.0
},
......@@ -190,7 +190,7 @@ static relopt_string stringRelOpts[] =
};
static relopt_gen **relOpts = NULL;
static int last_assigned_kind = RELOPT_KIND_LAST_DEFAULT + 1;
static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT << 1;
static int num_custom_options = 0;
static relopt_gen **custom_options = NULL;
......@@ -275,14 +275,20 @@ initialize_reloptions(void)
* Create a new relopt_kind value, to be used in custom reloptions by
* user-defined AMs.
*/
int
relopt_kind
add_reloption_kind(void)
{
relopt_kind kind;
/* don't hand out the last bit so that the wraparound check is portable */
if (last_assigned_kind >= RELOPT_KIND_MAX)
ereport(ERROR,
(errmsg("user-defined relation parameter types limit exceeded")));
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("user-defined relation parameter types limit exceeded")));
return last_assigned_kind++;
kind = (relopt_kind) last_assigned_kind;
last_assigned_kind <<= 1;
return kind;
}
/*
......@@ -325,7 +331,7 @@ add_reloption(relopt_gen *newoption)
* (for types other than string)
*/
static relopt_gen *
allocate_reloption(int kind, int type, char *name, char *desc)
allocate_reloption(bits32 kinds, int type, char *name, char *desc)
{
MemoryContext oldcxt;
size_t size;
......@@ -358,7 +364,7 @@ allocate_reloption(int kind, int type, char *name, char *desc)
newoption->desc = pstrdup(desc);
else
newoption->desc = NULL;
newoption->kind = kind;
newoption->kinds = kinds;
newoption->namelen = strlen(name);
newoption->type = type;
......@@ -372,11 +378,11 @@ allocate_reloption(int kind, int type, char *name, char *desc)
* Add a new boolean reloption
*/
void
add_bool_reloption(int kind, char *name, char *desc, bool default_val)
add_bool_reloption(bits32 kinds, char *name, char *desc, bool default_val)
{
relopt_bool *newoption;
newoption = (relopt_bool *) allocate_reloption(kind, RELOPT_TYPE_BOOL,
newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
name, desc);
newoption->default_val = default_val;
......@@ -388,12 +394,12 @@ add_bool_reloption(int kind, char *name, char *desc, bool default_val)
* Add a new integer reloption
*/
void
add_int_reloption(int kind, char *name, char *desc, int default_val,
add_int_reloption(bits32 kinds, char *name, char *desc, int default_val,
int min_val, int max_val)
{
relopt_int *newoption;
newoption = (relopt_int *) allocate_reloption(kind, RELOPT_TYPE_INT,
newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT,
name, desc);
newoption->default_val = default_val;
newoption->min = min_val;
......@@ -407,12 +413,12 @@ add_int_reloption(int kind, char *name, char *desc, int default_val,
* Add a new float reloption
*/
void
add_real_reloption(int kind, char *name, char *desc, double default_val,
add_real_reloption(bits32 kinds, char *name, char *desc, double default_val,
double min_val, double max_val)
{
relopt_real *newoption;
newoption = (relopt_real *) allocate_reloption(kind, RELOPT_TYPE_REAL,
newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL,
name, desc);
newoption->default_val = default_val;
newoption->min = min_val;
......@@ -431,7 +437,7 @@ add_real_reloption(int kind, char *name, char *desc, double default_val,
* the validation.
*/
void
add_string_reloption(int kind, char *name, char *desc, char *default_val,
add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
validate_string_relopt validator)
{
MemoryContext oldcxt;
......@@ -450,7 +456,7 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
newoption->gen.desc = pstrdup(desc);
else
newoption->gen.desc = NULL;
newoption->gen.kind = kind;
newoption->gen.kinds = kinds;
newoption->gen.namelen = strlen(name);
newoption->gen.type = RELOPT_TYPE_STRING;
newoption->validate_cb = validator;
......@@ -784,7 +790,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
/* Build a list of expected options, based on kind */
for (i = 0; relOpts[i]; i++)
if (relOpts[i]->kind == kind)
if (relOpts[i]->kinds & kind)
numoptions++;
if (numoptions == 0)
......@@ -797,7 +803,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
for (i = 0, j = 0; relOpts[i]; i++)
{
if (relOpts[i]->kind == kind)
if (relOpts[i]->kinds & kind)
{
reloptions[j].gen = relOpts[i];
reloptions[j].isset = false;
......@@ -1116,7 +1122,16 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
bytea *
heap_reloptions(char relkind, Datum reloptions, bool validate)
{
switch (relkind)
{
case RELKIND_TOASTVALUE:
return default_reloptions(reloptions, validate, RELOPT_KIND_TOAST);
case RELKIND_RELATION:
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
default:
/* sequences, composite types and views are not supported */
return NULL;
}
}
......
......@@ -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.13 2009/03/23 16:36:27 tgl Exp $
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.14 2009/04/04 00:45:02 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -33,15 +33,15 @@ typedef enum relopt_type
/* kinds supported by reloptions */
typedef enum relopt_kind
{
RELOPT_KIND_HEAP,
/* XXX do we need a separate kind for TOAST tables? */
RELOPT_KIND_BTREE,
RELOPT_KIND_HASH,
RELOPT_KIND_GIN,
RELOPT_KIND_GIST,
RELOPT_KIND_HEAP = (1 << 0),
RELOPT_KIND_TOAST = (1 << 1),
RELOPT_KIND_BTREE = (1 << 2),
RELOPT_KIND_HASH = (1 << 3),
RELOPT_KIND_GIN = (1 << 4),
RELOPT_KIND_GIST = (1 << 5),
/* if you add a new kind, make sure you update "last_default" too */
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
RELOPT_KIND_MAX = 255
RELOPT_KIND_MAX = (1 << 31)
} relopt_kind;
/* reloption namespaces allowed for heaps -- currently only TOAST */
......@@ -52,7 +52,7 @@ typedef struct relopt_gen
{
const char *name; /* must be first (used as list termination marker) */
const char *desc;
relopt_kind kind;
bits32 kinds;
int namelen;
relopt_type type;
} relopt_gen;
......@@ -232,14 +232,14 @@ typedef struct
(char *)(optstruct) + (optstruct)->member)
extern int add_reloption_kind(void);
extern void add_bool_reloption(int kind, char *name, char *desc,
extern relopt_kind add_reloption_kind(void);
extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
bool default_val);
extern void add_int_reloption(int kind, char *name, char *desc,
extern void add_int_reloption(bits32 kinds, char *name, char *desc,
int default_val, int min_val, int max_val);
extern void add_real_reloption(int kind, char *name, char *desc,
extern void add_real_reloption(bits32 kinds, char *name, char *desc,
double default_val, double min_val, double max_val);
extern void add_string_reloption(int kind, char *name, char *desc,
extern void add_string_reloption(bits32 kinds, char *name, char *desc,
char *default_val, validate_string_relopt validator);
extern Datum transformRelOptions(Datum oldOptions, List *defList,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment