Revert: Custom reloptions for table AM

This commit reverts 9bd99f4c26 and 422041542f per review by Andres Freund.

Discussion: https://postgr.es/m/20240410165236.rwyrny7ihi4ddxw4%40awork3.anarazel.de
This commit is contained in:
Alexander Korotkov 2024-04-11 15:46:35 +03:00
parent 87840b9741
commit bc1e2092eb
29 changed files with 161 additions and 650 deletions

View File

@ -24,7 +24,6 @@
#include "access/nbtree.h"
#include "access/reloptions.h"
#include "access/spgist_private.h"
#include "access/tableam.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/tablespace.h"
@ -45,7 +44,7 @@
* value, upper and lower bounds (if applicable); for strings, consider a
* validation routine.
* (ii) add a record below (or use add_<type>_reloption).
* (iii) add it to the appropriate options struct (perhaps HeapRdOptions)
* (iii) add it to the appropriate options struct (perhaps StdRdOptions)
* (iv) add it to the appropriate handling routine (perhaps
* default_reloptions)
* (v) make sure the lock level is set correctly for that operation
@ -1375,16 +1374,10 @@ untransformRelOptions(Datum options)
* tupdesc is pg_class' tuple descriptor. amoptions is a pointer to the index
* AM's options parser function in the case of a tuple corresponding to an
* index, or NULL otherwise.
*
* If common pointer is provided, then the corresponding struct will be
* filled with options that table AM exposes for external usage. That must
* be filled with defaults before passing here.
*/
bytea *
extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
const TableAmRoutine *tableam, amoptions_function amoptions,
CommonRdOptions *common)
amoptions_function amoptions)
{
bytea *options;
bool isnull;
@ -1406,8 +1399,7 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
options = tableam_reloptions(tableam, classForm->relkind,
datum, common, false);
options = heap_reloptions(classForm->relkind, datum, false);
break;
case RELKIND_PARTITIONED_TABLE:
options = partitioned_table_reloptions(datum, false);
@ -1703,7 +1695,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
* Given the result from parseRelOptions, allocate a struct that's of the
* specified base size plus any extra space that's needed for string variables.
*
* "base" should be sizeof(struct) of the reloptions struct (HeapRdOptions or
* "base" should be sizeof(struct) of the reloptions struct (StdRdOptions or
* equivalent).
*/
static void *
@ -1840,95 +1832,59 @@ fillRelOptions(void *rdopts, Size basesize,
/*
* Option parser for anything that uses HeapRdOptions.
* Option parser for anything that uses StdRdOptions.
*/
static bytea *
bytea *
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
{
static const relopt_parse_elt tab[] = {
{"fillfactor", RELOPT_TYPE_INT, offsetof(HeapRdOptions, fillfactor)},
{"fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor)},
{"autovacuum_enabled", RELOPT_TYPE_BOOL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, enabled)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled)},
{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_threshold)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
{"autovacuum_vacuum_insert_threshold", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_ins_threshold)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_ins_threshold)},
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, analyze_threshold)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)},
{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_cost_limit)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)},
{"autovacuum_freeze_min_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, freeze_min_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_min_age)},
{"autovacuum_freeze_max_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, freeze_max_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_max_age)},
{"autovacuum_freeze_table_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, freeze_table_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_table_age)},
{"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, multixact_freeze_min_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_min_age)},
{"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, multixact_freeze_max_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_max_age)},
{"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, multixact_freeze_table_age)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)},
{"log_autovacuum_min_duration", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, log_min_duration)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)},
{"toast_tuple_target", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, toast_tuple_target)},
offsetof(StdRdOptions, toast_tuple_target)},
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_cost_delay)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_scale_factor)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)},
{"autovacuum_vacuum_insert_scale_factor", RELOPT_TYPE_REAL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, vacuum_ins_scale_factor)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_ins_scale_factor)},
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, autovacuum) +
offsetof(AutoVacOpts, analyze_scale_factor)},
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_scale_factor)},
{"user_catalog_table", RELOPT_TYPE_BOOL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, user_catalog_table)},
offsetof(StdRdOptions, user_catalog_table)},
{"parallel_workers", RELOPT_TYPE_INT,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, parallel_workers)},
offsetof(StdRdOptions, parallel_workers)},
{"vacuum_index_cleanup", RELOPT_TYPE_ENUM,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, vacuum_index_cleanup)},
offsetof(StdRdOptions, vacuum_index_cleanup)},
{"vacuum_truncate", RELOPT_TYPE_BOOL,
offsetof(HeapRdOptions, common) +
offsetof(CommonRdOptions, vacuum_truncate)}
offsetof(StdRdOptions, vacuum_truncate)}
};
return (bytea *) build_reloptions(reloptions, validate, kind,
sizeof(HeapRdOptions),
sizeof(StdRdOptions),
tab, lengthof(tab));
}
@ -2056,65 +2012,30 @@ view_reloptions(Datum reloptions, bool validate)
tab, lengthof(tab));
}
/*
* Fill CommonRdOptions with the default values.
*/
void
fill_default_common_reloptions(CommonRdOptions *common)
{
common->autovacuum.enabled = true;
common->autovacuum.vacuum_threshold = -1;
common->autovacuum.vacuum_ins_threshold = -2;
common->autovacuum.analyze_threshold = -1;
common->autovacuum.vacuum_cost_limit = -1;
common->autovacuum.freeze_min_age = -1;
common->autovacuum.freeze_max_age = -1;
common->autovacuum.freeze_table_age = -1;
common->autovacuum.multixact_freeze_min_age = -1;
common->autovacuum.multixact_freeze_max_age = -1;
common->autovacuum.multixact_freeze_table_age = -1;
common->autovacuum.log_min_duration = -1;
common->autovacuum.vacuum_cost_delay = -1;
common->autovacuum.vacuum_scale_factor = -1;
common->autovacuum.vacuum_ins_scale_factor = -1;
common->autovacuum.analyze_scale_factor = -1;
common->parallel_workers = -1;
common->user_catalog_table = false;
common->vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO;
common->vacuum_truncate = true;
}
/*
* Parse options for heaps, views and toast tables.
*/
bytea *
heap_reloptions(char relkind, Datum reloptions,
CommonRdOptions *common, bool validate)
heap_reloptions(char relkind, Datum reloptions, bool validate)
{
HeapRdOptions *rdopts;
StdRdOptions *rdopts;
switch (relkind)
{
case RELKIND_TOASTVALUE:
rdopts = (HeapRdOptions *)
rdopts = (StdRdOptions *)
default_reloptions(reloptions, validate, RELOPT_KIND_TOAST);
if (rdopts != NULL)
{
/* adjust default-only parameters for TOAST relations */
rdopts->fillfactor = 100;
rdopts->common.autovacuum.analyze_threshold = -1;
rdopts->common.autovacuum.analyze_scale_factor = -1;
rdopts->autovacuum.analyze_threshold = -1;
rdopts->autovacuum.analyze_scale_factor = -1;
}
if (rdopts != NULL && common != NULL)
*common = rdopts->common;
return (bytea *) rdopts;
case RELKIND_RELATION:
case RELKIND_MATVIEW:
rdopts = (HeapRdOptions *)
default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
if (rdopts != NULL && common != NULL)
*common = rdopts->common;
return (bytea *) rdopts;
return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
default:
/* other relkinds are not supported */
return NULL;

View File

@ -2279,8 +2279,8 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
Assert(!(options & HEAP_INSERT_NO_LOGICAL));
needwal = RelationNeedsWAL(relation);
saveFreeSpace = HeapGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
/* Toast and set header data in all the slots */
heaptuples = palloc(ntuples * sizeof(HeapTuple));

View File

@ -23,7 +23,6 @@
#include "access/heapam.h"
#include "access/heaptoast.h"
#include "access/multixact.h"
#include "access/reloptions.h"
#include "access/rewriteheap.h"
#include "access/syncscan.h"
#include "access/tableam.h"
@ -2162,17 +2161,6 @@ heapam_relation_toast_am(Relation rel)
return rel->rd_rel->relam;
}
static bytea *
heapam_reloptions(char relkind, Datum reloptions,
CommonRdOptions *common, bool validate)
{
Assert(relkind == RELKIND_RELATION ||
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_MATVIEW);
return heap_reloptions(relkind, reloptions, common, validate);
}
/* ------------------------------------------------------------------------
* Planner related callbacks for the heap AM
@ -2734,7 +2722,6 @@ static const TableAmRoutine heapam_methods = {
.relation_needs_toast_table = heapam_relation_needs_toast_table,
.relation_toast_am = heapam_relation_toast_am,
.relation_fetch_toast_slice = heap_fetch_toast_slice,
.reloptions = heapam_reloptions,
.relation_estimate_size = heapam_estimate_rel_size,

View File

@ -32,13 +32,6 @@
#include "access/toast_internals.h"
#include "utils/fmgroids.h"
/*
* HeapGetToastTupleTarget
* Returns the heap relation's toast_tuple_target. Note multiple eval of argument!
*/
#define HeapGetToastTupleTarget(relation, defaulttarg) \
((HeapRdOptions *) (relation)->rd_options ? \
((HeapRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
/* ----------
* heap_toast_delete -
@ -181,7 +174,7 @@ heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
hoff += BITMAPLEN(numAttrs);
hoff = MAXALIGN(hoff);
/* now convert to a limit on the tuple data size */
maxDataLen = HeapGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff;
maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff;
/*
* Look for attributes with attstorage EXTENDED to compress. Also find

View File

@ -536,8 +536,8 @@ RelationGetBufferForTuple(Relation relation, Size len,
len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = HeapGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
saveFreeSpace = RelationGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
/*
* Since pages without tuples can still have line pointers, we consider

View File

@ -235,8 +235,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
* important than sometimes getting a wrong answer in what is after all
* just a heuristic estimate.
*/
minfree = HeapGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
minfree = RelationGetTargetPageFreeSpace(relation,
HEAP_DEFAULT_FILLFACTOR);
minfree = Max(minfree, BLCKSZ / 10);
if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)

View File

@ -641,8 +641,8 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
len, MaxHeapTupleSize)));
/* Compute desired extra freespace due to fillfactor option */
saveFreeSpace = HeapGetTargetPageFreeSpace(state->rs_new_rel,
HEAP_DEFAULT_FILLFACTOR);
saveFreeSpace = RelationGetTargetPageFreeSpace(state->rs_new_rel,
HEAP_DEFAULT_FILLFACTOR);
/* Now we can check to see if there's enough free space already. */
page = (Page) state->rs_buffer;

