In the thread https://www.postgresql.org/message-id/2620882.s52SJui4ql@x200m I've suggested to split one big StdRdOption that is used for options storage into into Options structures individual for each relkind and each relam
That patch have been split into smaller parts, most of them were already commit: https://commitfest.postgresql.org/25/2294/ - Remove StdRdOptions from AM https://commitfest.postgresql.org/25/2297/ - Do not use StdRdOption for partitioned tables https://commitfest.postgresql.org/25/2295/ - Some useful Asserts for view- related macroses. And here goes the last part of StrRdOptions removal patch, where StdRdOptions is replaced with HeapOptions and ToastOptions. What did I do here. - Added HeapOptions and ToastOptions structues - Moved options building tab for autovacuum into AUTOVACUUM_RELOPTIONS macro, so it can be used in relopt_parse_elt tab both for heap and toast - Changed everywhere in the code, where old heap_reloptions is used, to use new heap_reloptions or toast_reloptions - Changed heap & toast option fetching macros to use HeapOptions and ToastOptions - Added Asserts to heap and toast options macros. Now we finally can do it. What I did not do - I've split fillfactor related macros into heap and toast like RelationGetFillFactor will become HeapGetFillFactor and ToastGetFillFactor. I have to do it, because now they handle different structure. but there are heap only option macros like RelationGetParallelWorkers that should be better called HeapGetParallelWorkers, as it is heap related. But I did not change the name, as somebody from core team (I think it was Alvaro, it was a while ago) asked me not to change macros names unless in is inavoidable. So I kept the names, though I still think that naming them with Heap prefix will make code more clear. - vacuum_index_cleanup and vacuum_truncate options were added recently. They were added into StdRdOptions. I think their place is inside AutoVacOpts not in StdRdOptions, but did not dare to change it. If you see it the same way as I see, please let me know, I will move it to a proper place. -- Software Developer: https://www.upwork.com/freelancers/~014a87e140ff02c0da Body-oriented Therapist: https://vk.com/nataraj_rebalancing (Russian)
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 48377ac..8b18381 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -46,9 +46,8 @@ * 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 StdRdOptions) - * (iv) add it to the appropriate handling routine (perhaps - * default_reloptions) + * (iii) add it to the appropriate options struct + * (iv) add it to the appropriate handling routine * (v) make sure the lock level is set correctly for that operation * (vi) don't forget to document the option * @@ -1106,9 +1105,11 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, switch (classForm->relkind) { case RELKIND_RELATION: - case RELKIND_TOASTVALUE: case RELKIND_MATVIEW: - options = heap_reloptions(classForm->relkind, datum, false); + options = heap_reloptions(datum, false); + break; + case RELKIND_TOASTVALUE: + options = toast_reloptions(datum, false); break; case RELKIND_PARTITIONED_TABLE: options = partitioned_table_reloptions(datum, false); @@ -1480,55 +1481,62 @@ fillRelOptions(void *rdopts, Size basesize, /* - * Option parser for anything that uses StdRdOptions. + * Option parsing definition for autovacuum. Used in toast and heap options. + */ + +#define AUTOVACUUM_RELOPTIONS(OFFSET) \ + {"autovacuum_enabled", RELOPT_TYPE_BOOL, \ + OFFSET + offsetof(AutoVacOpts, enabled)}, \ + {"autovacuum_vacuum_threshold", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, vacuum_threshold)}, \ + {"autovacuum_analyze_threshold", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, analyze_threshold)}, \ + {"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL, \ + OFFSET + offsetof(AutoVacOpts, vacuum_cost_delay)}, \ + {"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, vacuum_cost_limit)}, \ + {"autovacuum_freeze_min_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, freeze_min_age)}, \ + {"autovacuum_freeze_max_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, freeze_max_age)}, \ + {"autovacuum_freeze_table_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, freeze_table_age)}, \ + {"autovacuum_multixact_freeze_min_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, multixact_freeze_min_age)}, \ + {"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, multixact_freeze_max_age)}, \ + {"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, multixact_freeze_table_age)}, \ + {"log_autovacuum_min_duration", RELOPT_TYPE_INT, \ + OFFSET + offsetof(AutoVacOpts, log_min_duration)}, \ + {"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL, \ + OFFSET + offsetof(AutoVacOpts, vacuum_scale_factor)}, \ + {"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL, \ + OFFSET + offsetof(AutoVacOpts, analyze_scale_factor)} +/* + * Option parser for heap */ bytea * -default_reloptions(Datum reloptions, bool validate, relopt_kind kind) +heap_reloptions(Datum reloptions, bool validate) { 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_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_multixact_freeze_min_age", RELOPT_TYPE_INT, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_min_age)}, - {"autovacuum_multixact_freeze_max_age", RELOPT_TYPE_INT, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_max_age)}, - {"autovacuum_multixact_freeze_table_age", RELOPT_TYPE_INT, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, multixact_freeze_table_age)}, - {"log_autovacuum_min_duration", RELOPT_TYPE_INT, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)}, + {"fillfactor", RELOPT_TYPE_INT, offsetof(HeapOptions, fillfactor)}, + AUTOVACUUM_RELOPTIONS(offsetof(HeapOptions, autovacuum)), {"toast_tuple_target", RELOPT_TYPE_INT, - offsetof(StdRdOptions, toast_tuple_target)}, - {"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)}, - {"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)}, + offsetof(HeapOptions, toast_tuple_target)}, {"user_catalog_table", RELOPT_TYPE_BOOL, - offsetof(StdRdOptions, user_catalog_table)}, + offsetof(HeapOptions, user_catalog_table)}, {"parallel_workers", RELOPT_TYPE_INT, - offsetof(StdRdOptions, parallel_workers)}, + offsetof(HeapOptions, parallel_workers)}, {"vacuum_index_cleanup", RELOPT_TYPE_BOOL, - offsetof(StdRdOptions, vacuum_index_cleanup)}, + offsetof(HeapOptions, vacuum_index_cleanup)}, {"vacuum_truncate", RELOPT_TYPE_BOOL, - offsetof(StdRdOptions, vacuum_truncate)} + offsetof(HeapOptions, vacuum_truncate)} }; - return (bytea *) build_reloptions(reloptions, validate, kind, - sizeof(StdRdOptions), + return (bytea *) build_reloptions(reloptions, validate, + RELOPT_KIND_HEAP, + sizeof(HeapOptions), tab, lengthof(tab)); } @@ -1596,6 +1604,32 @@ partitioned_table_reloptions(Datum reloptions, bool validate) } /* + * Option parser for toast + */ +bytea * +toast_reloptions(Datum reloptions, bool validate) +{ + ToastOptions *rdopts; + static const relopt_parse_elt tab[] = { + AUTOVACUUM_RELOPTIONS(offsetof(ToastOptions, autovacuum)), + {"vacuum_index_cleanup", RELOPT_TYPE_BOOL, + offsetof(ToastOptions, vacuum_index_cleanup)}, + {"vacuum_truncate", RELOPT_TYPE_BOOL, + offsetof(ToastOptions, vacuum_truncate)} + }; + + rdopts = build_reloptions(reloptions, validate, + RELOPT_KIND_TOAST, + sizeof(ToastOptions), + tab, lengthof(tab)); + /* adjust default-only parameters for TOAST relations */ + rdopts->autovacuum.analyze_threshold = -1; + rdopts->autovacuum.analyze_scale_factor = -1; + + return (bytea *) rdopts; +} + +/* * Option parser for views */ bytea * @@ -1615,37 +1649,6 @@ view_reloptions(Datum reloptions, bool validate) } /* - * Parse options for heaps, views and toast tables. - */ -bytea * -heap_reloptions(char relkind, Datum reloptions, bool validate) -{ - 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); - default: - /* other relkinds are not supported */ - return NULL; - } -} - - -/* * Parse options for indexes. * * amoptions index AM's option parser function diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 0128bb3..8c0d86c 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -2120,8 +2120,10 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, AssertArg(!(options & HEAP_INSERT_NO_LOGICAL)); needwal = !(options & HEAP_INSERT_SKIP_WAL) && RelationNeedsWAL(relation); - saveFreeSpace = RelationGetTargetPageFreeSpace(relation, - HEAP_DEFAULT_FILLFACTOR); + if (IsToastRelation(relation)) + saveFreeSpace = ToastGetTargetPageFreeSpace(); + else + saveFreeSpace = HeapGetTargetPageFreeSpace(relation); /* Toast and set header data in all the slots */ heaptuples = palloc(ntuples * sizeof(HeapTuple)); diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index d41d318..dad8c0d 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -19,6 +19,7 @@ #include "access/hio.h" #include "access/htup_details.h" #include "access/visibilitymap.h" +#include "catalog/catalog.h" #include "storage/bufmgr.h" #include "storage/freespace.h" #include "storage/lmgr.h" @@ -346,8 +347,10 @@ RelationGetBufferForTuple(Relation relation, Size len, len, MaxHeapTupleSize))); /* Compute desired extra freespace due to fillfactor option */ - saveFreeSpace = RelationGetTargetPageFreeSpace(relation, - HEAP_DEFAULT_FILLFACTOR); + if (IsToastRelation(relation)) + saveFreeSpace = ToastGetTargetPageFreeSpace(); + else + saveFreeSpace = HeapGetTargetPageFreeSpace(relation); if (otherBuffer != InvalidBuffer) otherBlock = BufferGetBlockNumber(otherBuffer); diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 6d62a96..af9acf9 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -129,8 +129,11 @@ 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 = RelationGetTargetPageFreeSpace(relation, - HEAP_DEFAULT_FILLFACTOR); + + if (IsToastRelation(relation)) + minfree = ToastGetTargetPageFreeSpace(); + else + minfree = HeapGetTargetPageFreeSpace(relation); minfree = Max(minfree, BLCKSZ / 10); if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree) diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index d285b1f..a3f8095 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -674,8 +674,10 @@ raw_heap_insert(RewriteState state, HeapTuple tup) len, MaxHeapTupleSize))); /* Compute desired extra freespace due to fillfactor option */ - saveFreeSpace = RelationGetTargetPageFreeSpace(state->rs_new_rel, - HEAP_DEFAULT_FILLFACTOR); + if (IsToastRelation(state->rs_new_rel)) + saveFreeSpace = ToastGetTargetPageFreeSpace(); + else + saveFreeSpace = HeapGetTargetPageFreeSpace(state->rs_new_rel); /* Now we can check to see if there's enough free space already. */ if (state->rs_buffer_valid) diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 2bf7083..c30cafd 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -130,7 +130,7 @@ create_ctas_internal(List *attrList, IntoClause *into) validnsps, true, false); - (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options, true); + (void) toast_reloptions(toast_options, true); NewRelationCreateToastTable(intoRelationAddr.objectId, toast_options); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 5440eb9..2130896 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -727,8 +727,12 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, case RELKIND_PARTITIONED_TABLE: (void) partitioned_table_reloptions(reloptions, true); break; - default: - (void) heap_reloptions(relkind, reloptions, true); + case RELKIND_TOASTVALUE: + (void) toast_reloptions(reloptions, true); + break; + case RELKIND_RELATION: + case RELKIND_MATVIEW: + (void) heap_reloptions(reloptions, true); } if (stmt->ofTypename) @@ -12194,9 +12198,11 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, switch (rel->rd_rel->relkind) { case RELKIND_RELATION: - case RELKIND_TOASTVALUE: case RELKIND_MATVIEW: - (void) heap_reloptions(rel->rd_rel->relkind, newOptions, true); + (void) heap_reloptions( newOptions, true); + break; + case RELKIND_TOASTVALUE: + (void) toast_reloptions(newOptions, true); break; case RELKIND_PARTITIONED_TABLE: (void) partitioned_table_reloptions(newOptions, true); @@ -12308,7 +12314,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, defList, "toast", validnsps, false, operation == AT_ResetRelOptions); - (void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true); + (void) toast_reloptions(newOptions, true); memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index da1da23..49cac91 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -31,6 +31,7 @@ #include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/namespace.h" #include "catalog/pg_database.h" #include "catalog/pg_inherits.h" @@ -1769,7 +1770,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params) if (params->index_cleanup == VACOPT_TERNARY_DEFAULT) { if (onerel->rd_options == NULL || - ((StdRdOptions *) onerel->rd_options)->vacuum_index_cleanup) + (!IsToastRelation(onerel) && + ((HeapOptions *) onerel->rd_options)->vacuum_index_cleanup) || + (IsToastRelation(onerel) && + ((ToastOptions *) onerel->rd_options)->vacuum_index_cleanup)) params->index_cleanup = VACOPT_TERNARY_ENABLED; else params->index_cleanup = VACOPT_TERNARY_DISABLED; @@ -1779,7 +1783,10 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params) if (params->truncate == VACOPT_TERNARY_DEFAULT) { if (onerel->rd_options == NULL || - ((StdRdOptions *) onerel->rd_options)->vacuum_truncate) + (!IsToastRelation(onerel) && + ((HeapOptions *) onerel->rd_options)->vacuum_truncate) || + (IsToastRelation(onerel) && + ((ToastOptions *) onerel->rd_options)->vacuum_truncate)) params->truncate = VACOPT_TERNARY_ENABLED; else params->truncate = VACOPT_TERNARY_DISABLED; diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 5e889d1..cd564c9 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -150,8 +150,15 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, estimate_rel_size(relation, rel->attr_widths - rel->min_attr, &rel->pages, &rel->tuples, &rel->allvisfrac); - /* Retrieve the parallel_workers reloption, or -1 if not set. */ - rel->rel_parallel_workers = RelationGetParallelWorkers(relation, -1); + /* + * Retrieve the parallel_workers for heap and mat.view relations. + * Use -1 if not set, or if we are dealing with other relation kinds + */ + if (relation->rd_rel->relkind == RELKIND_RELATION || + relation->rd_rel->relkind == RELKIND_MATVIEW) + rel->rel_parallel_workers = RelationGetParallelWorkers(relation, -1); + else + rel->rel_parallel_workers = -1; /* * Make list of indexes. Ignore indexes on system catalogs if told to. diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index c1dd816..0e8596b 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2722,6 +2722,7 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc) { bytea *relopts; AutoVacOpts *av; + AutoVacOpts *src; Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW || @@ -2731,8 +2732,13 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc) if (relopts == NULL) return NULL; + if (((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE) + src = &(((ToastOptions *) relopts)->autovacuum); + else + src = &(((HeapOptions *) relopts)->autovacuum); + av = palloc(sizeof(AutoVacOpts)); - memcpy(av, &(((StdRdOptions *) relopts)->autovacuum), sizeof(AutoVacOpts)); + memcpy(av, src, sizeof(AutoVacOpts)); pfree(relopts); return av; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 3a03ca7..6cc6119 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -1030,9 +1030,7 @@ ProcessUtilitySlow(ParseState *pstate, validnsps, true, false); - (void) heap_reloptions(RELKIND_TOASTVALUE, - toast_options, - true); + (void) toast_reloptions(toast_options, true); NewRelationCreateToastTable(address.objectId, toast_options); diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index d21c513..e642c3c 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -186,9 +186,8 @@ extern void *build_reloptions(Datum reloptions, bool validate, const relopt_parse_elt *relopt_elems, int num_relopt_elems); -extern bytea *default_reloptions(Datum reloptions, bool validate, - relopt_kind kind); -extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); +extern bytea *toast_reloptions(Datum reloptions, bool validate); +extern bytea *heap_reloptions(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, diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 31d8a1a..72f216f 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -234,14 +234,9 @@ typedef struct ForeignKeyCacheInfo /* - * 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. + * AutoVacOpts + * Auto Vacuum options used both in Heap and Toast relations */ - /* autovacuum-related reloptions. */ typedef struct AutoVacOpts { bool enabled; @@ -260,7 +255,11 @@ typedef struct AutoVacOpts float8 analyze_scale_factor; } AutoVacOpts; -typedef struct StdRdOptions +/* + * HeapOptions + * Binary representation of relation options for Heap relations. + */ +typedef struct HeapOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ @@ -271,40 +270,60 @@ typedef struct StdRdOptions int parallel_workers; /* max number of parallel workers */ bool vacuum_index_cleanup; /* enables index vacuuming and cleanup */ bool vacuum_truncate; /* enables vacuum to truncate a relation */ -} StdRdOptions; +} HeapOptions; #define HEAP_MIN_FILLFACTOR 10 #define HEAP_DEFAULT_FILLFACTOR 100 /* + * ToastOptions + * Binary representation of relation options for Toast relations. + */ +typedef struct ToastOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + AutoVacOpts autovacuum; /* autovacuum-related options */ + bool vacuum_index_cleanup; /* enables index vacuuming and cleanup */ + bool vacuum_truncate; /* enables vacuum to truncate a relation */ +} ToastOptions; + +#define TOAST_DEFAULT_FILLFACTOR 100 /* Only default is actually used */ + +/* * RelationGetToastTupleTarget - * Returns the relation's toast_tuple_target. Note multiple eval of argument! + * Returns the heap's toast_tuple_target. Note multiple eval of argument! */ -#define RelationGetToastTupleTarget(relation, defaulttarg) \ - ((relation)->rd_options ? \ - ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg)) +#define RelationGetToastTupleTarget(relation, defaulttarg) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_RELATION || \ + relation->rd_rel->relkind == RELKIND_MATVIEW), \ + (relation)->rd_options ? \ + ((HeapOptions *) (relation)->rd_options)->toast_tuple_target : \ + (defaulttarg)) /* - * RelationGetFillFactor - * Returns the relation's fillfactor. Note multiple eval of argument! + * HeapGetFillFactor + * Returns the heap's fillfactor. Note multiple eval of argument! */ -#define RelationGetFillFactor(relation, defaultff) \ - ((relation)->rd_options ? \ - ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff)) +#define HeapGetFillFactor(relation) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_RELATION || \ + relation->rd_rel->relkind == RELKIND_MATVIEW), \ + (relation)->rd_options ? \ + ((HeapOptions *) (relation)->rd_options)->fillfactor : \ + (HEAP_DEFAULT_FILLFACTOR)) /* - * RelationGetTargetPageUsage + * HeapGetTargetPageUsage * Returns the relation's desired space usage per page in bytes. */ -#define RelationGetTargetPageUsage(relation, defaultff) \ - (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100) +#define HeapGetTargetPageUsage(relation) \ + (BLCKSZ * HeapGetFillFactor(relation) / 100) /* - * RelationGetTargetPageFreeSpace + * HeapGetTargetPageFreeSpace * Returns the relation's desired freespace per page in bytes. */ -#define RelationGetTargetPageFreeSpace(relation, defaultff) \ - (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100) +#define HeapGetTargetPageFreeSpace(relation) \ + (BLCKSZ * (100 - HeapGetFillFactor(relation)) / 100) /* * RelationIsUsedAsCatalogTable @@ -315,16 +334,27 @@ typedef struct StdRdOptions ((relation)->rd_options && \ ((relation)->rd_rel->relkind == RELKIND_RELATION || \ (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \ - ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false) + ((HeapOptions *) (relation)->rd_options)->user_catalog_table : false) /* * RelationGetParallelWorkers - * Returns the relation's parallel_workers reloption setting. + * Returns the heap's parallel_workers reloption setting. * Note multiple eval of argument! */ -#define RelationGetParallelWorkers(relation, defaultpw) \ - ((relation)->rd_options ? \ - ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw)) +#define RelationGetParallelWorkers(relation, defaultpw) \ + (AssertMacro(relation->rd_rel->relkind == RELKIND_RELATION || \ + relation->rd_rel->relkind == RELKIND_MATVIEW), \ + (relation)->rd_options ? \ + ((HeapOptions *) (relation)->rd_options)->parallel_workers : \ + (defaultpw)) + +/* + * ToastGetTargetPageFreeSpace + * Returns the TOAST relation's desired freespace per page in bytes. + * Always calculated using default fillfactor value. + */ +#define ToastGetTargetPageFreeSpace() \ + (BLCKSZ * (100 - TOAST_DEFAULT_FILLFACTOR) / 100) /* ViewOptions->check_option values */ typedef enum ViewOptCheckOption
signature.asc
Description: This is a digitally signed message part.