agora inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
[PATCH v40 2/5] Add relation option incremental_view_maintenance
1+ messages / 1 participants
[nested] [flat]

* [PATCH v40 2/5] Add relation option incremental_view_maintenance
@ 2026-08-01 17:58  Yugo Nagata <nagata@sraoss.co.jp>
  0 siblings, 0 replies; 1+ messages in thread

From: Yugo Nagata @ 2026-08-01 17:58 UTC (permalink / raw)

Materialized views with this option enabled act as Incrementally
Maintainable Materialized View (IMMV). The option can only be
specified for materialized views and cannot be changed after creation
for now.
---
 src/backend/access/common/reloptions.c | 68 +++++++++++++++-----------
 src/include/access/reloptions.h        |  3 +-
 src/include/utils/rel.h                |  8 +++
 3 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 3e832c3797e..de21ad1507f 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -111,7 +111,7 @@ static relopt_bool boolRelOpts[] =
 		{
 			"autovacuum_enabled",
 			"Enables autovacuum in this relation",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		true
@@ -120,7 +120,7 @@ static relopt_bool boolRelOpts[] =
 		{
 			"user_catalog_table",
 			"Declare a table as an additional catalog table, e.g. for the purpose of logical replication",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			AccessExclusiveLock
 		},
 		false
@@ -162,6 +162,15 @@ static relopt_bool boolRelOpts[] =
 		},
 		true
 	},
+	{
+		{
+			"incremental_view_maintenance",
+			"Materialized view acts as an incrementally maintainable materialized view",
+			RELOPT_KIND_MATVIEW,
+			AccessExclusiveLock
+		},
+		false
+	},
 	/* list terminator */
 	{{NULL}}
 };
@@ -172,7 +181,7 @@ static relopt_ternary ternaryRelOpts[] =
 		{
 			"vacuum_truncate",
 			"Enables vacuum to truncate empty pages at the end of this table",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		}
 	},
@@ -190,7 +199,7 @@ static relopt_int intRelOpts[] =
 		{
 			"fillfactor",
 			"Packs table pages only to this percentage",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock	/* since it applies only to later
 										 * inserts */
 		},
@@ -240,7 +249,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_parallel_workers",
 			"Maximum number of parallel autovacuum workers that can be used for processing this table.",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, -1, 1024
@@ -249,7 +258,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_vacuum_threshold",
 			"Minimum number of tuple updates or deletes prior to vacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0, INT_MAX
@@ -258,7 +267,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_vacuum_max_threshold",
 			"Maximum number of tuple updates or deletes prior to vacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-2, -1, INT_MAX
@@ -267,7 +276,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_vacuum_insert_threshold",
 			"Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-2, -1, INT_MAX
@@ -276,7 +285,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_analyze_threshold",
 			"Minimum number of tuple inserts, updates or deletes prior to analyze",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0, INT_MAX
@@ -285,7 +294,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_vacuum_cost_limit",
 			"Vacuum cost amount available before napping, for autovacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 1, 10000
@@ -294,7 +303,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_freeze_min_age",
 			"Minimum age at which VACUUM should freeze a table row, for autovacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0, 1000000000
@@ -303,7 +312,7 @@ static relopt_int intRelOpts[] =
 		{
 			"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,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0, 1000000000
@@ -312,7 +321,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_freeze_max_age",
 			"Age at which to autovacuum a table to prevent transaction ID wraparound",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 100000, 2000000000
@@ -321,7 +330,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_multixact_freeze_max_age",
 			"Multixact age at which to autovacuum a table to prevent multixact wraparound",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 10000, 2000000000
@@ -330,7 +339,7 @@ static relopt_int intRelOpts[] =
 		{
 			"autovacuum_freeze_table_age",
 			"Age at which VACUUM should perform a full table sweep to freeze row versions",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		}, -1, 0, 2000000000
 	},
@@ -338,7 +347,7 @@ static relopt_int intRelOpts[] =
 		{
 			"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,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		}, -1, 0, 2000000000
 	},
