#include "access/htup.h"#include "access/tupdesc.h"#include "nodes/pg_list.h"

Go to the source code of this file.
Data Structures | |
| struct | relopt_gen |
| struct | relopt_value |
| struct | relopt_bool |
| struct | relopt_int |
| struct | relopt_real |
| struct | relopt_string |
| struct | relopt_parse_elt |
Defines | |
| #define | HEAP_RELOPT_NAMESPACES { "toast", NULL } |
| #define | HAVE_RELOPTION(optname, option) (pg_strncasecmp(option.gen->name, optname, option.gen->namelen + 1) == 0) |
| #define | HANDLE_INT_RELOPTION(optname, var, option, wasset) |
| #define | HANDLE_BOOL_RELOPTION(optname, var, option, wasset) |
| #define | HANDLE_REAL_RELOPTION(optname, var, option, wasset) |
| #define | HANDLE_STRING_RELOPTION(optname, var, option, base, offset, wasset) |
| #define | GET_STRING_RELOPTION_LEN(option) |
| #define | GET_STRING_RELOPTION(optstruct, member) |
Typedefs | |
| typedef enum relopt_type | relopt_type |
| typedef enum relopt_kind | relopt_kind |
| typedef struct relopt_gen | relopt_gen |
| typedef struct relopt_value | relopt_value |
| typedef struct relopt_bool | relopt_bool |
| typedef struct relopt_int | relopt_int |
| typedef struct relopt_real | relopt_real |
| typedef void(* | validate_string_relopt )(char *value) |
| typedef struct relopt_string | relopt_string |
Enumerations | |
| enum | relopt_type { RELOPT_TYPE_BOOL, RELOPT_TYPE_INT, RELOPT_TYPE_REAL, RELOPT_TYPE_STRING } |
| enum | relopt_kind { 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), RELOPT_KIND_ATTRIBUTE = (1 << 6), RELOPT_KIND_TABLESPACE = (1 << 7), RELOPT_KIND_SPGIST = (1 << 8), RELOPT_KIND_VIEW = (1 << 9), RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_VIEW, RELOPT_KIND_MAX = (1 << 30) } |
Functions | |
| relopt_kind | add_reloption_kind (void) |
| 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 nelems) |
| 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) |
| #define GET_STRING_RELOPTION | ( | optstruct, | ||
| member | ||||
| ) |
((optstruct)->member == 0 ? NULL : \ (char *)(optstruct) + (optstruct)->member)
Definition at line 238 of file reloptions.h.
| #define GET_STRING_RELOPTION_LEN | ( | option | ) |
((option).isset ? strlen((option).values.string_val) : \ ((relopt_string *) (option).gen)->default_len)
Definition at line 229 of file reloptions.h.
Referenced by allocateReloptStruct().
| #define HANDLE_BOOL_RELOPTION | ( | optname, | ||
| var, | ||||
| option, | ||||
| wasset | ||||
| ) |
do { \ if (option.isset) \ var = option.values.bool_val; \ else \ var = ((relopt_bool *) option.gen)->default_val; \ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \ } while (0)
Definition at line 175 of file reloptions.h.
| #define HANDLE_INT_RELOPTION | ( | optname, | ||
| var, | ||||
| option, | ||||
| wasset | ||||
| ) |
do { \ if (option.isset) \ var = option.values.int_val; \ else \ var = ((relopt_int *) option.gen)->default_val; \ (wasset) != NULL ? *(wasset) = option.isset : (dummyret)NULL; \ } while (0)
Definition at line 166 of file reloptions.h.
| #define HANDLE_REAL_RELOPTION | ( | optname, | ||
| var, | ||||
| option, | ||||
| wasset | ||||
| ) |
do { \ if (option.isset) \ var = option.values.real_val; \ else \ var = ((relopt_real *) option.gen)->default_val; \ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \ } while (0)
Definition at line 184 of file reloptions.h.
| #define HANDLE_STRING_RELOPTION | ( | optname, | ||
| var, | ||||
| option, | ||||
| base, | ||||
| offset, | ||||
| wasset | ||||
| ) |
do { \ relopt_string *optstring = (relopt_string *) option.gen;\ char *string_val; \ if (option.isset) \ string_val = option.values.string_val; \ else if (!optstring->default_isnull) \ string_val = optstring->default_val; \ else \ string_val = NULL; \ (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \ if (string_val == NULL) \ var = 0; \ else \ { \ strcpy(((char *)(base)) + (offset), string_val); \ var = (offset); \ (offset) += strlen(string_val) + 1; \ } \ } while (0)
Definition at line 204 of file reloptions.h.
| #define HAVE_RELOPTION | ( | optname, | ||
| option | ||||
| ) | (pg_strncasecmp(option.gen->name, optname, option.gen->namelen + 1) == 0) |
Definition at line 163 of file reloptions.h.
| #define HEAP_RELOPT_NAMESPACES { "toast", NULL } |
Definition at line 55 of file reloptions.h.
| typedef struct relopt_bool relopt_bool |
| typedef struct relopt_gen relopt_gen |
| typedef struct relopt_int relopt_int |
| typedef enum relopt_kind relopt_kind |
| typedef struct relopt_real relopt_real |
| typedef struct relopt_string relopt_string |
| typedef enum relopt_type relopt_type |
| typedef struct relopt_value relopt_value |
| typedef void(* validate_string_relopt)(char *value) |
Definition at line 106 of file reloptions.h.
| enum relopt_kind |
Definition at line 36 of file reloptions.h.
{
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),
RELOPT_KIND_ATTRIBUTE = (1 << 6),
RELOPT_KIND_TABLESPACE = (1 << 7),
RELOPT_KIND_SPGIST = (1 << 8),
RELOPT_KIND_VIEW = (1 << 9),
/* if you add a new kind, make sure you update "last_default" too */
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_VIEW,
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
RELOPT_KIND_MAX = (1 << 30)
} relopt_kind;
| enum relopt_type |
Definition at line 27 of file reloptions.h.
{
RELOPT_TYPE_BOOL,
RELOPT_TYPE_INT,
RELOPT_TYPE_REAL,
RELOPT_TYPE_STRING
} relopt_type;
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);
}
| 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);
}
| 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 | nelems | |||
| ) |
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);
}
| 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;
}
1.7.1