#include "postgres.h"#include "access/gist_private.h"#include "access/hash.h"#include "access/htup_details.h"#include "access/nbtree.h"#include "access/reloptions.h"#include "access/spgist.h"#include "catalog/pg_type.h"#include "commands/defrem.h"#include "commands/tablespace.h"#include "nodes/makefuncs.h"#include "utils/array.h"#include "utils/attoptcache.h"#include "utils/builtins.h"#include "utils/guc.h"#include "utils/memutils.h"#include "utils/rel.h"
Go to the source code of this file.
Functions | |
| static void | initialize_reloptions (void) |
| static void | parse_one_reloption (relopt_value *option, char *text_str, int text_len, bool validate) |
| relopt_kind | add_reloption_kind (void) |
| static void | add_reloption (relopt_gen *newoption) |
| static relopt_gen * | allocate_reloption (bits32 kinds, int type, char *name, char *desc) |
| void | add_bool_reloption (bits32 kinds, char *name, char *desc, bool default_val) |
| void | add_int_reloption (bits32 kinds, char *name, char *desc, int default_val, int min_val, int max_val) |
| void | add_real_reloption (bits32 kinds, char *name, char *desc, double default_val, double min_val, double max_val) |
| void | add_string_reloption (bits32 kinds, char *name, char *desc, char *default_val, validate_string_relopt validator) |
| Datum | transformRelOptions (Datum oldOptions, List *defList, char *namspace, char *validnsps[], bool ignoreOids, bool isReset) |
| List * | untransformRelOptions (Datum options) |
| bytea * | extractRelOptions (HeapTuple tuple, TupleDesc tupdesc, Oid amoptions) |
| relopt_value * | parseRelOptions (Datum options, bool validate, relopt_kind kind, int *numrelopts) |
| void * | allocateReloptStruct (Size base, relopt_value *options, int numoptions) |
| void | fillRelOptions (void *rdopts, Size basesize, relopt_value *options, int numoptions, bool validate, const relopt_parse_elt *elems, int numelems) |
| bytea * | default_reloptions (Datum reloptions, bool validate, relopt_kind kind) |
| bytea * | heap_reloptions (char relkind, Datum reloptions, bool validate) |
| bytea * | index_reloptions (RegProcedure amoptions, Datum reloptions, bool validate) |
| bytea * | attribute_reloptions (Datum reloptions, bool validate) |
| bytea * | tablespace_reloptions (Datum reloptions, bool validate) |
Variables | |
| static relopt_bool | boolRelOpts [] |
| static relopt_int | intRelOpts [] |
| static relopt_real | realRelOpts [] |
| static relopt_string | stringRelOpts [] |
| static relopt_gen ** | relOpts = NULL |
| static bits32 | last_assigned_kind = RELOPT_KIND_LAST_DEFAULT |
| static int | num_custom_options = 0 |
| static relopt_gen ** | custom_options = NULL |
| static bool | need_initialization = true |
Definition at line 445 of file reloptions.c.
References add_reloption(), allocate_reloption(), relopt_bool::default_val, and RELOPT_TYPE_BOOL.
{
relopt_bool *newoption;
newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
name, desc);
newoption->default_val = default_val;
add_reloption((relopt_gen *) newoption);
}
| void add_int_reloption | ( | bits32 | kinds, | |
| char * | name, | |||
| char * | desc, | |||
| int | default_val, | |||
| int | min_val, | |||
| int | max_val | |||
| ) |
Definition at line 461 of file reloptions.c.
References add_reloption(), allocate_reloption(), relopt_int::default_val, relopt_int::max, relopt_int::min, and RELOPT_TYPE_INT.
{
relopt_int *newoption;
newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT,
name, desc);
newoption->default_val = default_val;
newoption->min = min_val;
newoption->max = max_val;
add_reloption((relopt_gen *) newoption);
}
| void add_real_reloption | ( | bits32 | kinds, | |
| char * | name, | |||
| char * | desc, | |||
| double | default_val, | |||
| double | min_val, | |||
| double | max_val | |||
| ) |
Definition at line 480 of file reloptions.c.
References add_reloption(), allocate_reloption(), relopt_real::default_val, relopt_real::max, relopt_real::min, and RELOPT_TYPE_REAL.
{
relopt_real *newoption;
newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL,
name, desc);
newoption->default_val = default_val;
newoption->min = min_val;
newoption->max = max_val;
add_reloption((relopt_gen *) newoption);
}
| static void add_reloption | ( | relopt_gen * | newoption | ) | [static] |
Definition at line 363 of file reloptions.c.
References MemoryContextSwitchTo(), need_initialization, num_custom_options, palloc(), repalloc(), and TopMemoryContext.
Referenced by add_bool_reloption(), add_int_reloption(), add_real_reloption(), and add_string_reloption().
{
static int max_custom_options = 0;
if (num_custom_options >= max_custom_options)
{
MemoryContext oldcxt;
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
if (max_custom_options == 0)
{
max_custom_options = 8;
custom_options = palloc(max_custom_options * sizeof(relopt_gen *));
}
else
{
max_custom_options *= 2;
custom_options = repalloc(custom_options,
max_custom_options * sizeof(relopt_gen *));
}
MemoryContextSwitchTo(oldcxt);
}
custom_options[num_custom_options++] = newoption;
need_initialization = true;
}
| relopt_kind add_reloption_kind | ( | void | ) |
Definition at line 346 of file reloptions.c.
References ereport, errcode(), errmsg(), ERROR, last_assigned_kind, and RELOPT_KIND_MAX.
{
/* don't hand out the last bit so that the enum's behavior is portable */
if (last_assigned_kind >= RELOPT_KIND_MAX)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("user-defined relation parameter types limit exceeded")));
last_assigned_kind <<= 1;
return (relopt_kind) last_assigned_kind;
}
| void add_string_reloption | ( | bits32 | kinds, | |
| char * | name, | |||
| char * | desc, | |||
| char * | default_val, | |||
| validate_string_relopt | validator | |||
| ) |
Definition at line 504 of file reloptions.c.
References add_reloption(), allocate_reloption(), relopt_string::default_isnull, relopt_string::default_len, relopt_string::default_val, MemoryContextStrdup(), RELOPT_TYPE_STRING, TopMemoryContext, and relopt_string::validate_cb.
{
relopt_string *newoption;
/* make sure the validator/default combination is sane */
if (validator)
(validator) (default_val);
newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING,
name, desc);
newoption->validate_cb = validator;
if (default_val)
{
newoption->default_val = MemoryContextStrdup(TopMemoryContext,
default_val);
newoption->default_len = strlen(default_val);
newoption->default_isnull = false;
}
else
{
newoption->default_val = "";
newoption->default_len = 0;
newoption->default_isnull = true;
}
add_reloption((relopt_gen *) newoption);
}
| static relopt_gen* allocate_reloption | ( | bits32 | kinds, | |
| int | type, | |||
| char * | name, | |||
| char * | desc | |||
| ) | [static] |
Definition at line 397 of file reloptions.c.
References relopt_gen::desc, elog, ERROR, relopt_gen::kinds, MemoryContextSwitchTo(), relopt_gen::name, relopt_gen::namelen, palloc(), pstrdup(), RELOPT_TYPE_BOOL, RELOPT_TYPE_INT, RELOPT_TYPE_REAL, RELOPT_TYPE_STRING, TopMemoryContext, and relopt_gen::type.
Referenced by add_bool_reloption(), add_int_reloption(), add_real_reloption(), and add_string_reloption().
{
MemoryContext oldcxt;
size_t size;
relopt_gen *newoption;
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
switch (type)
{
case RELOPT_TYPE_BOOL:
size = sizeof(relopt_bool);
break;
case RELOPT_TYPE_INT:
size = sizeof(relopt_int);
break;
case RELOPT_TYPE_REAL:
size = sizeof(relopt_real);
break;
case RELOPT_TYPE_STRING:
size = sizeof(relopt_string);
break;
default:
elog(ERROR, "unsupported option type");
return NULL; /* keep compiler quiet */
}
newoption = palloc(size);
newoption->name = pstrdup(name);
if (desc)
newoption->desc = pstrdup(desc);
else
newoption->desc = NULL;
newoption->kinds = kinds;
newoption->namelen = strlen(name);
newoption->type = type;
MemoryContextSwitchTo(oldcxt);
return newoption;
}
| void* allocateReloptStruct | ( | Size | base, | |
| relopt_value * | options, | |||
| int | numoptions | |||
| ) |
Definition at line 1024 of file reloptions.c.
References GET_STRING_RELOPTION_LEN, i, palloc0(), and RELOPT_TYPE_STRING.
Referenced by attribute_reloptions(), default_reloptions(), ginoptions(), gistoptions(), and tablespace_reloptions().
{
Size size = base;
int i;
for (i = 0; i < numoptions; i++)
if (options[i].gen->type == RELOPT_TYPE_STRING)
size += GET_STRING_RELOPTION_LEN(options[i]) + 1;
return palloc0(size);
}
Definition at line 1248 of file reloptions.c.
References allocateReloptStruct(), fillRelOptions(), lengthof, offsetof, parseRelOptions(), pfree(), and RELOPT_KIND_ATTRIBUTE.
Referenced by ATExecSetOptions(), and get_attribute_options().
{
relopt_value *options;
AttributeOpts *aopts;
int numoptions;
static const relopt_parse_elt tab[] = {
{"n_distinct", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct)},
{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
};
options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
&numoptions);
/* if none set, we're done */
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;
}
| bytea* default_reloptions | ( | Datum | reloptions, | |
| bool | validate, | |||
| relopt_kind | kind | |||
| ) |
Definition at line 1126 of file reloptions.c.
References allocateReloptStruct(), fillfactor, fillRelOptions(), lengthof, offsetof, parseRelOptions(), and pfree().
Referenced by btoptions(), hashoptions(), heap_reloptions(), and spgoptions().
{
relopt_value *options;
StdRdOptions *rdopts;
int numoptions;
static const relopt_parse_elt tab[] = {
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
{"autovacuum_enabled", RELOPT_TYPE_BOOL,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, enabled)},
{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_threshold)},
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_threshold)},
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_cost_delay)},
{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_cost_limit)},
{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, freeze_min_age)},
{"autovacuum_freeze_max_age", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, freeze_max_age)},
{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, freeze_table_age)},
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_scale_factor)},
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)},
{"security_barrier", RELOPT_TYPE_BOOL,
offsetof(StdRdOptions, security_barrier)},
};
options = parseRelOptions(reloptions, validate, kind, &numoptions);
/* if none set, we're done */
if (numoptions == 0)
return NULL;
rdopts = allocateReloptStruct(sizeof(StdRdOptions), options, numoptions);
fillRelOptions((void *) rdopts, sizeof(StdRdOptions), options, numoptions,
validate, tab, lengthof(tab));
pfree(options);
return (bytea *) rdopts;
}
Definition at line 772 of file reloptions.c.
References Anum_pg_class_reloptions, Assert, fastgetattr, GETSTRUCT, heap_reloptions(), index_reloptions(), RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_TOASTVALUE, and RELKIND_VIEW.
Referenced by extract_autovac_opts(), and RelationParseRelOptions().
{
bytea *options;
bool isnull;
Datum datum;
Form_pg_class classForm;
datum = fastgetattr(tuple,
Anum_pg_class_reloptions,
tupdesc,
&isnull);
if (isnull)
return NULL;
classForm = (Form_pg_class) GETSTRUCT(tuple);
/* Parse into appropriate format; don't error out here */
switch (classForm->relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_VIEW:
case RELKIND_MATVIEW:
options = heap_reloptions(classForm->relkind, datum, false);
break;
case RELKIND_INDEX:
options = index_reloptions(amoptions, datum, false);
break;
case RELKIND_FOREIGN_TABLE:
options = NULL;
break;
default:
Assert(false); /* can't get here */
options = NULL; /* keep compiler quiet */
break;
}
return options;
}
| void fillRelOptions | ( | void * | rdopts, | |
| Size | basesize, | |||
| relopt_value * | options, | |||
| int | numoptions, | |||
| bool | validate, | |||
| const relopt_parse_elt * | elems, | |||
| int | numelems | |||
| ) |
Definition at line 1048 of file reloptions.c.
References relopt_string::default_isnull, relopt_string::default_val, elog, ERROR, relopt_value::gen, i, NULL, relopt_parse_elt::offset, relopt_parse_elt::optname, pg_strcasecmp(), RELOPT_TYPE_BOOL, RELOPT_TYPE_INT, RELOPT_TYPE_REAL, RELOPT_TYPE_STRING, SET_VARSIZE, relopt_value::string_val, relopt_value::values, and values.
Referenced by attribute_reloptions(), default_reloptions(), ginoptions(), gistoptions(), and tablespace_reloptions().
{
int i;
int offset = basesize;
for (i = 0; i < numoptions; i++)
{
int j;
bool found = false;
for (j = 0; j < numelems; j++)
{
if (pg_strcasecmp(options[i].gen->name, elems[j].optname) == 0)
{
relopt_string *optstring;
char *itempos = ((char *) rdopts) + elems[j].offset;
char *string_val;
switch (options[i].gen->type)
{
case RELOPT_TYPE_BOOL:
*(bool *) itempos = options[i].isset ?
options[i].values.bool_val :
((relopt_bool *) options[i].gen)->default_val;
break;
case RELOPT_TYPE_INT:
*(int *) itempos = options[i].isset ?
options[i].values.int_val :
((relopt_int *) options[i].gen)->default_val;
break;
case RELOPT_TYPE_REAL:
*(double *) itempos = options[i].isset ?
options[i].values.real_val :
((relopt_real *) options[i].gen)->default_val;
break;
case RELOPT_TYPE_STRING:
optstring = (relopt_string *) options[i].gen;
if (options[i].isset)
string_val = options[i].values.string_val;
else if (!optstring->default_isnull)
string_val = optstring->default_val;
else
string_val = NULL;
if (string_val == NULL)
*(int *) itempos = 0;
else
{
strcpy((char *) rdopts + offset, string_val);
*(int *) itempos = offset;
offset += strlen(string_val) + 1;
}
break;
default:
elog(ERROR, "unrecognized reloption type %c",
options[i].gen->type);
break;
}
found = true;
break;
}
}
if (validate && !found)
elog(ERROR, "reloption \"%s\" not found in parse table",
options[i].gen->name);
}
SET_VARSIZE(rdopts, offset);
}
Definition at line 1177 of file reloptions.c.
References AutoVacOpts::analyze_scale_factor, AutoVacOpts::analyze_threshold, StdRdOptions::autovacuum, default_reloptions(), StdRdOptions::fillfactor, NULL, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_TOASTVALUE, RELKIND_VIEW, RELOPT_KIND_HEAP, RELOPT_KIND_TOAST, and RELOPT_KIND_VIEW.
Referenced by ATExecSetRelOptions(), DefineRelation(), extractRelOptions(), intorel_startup(), and ProcessUtilitySlow().
{
StdRdOptions *rdopts;
switch (relkind)
{
case RELKIND_TOASTVALUE:
rdopts = (StdRdOptions *)
default_reloptions(reloptions, validate, RELOPT_KIND_TOAST);
if (rdopts != NULL)
{
/* adjust default-only parameters for TOAST relations */
rdopts->fillfactor = 100;
rdopts->autovacuum.analyze_threshold = -1;
rdopts->autovacuum.analyze_scale_factor = -1;
}
return (bytea *) rdopts;
case RELKIND_RELATION:
case RELKIND_MATVIEW:
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
case RELKIND_VIEW:
return default_reloptions(reloptions, validate, RELOPT_KIND_VIEW);
default:
/* other relkinds are not supported */
return NULL;
}
}
| bytea* index_reloptions | ( | RegProcedure | amoptions, | |
| Datum | reloptions, | |||
| bool | validate | |||
| ) |
Definition at line 1214 of file reloptions.c.
References FunctionCallInfoData::arg, FunctionCallInfoData::argnull, Assert, BoolGetDatum, DatumGetByteaP, DatumGetPointer, fmgr_info(), FunctionCallInvoke, InitFunctionCallInfoData, InvalidOid, FunctionCallInfoData::isnull, NULL, PointerIsValid, and RegProcedureIsValid.
Referenced by ATExecSetRelOptions(), DefineIndex(), and extractRelOptions().
{
FmgrInfo flinfo;
FunctionCallInfoData fcinfo;
Datum result;
Assert(RegProcedureIsValid(amoptions));
/* Assume function is strict */
if (!PointerIsValid(DatumGetPointer(reloptions)))
return NULL;
/* Can't use OidFunctionCallN because we might get a NULL result */
fmgr_info(amoptions, &flinfo);
InitFunctionCallInfoData(fcinfo, &flinfo, 2, InvalidOid, NULL, NULL);
fcinfo.arg[0] = reloptions;
fcinfo.arg[1] = BoolGetDatum(validate);
fcinfo.argnull[0] = false;
fcinfo.argnull[1] = false;
result = FunctionCallInvoke(&fcinfo);
if (fcinfo.isnull || DatumGetPointer(result) == NULL)
return NULL;
return DatumGetByteaP(result);
}
| static void initialize_reloptions | ( | void | ) | [static] |
Definition at line 273 of file reloptions.c.
References relopt_string::gen, relopt_real::gen, relopt_int::gen, relopt_bool::gen, i, MemoryContextAlloc(), name, relopt_gen::name, relopt_gen::namelen, need_initialization, num_custom_options, pfree(), TopMemoryContext, and relopt_gen::type.
Referenced by parseRelOptions().
{
int i;
int j;
j = 0;
for (i = 0; boolRelOpts[i].gen.name; i++)
j++;
for (i = 0; intRelOpts[i].gen.name; i++)
j++;
for (i = 0; realRelOpts[i].gen.name; i++)
j++;
for (i = 0; stringRelOpts[i].gen.name; i++)
j++;
j += num_custom_options;
if (relOpts)
pfree(relOpts);
relOpts = MemoryContextAlloc(TopMemoryContext,
(j + 1) * sizeof(relopt_gen *));
j = 0;
for (i = 0; boolRelOpts[i].gen.name; i++)
{
relOpts[j] = &boolRelOpts[i].gen;
relOpts[j]->type = RELOPT_TYPE_BOOL;
relOpts[j]->namelen = strlen(relOpts[j]->name);
j++;
}
for (i = 0; intRelOpts[i].gen.name; i++)
{
relOpts[j] = &intRelOpts[i].gen;
relOpts[j]->type = RELOPT_TYPE_INT;
relOpts[j]->namelen = strlen(relOpts[j]->name);
j++;
}
for (i = 0; realRelOpts[i].gen.name; i++)
{
relOpts[j] = &realRelOpts[i].gen;
relOpts[j]->type = RELOPT_TYPE_REAL;
relOpts[j]->namelen = strlen(relOpts[j]->name);
j++;
}
for (i = 0; stringRelOpts[i].gen.name; i++)
{
relOpts[j] = &stringRelOpts[i].gen;
relOpts[j]->type = RELOPT_TYPE_STRING;
relOpts[j]->namelen = strlen(relOpts[j]->name);
j++;
}
for (i = 0; i < num_custom_options; i++)
{
relOpts[j] = custom_options[i];
j++;
}
/* add a list terminator */
relOpts[j] = NULL;
/* flag the work is complete */
need_initialization = false;
}
| static void parse_one_reloption | ( | relopt_value * | option, | |
| char * | text_str, | |||
| int | text_len, | |||
| bool | validate | |||
| ) | [static] |
Definition at line 927 of file reloptions.c.
References relopt_value::bool_val, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, relopt_value::gen, relopt_value::int_val, relopt_value::isset, relopt_real::max, relopt_int::max, relopt_real::min, relopt_int::min, relopt_gen::name, relopt_gen::namelen, NULL, palloc(), parse_bool(), parse_int(), parse_real(), pfree(), relopt_value::real_val, RELOPT_TYPE_BOOL, RELOPT_TYPE_INT, RELOPT_TYPE_REAL, RELOPT_TYPE_STRING, relopt_value::string_val, relopt_gen::type, relopt_string::validate_cb, value, and relopt_value::values.
Referenced by parseRelOptions().
{
char *value;
int value_len;
bool parsed;
bool nofree = false;
if (option->isset && validate)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("parameter \"%s\" specified more than once",
option->gen->name)));
value_len = text_len - option->gen->namelen - 1;
value = (char *) palloc(value_len + 1);
memcpy(value, text_str + option->gen->namelen + 1, value_len);
value[value_len] = '\0';
switch (option->gen->type)
{
case RELOPT_TYPE_BOOL:
{
parsed = parse_bool(value, &option->values.bool_val);
if (validate && !parsed)
ereport(ERROR,
(errmsg("invalid value for boolean option \"%s\": %s",
option->gen->name, value)));
}
break;
case RELOPT_TYPE_INT:
{
relopt_int *optint = (relopt_int *) option->gen;
parsed = parse_int(value, &option->values.int_val, 0, NULL);
if (validate && !parsed)
ereport(ERROR,
(errmsg("invalid value for integer option \"%s\": %s",
option->gen->name, value)));
if (validate && (option->values.int_val < optint->min ||
option->values.int_val > optint->max))
ereport(ERROR,
(errmsg("value %s out of bounds for option \"%s\"",
value, option->gen->name),
errdetail("Valid values are between \"%d\" and \"%d\".",
optint->min, optint->max)));
}
break;
case RELOPT_TYPE_REAL:
{
relopt_real *optreal = (relopt_real *) option->gen;
parsed = parse_real(value, &option->values.real_val);
if (validate && !parsed)
ereport(ERROR,
(errmsg("invalid value for floating point option \"%s\": %s",
option->gen->name, value)));
if (validate && (option->values.real_val < optreal->min ||
option->values.real_val > optreal->max))
ereport(ERROR,
(errmsg("value %s out of bounds for option \"%s\"",
value, option->gen->name),
errdetail("Valid values are between \"%f\" and \"%f\".",
optreal->min, optreal->max)));
}
break;
case RELOPT_TYPE_STRING:
{
relopt_string *optstring = (relopt_string *) option->gen;
option->values.string_val = value;
nofree = true;
if (validate && optstring->validate_cb)
(optstring->validate_cb) (value);
parsed = true;
}
break;
default:
elog(ERROR, "unsupported reloption type %d", option->gen->type);
parsed = true; /* quiet compiler */
break;
}
if (parsed)
option->isset = true;
if (!nofree)
pfree(value);
}
| relopt_value* parseRelOptions | ( | Datum | options, | |
| bool | validate, | |||
| relopt_kind | kind, | |||
| int * | numrelopts | |||
| ) |
Definition at line 831 of file reloptions.c.
References ARR_ELEMTYPE, Assert, DatumGetArrayTypeP, DatumGetPointer, DatumGetTextP, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, relopt_value::gen, i, initialize_reloptions(), relopt_value::isset, relopt_gen::namelen, need_initialization, NULL, palloc(), parse_one_reloption(), pg_strncasecmp(), PointerIsValid, TextDatumGetCString, TEXTOID, VARDATA, and VARSIZE.
Referenced by attribute_reloptions(), default_reloptions(), ginoptions(), gistoptions(), and tablespace_reloptions().
{
relopt_value *reloptions;
int numoptions = 0;
int i;
int j;
if (need_initialization)
initialize_reloptions();
/* Build a list of expected options, based on kind */
for (i = 0; relOpts[i]; i++)
if (relOpts[i]->kinds & kind)
numoptions++;
if (numoptions == 0)
{
*numrelopts = 0;
return NULL;
}
reloptions = palloc(numoptions * sizeof(relopt_value));
for (i = 0, j = 0; relOpts[i]; i++)
{
if (relOpts[i]->kinds & kind)
{
reloptions[j].gen = relOpts[i];
reloptions[j].isset = false;
j++;
}
}
/* Done if no options */
if (PointerIsValid(DatumGetPointer(options)))
{
ArrayType *array;
Datum *optiondatums;
int noptions;
array = DatumGetArrayTypeP(options);
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i',
&optiondatums, NULL, &noptions);
for (i = 0; i < noptions; i++)
{
text *optiontext = DatumGetTextP(optiondatums[i]);
char *text_str = VARDATA(optiontext);
int text_len = VARSIZE(optiontext) - VARHDRSZ;
int j;
/* Search for a match in reloptions */
for (j = 0; j < numoptions; j++)
{
int kw_len = reloptions[j].gen->namelen;
if (text_len > kw_len && text_str[kw_len] == '=' &&
pg_strncasecmp(text_str, reloptions[j].gen->name,
kw_len) == 0)
{
parse_one_reloption(&reloptions[j], text_str, text_len,
validate);
break;
}
}
if (j >= numoptions && validate)
{
char *s;
char *p;
s = TextDatumGetCString(optiondatums[i]);
p = strchr(s, '=');
if (p)
*p = '\0';
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter \"%s\"", s)));
}
}
}
*numrelopts = numoptions;
return reloptions;
}
Definition at line 1279 of file reloptions.c.
References allocateReloptStruct(), fillRelOptions(), lengthof, offsetof, parseRelOptions(), pfree(), random_page_cost, RELOPT_KIND_TABLESPACE, and seq_page_cost.
Referenced by AlterTableSpaceOptions(), and get_tablespace().
{
relopt_value *options;
TableSpaceOpts *tsopts;
int numoptions;
static const relopt_parse_elt tab[] = {
{"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)},
{"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)}
};
options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE,
&numoptions);
/* if none set, we're done */
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;
}
| Datum transformRelOptions | ( | Datum | oldOptions, | |
| List * | defList, | |||
| char * | namspace, | |||
| char * | validnsps[], | |||
| bool | ignoreOids, | |||
| bool | isReset | |||
| ) |
Definition at line 557 of file reloptions.c.
References accumArrayResult(), DefElem::arg, ARR_ELEMTYPE, Assert, CurrentMemoryContext, DatumGetArrayTypeP, DatumGetPointer, DatumGetTextP, deconstruct_array(), defGetString(), DefElem::defname, DefElem::defnamespace, ereport, errcode(), errmsg(), ERROR, i, lfirst, makeArrayResult(), NIL, NULL, palloc(), pg_strcasecmp(), pg_strncasecmp(), PointerGetDatum, PointerIsValid, SET_VARSIZE, TEXTOID, value, VARDATA, VARHDRSZ, and VARSIZE.
Referenced by AlterTableSpaceOptions(), ATExecSetOptions(), ATExecSetRelOptions(), DefineIndex(), DefineRelation(), intorel_startup(), and ProcessUtilitySlow().
{
Datum result;
ArrayBuildState *astate;
ListCell *cell;
/* no change if empty list */
if (defList == NIL)
return oldOptions;
/* We build new array using accumArrayResult */
astate = NULL;
/* Copy any oldOptions that aren't to be replaced */
if (PointerIsValid(DatumGetPointer(oldOptions)))
{
ArrayType *array = DatumGetArrayTypeP(oldOptions);
Datum *oldoptions;
int noldoptions;
int i;
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i',
&oldoptions, NULL, &noldoptions);
for (i = 0; i < noldoptions; i++)
{
text *oldoption = DatumGetTextP(oldoptions[i]);
char *text_str = VARDATA(oldoption);
int text_len = VARSIZE(oldoption) - VARHDRSZ;
/* Search for a match in defList */
foreach(cell, defList)
{
DefElem *def = (DefElem *) lfirst(cell);
int kw_len;
/* ignore if not in the same namespace */
if (namspace == NULL)
{
if (def->defnamespace != NULL)
continue;
}
else if (def->defnamespace == NULL)
continue;
else if (pg_strcasecmp(def->defnamespace, namspace) != 0)
continue;
kw_len = strlen(def->defname);
if (text_len > kw_len && text_str[kw_len] == '=' &&
pg_strncasecmp(text_str, def->defname, kw_len) == 0)
break;
}
if (!cell)
{
/* No match, so keep old option */
astate = accumArrayResult(astate, oldoptions[i],
false, TEXTOID,
CurrentMemoryContext);
}
}
}
/*
* If CREATE/SET, add new options to array; if RESET, just check that the
* user didn't say RESET (option=val). (Must do this because the grammar
* doesn't enforce it.)
*/
foreach(cell, defList)
{
DefElem *def = (DefElem *) lfirst(cell);
if (isReset)
{
if (def->arg != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("RESET must not include values for parameters")));
}
else
{
text *t;
const char *value;
Size len;
/*
* Error out if the namespace is not valid. A NULL namespace is
* always valid.
*/
if (def->defnamespace != NULL)
{
bool valid = false;
int i;
if (validnsps)
{
for (i = 0; validnsps[i]; i++)
{
if (pg_strcasecmp(def->defnamespace,
validnsps[i]) == 0)
{
valid = true;
break;
}
}
}
if (!valid)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter namespace \"%s\"",
def->defnamespace)));
}
if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
continue;
/* ignore if not in the same namespace */
if (namspace == NULL)
{
if (def->defnamespace != NULL)
continue;
}
else if (def->defnamespace == NULL)
continue;
else if (pg_strcasecmp(def->defnamespace, namspace) != 0)
continue;
/*
* Flatten the DefElem into a text string like "name=arg". If we
* have just "name", assume "name=true" is meant. Note: the
* namespace is not output.
*/
if (def->arg != NULL)
value = defGetString(def);
else
value = "true";
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
/* +1 leaves room for sprintf's trailing null */
t = (text *) palloc(len + 1);
SET_VARSIZE(t, len);
sprintf(VARDATA(t), "%s=%s", def->defname, value);
astate = accumArrayResult(astate, PointerGetDatum(t),
false, TEXTOID,
CurrentMemoryContext);
}
}
if (astate)
result = makeArrayResult(astate, CurrentMemoryContext);
else
result = (Datum) 0;
return result;
}
Definition at line 722 of file reloptions.c.
References ARR_ELEMTYPE, Assert, DatumGetArrayTypeP, DatumGetPointer, deconstruct_array(), i, lappend(), makeDefElem(), makeString(), NULL, PointerIsValid, pstrdup(), TextDatumGetCString, TEXTOID, and val.
Referenced by dblink_fdw_validator(), file_fdw_validator(), generateClonedIndexStmt(), GetForeignColumnOptions(), GetForeignDataWrapper(), GetForeignServer(), GetForeignTable(), GetUserMapping(), pg_options_to_table(), postgres_fdw_validator(), postgresql_fdw_validator(), and transformGenericOptions().
{
List *result = NIL;
ArrayType *array;
Datum *optiondatums;
int noptions;
int i;
/* Nothing to do if no options */
if (!PointerIsValid(DatumGetPointer(options)))
return result;
array = DatumGetArrayTypeP(options);
Assert(ARR_ELEMTYPE(array) == TEXTOID);
deconstruct_array(array, TEXTOID, -1, false, 'i',
&optiondatums, NULL, &noptions);
for (i = 0; i < noptions; i++)
{
char *s;
char *p;
Node *val = NULL;
s = TextDatumGetCString(optiondatums[i]);
p = strchr(s, '=');
if (p)
{
*p++ = '\0';
val = (Node *) makeString(pstrdup(p));
}
result = lappend(result, makeDefElem(pstrdup(s), val));
}
return result;
}
relopt_bool boolRelOpts[] [static] |
{
{
{
"autovacuum_enabled",
"Enables autovacuum in this relation",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST
},
true
},
{
{
"fastupdate",
"Enables \"fast update\" feature for this GIN index",
RELOPT_KIND_GIN
},
true
},
{
{
"security_barrier",
"View acts as a row security barrier",
RELOPT_KIND_VIEW
},
false
},
{{NULL}}
}
Definition at line 53 of file reloptions.c.
relopt_gen** custom_options = NULL [static] |
Definition at line 259 of file reloptions.c.
relopt_int intRelOpts[] [static] |
Definition at line 83 of file reloptions.c.
bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT [static] |
Definition at line 256 of file reloptions.c.
Referenced by add_reloption_kind().
bool need_initialization = true [static] |
Definition at line 260 of file reloptions.c.
Referenced by add_reloption(), initialize_reloptions(), and parseRelOptions().
int num_custom_options = 0 [static] |
Definition at line 258 of file reloptions.c.
Referenced by add_reloption(), and initialize_reloptions().
relopt_real realRelOpts[] [static] |
Definition at line 184 of file reloptions.c.
relopt_gen** relOpts = NULL [static] |
Definition at line 255 of file reloptions.c.
relopt_string stringRelOpts[] [static] |
{
{
{
"buffering",
"Enables buffering build for this GiST index",
RELOPT_KIND_GIST
},
4,
false,
gistValidateBufferingOption,
"auto"
},
{{NULL}}
}
Definition at line 238 of file reloptions.c.
1.7.1