{
"autovacuum_enabled",
"Enables autovacuum in this relation",
- RELOPT_KIND_HEAP
+ RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
true
},
{
"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
},
{
"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
},
{
"autovacuum_vacuum_cost_delay",
"Vacuum cost delay in milliseconds, for autovacuum",
- RELOPT_KIND_HEAP
+ RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
20, 0, 100
},
{
"autovacuum_vacuum_cost_limit",
"Vacuum cost amount available before napping, for autovacuum",
- RELOPT_KIND_HEAP
+ RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
200, 1, 10000
},
{
"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
},
{
"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
},
{
"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 */
{
"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
},
{
"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
},
};
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;
* 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;
}
/*
* (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;
newoption->desc = pstrdup(desc);
else
newoption->desc = NULL;
- newoption->kind = kind;
+ newoption->kinds = kinds;
newoption->namelen = strlen(name);
newoption->type = type;
* 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;
* 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;
* 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;
* 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;
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;
/* 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)
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;
bytea *
heap_reloptions(char relkind, Datum reloptions, bool validate)
{
- return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
+ 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;
+ }
}
/* 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 */
{
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;
(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,