summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorAlexander Korotkov2024-04-08 08:23:28 +0000
committerAlexander Korotkov2024-04-08 08:23:28 +0000
commit9bd99f4c26fe37b8ee2f199aa868a0e2fdba4c43 (patch)
treeacbadc21922045fa7f729f5c199e4e33c30e2541 /src/include
parent6f3d8d5e7cc2f2e2367cd6da6f8affe98d1f5729 (diff)
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
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/reloptions.h10
-rw-r--r--src/include/access/tableam.h50
-rw-r--r--src/include/utils/rel.h148
3 files changed, 134 insertions, 74 deletions
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 81829b8270a..342b9cdd6ed 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -21,6 +21,7 @@
#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"
@@ -224,7 +225,9 @@ extern Datum transformRelOptions(Datum oldOptions, List *defList,
bool acceptOidsOff, bool isReset);
extern List *untransformRelOptions(Datum options);
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
- amoptions_function amoptions);
+ const TableAmRoutine *tableam,
+ amoptions_function amoptions,
+ CommonRdOptions *common);
extern void *build_reloptions(Datum reloptions, bool validate,
relopt_kind kind,
Size relopt_struct_size,
@@ -233,9 +236,8 @@ extern void *build_reloptions(Datum reloptions, bool validate,
extern void *build_local_reloptions(local_relopts *relopts, Datum options,
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 *heap_reloptions(char relkind, Datum reloptions,
+ CommonRdOptions *common, 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/access/tableam.h b/src/include/access/tableam.h
index be198fa3158..ec827ac12bf 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -746,6 +746,34 @@ 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.
@@ -1945,6 +1973,27 @@ 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
@@ -2123,6 +2172,7 @@ 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
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f25f769af2b..56e3e782d27 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -48,6 +48,52 @@ 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.
*/
@@ -168,11 +214,19 @@ typedef struct RelationData
PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */
/*
- * 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".
+ * 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".
+ */
+ 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; /* parsed pg_class.reloptions */
+ bytea *rd_options;
/*
* Oid of the handler for this relation. For an index this is a function
@@ -297,88 +351,42 @@ typedef struct ForeignKeyCacheInfo
Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
} 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.
+ * HeapRdOptions
+ * Contents of rd_options specific for heap tables.
*/
- /* 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
+typedef struct HeapRdOptions
{
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 */
- 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;
+} HeapRdOptions;
#define HEAP_MIN_FILLFACTOR 10
#define HEAP_DEFAULT_FILLFACTOR 100
/*
- * RelationGetToastTupleTarget
- * Returns the relation's toast_tuple_target. Note multiple eval of argument!
+ * HeapGetFillFactor
+ * Returns the heap relation's fillfactor. Note multiple eval of argument!
*/
-#define RelationGetToastTupleTarget(relation, defaulttarg) \
+#define HeapGetFillFactor(relation, defaultff) \
((relation)->rd_options ? \
- ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
+ ((HeapRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
/*
- * 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
+ * HeapGetTargetPageUsage
* Returns the relation's desired space usage per page in bytes.
*/
-#define RelationGetTargetPageUsage(relation, defaultff) \
- (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
+#define HeapGetTargetPageUsage(relation, defaultff) \
+ (BLCKSZ * HeapGetFillFactor(relation, defaultff) / 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, defaultff) \
+ (BLCKSZ * (100 - HeapGetFillFactor(relation, defaultff)) / 100)
/*
* RelationIsUsedAsCatalogTable
@@ -386,10 +394,10 @@ typedef struct StdRdOptions
* from the pov of logical decoding. Note multiple eval of argument!
*/
#define RelationIsUsedAsCatalogTable(relation) \
- ((relation)->rd_options && \
- ((relation)->rd_rel->relkind == RELKIND_RELATION || \
+ ((relation)->rd_common_options && \
+ ((relation)->rd_rel->relkind == RELKIND_RELATION || \
(relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
- ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
+ (relation)->rd_common_options->user_catalog_table : false)
/*
* RelationGetParallelWorkers
@@ -397,8 +405,8 @@ typedef struct StdRdOptions
* Note multiple eval of argument!
*/
#define RelationGetParallelWorkers(relation, defaultpw) \
- ((relation)->rd_options ? \
- ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
+ ((relation)->rd_common_options ? \
+ (relation)->rd_common_options->parallel_workers : (defaultpw))
/* ViewOptions->check_option values */
typedef enum ViewOptCheckOption