mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
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.)
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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",
|
"autovacuum_enabled",
|
||||||
"Enables autovacuum in this relation",
|
"Enables autovacuum in this relation",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
@ -106,7 +106,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_vacuum_threshold",
|
"autovacuum_vacuum_threshold",
|
||||||
"Minimum number of tuple updates or deletes prior to vacuum",
|
"Minimum number of tuple updates or deletes prior to vacuum",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
50, 0, INT_MAX
|
50, 0, INT_MAX
|
||||||
},
|
},
|
||||||
@ -114,7 +114,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_analyze_threshold",
|
"autovacuum_analyze_threshold",
|
||||||
"Minimum number of tuple inserts, updates or deletes prior to analyze",
|
"Minimum number of tuple inserts, updates or deletes prior to analyze",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
50, 0, INT_MAX
|
50, 0, INT_MAX
|
||||||
},
|
},
|
||||||
@ -122,7 +122,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_vacuum_cost_delay",
|
"autovacuum_vacuum_cost_delay",
|
||||||
"Vacuum cost delay in milliseconds, for autovacuum",
|
"Vacuum cost delay in milliseconds, for autovacuum",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
20, 0, 100
|
20, 0, 100
|
||||||
},
|
},
|
||||||
@ -130,7 +130,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_vacuum_cost_limit",
|
"autovacuum_vacuum_cost_limit",
|
||||||
"Vacuum cost amount available before napping, for autovacuum",
|
"Vacuum cost amount available before napping, for autovacuum",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
200, 1, 10000
|
200, 1, 10000
|
||||||
},
|
},
|
||||||
@ -138,7 +138,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_freeze_min_age",
|
"autovacuum_freeze_min_age",
|
||||||
"Minimum age at which VACUUM should freeze a table row, for autovacuum",
|
"Minimum age at which VACUUM should freeze a table row, for autovacuum",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
100000000, 0, 1000000000
|
100000000, 0, 1000000000
|
||||||
},
|
},
|
||||||
@ -146,7 +146,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_freeze_max_age",
|
"autovacuum_freeze_max_age",
|
||||||
"Age at which to autovacuum a table to prevent transaction ID wraparound",
|
"Age at which to autovacuum a table to prevent transaction ID wraparound",
|
||||||
RELOPT_KIND_HEAP
|
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
|
||||||
},
|
},
|
||||||
200000000, 100000000, 2000000000
|
200000000, 100000000, 2000000000
|
||||||
},
|
},
|
||||||
@ -154,7 +154,7 @@ static relopt_int intRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_freeze_table_age",
|
"autovacuum_freeze_table_age",
|
||||||
"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
|
"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
|
}, 150000000, 0, 2000000000
|
||||||
},
|
},
|
||||||
/* list terminator */
|
/* list terminator */
|
||||||
@ -167,7 +167,7 @@ static relopt_real realRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_vacuum_scale_factor",
|
"autovacuum_vacuum_scale_factor",
|
||||||
"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
|
"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
|
0.2, 0.0, 100.0
|
||||||
},
|
},
|
||||||
@ -175,7 +175,7 @@ static relopt_real realRelOpts[] =
|
|||||||
{
|
{
|
||||||
"autovacuum_analyze_scale_factor",
|
"autovacuum_analyze_scale_factor",
|
||||||
"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
|
"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
|
0.1, 0.0, 100.0
|
||||||
},
|
},
|
||||||
@ -190,7 +190,7 @@ static relopt_string stringRelOpts[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static relopt_gen **relOpts = NULL;
|
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 int num_custom_options = 0;
|
||||||
static relopt_gen **custom_options = NULL;
|
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
|
* Create a new relopt_kind value, to be used in custom reloptions by
|
||||||
* user-defined AMs.
|
* user-defined AMs.
|
||||||
*/
|
*/
|
||||||
int
|
relopt_kind
|
||||||
add_reloption_kind(void)
|
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)
|
if (last_assigned_kind >= RELOPT_KIND_MAX)
|
||||||
ereport(ERROR,
|
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)
|
* (for types other than string)
|
||||||
*/
|
*/
|
||||||
static relopt_gen *
|
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;
|
MemoryContext oldcxt;
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -358,7 +364,7 @@ allocate_reloption(int kind, int type, char *name, char *desc)
|
|||||||
newoption->desc = pstrdup(desc);
|
newoption->desc = pstrdup(desc);
|
||||||
else
|
else
|
||||||
newoption->desc = NULL;
|
newoption->desc = NULL;
|
||||||
newoption->kind = kind;
|
newoption->kinds = kinds;
|
||||||
newoption->namelen = strlen(name);
|
newoption->namelen = strlen(name);
|
||||||
newoption->type = type;
|
newoption->type = type;
|
||||||
|
|
||||||
@ -372,11 +378,11 @@ allocate_reloption(int kind, int type, char *name, char *desc)
|
|||||||
* Add a new boolean reloption
|
* Add a new boolean reloption
|
||||||
*/
|
*/
|
||||||
void
|
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;
|
relopt_bool *newoption;
|
||||||
|
|
||||||
newoption = (relopt_bool *) allocate_reloption(kind, RELOPT_TYPE_BOOL,
|
newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
|
||||||
name, desc);
|
name, desc);
|
||||||
newoption->default_val = default_val;
|
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
|
* Add a new integer reloption
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
int min_val, int max_val)
|
||||||
{
|
{
|
||||||
relopt_int *newoption;
|
relopt_int *newoption;
|
||||||
|
|
||||||
newoption = (relopt_int *) allocate_reloption(kind, RELOPT_TYPE_INT,
|
newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT,
|
||||||
name, desc);
|
name, desc);
|
||||||
newoption->default_val = default_val;
|
newoption->default_val = default_val;
|
||||||
newoption->min = min_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
|
* Add a new float reloption
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
double min_val, double max_val)
|
||||||
{
|
{
|
||||||
relopt_real *newoption;
|
relopt_real *newoption;
|
||||||
|
|
||||||
newoption = (relopt_real *) allocate_reloption(kind, RELOPT_TYPE_REAL,
|
newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL,
|
||||||
name, desc);
|
name, desc);
|
||||||
newoption->default_val = default_val;
|
newoption->default_val = default_val;
|
||||||
newoption->min = min_val;
|
newoption->min = min_val;
|
||||||
@ -431,7 +437,7 @@ add_real_reloption(int kind, char *name, char *desc, double default_val,
|
|||||||
* the validation.
|
* the validation.
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
validate_string_relopt validator)
|
||||||
{
|
{
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
@ -450,7 +456,7 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
|
|||||||
newoption->gen.desc = pstrdup(desc);
|
newoption->gen.desc = pstrdup(desc);
|
||||||
else
|
else
|
||||||
newoption->gen.desc = NULL;
|
newoption->gen.desc = NULL;
|
||||||
newoption->gen.kind = kind;
|
newoption->gen.kinds = kinds;
|
||||||
newoption->gen.namelen = strlen(name);
|
newoption->gen.namelen = strlen(name);
|
||||||
newoption->gen.type = RELOPT_TYPE_STRING;
|
newoption->gen.type = RELOPT_TYPE_STRING;
|
||||||
newoption->validate_cb = validator;
|
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 */
|
/* Build a list of expected options, based on kind */
|
||||||
|
|
||||||
for (i = 0; relOpts[i]; i++)
|
for (i = 0; relOpts[i]; i++)
|
||||||
if (relOpts[i]->kind == kind)
|
if (relOpts[i]->kinds & kind)
|
||||||
numoptions++;
|
numoptions++;
|
||||||
|
|
||||||
if (numoptions == 0)
|
if (numoptions == 0)
|
||||||
@ -797,7 +803,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
|
|||||||
|
|
||||||
for (i = 0, j = 0; relOpts[i]; i++)
|
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].gen = relOpts[i];
|
||||||
reloptions[j].isset = false;
|
reloptions[j].isset = false;
|
||||||
@ -1116,7 +1122,16 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
|||||||
bytea *
|
bytea *
|
||||||
heap_reloptions(char relkind, Datum reloptions, bool validate)
|
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);
|
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) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 */
|
/* kinds supported by reloptions */
|
||||||
typedef enum relopt_kind
|
typedef enum relopt_kind
|
||||||
{
|
{
|
||||||
RELOPT_KIND_HEAP,
|
RELOPT_KIND_HEAP = (1 << 0),
|
||||||
/* XXX do we need a separate kind for TOAST tables? */
|
RELOPT_KIND_TOAST = (1 << 1),
|
||||||
RELOPT_KIND_BTREE,
|
RELOPT_KIND_BTREE = (1 << 2),
|
||||||
RELOPT_KIND_HASH,
|
RELOPT_KIND_HASH = (1 << 3),
|
||||||
RELOPT_KIND_GIN,
|
RELOPT_KIND_GIN = (1 << 4),
|
||||||
RELOPT_KIND_GIST,
|
RELOPT_KIND_GIST = (1 << 5),
|
||||||
/* if you add a new kind, make sure you update "last_default" too */
|
/* if you add a new kind, make sure you update "last_default" too */
|
||||||
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
|
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
|
||||||
RELOPT_KIND_MAX = 255
|
RELOPT_KIND_MAX = (1 << 31)
|
||||||
} relopt_kind;
|
} relopt_kind;
|
||||||
|
|
||||||
/* reloption namespaces allowed for heaps -- currently only TOAST */
|
/* 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 *name; /* must be first (used as list termination marker) */
|
||||||
const char *desc;
|
const char *desc;
|
||||||
relopt_kind kind;
|
bits32 kinds;
|
||||||
int namelen;
|
int namelen;
|
||||||
relopt_type type;
|
relopt_type type;
|
||||||
} relopt_gen;
|
} relopt_gen;
|
||||||
@ -232,14 +232,14 @@ typedef struct
|
|||||||
(char *)(optstruct) + (optstruct)->member)
|
(char *)(optstruct) + (optstruct)->member)
|
||||||
|
|
||||||
|
|
||||||
extern int add_reloption_kind(void);
|
extern relopt_kind add_reloption_kind(void);
|
||||||
extern void add_bool_reloption(int kind, char *name, char *desc,
|
extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
|
||||||
bool default_val);
|
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);
|
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);
|
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);
|
char *default_val, validate_string_relopt validator);
|
||||||
|
|
||||||
extern Datum transformRelOptions(Datum oldOptions, List *defList,
|
extern Datum transformRelOptions(Datum oldOptions, List *defList,
|
||||||
|
Reference in New Issue
Block a user