Refactor code building relation options
Historically, the code to build relation options has been shaped the same way in multiple code paths by using a set of datums in input with the options parsed with a static table which is then filled with the option values. This introduces a new common routine in reloptions.c to do most of the legwork for the in-core code paths. Author: Amit Langote Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/CA+HiwqGsoSn_uTPPYT19WrtR7oYpYtv4CdS0xuedTKiHHWuk_g@mail.gmail.com
This commit is contained in:
parent
5102f39440
commit
3534fa2233
@ -475,18 +475,18 @@ BloomInitMetapage(Relation index)
|
|||||||
bytea *
|
bytea *
|
||||||
bloptions(Datum reloptions, bool validate)
|
bloptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
int numoptions;
|
|
||||||
BloomOptions *rdopts;
|
BloomOptions *rdopts;
|
||||||
|
|
||||||
/* Parse the user-given reloptions */
|
/* Parse the user-given reloptions */
|
||||||
options = parseRelOptions(reloptions, validate, bl_relopt_kind, &numoptions);
|
rdopts = (BloomOptions *) build_reloptions(reloptions, validate,
|
||||||
rdopts = allocateReloptStruct(sizeof(BloomOptions), options, numoptions);
|
bl_relopt_kind,
|
||||||
fillRelOptions((void *) rdopts, sizeof(BloomOptions), options, numoptions,
|
sizeof(BloomOptions),
|
||||||
validate, bl_relopt_tab, lengthof(bl_relopt_tab));
|
bl_relopt_tab,
|
||||||
|
lengthof(bl_relopt_tab));
|
||||||
|
|
||||||
/* Convert signature length from # of bits to # to words, rounding up */
|
/* Convert signature length from # of bits to # to words, rounding up */
|
||||||
rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
|
if (rdopts)
|
||||||
|
rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
return (bytea *) rdopts;
|
||||||
}
|
}
|
||||||
|
@ -820,29 +820,15 @@ brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
|
|||||||
bytea *
|
bytea *
|
||||||
brinoptions(Datum reloptions, bool validate)
|
brinoptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
BrinOptions *rdopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"pages_per_range", RELOPT_TYPE_INT, offsetof(BrinOptions, pagesPerRange)},
|
{"pages_per_range", RELOPT_TYPE_INT, offsetof(BrinOptions, pagesPerRange)},
|
||||||
{"autosummarize", RELOPT_TYPE_BOOL, offsetof(BrinOptions, autosummarize)}
|
{"autosummarize", RELOPT_TYPE_BOOL, offsetof(BrinOptions, autosummarize)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_BRIN,
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
&numoptions);
|
RELOPT_KIND_BRIN,
|
||||||
|
sizeof(BrinOptions),
|
||||||
/* if none set, we're done */
|
tab, lengthof(tab));
|
||||||
if (numoptions == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rdopts = allocateReloptStruct(sizeof(BrinOptions), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) rdopts, sizeof(BrinOptions), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1474,9 +1474,6 @@ fillRelOptions(void *rdopts, Size basesize,
|
|||||||
bytea *
|
bytea *
|
||||||
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
StdRdOptions *rdopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
|
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
|
||||||
{"autovacuum_enabled", RELOPT_TYPE_BOOL,
|
{"autovacuum_enabled", RELOPT_TYPE_BOOL,
|
||||||
@ -1521,20 +1518,57 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
|||||||
offsetof(StdRdOptions, vacuum_truncate)}
|
offsetof(StdRdOptions, vacuum_truncate)}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return (bytea *) build_reloptions(reloptions, validate, kind,
|
||||||
|
sizeof(StdRdOptions),
|
||||||
|
tab, lengthof(tab));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* build_reloptions
|
||||||
|
*
|
||||||
|
* Parses "reloptions" provided by the caller, returning them in a
|
||||||
|
* structure containing the parsed options. The parsing is done with
|
||||||
|
* the help of a parsing table describing the allowed options, defined
|
||||||
|
* by "relopt_elems" of length "num_relopt_elems".
|
||||||
|
*
|
||||||
|
* "validate" must be true if reloptions value is freshly built by
|
||||||
|
* transformRelOptions(), as opposed to being read from the catalog, in which
|
||||||
|
* case the values contained in it must already be valid.
|
||||||
|
*
|
||||||
|
* NULL is returned if the passed-in options did not match any of the options
|
||||||
|
* in the parsing table, unless validate is true in which case an error would
|
||||||
|
* be reported.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
build_reloptions(Datum reloptions, bool validate,
|
||||||
|
relopt_kind kind,
|
||||||
|
Size relopt_struct_size,
|
||||||
|
const relopt_parse_elt *relopt_elems,
|
||||||
|
int num_relopt_elems)
|
||||||
|
{
|
||||||
|
int numoptions;
|
||||||
|
relopt_value *options;
|
||||||
|
void *rdopts;
|
||||||
|
|
||||||
|
/* parse options specific to given relation option kind */
|
||||||
options = parseRelOptions(reloptions, validate, kind, &numoptions);
|
options = parseRelOptions(reloptions, validate, kind, &numoptions);
|
||||||
|
Assert(numoptions <= num_relopt_elems);
|
||||||
|
|
||||||
/* if none set, we're done */
|
/* if none set, we're done */
|
||||||
if (numoptions == 0)
|
if (numoptions == 0)
|
||||||
|
{
|
||||||
|
Assert(options == NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
rdopts = allocateReloptStruct(sizeof(StdRdOptions), options, numoptions);
|
/* allocate and fill the structure */
|
||||||
|
rdopts = allocateReloptStruct(relopt_struct_size, options, numoptions);
|
||||||
fillRelOptions((void *) rdopts, sizeof(StdRdOptions), options, numoptions,
|
fillRelOptions(rdopts, relopt_struct_size, options, numoptions,
|
||||||
validate, tab, lengthof(tab));
|
validate, relopt_elems, num_relopt_elems);
|
||||||
|
|
||||||
pfree(options);
|
pfree(options);
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
return rdopts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1543,9 +1577,6 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
|||||||
bytea *
|
bytea *
|
||||||
view_reloptions(Datum reloptions, bool validate)
|
view_reloptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
ViewOptions *vopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"security_barrier", RELOPT_TYPE_BOOL,
|
{"security_barrier", RELOPT_TYPE_BOOL,
|
||||||
offsetof(ViewOptions, security_barrier)},
|
offsetof(ViewOptions, security_barrier)},
|
||||||
@ -1553,20 +1584,10 @@ view_reloptions(Datum reloptions, bool validate)
|
|||||||
offsetof(ViewOptions, check_option)}
|
offsetof(ViewOptions, check_option)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_VIEW, &numoptions);
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
|
RELOPT_KIND_VIEW,
|
||||||
/* if none set, we're done */
|
sizeof(ViewOptions),
|
||||||
if (numoptions == 0)
|
tab, lengthof(tab));
|
||||||
return NULL;
|
|
||||||
|
|
||||||
vopts = allocateReloptStruct(sizeof(ViewOptions), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) vopts, sizeof(ViewOptions), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) vopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1628,29 +1649,15 @@ index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate)
|
|||||||
bytea *
|
bytea *
|
||||||
attribute_reloptions(Datum reloptions, bool validate)
|
attribute_reloptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
AttributeOpts *aopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
|
{"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
|
||||||
{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
|
{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
&numoptions);
|
RELOPT_KIND_ATTRIBUTE,
|
||||||
|
sizeof(AttributeOpts),
|
||||||
/* if none set, we're done */
|
tab, lengthof(tab));
|
||||||
if (numoptions == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
aopts = allocateReloptStruct(sizeof(AttributeOpts), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) aopts, sizeof(AttributeOpts), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) aopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1659,30 +1666,16 @@ attribute_reloptions(Datum reloptions, bool validate)
|
|||||||
bytea *
|
bytea *
|
||||||
tablespace_reloptions(Datum reloptions, bool validate)
|
tablespace_reloptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
TableSpaceOpts *tsopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)},
|
{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)},
|
||||||
{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)},
|
{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)},
|
||||||
{"effective_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, effective_io_concurrency)}
|
{"effective_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, effective_io_concurrency)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE,
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
&numoptions);
|
RELOPT_KIND_TABLESPACE,
|
||||||
|
sizeof(TableSpaceOpts),
|
||||||
/* if none set, we're done */
|
tab, lengthof(tab));
|
||||||
if (numoptions == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tsopts = allocateReloptStruct(sizeof(TableSpaceOpts), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) tsopts, sizeof(TableSpaceOpts), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) tsopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -602,30 +602,16 @@ ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
|
|||||||
bytea *
|
bytea *
|
||||||
ginoptions(Datum reloptions, bool validate)
|
ginoptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
GinOptions *rdopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)},
|
{"fastupdate", RELOPT_TYPE_BOOL, offsetof(GinOptions, useFastUpdate)},
|
||||||
{"gin_pending_list_limit", RELOPT_TYPE_INT, offsetof(GinOptions,
|
{"gin_pending_list_limit", RELOPT_TYPE_INT, offsetof(GinOptions,
|
||||||
pendingListCleanupSize)}
|
pendingListCleanupSize)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIN,
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
&numoptions);
|
RELOPT_KIND_GIN,
|
||||||
|
sizeof(GinOptions),
|
||||||
/* if none set, we're done */
|
tab, lengthof(tab));
|
||||||
if (numoptions == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rdopts = allocateReloptStruct(sizeof(GinOptions), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) rdopts, sizeof(GinOptions), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -908,29 +908,15 @@ gistPageRecyclable(Page page)
|
|||||||
bytea *
|
bytea *
|
||||||
gistoptions(Datum reloptions, bool validate)
|
gistoptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
|
||||||
GiSTOptions *rdopts;
|
|
||||||
int numoptions;
|
|
||||||
static const relopt_parse_elt tab[] = {
|
static const relopt_parse_elt tab[] = {
|
||||||
{"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)},
|
{"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)},
|
||||||
{"buffering", RELOPT_TYPE_ENUM, offsetof(GiSTOptions, buffering_mode)}
|
{"buffering", RELOPT_TYPE_ENUM, offsetof(GiSTOptions, buffering_mode)}
|
||||||
};
|
};
|
||||||
|
|
||||||
options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIST,
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
&numoptions);
|
RELOPT_KIND_GIST,
|
||||||
|
sizeof(GiSTOptions),
|
||||||
/* if none set, we're done */
|
tab, lengthof(tab));
|
||||||
if (numoptions == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rdopts = allocateReloptStruct(sizeof(GiSTOptions), options, numoptions);
|
|
||||||
|
|
||||||
fillRelOptions((void *) rdopts, sizeof(GiSTOptions), options, numoptions,
|
|
||||||
validate, tab, lengthof(tab));
|
|
||||||
|
|
||||||
pfree(options);
|
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -296,6 +296,11 @@ extern void fillRelOptions(void *rdopts, Size basesize,
|
|||||||
relopt_value *options, int numoptions,
|
relopt_value *options, int numoptions,
|
||||||
bool validate,
|
bool validate,
|
||||||
const relopt_parse_elt *elems, int nelems);
|
const relopt_parse_elt *elems, int nelems);
|
||||||
|
extern void *build_reloptions(Datum reloptions, bool validate,
|
||||||
|
relopt_kind kind,
|
||||||
|
Size relopt_struct_size,
|
||||||
|
const relopt_parse_elt *relopt_elems,
|
||||||
|
int num_relopt_elems);
|
||||||
|
|
||||||
extern bytea *default_reloptions(Datum reloptions, bool validate,
|
extern bytea *default_reloptions(Datum reloptions, bool validate,
|
||||||
relopt_kind kind);
|
relopt_kind kind);
|
||||||
|
@ -222,17 +222,10 @@ dicostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
|
|||||||
static bytea *
|
static bytea *
|
||||||
dioptions(Datum reloptions, bool validate)
|
dioptions(Datum reloptions, bool validate)
|
||||||
{
|
{
|
||||||
relopt_value *options;
|
return (bytea *) build_reloptions(reloptions, validate,
|
||||||
int numoptions;
|
di_relopt_kind,
|
||||||
DummyIndexOptions *rdopts;
|
sizeof(DummyIndexOptions),
|
||||||
|
di_relopt_tab, lengthof(di_relopt_tab));
|
||||||
/* Parse the user-given reloptions */
|
|
||||||
options = parseRelOptions(reloptions, validate, di_relopt_kind, &numoptions);
|
|
||||||
rdopts = allocateReloptStruct(sizeof(DummyIndexOptions), options, numoptions);
|
|
||||||
fillRelOptions((void *) rdopts, sizeof(DummyIndexOptions), options, numoptions,
|
|
||||||
validate, di_relopt_tab, lengthof(di_relopt_tab));
|
|
||||||
|
|
||||||
return (bytea *) rdopts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user