@@ -346,7 +355,7 @@ static relopt_int intRelOpts[] =
 		{
 			"log_autovacuum_min_duration",
 			"Sets the minimum execution time above which vacuum actions by autovacuum will be logged",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, -1, INT_MAX
@@ -355,7 +364,7 @@ static relopt_int intRelOpts[] =
 		{
 			"log_autoanalyze_min_duration",
 			"Sets the minimum execution time above which analyze actions by autovacuum will be logged",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, -1, INT_MAX
@@ -364,7 +373,7 @@ static relopt_int intRelOpts[] =
 		{
 			"toast_tuple_target",
 			"Sets the target tuple length at which external columns will be toasted",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		TOAST_TUPLE_TARGET, 128, TOAST_TUPLE_TARGET_MAIN
@@ -408,7 +417,7 @@ static relopt_int intRelOpts[] =
 		{
 			"parallel_workers",
 			"Number of parallel processes that can be used per executor node for this relation.",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0, 1024
@@ -424,7 +433,7 @@ static relopt_real realRelOpts[] =
 		{
 			"autovacuum_vacuum_cost_delay",
 			"Vacuum cost delay in milliseconds, for autovacuum",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0.0, 100.0
@@ -433,7 +442,7 @@ static relopt_real realRelOpts[] =
 		{
 			"autovacuum_vacuum_scale_factor",
 			"Number of tuple updates or deletes prior to vacuum as a fraction of reltuples",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0.0, 100.0
@@ -442,7 +451,7 @@ static relopt_real realRelOpts[] =
 		{
 			"autovacuum_vacuum_insert_scale_factor",
 			"Number of tuple inserts prior to vacuum as a fraction of reltuples",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0.0, 100.0
@@ -451,7 +460,7 @@ static relopt_real realRelOpts[] =
 		{
 			"autovacuum_analyze_scale_factor",
 			"Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples",
-			RELOPT_KIND_HEAP,
+			RELOPT_KIND_HEAP | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0.0, 100.0
@@ -460,7 +469,7 @@ static relopt_real realRelOpts[] =
 		{
 			"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,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		-1, 0.0, 1.0
@@ -554,7 +563,7 @@ static relopt_enum enumRelOpts[] =
 		{
 			"vacuum_index_cleanup",
 			"Controls index vacuuming and index cleanup",
-			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
+			RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_MATVIEW,
 			ShareUpdateExclusiveLock
 		},
 		StdRdOptIndexCleanupValues,
@@ -2025,7 +2034,9 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
 		{"vacuum_truncate", RELOPT_TYPE_TERNARY,
 		offsetof(StdRdOptions, vacuum_truncate)},
 		{"vacuum_max_eager_freeze_failure_rate", RELOPT_TYPE_REAL,
-		offsetof(StdRdOptions, vacuum_max_eager_freeze_failure_rate)}
+		offsetof(StdRdOptions, vacuum_max_eager_freeze_failure_rate)},
+		{"incremental_view_maintenance", RELOPT_TYPE_BOOL,
+		offsetof(StdRdOptions, incremental_view_maintenance)}
 	};
 
 	return (bytea *) build_reloptions(reloptions, validate, kind,
@@ -2179,8 +2190,9 @@ heap_reloptions(char relkind, Datum reloptions, bool validate)
 			}
 			return (bytea *) rdopts;
 		case RELKIND_RELATION:
-		case RELKIND_MATVIEW:
 			return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP);
+		case RELKIND_MATVIEW:
+			return default_reloptions(reloptions, validate, RELOPT_KIND_MATVIEW);
 		default:
 			/* other relkinds are not supported */
 			return NULL;
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index e8cb7f7a627..4c2c83d1e1a 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -51,8 +51,9 @@ typedef enum relopt_kind
 	RELOPT_KIND_VIEW = (1 << 9),
 	RELOPT_KIND_BRIN = (1 << 10),
 	RELOPT_KIND_PARTITIONED = (1 << 11),
+	RELOPT_KIND_MATVIEW = (1 << 12),
 	/* if you add a new kind, make sure you update "last_default" too */
-	RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED,
+	RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_MATVIEW,
 	/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
 	RELOPT_KIND_MAX = (1 << 30)
 } relopt_kind;
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 89c159b133f..80a4cc0dea3 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -356,6 +356,9 @@ typedef struct StdRdOptions
 	 * to freeze. 0 if disabled, -1 if unspecified.
 	 */
 	double		vacuum_max_eager_freeze_failure_rate;
+
+	/* enables incremental view maintenance */
+	bool		incremental_view_maintenance;
 } StdRdOptions;
 
 #define HEAP_MIN_FILLFACTOR			10
@@ -411,6 +414,11 @@ typedef struct StdRdOptions
 	((relation)->rd_options ? \
 	 ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
 
+#define RelationIsIMMV(relation)	\
+	(AssertMacro(relation->rd_rel->relkind == RELKIND_MATVIEW),				\
+	 (relation)->rd_options ?												\
+	  ((StdRdOptions *) (relation)->rd_options)->incremental_view_maintenance : false)
+
 /* ViewOptions->check_option values */
 typedef enum ViewOptCheckOption
 {
-- 
2.43.0


--Multipart=_Sun__2_Aug_2026_13_39_23_+0900_ERMG4bYmcAMN_ECT
Content-Type: text/x-diff;
 name="v40-0001-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Disposition: attachment;
 filename="v40-0001-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Transfer-Encoding: 7bit



^ permalink  raw  reply  [nested|flat] 1+ messages in thread


only message in thread

Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-08-01 17:58 [PATCH v40 2/5] Add relation option incremental_view_maintenance Yugo Nagata <nagata@sraoss.co.jp>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox