Skip to content

Commit 1c855f0

Browse files
committed
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.)
1 parent 591f294 commit 1c855f0

File tree

2 files changed

+57
-42
lines changed

2 files changed

+57
-42
lines changed

src/backend/access/common/reloptions.c

Lines changed: 43 additions & 28 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.24 2009/03/24 20:17:09 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.25 2009/04/04 00:45:02 alvherre Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -52,7 +52,7 @@ static relopt_bool boolRelOpts[] =
5252
{
5353
"autovacuum_enabled",
5454
"Enables autovacuum in this relation",
55-
RELOPT_KIND_HEAP
55+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
5656
},
5757
true
5858
},
@@ -106,55 +106,55 @@ static relopt_int intRelOpts[] =
106106
{
107107
"autovacuum_vacuum_threshold",
108108
"Minimum number of tuple updates or deletes prior to vacuum",
109-
RELOPT_KIND_HEAP
109+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
110110
},
111111
50, 0, INT_MAX
112112
},
113113
{
114114
{
115115
"autovacuum_analyze_threshold",
116116
"Minimum number of tuple inserts, updates or deletes prior to analyze",
117-
RELOPT_KIND_HEAP
117+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
118118
},
119119
50, 0, INT_MAX
120120
},
121121
{
122122
{
123123
"autovacuum_vacuum_cost_delay",
124124
"Vacuum cost delay in milliseconds, for autovacuum",
125-
RELOPT_KIND_HEAP
125+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
126126
},
127127
20, 0, 100
128128
},
129129
{
130130
{
131131
"autovacuum_vacuum_cost_limit",
132132
"Vacuum cost amount available before napping, for autovacuum",
133-
RELOPT_KIND_HEAP
133+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
134134
},
135135
200, 1, 10000
136136
},
137137
{
138138
{
139139
"autovacuum_freeze_min_age",
140140
"Minimum age at which VACUUM should freeze a table row, for autovacuum",
141-
RELOPT_KIND_HEAP
141+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
142142
},
143143
100000000, 0, 1000000000
144144
},
145145
{
146146
{
147147
"autovacuum_freeze_max_age",
148148
"Age at which to autovacuum a table to prevent transaction ID wraparound",
149-
RELOPT_KIND_HEAP
149+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
150150
},
151151
200000000, 100000000, 2000000000
152152
},
153153
{
154154
{
155155
"autovacuum_freeze_table_age",
156156
"Age at which VACUUM should perform a full table sweep to replace old Xid values with FrozenXID",
157-
RELOPT_KIND_HEAP
157+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
158158
}, 150000000, 0, 2000000000
159159
},
160160
/* list terminator */
@@ -167,15 +167,15 @@ static relopt_real realRelOpts[] =
167167
{
168168
"autovacuum_vacuum_scale_factor",
169169
"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
170-
RELOPT_KIND_HEAP
170+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
171171
},
172172
0.2, 0.0, 100.0
173173
},
174174
{
175175
{
176176
"autovacuum_analyze_scale_factor",
177177
"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
178-
RELOPT_KIND_HEAP
178+
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
179179
},
180180
0.1, 0.0, 100.0
181181
},
@@ -190,7 +190,7 @@ static relopt_string stringRelOpts[] =
190190
};
191191

192192
static relopt_gen **relOpts = NULL;
193-
static int last_assigned_kind = RELOPT_KIND_LAST_DEFAULT + 1;
193+
static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT << 1;
194194

195195
static int num_custom_options = 0;
196196
static relopt_gen **custom_options = NULL;
@@ -275,14 +275,20 @@ initialize_reloptions(void)
275275
* Create a new relopt_kind value, to be used in custom reloptions by
276276
* user-defined AMs.
277277
*/
278-
int
278+
relopt_kind
279279
add_reloption_kind(void)
280280
{
281+
relopt_kind kind;
282+
283+
/* don't hand out the last bit so that the wraparound check is portable */
281284
if (last_assigned_kind >= RELOPT_KIND_MAX)
282285
ereport(ERROR,
283-
(errmsg("user-defined relation parameter types limit exceeded")));
286+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
287+
errmsg("user-defined relation parameter types limit exceeded")));
284288

285-
return last_assigned_kind++;
289+
kind = (relopt_kind) last_assigned_kind;
290+
last_assigned_kind <<= 1;
291+
return kind;
286292
}
287293

288294
/*
@@ -325,7 +331,7 @@ add_reloption(relopt_gen *newoption)
325331
* (for types other than string)
326332
*/
327333
static relopt_gen *
328-
allocate_reloption(int kind, int type, char *name, char *desc)
334+
allocate_reloption(bits32 kinds, int type, char *name, char *desc)
329335
{
330336
MemoryContext oldcxt;
331337
size_t size;
@@ -358,7 +364,7 @@ allocate_reloption(int kind, int type, char *name, char *desc)
358364
newoption->desc = pstrdup(desc);
359365
else
360366
newoption->desc = NULL;
361-
newoption->kind = kind;
367+
newoption->kinds = kinds;
362368
newoption->namelen = strlen(name);
363369
newoption->type = type;
364370

@@ -372,11 +378,11 @@ allocate_reloption(int kind, int type, char *name, char *desc)
372378
* Add a new boolean reloption
373379
*/
374380
void
375-
add_bool_reloption(int kind, char *name, char *desc, bool default_val)
381+
add_bool_reloption(bits32 kinds, char *name, char *desc, bool default_val)
376382
{
377383
relopt_bool *newoption;
378384

379-
newoption = (relopt_bool *) allocate_reloption(kind, RELOPT_TYPE_BOOL,
385+
newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
380386
name, desc);
381387
newoption->default_val = default_val;
382388

@@ -388,12 +394,12 @@ add_bool_reloption(int kind, char *name, char *desc, bool default_val)
388394
* Add a new integer reloption
389395
*/
390396
void
391-
add_int_reloption(int kind, char *name, char *desc, int default_val,
397+
add_int_reloption(bits32 kinds, char *name, char *desc, int default_val,
392398
int min_val, int max_val)
393399
{
394400
relopt_int *newoption;
395401

396-
newoption = (relopt_int *) allocate_reloption(kind, RELOPT_TYPE_INT,
402+
newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT,
397403
name, desc);
398404
newoption->default_val = default_val;
399405
newoption->min = min_val;
@@ -407,12 +413,12 @@ add_int_reloption(int kind, char *name, char *desc, int default_val,
407413
* Add a new float reloption
408414
*/
409415
void
410-
add_real_reloption(int kind, char *name, char *desc, double default_val,
416+
add_real_reloption(bits32 kinds, char *name, char *desc, double default_val,
411417
double min_val, double max_val)
412418
{
413419
relopt_real *newoption;
414420

415-
newoption = (relopt_real *) allocate_reloption(kind, RELOPT_TYPE_REAL,
421+
newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL,
416422
name, desc);
417423
newoption->default_val = default_val;
418424
newoption->min = min_val;
@@ -431,7 +437,7 @@ add_real_reloption(int kind, char *name, char *desc, double default_val,
431437
* the validation.
432438
*/
433439
void
434-
add_string_reloption(int kind, char *name, char *desc, char *default_val,
440+
add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
435441
validate_string_relopt validator)
436442
{
437443
MemoryContext oldcxt;
@@ -450,7 +456,7 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
450456
newoption->gen.desc = pstrdup(desc);
451457
else
452458
newoption->gen.desc = NULL;
453-
newoption->gen.kind = kind;
459+
newoption->gen.kinds = kinds;
454460
newoption->gen.namelen = strlen(name);
455461
newoption->gen.type = RELOPT_TYPE_STRING;
456462
newoption->validate_cb = validator;
@@ -784,7 +790,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
784790
/* Build a list of expected options, based on kind */
785791

786792
for (i = 0; relOpts[i]; i++)
787-
if (relOpts[i]->kind == kind)
793+
if (relOpts[i]->kinds & kind)
788794
numoptions++;
789795

790796
if (numoptions == 0)
@@ -797,7 +803,7 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
797803

798804
for (i = 0, j = 0; relOpts[i]; i++)
799805
{
800-
if (relOpts[i]->kind == kind)
806+
if (relOpts[i]->kinds & kind)
801807
{
802808
reloptions[j].gen = relOpts[i];
803809
reloptions[j].isset = false;
@@ -1116,7 +1122,16 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
11161122
bytea *
11171123
heap_reloptions(char relkind, Datum reloptions, bool validate)
11181124
{
1119-
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
1125+
switch (relkind)
1126+
{
1127+
case RELKIND_TOASTVALUE:
1128+
return default_reloptions(reloptions, validate, RELOPT_KIND_TOAST);
1129+
case RELKIND_RELATION:
1130+
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
1131+
default:
1132+
/* sequences, composite types and views are not supported */
1133+
return NULL;
1134+
}
11201135
}
11211136

11221137

src/include/access/reloptions.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
14-
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.13 2009/03/23 16:36:27 tgl Exp $
14+
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.14 2009/04/04 00:45:02 alvherre Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -33,15 +33,15 @@ typedef enum relopt_type
3333
/* kinds supported by reloptions */
3434
typedef enum relopt_kind
3535
{
36-
RELOPT_KIND_HEAP,
37-
/* XXX do we need a separate kind for TOAST tables? */
38-
RELOPT_KIND_BTREE,
39-
RELOPT_KIND_HASH,
40-
RELOPT_KIND_GIN,
41-
RELOPT_KIND_GIST,
36+
RELOPT_KIND_HEAP = (1 << 0),
37+
RELOPT_KIND_TOAST = (1 << 1),
38+
RELOPT_KIND_BTREE = (1 << 2),
39+
RELOPT_KIND_HASH = (1 << 3),
40+
RELOPT_KIND_GIN = (1 << 4),
41+
RELOPT_KIND_GIST = (1 << 5),
4242
/* if you add a new kind, make sure you update "last_default" too */
4343
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
44-
RELOPT_KIND_MAX = 255
44+
RELOPT_KIND_MAX = (1 << 31)
4545
} relopt_kind;
4646

4747
/* reloption namespaces allowed for heaps -- currently only TOAST */
@@ -52,7 +52,7 @@ typedef struct relopt_gen
5252
{
5353
const char *name; /* must be first (used as list termination marker) */
5454
const char *desc;
55-
relopt_kind kind;
55+
bits32 kinds;
5656
int namelen;
5757
relopt_type type;
5858
} relopt_gen;
@@ -232,14 +232,14 @@ typedef struct
232232
(char *)(optstruct) + (optstruct)->member)
233233

234234

235-
extern int add_reloption_kind(void);
236-
extern void add_bool_reloption(int kind, char *name, char *desc,
235+
extern relopt_kind add_reloption_kind(void);
236+
extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
237237
bool default_val);
238-
extern void add_int_reloption(int kind, char *name, char *desc,
238+
extern void add_int_reloption(bits32 kinds, char *name, char *desc,
239239
int default_val, int min_val, int max_val);
240-
extern void add_real_reloption(int kind, char *name, char *desc,
240+
extern void add_real_reloption(bits32 kinds, char *name, char *desc,
241241
double default_val, double min_val, double max_val);
242-
extern void add_string_reloption(int kind, char *name, char *desc,
242+
extern void add_string_reloption(bits32 kinds, char *name, char *desc,
243243
char *default_val, validate_string_relopt validator);
244244

245245
extern Datum transformRelOptions(Datum oldOptions, List *defList,

0 commit comments

Comments
 (0)