mirror of
https://github.com/postgres/postgres.git
synced 2025-11-04 20:11:56 +03:00
Custom reloptions for table AM
Let table AM define custom reloptions for its tables. This allows specifying AM-specific parameters by the WITH clause when creating a table. The reloptions, which could be used outside of table AM, are now extracted into the CommonRdOptions data structure. These options could be by decision of table AM directly specified by a user or calculated in some way. The new test module test_tam_options evaluates the ability to set up custom reloptions and calculate fields of CommonRdOptions on their base. The code may use some parts from prior work by Hao Wu. Discussion: https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.com Discussion: https://postgr.es/m/AMUA1wBBBxfc3tKRLLdU64rb.1.1683276279979.Hmail.wuhao%40hashdata.cn Reviewed-by: Reviewed-by: Pavel Borisov, Matthias van de Meent, Jess Davis
This commit is contained in:
73
src/backend/utils/cache/relcache.c
vendored
73
src/backend/utils/cache/relcache.c
vendored
@@ -33,6 +33,7 @@
|
||||
#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"
|
||||
@@ -464,9 +465,48 @@ 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));
|
||||
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;
|
||||
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.
|
||||
@@ -478,6 +518,7 @@ 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:
|
||||
@@ -493,7 +534,8 @@ 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(), amoptsfn);
|
||||
options = extractRelOptions(tuple, GetPgClassDescriptor(),
|
||||
tableam, amoptsfn, common);
|
||||
|
||||
/*
|
||||
* Copy parsed data into CacheMemoryContext. To guard against the
|
||||
@@ -2300,6 +2342,8 @@ 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);
|
||||
@@ -2487,6 +2531,8 @@ 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);
|
||||
@@ -4226,6 +4272,8 @@ 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);
|
||||
|
||||
/*
|
||||
@@ -6162,7 +6210,7 @@ load_relcache_init_file(bool shared)
|
||||
has_not_null |= attr->attnotnull;
|
||||
}
|
||||
|
||||
/* next read the access method specific field */
|
||||
/* next read the access method specific fields */
|
||||
if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
goto read_failed;
|
||||
if (len > 0)
|
||||
@@ -6178,6 +6226,21 @@ 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)
|
||||
{
|
||||
@@ -6579,11 +6642,15 @@ write_relcache_init_file(bool shared)
|
||||
ATTRIBUTE_FIXED_PART_SIZE, fp);
|
||||
}
|
||||
|
||||
/* next, do the access method specific field */
|
||||
/* next, do the access method specific fields */
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user