static relopt_bool boolRelOpts[] =
{
{
{ "autosummarize", "Enables automatic summarization on this BRIN index",
RELOPT_KIND_BRIN,
AccessExclusiveLock
}, false
},
{
{ "autovacuum_enabled", "Enables autovacuum in this relation",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
}, true
},
{
{ "user_catalog_table", "Declare a table as an additional catalog table, e.g. for the purpose of logical replication",
RELOPT_KIND_HEAP,
AccessExclusiveLock
}, false
},
{
{ "fastupdate", "Enables \"fast update\" feature for this GIN index",
RELOPT_KIND_GIN,
AccessExclusiveLock
}, true
},
{
{ "security_barrier", "View acts as a row security barrier",
RELOPT_KIND_VIEW,
AccessExclusiveLock
}, false
},
{
{ "security_invoker", "Privileges on underlying relations are checked as the invoking user, not the view owner",
RELOPT_KIND_VIEW,
AccessExclusiveLock
}, false
},
{
{ "vacuum_truncate", "Enables vacuum to truncate empty pages at the end of this table",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
}, true
},
{
{ "deduplicate_items", "Enables \"deduplicate items\" feature for this btree index",
RELOPT_KIND_BTREE,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
}, true
}, /* list terminator */
{{NULL}}
};
static relopt_int intRelOpts[] =
{
{
{ "fillfactor", "Packs table pages only to this percentage",
RELOPT_KIND_HEAP,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
},
HEAP_DEFAULT_FILLFACTOR, HEAP_MIN_FILLFACTOR, 100
},
{
{ "fillfactor", "Packs btree index pages only to this percentage",
RELOPT_KIND_BTREE,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
},
BTREE_DEFAULT_FILLFACTOR, BTREE_MIN_FILLFACTOR, 100
},
{
{ "fillfactor", "Packs hash index pages only to this percentage",
RELOPT_KIND_HASH,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
},
HASH_DEFAULT_FILLFACTOR, HASH_MIN_FILLFACTOR, 100
},
{
{ "fillfactor", "Packs gist index pages only to this percentage",
RELOPT_KIND_GIST,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
},
GIST_DEFAULT_FILLFACTOR, GIST_MIN_FILLFACTOR, 100
},
{
{ "fillfactor", "Packs spgist index pages only to this percentage",
RELOPT_KIND_SPGIST,
ShareUpdateExclusiveLock /* since it applies only to later
* inserts */
},
SPGIST_DEFAULT_FILLFACTOR, SPGIST_MIN_FILLFACTOR, 100
},
{
{ "autovacuum_vacuum_threshold", "Minimum number of tuple updates or deletes prior to vacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0, INT_MAX
},
{
{ "autovacuum_vacuum_max_threshold", "Maximum number of tuple updates or deletes prior to vacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-2, -1, INT_MAX
},
{
{ "autovacuum_vacuum_insert_threshold", "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-2, -1, INT_MAX
},
{
{ "autovacuum_analyze_threshold", "Minimum number of tuple inserts, updates or deletes prior to analyze",
RELOPT_KIND_HEAP,
ShareUpdateExclusiveLock
},
-1, 0, INT_MAX
},
{
{ "autovacuum_vacuum_cost_limit", "Vacuum cost amount available before napping, for autovacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 1, 10000
},
{
{ "autovacuum_freeze_min_age", "Minimum age at which VACUUM should freeze a table row, for autovacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0, 1000000000
},
{
{ "autovacuum_multixact_freeze_min_age", "Minimum multixact age at which VACUUM should freeze a row multixact's, for autovacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0, 1000000000
},
{
{ "autovacuum_freeze_max_age", "Age at which to autovacuum a table to prevent transaction ID wraparound",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 100000, 2000000000
},
{
{ "autovacuum_multixact_freeze_max_age", "Multixact age at which to autovacuum a table to prevent multixact wraparound",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 10000, 2000000000
},
{
{ "autovacuum_freeze_table_age", "Age at which VACUUM should perform a full table sweep to freeze row versions",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
}, -1, 0, 2000000000
},
{
{ "autovacuum_multixact_freeze_table_age", "Age of multixact at which VACUUM should perform a full table sweep to freeze row versions",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
}, -1, 0, 2000000000
},
{
{ "log_autovacuum_min_duration", "Sets the minimum execution time above which autovacuum actions will be logged",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, -1, INT_MAX
},
{
{ "toast_tuple_target", "Sets the target tuple length at which external columns will be toasted",
RELOPT_KIND_HEAP,
ShareUpdateExclusiveLock
},
TOAST_TUPLE_TARGET, 128, TOAST_TUPLE_TARGET_MAIN
},
{
{ "pages_per_range", "Number of pages that each page range covers in a BRIN index",
RELOPT_KIND_BRIN,
AccessExclusiveLock
}, 128, 1, 131072
},
{
{ "gin_pending_list_limit", "Maximum size of the pending list for this GIN index, in kilobytes.",
RELOPT_KIND_GIN,
AccessExclusiveLock
},
-1, 64, MAX_KILOBYTES
},
{
{ "effective_io_concurrency", "Number of simultaneous requests that can be handled efficiently by the disk subsystem.",
RELOPT_KIND_TABLESPACE,
ShareUpdateExclusiveLock
},
-1, 0, MAX_IO_CONCURRENCY
},
{
{ "maintenance_io_concurrency", "Number of simultaneous requests that can be handled efficiently by the disk subsystem for maintenance work.",
RELOPT_KIND_TABLESPACE,
ShareUpdateExclusiveLock
},
-1, 0, MAX_IO_CONCURRENCY
},
{
{ "parallel_workers", "Number of parallel processes that can be used per executor node for this relation.",
RELOPT_KIND_HEAP,
ShareUpdateExclusiveLock
},
-1, 0, 1024
},
/* list terminator */
{{NULL}}
};
static relopt_real realRelOpts[] =
{
{
{ "autovacuum_vacuum_cost_delay", "Vacuum cost delay in milliseconds, for autovacuum",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0.0, 100.0
},
{
{ "autovacuum_vacuum_scale_factor", "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0.0, 100.0
},
{
{ "autovacuum_vacuum_insert_scale_factor", "Number of tuple inserts prior to vacuum as a fraction of reltuples",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 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,
ShareUpdateExclusiveLock
},
-1, 0.0, 100.0
},
{
{ "vacuum_max_eager_freeze_failure_rate", "Fraction of pages in a relation vacuum can scan and fail to freeze before disabling eager scanning.",
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
ShareUpdateExclusiveLock
},
-1, 0.0, 1.0
},
{
{ "seq_page_cost", "Sets the planner's estimate of the cost of a sequentially fetched disk page.",
RELOPT_KIND_TABLESPACE,
ShareUpdateExclusiveLock
},
-1, 0.0, DBL_MAX
},
{
{ "random_page_cost", "Sets the planner's estimate of the cost of a nonsequentially fetched disk page.",
RELOPT_KIND_TABLESPACE,
ShareUpdateExclusiveLock
},
-1, 0.0, DBL_MAX
},
{
{ "n_distinct", "Sets the planner's estimate of the number of distinct values appearing in a column (excluding child relations).",
RELOPT_KIND_ATTRIBUTE,
ShareUpdateExclusiveLock
}, 0, -1.0, DBL_MAX
},
{
{ "n_distinct_inherited", "Sets the planner's estimate of the number of distinct values appearing in a column (including child relations).",
RELOPT_KIND_ATTRIBUTE,
ShareUpdateExclusiveLock
}, 0, -1.0, DBL_MAX
},
{
{ "vacuum_cleanup_index_scale_factor", "Deprecated B-Tree parameter.",
RELOPT_KIND_BTREE,
ShareUpdateExclusiveLock
},
-1, 0.0, 1e10
}, /* list terminator */
{{NULL}}
};
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; enumRelOpts[i].gen.name; i++)
{
relOpts[j] = &enumRelOpts[i].gen;
relOpts[j]->type = RELOPT_TYPE_ENUM;
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;
}
/* *add_reloption_kind *Createanewrelopt_kindvalue,tobeusedincustomreloptionsby *user-definedAMs.
*/
relopt_kind
add_reloption_kind(void)
{ /* 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;
}
/* 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;
for (i = 0; i < noldoptions; i++)
{ char *text_str = VARDATA(oldoptions[i]); int text_len = VARSIZE(oldoptions[i]) - 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;
} elseif (def->defnamespace == NULL) continue; elseif (strcmp(def->defnamespace, namspace) != 0) continue;
kw_len = strlen(def->defname); if (text_len > kw_len && text_str[kw_len] == '=' &&
strncmp(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 (isReset)
{ if (def->arg != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("RESET must not include values for parameters")));
} else
{ constchar *name; constchar *value;
text *t;
Size len;
/* *Erroroutifthenamespaceisnotvalid.ANULLnamespaceis *alwaysvalid.
*/ if (def->defnamespace != NULL)
{ bool valid = false; int i;
if (validnsps)
{ for (i = 0; validnsps[i]; i++)
{ if (strcmp(def->defnamespace, validnsps[i]) == 0)
{
valid = true; break;
}
}
}
if (!valid)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter namespace \"%s\"",
def->defnamespace)));
}
/* ignore if not in the same namespace */ if (namspace == NULL)
{ if (def->defnamespace != NULL) continue;
} elseif (def->defnamespace == NULL) continue; elseif (strcmp(def->defnamespace, namspace) != 0) continue;
/* *FlattentheDefElemintoatextstringlike"name=arg".Ifwe *havejust"name",assume"name=true"ismeant.Note:the *namespaceisnotoutput.
*/
name = def->defname; if (def->arg != NULL)
value = defGetString(def); else
value = "true";
/* Insist that name not contain "=", else "a=b=c" is ambiguous */ if (strchr(name, '=') != NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid option name \"%s\": must not contain \"=\"",
name)));
/* *Thisisnotagreatplaceforthistest,butthere'snoother *convenientplacetofiltertheoptionout.AsWITH(oids= *false)willberemovedsomeday,thisseemslikeanacceptable *amountofugly.
*/ if (acceptOidsOff && def->defnamespace == NULL &&
strcmp(name, "oids") == 0)
{ if (defGetBoolean(def))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("tables declared WITH OIDS are not supported"))); /* skip over option, reloptions machinery doesn't know it */ continue;
}
if (astate)
result = makeArrayResult(astate, CurrentMemoryContext); else
result = (Datum) 0;
return result;
}
/* *Convertthetext-arrayformatofreloptionsintoaListofDefElem. *ThisistheinverseoftransformRelOptions().
*/
List *
untransformRelOptions(Datum options)
{
List *result = NIL;
ArrayType *array;
Datum *optiondatums; int noptions; int i;
/* Nothing to do if no options */ if (!PointerIsValid(DatumGetPointer(options))) return result;
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_MATVIEW:
options = heap_reloptions(classForm->relkind, datum, false); break; case RELKIND_PARTITIONED_TABLE:
options = partitioned_table_reloptions(datum, false); break; case RELKIND_VIEW:
options = view_reloptions(datum, false); break; case RELKIND_INDEX: case RELKIND_PARTITIONED_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;
}
staticvoid
parseRelOptionsInternal(Datum options, bool validate,
relopt_value *reloptions, int numoptions)
{
ArrayType *array = DatumGetArrayTypeP(options);
Datum *optiondatums; int noptions; int i;
if (option->isset && validate)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("parameter \"%s\" specified more than once",
option->gen->name)));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.