View File

@ -750,7 +750,7 @@ table_block_relation_estimate_size(Relation rel, int32 *attr_widths,
* The other branch considers it implicitly by calculating density
* from actual relpages/reltuples statistics.
*/
fillfactor = HeapGetFillFactor(rel, HEAP_DEFAULT_FILLFACTOR);
fillfactor = RelationGetFillFactor(rel, HEAP_DEFAULT_FILLFACTOR);
tuple_width = get_rel_data_width(rel, attr_widths);
tuple_width += overhead_bytes_per_tuple;

View File

@ -13,11 +13,9 @@
#include "access/tableam.h"
#include "access/xact.h"
#include "catalog/pg_am.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "utils/guc_hooks.h"
#include "utils/syscache.h"
/*
@ -100,29 +98,6 @@ GetTableAmRoutine(Oid amhandler)
return routine;
}
/*
* GetTableAmRoutineByAmOid
* Given the table access method oid get its TableAmRoutine struct, which
* will be palloc'd in the caller's memory context.
*/
const TableAmRoutine *
GetTableAmRoutineByAmOid(Oid amoid)
{
HeapTuple ht_am;
Form_pg_am amrec;
const TableAmRoutine *tableam = NULL;
ht_am = SearchSysCache1(AMOID, ObjectIdGetDatum(amoid));
if (!HeapTupleIsValid(ht_am))
elog(ERROR, "cache lookup failed for access method %u",
amoid);
amrec = (Form_pg_am) GETSTRUCT(ht_am);
tableam = GetTableAmRoutine(amrec->amhandler);
ReleaseSysCache(ht_am);
return tableam;
}
/* check_hook: validate new default_table_access_method */
bool
check_default_table_access_method(char **newval, void **extra, GucSource source)

View File

@ -85,9 +85,6 @@ create_ctas_internal(List *attrList, IntoClause *into)
Datum toast_options;
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
ObjectAddress intoRelationAddr;
const TableAmRoutine *tableam = NULL;
Oid accessMethodId = InvalidOid;
Relation rel;
/* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */
is_matview = (into->viewQuery != NULL);
@ -128,15 +125,7 @@ create_ctas_internal(List *attrList, IntoClause *into)
validnsps,
true, false);
rel = relation_open(intoRelationAddr.objectId, AccessShareLock);
accessMethodId = table_relation_toast_am(rel);
relation_close(rel, AccessShareLock);
if (OidIsValid(accessMethodId))
{
tableam = GetTableAmRoutineByAmOid(accessMethodId);
(void) tableam_reloptions(tableam, RELKIND_TOASTVALUE, toast_options, NULL, true);
}
(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true);
NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options);

View File

@ -720,7 +720,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
ObjectAddress address;
LOCKMODE parentLockmode;
Oid accessMethodId = InvalidOid;
const TableAmRoutine *tableam = NULL;
/*
* Truncate relname to appropriate length (probably a waste of time, as
@ -856,28 +855,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
if (!OidIsValid(ownerId))
ownerId = GetUserId();
/*
* For relations with table AM and partitioned tables, select access
* method to use: an explicitly indicated one, or (in the case of a
* partitioned table) the parent's, if it has one.
*/
if (stmt->accessMethod != NULL)
{
Assert(RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE);
accessMethodId = get_table_am_oid(stmt->accessMethod, false);
}
else if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE)
{
if (stmt->partbound)
{
Assert(list_length(inheritOids) == 1);
accessMethodId = get_rel_relam(linitial_oid(inheritOids));
}
if (RELKIND_HAS_TABLE_AM(relkind) && !OidIsValid(accessMethodId))
accessMethodId = get_table_am_oid(default_table_access_method, false);
}
/*
* Parse and validate reloptions, if any.
*/
@ -886,12 +863,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
switch (relkind)
{
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
tableam = GetTableAmRoutineByAmOid(accessMethodId);
(void) tableam_reloptions(tableam, relkind, reloptions, NULL, true);
break;
case RELKIND_VIEW:
(void) view_reloptions(reloptions, true);
break;
@ -899,12 +870,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
(void) partitioned_table_reloptions(reloptions, true);
break;
default:
if (OidIsValid(accessMethodId))
{
tableam = GetTableAmRoutineByAmOid(accessMethodId);
(void) tableam_reloptions(tableam, relkind, reloptions, NULL, true);
}
break;
(void) heap_reloptions(relkind, reloptions, true);
}
if (stmt->ofTypename)
@ -996,6 +962,28 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
}
}
/*
* For relations with table AM and partitioned tables, select access
* method to use: an explicitly indicated one, or (in the case of a
* partitioned table) the parent's, if it has one.
*/
if (stmt->accessMethod != NULL)
{
Assert(RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE);
accessMethodId = get_table_am_oid(stmt->accessMethod, false);
}
else if (RELKIND_HAS_TABLE_AM(relkind) || relkind == RELKIND_PARTITIONED_TABLE)
{
if (stmt->partbound)
{
Assert(list_length(inheritOids) == 1);
accessMethodId = get_rel_relam(linitial_oid(inheritOids));
}
if (RELKIND_HAS_TABLE_AM(relkind) && !OidIsValid(accessMethodId))
accessMethodId = get_table_am_oid(default_table_access_method, false);
}
/*
* Create the relation. Inherited defaults and constraints are passed in
* for immediate handling --- since they don't need parsing, they can be
@ -15583,8 +15571,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
case RELKIND_RELATION:
case RELKIND_TOASTVALUE:
case RELKIND_MATVIEW:
(void) table_reloptions(rel, rel->rd_rel->relkind,
newOptions, NULL, true);
(void) heap_reloptions(rel->rd_rel->relkind, newOptions, true);
break;
case RELKIND_PARTITIONED_TABLE:
(void) partitioned_table_reloptions(newOptions, true);
@ -15697,7 +15684,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
defList, "toast", validnsps, false,
operation == AT_ResetRelOptions);
(void) table_reloptions(rel, RELKIND_TOASTVALUE, newOptions, NULL, true);
(void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
memset(repl_val, 0, sizeof(repl_val));
memset(repl_null, false, sizeof(repl_null));

View File

@ -2121,11 +2121,11 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
{
StdRdOptIndexCleanup vacuum_index_cleanup;
if (rel->rd_common_options == NULL)
if (rel->rd_options == NULL)
vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO;
else
vacuum_index_cleanup =
rel->rd_common_options->vacuum_index_cleanup;
((StdRdOptions *) rel->rd_options)->vacuum_index_cleanup;
if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO)
params->index_cleanup = VACOPTVALUE_AUTO;
@ -2145,8 +2145,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
*/
if (params->truncate == VACOPTVALUE_UNSPECIFIED)
{
if (rel->rd_common_options == NULL ||
rel->rd_common_options->vacuum_truncate)
if (rel->rd_options == NULL ||
((StdRdOptions *) rel->rd_options)->vacuum_truncate)
params->truncate = VACOPTVALUE_ENABLED;
else
params->truncate = VACOPTVALUE_DISABLED;

View File

@ -2674,22 +2674,19 @@ static AutoVacOpts *
extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
{
bytea *relopts;
CommonRdOptions common;
AutoVacOpts *av;
Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
fill_default_common_reloptions(&common);
relopts = extractRelOptions(tup, pg_class_desc,
GetTableAmRoutineByAmOid(((Form_pg_class) GETSTRUCT(tup))->relam),
NULL, &common);
if (relopts)
pfree(relopts);
relopts = extractRelOptions(tup, pg_class_desc, NULL);
if (relopts == NULL)
return NULL;
av = palloc(sizeof(AutoVacOpts));
memcpy(av, &(common.autovacuum), sizeof(AutoVacOpts));
memcpy(av, &(((StdRdOptions *) relopts)->autovacuum), sizeof(AutoVacOpts));
pfree(relopts);
return av;
}

View File

@ -65,7 +65,6 @@
#include "utils/acl.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "access/relation.h"
/* Hook for plugins to get control in ProcessUtility() */
ProcessUtility_hook_type ProcessUtility_hook = NULL;
@ -1157,9 +1156,6 @@ ProcessUtilitySlow(ParseState *pstate,
CreateStmt *cstmt = (CreateStmt *) stmt;
Datum toast_options;
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
const TableAmRoutine *tableam = NULL;
Oid accessMethodId;
Relation rel;
/* Remember transformed RangeVar for LIKE */
table_rv = cstmt->relation;
@ -1189,27 +1185,9 @@ ProcessUtilitySlow(ParseState *pstate,
validnsps,
true,
false);
/*
* Get toast table AM to validate its options.
* Only relevant if table itself has a table AM.
* We don't need to place the lock given that
* DefineRelation() already placed the
* AccessExclusiveLock.
*/
rel = relation_open(address.objectId, NoLock);
accessMethodId = rel->rd_tableam ?
table_relation_toast_am(rel) : InvalidOid;
relation_close(rel, NoLock);
if (OidIsValid(accessMethodId))
{
tableam = GetTableAmRoutineByAmOid(accessMethodId);
(void) tableam_reloptions(tableam, RELKIND_TOASTVALUE,
toast_options,
NULL,
true);
}
(void) heap_reloptions(RELKIND_TOASTVALUE,
toast_options,
true);
NewRelationCreateToastTable(address.objectId,
toast_options);

View File

@ -33,7 +33,6 @@
#include "access/htup_details.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/relation.h"
#include "access/reloptions.h"
#include "access/sysattr.h"
#include "access/table.h"
@ -465,29 +464,9 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
{
bytea *options;
amoptions_function amoptsfn;
CommonRdOptions *common = NULL;
const TableAmRoutine *tableam = NULL;
relation->rd_options = NULL;
/*
* Fill the rd_common_options with default values for appropriate
* relkinds. The values might be later changed by extractRelOptions().
*/
if (relation->rd_rel->relkind == RELKIND_RELATION ||
relation->rd_rel->relkind == RELKIND_TOASTVALUE ||
relation->rd_rel->relkind == RELKIND_MATVIEW)
{
common = MemoryContextAlloc(CacheMemoryContext,
sizeof(CommonRdOptions));
fill_default_common_reloptions(common);
relation->rd_common_options = common;
}
else
{
relation->rd_common_options = NULL;
}
/*
* Look up any AM-specific parse function; fall out if relkind should not
* have options.
@ -499,7 +478,6 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
case RELKIND_VIEW:
case RELKIND_MATVIEW:
case RELKIND_PARTITIONED_TABLE:
tableam = relation->rd_tableam;
amoptsfn = NULL;
break;
case RELKIND_INDEX:
@ -515,8 +493,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple)
* we might not have any other for pg_class yet (consider executing this
* code for pg_class itself)
*/
options = extractRelOptions(tuple, GetPgClassDescriptor(),
tableam, amoptsfn, common);
options = extractRelOptions(tuple, GetPgClassDescriptor(), amoptsfn);
/*
* Copy parsed data into CacheMemoryContext. To guard against the
@ -2323,8 +2300,6 @@ RelationReloadIndexInfo(Relation relation)
/* Reload reloptions in case they changed */
if (relation->rd_options)
pfree(relation->rd_options);
if (relation->rd_common_options)
pfree(relation->rd_common_options);
RelationParseRelOptions(relation, pg_class_tuple);
/* done with pg_class tuple */
heap_freetuple(pg_class_tuple);
@ -2512,8 +2487,6 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc)
pfree(relation->rd_pubdesc);
if (relation->rd_options)
pfree(relation->rd_options);
if (relation->rd_common_options)
pfree(relation->rd_common_options);
if (relation->rd_indextuple)
pfree(relation->rd_indextuple);
table_free_rd_amcache(relation);
@ -4253,8 +4226,6 @@ RelationCacheInitializePhase3(void)
/* Update rd_options while we have the tuple */
if (relation->rd_options)
pfree(relation->rd_options);
if (relation->rd_common_options)
pfree(relation->rd_common_options);
RelationParseRelOptions(relation, htup);
/*
@ -6191,7 +6162,7 @@ load_relcache_init_file(bool shared)
has_not_null |= attr->attnotnull;
}
/* next read the access method specific fields */
/* next read the access method specific field */
if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
goto read_failed;
if (len > 0)
@ -6207,21 +6178,6 @@ load_relcache_init_file(bool shared)
rel->rd_options = NULL;
}
if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
goto read_failed;
if (len > 0)
{
if (len != sizeof(CommonRdOptions))
goto read_failed;
rel->rd_common_options = palloc(len);
if (fread(rel->rd_common_options, 1, len, fp) != len)
goto read_failed;
}
else
{
rel->rd_common_options = NULL;
}
/* mark not-null status */
if (has_not_null)
{
@ -6623,15 +6579,11 @@ write_relcache_init_file(bool shared)
ATTRIBUTE_FIXED_PART_SIZE, fp);
}
/* next, do the access method specific fields */
/* next, do the access method specific field */
write_item(rel->rd_options,
(rel->rd_options ? VARSIZE(rel->rd_options) : 0),
fp);
write_item(rel->rd_common_options,
(rel->rd_common_options ? sizeof(CommonRdOptions) : 0),
fp);
/*
* If it's an index, there's more to do. Note we explicitly ignore
* partitioned indexes here.

View File

@ -21,7 +21,6 @@
#include "access/amapi.h"
#include "access/htup.h"
#include "access/tableam.h"
#include "access/tupdesc.h"
#include "nodes/pg_list.h"
#include "storage/lock.h"
@ -225,9 +224,7 @@ extern Datum transformRelOptions(Datum oldOptions, List *defList,
bool acceptOidsOff, bool isReset);
extern List *untransformRelOptions(Datum options);
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
const TableAmRoutine *tableam,
amoptions_function amoptions,
CommonRdOptions *common);
amoptions_function amoptions);
extern void *build_reloptions(Datum reloptions, bool validate,
relopt_kind kind,
Size relopt_struct_size,
@ -236,9 +233,9 @@ extern void *build_reloptions(Datum reloptions, bool validate,
extern void *build_local_reloptions(local_relopts *relopts, Datum options,
bool validate);
extern void fill_default_common_reloptions(CommonRdOptions *common);
extern bytea *heap_reloptions(char relkind, Datum reloptions,
CommonRdOptions *common, bool validate);
extern bytea *default_reloptions(Datum reloptions, bool validate,
relopt_kind kind);
extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
extern bytea *view_reloptions(Datum reloptions, bool validate);
extern bytea *partitioned_table_reloptions(Datum reloptions, bool validate);
extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions,

View File

@ -746,34 +746,6 @@ typedef struct TableAmRoutine
int32 slicelength,
struct varlena *result);
/*
* This callback parses and validates the reloptions array for a table.
*
* This is called only when a non-null reloptions array exists for the
* table. 'reloptions' is a text array containing entries of the form
* "name=value". The function should construct a bytea value, which will
* be copied into the rd_options field of the table's relcache entry. The
* data contents of the bytea value are open for the access method to
* define.
*
* The '*common' represents the common values, which the table access
* method exposes for autovacuum, query planner, and others. The caller
* should fill them with default values. The table access method may
* modify them on the base of options specified by a user.
*
* When 'validate' is true, the function should report a suitable error
* message if any of the options are unrecognized or have invalid values;
* when 'validate' is false, invalid entries should be silently ignored.
* ('validate' is false when loading options already stored in pg_catalog;
* an invalid entry could only be found if the access method has changed
* its rules for options, and in that case ignoring obsolete entries is
* appropriate.)
*
* It is OK to return NULL if default behavior is wanted.
*/
bytea *(*reloptions) (char relkind, Datum reloptions,
CommonRdOptions *common, bool validate);
/* ------------------------------------------------------------------------
* Planner related functions.
@ -1986,27 +1958,6 @@ table_relation_fetch_toast_slice(Relation toastrel, Oid valueid,
result);
}
/*
* Parse table options without knowledge of particular table.
*/
static inline bytea *
tableam_reloptions(const TableAmRoutine *tableam, char relkind,
Datum reloptions, CommonRdOptions *common, bool validate)
{
return tableam->reloptions(relkind, reloptions, common, validate);
}
/*
* Parse options for given table.
*/
static inline bytea *
table_reloptions(Relation rel, char relkind,
Datum reloptions, CommonRdOptions *common, bool validate)
{
return tableam_reloptions(rel->rd_tableam, relkind, reloptions,
common, validate);
}
/* ----------------------------------------------------------------------------
* Planner related functionality
@ -2185,7 +2136,6 @@ extern void table_block_relation_estimate_size(Relation rel,
*/
extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler);
extern const TableAmRoutine *GetTableAmRoutineByAmOid(Oid amoid);
/* ----------------------------------------------------------------------------
* Functions in heapam_handler.c

View File

@ -48,52 +48,6 @@ typedef struct LockInfoData
typedef LockInfoData *LockInfo;
/* autovacuum-related reloptions. */
typedef struct AutoVacOpts
{
bool enabled;
int vacuum_threshold;
int vacuum_ins_threshold;
int analyze_threshold;
int vacuum_cost_limit;
int freeze_min_age;
int freeze_max_age;
int freeze_table_age;
int multixact_freeze_min_age;
int multixact_freeze_max_age;
int multixact_freeze_table_age;
int log_min_duration;
float8 vacuum_cost_delay;
float8 vacuum_scale_factor;
float8 vacuum_ins_scale_factor;
float8 analyze_scale_factor;
} AutoVacOpts;
/* StdRdOptions->vacuum_index_cleanup values */
typedef enum StdRdOptIndexCleanup
{
STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
} StdRdOptIndexCleanup;
/*
* CommonRdOptions
* Contents of rd_common_options for tables. It contains the options,
* which the table access method exposes for autovacuum, query planner,
* and others. These options could be by decision of table AM directly
* specified by a user or calculated in some way.
*/
typedef struct CommonRdOptions
{
AutoVacOpts autovacuum; /* autovacuum-related options */
bool user_catalog_table; /* use as an additional catalog relation */
int parallel_workers; /* max number of parallel workers */
StdRdOptIndexCleanup vacuum_index_cleanup; /* controls index vacuuming */
bool vacuum_truncate; /* enables vacuum to truncate a relation */
} CommonRdOptions;
/*
* Here are the contents of a relation cache entry.
*/
@ -214,19 +168,11 @@ typedef struct RelationData
PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */
/*
* rd_options and rd_common_options are set whenever rd_rel is loaded into
* the relcache entry. Note that you can NOT look into rd_rel for this
* data. NULLs means "use defaults".
* rd_options is set whenever rd_rel is loaded into the relcache entry.
* Note that you can NOT look into rd_rel for this data. NULL means "use
* defaults".
*/
CommonRdOptions *rd_common_options; /* the options, which table AM exposes
* for external usage */
/*
* am-specific part of pg_class.reloptions parsed by table am specific
* structure (e.g. struct HeapRdOptions) Contents are not to be accessed
* outside of table am
*/
bytea *rd_options;
bytea *rd_options; /* parsed pg_class.reloptions */
/*
* Oid of the handler for this relation. For an index this is a function
@ -351,42 +297,88 @@ typedef struct ForeignKeyCacheInfo
Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
} ForeignKeyCacheInfo;
/*
* HeapRdOptions
* Contents of rd_options specific for heap tables.
* StdRdOptions
* Standard contents of rd_options for heaps.
*
* RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only
* be applied to relations that use this format or a superset for
* private options data.
*/
typedef struct HeapRdOptions
/* autovacuum-related reloptions. */
typedef struct AutoVacOpts
{
bool enabled;
int vacuum_threshold;
int vacuum_ins_threshold;
int analyze_threshold;
int vacuum_cost_limit;
int freeze_min_age;
int freeze_max_age;
int freeze_table_age;
int multixact_freeze_min_age;
int multixact_freeze_max_age;
int multixact_freeze_table_age;
int log_min_duration;
float8 vacuum_cost_delay;
float8 vacuum_scale_factor;
float8 vacuum_ins_scale_factor;
float8 analyze_scale_factor;
} AutoVacOpts;
/* StdRdOptions->vacuum_index_cleanup values */
typedef enum StdRdOptIndexCleanup
{
STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
} StdRdOptIndexCleanup;
typedef struct StdRdOptions
{
int32 vl_len_; /* varlena header (do not touch directly!) */
CommonRdOptions common;
int fillfactor; /* page fill factor in percent (0..100) */
int toast_tuple_target; /* target for tuple toasting */
} HeapRdOptions;
AutoVacOpts autovacuum; /* autovacuum-related options */
bool user_catalog_table; /* use as an additional catalog relation */
int parallel_workers; /* max number of parallel workers */
StdRdOptIndexCleanup vacuum_index_cleanup; /* controls index vacuuming */
bool vacuum_truncate; /* enables vacuum to truncate a relation */
} StdRdOptions;
#define HEAP_MIN_FILLFACTOR 10
#define HEAP_DEFAULT_FILLFACTOR 100
/*
* HeapGetFillFactor
* Returns the heap relation's fillfactor. Note multiple eval of argument!
* RelationGetToastTupleTarget
* Returns the relation's toast_tuple_target. Note multiple eval of argument!
*/
#define HeapGetFillFactor(relation, defaultff) \
#define RelationGetToastTupleTarget(relation, defaulttarg) \
((relation)->rd_options ? \
((HeapRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
/*
* HeapGetTargetPageUsage
* RelationGetFillFactor
* Returns the relation's fillfactor. Note multiple eval of argument!
*/
#define RelationGetFillFactor(relation, defaultff) \
((relation)->rd_options ? \
((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
/*
* RelationGetTargetPageUsage
* Returns the relation's desired space usage per page in bytes.
*/
#define HeapGetTargetPageUsage(relation, defaultff) \
(BLCKSZ * HeapGetFillFactor(relation, defaultff) / 100)
#define RelationGetTargetPageUsage(relation, defaultff) \
(BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
/*
* HeapGetTargetPageFreeSpace
* RelationGetTargetPageFreeSpace
* Returns the relation's desired freespace per page in bytes.
*/
#define HeapGetTargetPageFreeSpace(relation, defaultff) \
(BLCKSZ * (100 - HeapGetFillFactor(relation, defaultff)) / 100)
#define RelationGetTargetPageFreeSpace(relation, defaultff) \
(BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100)
/*
* RelationIsUsedAsCatalogTable
@ -394,10 +386,10 @@ typedef struct HeapRdOptions
* from the pov of logical decoding. Note multiple eval of argument!
*/
#define RelationIsUsedAsCatalogTable(relation) \
((relation)->rd_common_options && \
((relation)->rd_rel->relkind == RELKIND_RELATION || \
((relation)->rd_options && \
((relation)->rd_rel->relkind == RELKIND_RELATION || \
(relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
(relation)->rd_common_options->user_catalog_table : false)
((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
/*
* RelationGetParallelWorkers
@ -405,8 +397,8 @@ typedef struct HeapRdOptions
* Note multiple eval of argument!
*/
#define RelationGetParallelWorkers(relation, defaultpw) \
((relation)->rd_common_options ? \
(relation)->rd_common_options->parallel_workers : (defaultpw))
((relation)->rd_options ? \
((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
/* ViewOptions->check_option values */
typedef enum ViewOptCheckOption

View File

@ -36,7 +36,6 @@ SUBDIRS = \
test_rls_hooks \
test_shm_mq \
test_slru \
test_tam_options \
test_tidstore \
unsafe_tests \
worker_spi \

View File

@ -35,7 +35,6 @@ subdir('test_resowner')
subdir('test_rls_hooks')
subdir('test_shm_mq')
subdir('test_slru')
subdir('test_tam_options')
subdir('test_tidstore')
subdir('unsafe_tests')
subdir('worker_spi')

View File

@ -1,4 +0,0 @@
# Generated subdirectories
/log/
/results/
/tmp_check/

View File

@ -1,23 +0,0 @@
# src/test/modules/test_tam_options/Makefile
MODULE_big = test_tam_options
OBJS = \
$(WIN32RES) \
test_tam_options.o
PGFILEDESC = "test_tam_options - test code for table access method reloptions"
EXTENSION = test_tam_options
DATA = test_tam_options--1.0.sql
REGRESS = test_tam_options
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = src/test/modules/test_tam_options
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif

View File

@ -1,36 +0,0 @@
CREATE EXTENSION test_tam_options;
-- encourage use of parallel plans
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = 0;
SET max_parallel_workers_per_gather = 4;
CREATE TABLE test (i int) USING heap_alter_options;
INSERT INTO test SELECT i FROM generate_series(1, 10000) i;
VACUUM ANALYZE test;
EXPLAIN (costs off)
SELECT * FROM test;
QUERY PLAN
---------------------------------
Gather
Workers Planned: 4
-> Parallel Seq Scan on test
(3 rows)
ALTER TABLE test SET (enable_parallel = OFF);
EXPLAIN (costs off)
SELECT * FROM test;
QUERY PLAN
------------------
Seq Scan on test
(1 row)
ALTER TABLE test SET (enable_parallel = ON);
EXPLAIN (costs off)
SELECT * FROM test;
QUERY PLAN
---------------------------------
Gather
Workers Planned: 4
-> Parallel Seq Scan on test
(3 rows)

View File

@ -1,33 +0,0 @@
# Copyright (c) 2024, PostgreSQL Global Development Group
test_tam_options_sources = files(
'test_tam_options.c',
)
if host_system == 'windows'
test_tam_options_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
'--NAME', 'test_tam_options',
'--FILEDESC', 'test_tam_options - test code for table access method reloptions',])
endif
test_tam_options = shared_module('test_tam_options',
test_tam_options_sources,
kwargs: pg_test_mod_args,
)
test_install_libs += test_tam_options
test_install_data += files(
'test_tam_options.control',
'test_tam_options--1.0.sql',
)
tests += {
'name': 'test_tam_options',
'sd': meson.current_source_dir(),
'bd': meson.current_build_dir(),
'regress': {
'sql': [
'test_tam_options',
],
},
}

View File

@ -1,25 +0,0 @@
CREATE EXTENSION test_tam_options;
-- encourage use of parallel plans
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = 0;
SET max_parallel_workers_per_gather = 4;
CREATE TABLE test (i int) USING heap_alter_options;
INSERT INTO test SELECT i FROM generate_series(1, 10000) i;
VACUUM ANALYZE test;
EXPLAIN (costs off)
SELECT * FROM test;
ALTER TABLE test SET (enable_parallel = OFF);
EXPLAIN (costs off)
SELECT * FROM test;
ALTER TABLE test SET (enable_parallel = ON);
EXPLAIN (costs off)
SELECT * FROM test;

View File

@ -1,12 +0,0 @@
/* src/test/modules/test_tam_options/test_tam_options--1.0.sql */
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION test_tam_options" to load this file. \quit
CREATE FUNCTION heap_alter_options_tam_handler(internal)
RETURNS table_am_handler
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT;
CREATE ACCESS METHOD heap_alter_options TYPE TABLE
HANDLER heap_alter_options_tam_handler;

View File

@ -1,66 +0,0 @@
/*--------------------------------------------------------------------------
*
* test_tam_options.c
* Test code for table access method reloptions.
*
* Copyright (c) 2024, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/test/modules/test_tam_options/test_tam_options.c
*
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/reloptions.h"
#include "access/tableam.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(heap_alter_options_tam_handler);
/* An alternative relation options for heap */
typedef struct
{
int32 vl_len_; /* varlena header (do not touch directly!) */
bool enable_parallel; /* enable parallel scans? */
} HeapAlterRdOptions;
static bytea *
heap_alter_reloptions(char relkind, Datum reloptions,
CommonRdOptions *common, bool validate)
{
local_relopts relopts;
HeapAlterRdOptions *result;
Assert(relkind == RELKIND_RELATION ||
relkind == RELKIND_TOASTVALUE ||
relkind == RELKIND_MATVIEW);
init_local_reloptions(&relopts, sizeof(HeapAlterRdOptions));
add_local_bool_reloption(&relopts, "enable_parallel",
"enable parallel scan", true,
offsetof(HeapAlterRdOptions, enable_parallel));
result = (HeapAlterRdOptions *) build_local_reloptions(&relopts,
reloptions,
validate);
if (result != NULL && common != NULL)
{
common->parallel_workers = result->enable_parallel ? -1 : 0;
}
return (bytea *) result;
}
Datum
heap_alter_options_tam_handler(PG_FUNCTION_ARGS)
{
static TableAmRoutine tam_routine;
tam_routine = *GetHeapamTableAmRoutine();
tam_routine.reloptions = heap_alter_reloptions;
PG_RETURN_POINTER(&tam_routine);
}

View File

@ -1,4 +0,0 @@
comment = 'Test code for table access method reloptions'
default_version = '1.0'
module_pathname = '$libdir/test_tam_options'
relocatable = true

View File

@ -442,7 +442,6 @@ CommentStmt
CommitTimestampEntry
CommitTimestampShared
CommonEntry
CommonRdOptions
CommonTableExpr
CompareScalarsContext
CompiledExprState
@ -1130,10 +1129,8 @@ HbaLine
HeadlineJsonState
HeadlineParsedText
HeadlineWordEntry
HeapAlterRdOptions
HeapCheckContext
HeapPageFreeze
HeapRdOptions
HeapScanDesc
HeapTuple
HeapTupleData
@ -2726,6 +2723,7 @@ StatsElem
StatsExtInfo
StdAnalyzeData
StdRdOptIndexCleanup
StdRdOptions
Step
StopList
StrategyNumber