agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v24 02/15] Add relisivm column to pg_class system catalog
171+ messages / 2 participants
[nested] [flat]

* [PATCH v24 02/15] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 81cc39fb70..e2bc308dff 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -966,6 +966,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 26bfa74ce7..763f442a1d 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -961,6 +961,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 4ebaa552a2..c626df32cc 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2013,6 +2013,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 9fa9e671a1..d80b652f55 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1916,6 +1916,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index fef9945ed8..2058978b89 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 77871aaefc..09346aaa17 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index b4faa1c123..b5028f3449 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -649,6 +649,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Fri__29_Oct_2021_18_16_28_+0900_jlYRKjywLqhZ7oyk
Content-Type: text/x-diff;
 name="v24-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Disposition: attachment;
 filename="v24-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v27 2/9] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 9b512ccd3c..a9a314fefe 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -920,6 +920,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index fd389c28d8..4d1c99a8bd 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -982,6 +982,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 1b7e11b93e..3275963886 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2023,6 +2023,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 43f14c233d..a67ba4d8b1 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1923,6 +1923,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 304e8c18d5..fbaa1438d6 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d4a9..cc2f635122 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index eadbd00904..0e28716e6b 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -661,6 +661,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


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



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

* [PATCH v27 2/9] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 9b512ccd3c..a9a314fefe 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -920,6 +920,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index fd389c28d8..4d1c99a8bd 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -982,6 +982,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 1b7e11b93e..3275963886 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2023,6 +2023,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 43f14c233d..a67ba4d8b1 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1923,6 +1923,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 304e8c18d5..fbaa1438d6 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d4a9..cc2f635122 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index eadbd00904..0e28716e6b 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -661,6 +661,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Fri__22_Apr_2022_14_58_01_+0900_MN3L/o2YUVF2g4zw
Content-Type: text/x-diff;
 name="v27-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Disposition: attachment;
 filename="v27-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v39 2/8] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 6c1c5545cb5..c132472dfbb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index e266f501d87..9d136c89dd1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__3_Jul_2026_19_11_16_+0900_CskxSIu_iGcDMEyM
Content-Type: text/x-diff;
 name="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v39-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v37 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 73a1c1c4670..4db2cafdb6a 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036086057d7..0ab1604ec42 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2273,6 +2273,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab424e7..6b56d95a892 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1943,6 +1943,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8545e67a632..f7b45f6a89d 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -146,6 +146,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Fri__29_May_2026_23_14_17_+0900_Te0o73X2VqYK57Gd
Content-Type: text/x-diff;
 name="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v37-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v38 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 88087654de9..d7eca35d080 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -971,6 +971,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357f27..7ba874417c5 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1014,6 +1014,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 8f129baec90..7f0112f9d61 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -151,6 +151,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 036de5f79ef..33e6b0027b4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2348,6 +2348,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fb4e042be8a..6a208401ef0 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1945,6 +1945,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index c4af599dc90..ed5cfa20587 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -124,6 +124,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 865980cb0f1..de456145b31 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -148,6 +148,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index fa07ebf8ff7..fce5bbc1882 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -696,6 +696,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a65a5bf0c4f..c5febf6a3d6 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1415,6 +1415,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.43.0


--Multipart=_Wed__1_Jul_2026_00_04_01_+0900_OVSy2WWK_9aByzDJ
Content-Type: text/x-diff;
 name="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v38-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v33 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 00074c8a94..8d5470c8f7 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -938,6 +938,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index a819b4197c..eb81685f6b 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1007,6 +1007,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 19cabc9a47..c88c8af96b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 48a280d089..59c06b853c 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2042,6 +2042,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 66ed24e401..cba2eac1e8 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1931,6 +1931,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0fc2c093b0..80cbee29ca 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 20446f6f83..6b17921d23 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -139,6 +139,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 8700204953..7f36d6f5fa 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -676,6 +676,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 4c789279e5..c7ba7be647 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1393,6 +1393,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


--Multipart=_Tue__2_Jul_2024_17_03_11_+0900_6OrVBZxOB4o_k6A1
Content-Type: text/x-diff;
 name="v33-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v33-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v34 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 00074c8a94..8d5470c8f7 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -938,6 +938,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index a819b4197c..eb81685f6b 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1007,6 +1007,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 19cabc9a47..c88c8af96b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 48a280d089..59c06b853c 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2042,6 +2042,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 66ed24e401..cba2eac1e8 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1931,6 +1931,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0fc2c093b0..80cbee29ca 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 20446f6f83..6b17921d23 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -139,6 +139,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 8700204953..7f36d6f5fa 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -676,6 +676,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 4c789279e5..c7ba7be647 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1393,6 +1393,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.34.1


--Multipart=_Thu__11_Jul_2024_13_23_57_+0900_hKsU2G3a3BgS2FFs
Content-Type: text/x-diff;
 name="v34-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v34-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v30 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  2 ++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 36 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 348943e36c..b186d9e82c 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -927,6 +927,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 4b88a9cb87..3b59c44b0e 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -992,6 +992,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 04227a72d1..273ae3062f 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index f730aa26c4..20b873b38e 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2019,6 +2019,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 50acae4529..278b8519b1 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1927,6 +1927,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 3b7533e7bb..23a933e46c 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index e4a200b00e..544fa94a68 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index ab9fa4faf9..ae693adaa5 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -675,6 +675,8 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 0cd2c64fca..984fe16bb8 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1392,6 +1392,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


--Multipart=_Mon__4_Mar_2024_11_58_46_+0900_UaponF/qQhQrVCFt
Content-Type: text/x-diff;
 name="v30-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Disposition: attachment;
 filename="v30-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v31 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index cc31909012..1d2e2228c4 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -937,6 +937,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b6a7c60e23..906ec6c088 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1007,6 +1007,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 401fb35947..16c3399975 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 26368ffcc9..01af4ad5bb 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2020,6 +2020,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 1f419c2a6d..71c0fd506c 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1932,6 +1932,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0fc2c093b0..80cbee29ca 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 35a8dec2b9..93c2fcb21c 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f25f769af2..d3144c949f 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -678,6 +678,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index f53c3036a6..c6e878c3ab 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1392,6 +1392,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


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



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

* [PATCH v32 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  6 ++++++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 40 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index cc31909012..1d2e2228c4 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -937,6 +937,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b6a7c60e23..906ec6c088 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1007,6 +1007,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 401fb35947..16c3399975 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 26368ffcc9..01af4ad5bb 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2020,6 +2020,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 039c0d3eef..c64b9e7bf5 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1936,6 +1936,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0fc2c093b0..80cbee29ca 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 35a8dec2b9..93c2fcb21c 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_rel_relam(Oid relid);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f25f769af2..d3144c949f 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -678,6 +678,12 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+/*
+ * RelationIsIVM
+ *		True if relation is an incrementally maintainable materialized view.
+ */
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 5e45ce64f7..04c54482a1 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1392,6 +1392,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


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



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

* [PATCH v29 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  2 ++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 36 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b534da7d80..d9eac41463 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -924,6 +924,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index fd09378848..e4b52fdd21 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -993,6 +993,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 77b06e2a7a..2b60ed9e52 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index fc6d267e44..2b29ab4409 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2046,6 +2046,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 7234cb3da6..96cd510780 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1924,6 +1924,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 2d1bb7af3a..62b9c0e5cb 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index f5fdbfe116..7b433749f5 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -138,6 +138,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 1426a353cd..b8961176bb 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -677,6 +677,8 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 5058be5411..cc5287344d 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1392,6 +1392,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


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



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

* [PATCH v29 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.

Also, isimmv columns is added to pg_matviews system view.

isimmv
---
 src/backend/catalog/heap.c           |  1 +
 src/backend/catalog/index.c          |  1 +
 src/backend/catalog/system_views.sql |  1 +
 src/backend/utils/cache/lsyscache.c  | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c   |  2 ++
 src/include/catalog/pg_class.h       |  3 +++
 src/include/utils/lsyscache.h        |  1 +
 src/include/utils/rel.h              |  2 ++
 src/test/regress/expected/rules.out  |  1 +
 9 files changed, 36 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index b534da7d80..d9eac41463 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -924,6 +924,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index fd09378848..e4b52fdd21 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -993,6 +993,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 77b06e2a7a..2b60ed9e52 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -146,6 +146,7 @@ CREATE VIEW pg_matviews AS
         T.spcname AS tablespace,
         C.relhasindex AS hasindexes,
         C.relispopulated AS ispopulated,
+        C.relisivm AS isimmv,
         pg_get_viewdef(C.oid) AS definition
     FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
          LEFT JOIN pg_tablespace T ON (T.oid = C.reltablespace)
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index fc6d267e44..2b29ab4409 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2046,6 +2046,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 7234cb3da6..96cd510780 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1924,6 +1924,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 2d1bb7af3a..62b9c0e5cb 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index f5fdbfe116..7b433749f5 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -138,6 +138,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 1426a353cd..b8961176bb 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -677,6 +677,8 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 5058be5411..cc5287344d 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1392,6 +1392,7 @@ pg_matviews| SELECT n.nspname AS schemaname,
     t.spcname AS tablespace,
     c.relhasindex AS hasindexes,
     c.relispopulated AS ispopulated,
+    c.relisivm AS isimmv,
     pg_get_viewdef(c.oid) AS definition
    FROM ((pg_class c
      LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace)))
-- 
2.25.1


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



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

* [PATCH v28 02/11] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 2a0d82aedd..37a7759753 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -924,6 +924,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 352e43d0e6..f715cf31ac 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -994,6 +994,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 60978f9415..c3bf9aeac6 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2024,6 +2024,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 8a08463c2b..1ba5c3c883 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1924,6 +1924,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 2d1bb7af3a..62b9c0e5cb 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 4f5418b972..078cdf963b 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 1426a353cd..b8961176bb 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -677,6 +677,8 @@ RelationCloseSmgr(Relation relation)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.25.1


--Multipart=_Thu__1_Jun_2023_23_59_09_+0900_/G5+8nG46.f1T42K
Content-Type: text/x-diff;
 name="v28-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Disposition: attachment;
 filename="v28-0003-Allow-to-prolong-life-span-of-transition-tables-.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v25 02/15] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 7e99de88b3..212a6293aa 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -935,6 +935,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 2308d40256..244c9af7b8 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -981,6 +981,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index feef999863..1db83878c6 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2013,6 +2013,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 2e760e8a3b..0dd901d6ed 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1902,6 +1902,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 304e8c18d5..fbaa1438d6 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d4a9..cc2f635122 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 6da1b220cd..6356c24f84 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -650,6 +650,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Fri__4_Feb_2022_01_48_06_+0900_N8BNZpfOR27sWrgY
Content-Type: text/x-diff;
 name="v25-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v25-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v26 02/10] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 7e99de88b3..212a6293aa 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -935,6 +935,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 5e3fc2b35d..d861211f66 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -982,6 +982,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 1b7e11b93e..3275963886 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2023,6 +2023,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index fccffce572..149c84535c 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1903,6 +1903,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 304e8c18d5..fbaa1438d6 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b8dd27d4a9..cc2f635122 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 3b4ab65ae2..fc6b6ddec8 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -650,6 +650,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Mon__14_Mar_2022_19_12_17_+0900_E9HVp8j5QFkIIek.
Content-Type: text/x-diff;
 name="v26-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Disposition: attachment;
 filename="v26-0001-Add-a-syntax-to-create-Incrementally-Maintainabl.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v23 02/15] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 83746d3fd9..ade3586779 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -963,6 +963,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 26bfa74ce7..763f442a1d 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -961,6 +961,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 6bba5f8ec4..8d5214fb90 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2013,6 +2013,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 13d9994af3..5b130f0ed2 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1865,6 +1865,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index fef9945ed8..2058978b89 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 77871aaefc..09346aaa17 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index b4faa1c123..b5028f3449 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -649,6 +649,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Mon__2_Aug_2021_15_28_34_+0900_wlHCjIpnD/FrGAKu
Content-Type: text/x-diff;
 name="v23-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Disposition: attachment;
 filename="v23-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v24 02/15] Add relisivm column to pg_class system catalog
@ 2019-12-20 01:07  Yugo Nagata <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Yugo Nagata @ 2019-12-20 01:07 UTC (permalink / raw)

If this boolean column is true, a relations is Incrementally Maintainable
Materialized View (IMMV). This is set when IMMV is created.
---
 src/backend/catalog/heap.c          |  1 +
 src/backend/catalog/index.c         |  1 +
 src/backend/utils/cache/lsyscache.c | 24 ++++++++++++++++++++++++
 src/backend/utils/cache/relcache.c  |  2 ++
 src/include/catalog/pg_class.h      |  3 +++
 src/include/utils/lsyscache.h       |  1 +
 src/include/utils/rel.h             |  2 ++
 7 files changed, 34 insertions(+)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 83746d3fd9..ade3586779 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -963,6 +963,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relrewrite - 1] = ObjectIdGetDatum(rd_rel->relrewrite);
 	values[Anum_pg_class_relfrozenxid - 1] = TransactionIdGetDatum(rd_rel->relfrozenxid);
 	values[Anum_pg_class_relminmxid - 1] = MultiXactIdGetDatum(rd_rel->relminmxid);
+	values[Anum_pg_class_relisivm - 1] = BoolGetDatum(rd_rel->relisivm);
 	if (relacl != (Datum) 0)
 		values[Anum_pg_class_relacl - 1] = relacl;
 	else
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 26bfa74ce7..763f442a1d 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -961,6 +961,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
+	indexRelation->rd_rel->relisivm = false;
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 4ebaa552a2..c626df32cc 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2013,6 +2013,30 @@ get_rel_relispartition(Oid relid)
 		return false;
 }
 
+/*
+ * get_rel_relisivm
+ *
+ *		Returns the relisivm flag associated with a given relation.
+ */
+bool
+get_rel_relisivm(Oid relid)
+{
+	HeapTuple	tp;
+
+	tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
+	if (HeapTupleIsValid(tp))
+	{
+		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);
+		bool		result;
+
+		result = reltup->relisivm;
+		ReleaseSysCache(tp);
+		return result;
+	}
+	else
+		return false;
+}
+
 /*
  * get_rel_tablespace
  *
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 13d9994af3..5b130f0ed2 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1865,6 +1865,8 @@ formrdesc(const char *relationName, Oid relationReltype,
 
 	/* ... and they're always populated, too */
 	relation->rd_rel->relispopulated = true;
+	/* ... and they're always no ivm, too */
+	relation->rd_rel->relisivm = false;
 
 	relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING;
 	relation->rd_rel->relpages = 0;
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index fef9945ed8..2058978b89 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -119,6 +119,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	/* is relation a partition? */
 	bool		relispartition BKI_DEFAULT(f);
 
+	/* is relation a matview with ivm? */
+	bool		relisivm BKI_DEFAULT(f);
+
 	/* link to original rel during table rewrite; otherwise 0 */
 	Oid			relrewrite BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
 
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 77871aaefc..09346aaa17 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -137,6 +137,7 @@ extern Oid	get_rel_namespace(Oid relid);
 extern Oid	get_rel_type_id(Oid relid);
 extern char get_rel_relkind(Oid relid);
 extern bool get_rel_relispartition(Oid relid);
+extern bool get_rel_relisivm(Oid relid);
 extern Oid	get_rel_tablespace(Oid relid);
 extern char get_rel_persistence(Oid relid);
 extern Oid	get_transform_fromsql(Oid typid, Oid langid, List *trftypes);
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index b4faa1c123..b5028f3449 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -649,6 +649,8 @@ RelationGetSmgr(Relation rel)
  */
 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
 
+#define RelationIsIVM(relation) ((relation)->rd_rel->relisivm)
+
 /*
  * RelationIsAccessibleInLogicalDecoding
  *		True if we need to log enough information to have access via
-- 
2.17.1


--Multipart=_Thu__23_Sep_2021_04_57_30_+0900_b5pmgR1N8oMaMz.U
Content-Type: text/x-diff;
 name="v24-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Disposition: attachment;
 filename="v24-0003-Add-new-deptype-option-m-in-pg_depend-system-cat.patch"
Content-Transfer-Encoding: 7bit



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

* [PATCH v23 6/8] Row pattern recognition patch (docs).
@ 2024-10-25 03:56  Tatsuo Ishii <[email protected]>
  0 siblings, 0 replies; 171+ messages in thread

From: Tatsuo Ishii @ 2024-10-25 03:56 UTC (permalink / raw)

---
 doc/src/sgml/advanced.sgml   | 82 ++++++++++++++++++++++++++++++++++++
 doc/src/sgml/func.sgml       | 54 ++++++++++++++++++++++++
 doc/src/sgml/ref/select.sgml | 38 ++++++++++++++++-
 3 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml
index 755c9f1485..b0b1d1c51e 100644
--- a/doc/src/sgml/advanced.sgml
+++ b/doc/src/sgml/advanced.sgml
@@ -537,6 +537,88 @@ WHERE pos &lt; 3;
     <literal>rank</literal> less than 3.
    </para>
 
+   <para>
+    Row pattern common syntax can be used to perform row pattern recognition
+    in a query. The row pattern common syntax includes two sub
+    clauses: <literal>DEFINE</literal>
+    and <literal>PATTERN</literal>. <literal>DEFINE</literal> defines
+    definition variables along with an expression. The expression must be a
+    logical expression, which means it must
+    return <literal>TRUE</literal>, <literal>FALSE</literal>
+    or <literal>NULL</literal>. The expression may comprise column references
+    and functions. Window functions, aggregate functions and subqueries are
+    not allowed. An example of <literal>DEFINE</literal> is as follows.
+
+<programlisting>
+DEFINE
+ LOWPRICE AS price &lt;= 100,
+ UP AS price &gt; PREV(price),
+ DOWN AS price &lt; PREV(price)
+</programlisting>
+
+    Note that <function>PREV</function> returns the price column in the
+    previous row if it's called in a context of row pattern recognition. Thus in
+    the second line the definition variable "UP" is <literal>TRUE</literal>
+    when the price column in the current row is greater than the price column
+    in the previous row. Likewise, "DOWN" is <literal>TRUE</literal> when when
+    the price column in the current row is lower than the price column in the
+    previous row.
+   </para>
+   <para>
+    Once <literal>DEFINE</literal> exists, <literal>PATTERN</literal> can be
+    used. <literal>PATTERN</literal> defines a sequence of rows that satisfies
+    certain conditions.  For example following <literal>PATTERN</literal>
+    defines that a row starts with the condition "LOWPRICE", then one or more
+    rows satisfy "UP" and finally one or more rows satisfy "DOWN". Note that
+    "+" means one or more matches. Also you can use "*", which means zero or
+    more matches. If a sequence of rows which satisfies the PATTERN is found,
+    in the starting row of the sequence of rows all window functions and
+    aggregates are shown in the target list. Note that aggregations only look
+    into the matched rows, rather than whole frame. On the second or
+    subsequent rows all window functions are NULL. Aggregates are NULL or 0
+    (count case) depending on its aggregation definition. For rows that do not
+    match on the PATTERN, all window functions and aggregates are shown AS
+    NULL too, except count showing 0. This is because the rows do not match,
+    thus they are in an empty frame. Example of a <literal>SELECT</literal>
+    using the <literal>DEFINE</literal> and <literal>PATTERN</literal> clause
+    is as follows.
+
+<programlisting>
+SELECT company, tdate, price,
+ first_value(price) OVER w,
+ max(price) OVER w,
+ count(price) OVER w
+FROM stock
+ WINDOW w AS (
+ PARTITION BY company
+ ORDER BY tdate
+ ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ AFTER MATCH SKIP PAST LAST ROW
+ INITIAL
+ PATTERN (LOWPRICE UP+ DOWN+)
+ DEFINE
+  LOWPRICE AS price &lt;= 100,
+  UP AS price &gt; PREV(price),
+  DOWN AS price &lt; PREV(price)
+);
+</programlisting>
+<screen>
+ company  |   tdate    | price | first_value | max | count 
+----------+------------+-------+-------------+-----+-------
+ company1 | 2023-07-01 |   100 |         100 | 200 |     4
+ company1 | 2023-07-02 |   200 |             |     |     0
+ company1 | 2023-07-03 |   150 |             |     |     0
+ company1 | 2023-07-04 |   140 |             |     |     0
+ company1 | 2023-07-05 |   150 |             |     |     0
+ company1 | 2023-07-06 |    90 |          90 | 130 |     4
+ company1 | 2023-07-07 |   110 |             |     |     0
+ company1 | 2023-07-08 |   130 |             |     |     0
+ company1 | 2023-07-09 |   120 |             |     |     0
+ company1 | 2023-07-10 |   130 |             |     |     0
+(10 rows)
+</screen>
+   </para>
+
    <para>
     When a query involves multiple window functions, it is possible to write
     out each one with a separate <literal>OVER</literal> clause, but this is
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 58dc06b68b..ef4fa7144f 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -23263,6 +23263,7 @@ SELECT count(*) FROM sometable;
         returns <literal>NULL</literal> if there is no such row.
        </para></entry>
       </row>
+
      </tbody>
     </tgroup>
    </table>
@@ -23302,6 +23303,59 @@ SELECT count(*) FROM sometable;
    Other frame specifications can be used to obtain other effects.
   </para>
 
+  <para>
+   Row pattern recognition navigation functions are listed in
+   <xref linkend="functions-rpr-navigation-table"/>.  These functions
+   can be used to describe DEFINE clause of Row pattern recognition.
+  </para>
+
+   <table id="functions-rpr-navigation-table">
+    <title>Row Pattern Navigation Functions</title>
+    <tgroup cols="1">
+     <thead>
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        Function
+       </para>
+       <para>
+        Description
+       </para></entry>
+      </row>
+     </thead>
+
+     <tbody>
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>prev</primary>
+        </indexterm>
+        <function>prev</function> ( <parameter>value</parameter> <type>anyelement</type> )
+        <returnvalue>anyelement</returnvalue>
+       </para>
+       <para>
+        Returns the column value at the previous row;
+        returns NULL if there is no previous row in the window frame.
+       </para></entry>
+      </row>
+
+      <row>
+       <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>next</primary>
+        </indexterm>
+        <function>next</function> ( <parameter>value</parameter> <type>anyelement</type> )
+        <returnvalue>anyelement</returnvalue>
+       </para>
+       <para>
+        Returns the column value at the next row;
+        returns NULL if there is no next row in the window frame.
+       </para></entry>
+      </row>
+
+     </tbody>
+    </tgroup>
+   </table>
+
   <note>
    <para>
     The SQL standard defines a <literal>RESPECT NULLS</literal> or
diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml
index d7089eac0b..7e1c9989ba 100644
--- a/doc/src/sgml/ref/select.sgml
+++ b/doc/src/sgml/ref/select.sgml
@@ -969,8 +969,8 @@ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceabl
     The <replaceable class="parameter">frame_clause</replaceable> can be one of
 
 <synopsis>
-{ RANGE | ROWS | GROUPS } <replaceable>frame_start</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
-{ RANGE | ROWS | GROUPS } BETWEEN <replaceable>frame_start</replaceable> AND <replaceable>frame_end</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
+{ RANGE | ROWS | GROUPS } <replaceable>frame_start</replaceable> [ <replaceable>frame_exclusion</replaceable> ] [row_pattern_common_syntax]
+{ RANGE | ROWS | GROUPS } BETWEEN <replaceable>frame_start</replaceable> AND <replaceable>frame_end</replaceable> [ <replaceable>frame_exclusion</replaceable> ] [row_pattern_common_syntax]
 </synopsis>
 
     where <replaceable>frame_start</replaceable>
@@ -1077,6 +1077,40 @@ EXCLUDE NO OTHERS
     a given peer group will be in the frame or excluded from it.
    </para>
 
+   <para>
+    The
+    optional <replaceable class="parameter">row_pattern_common_syntax</replaceable>
+    defines the <firstterm>row pattern recognition condition</firstterm> for
+    this
+    window. <replaceable class="parameter">row_pattern_common_syntax</replaceable>
+    includes following subclauses. <literal>AFTER MATCH SKIP PAST LAST
+    ROW</literal> or <literal>AFTER MATCH SKIP TO NEXT ROW</literal> controls
+    how to proceed to next row position after a match
+    found. With <literal>AFTER MATCH SKIP PAST LAST ROW</literal> (the
+    default) next row position is next to the last row of previous match. On
+    the other hand, with <literal>AFTER MATCH SKIP TO NEXT ROW</literal> next
+    row position is always next to the last row of previous
+    match. <literal>DEFINE</literal> defines definition variables along with a
+    boolean expression. <literal>PATTERN</literal> defines a sequence of rows
+    that satisfies certain conditions using variables defined
+    in <literal>DEFINE</literal> clause. If the variable is not defined in
+    the <literal>DEFINE</literal> clause, it is implicitly assumed
+    following is defined in the <literal>DEFINE</literal> clause.
+
+<synopsis>
+<literal>variable_name</literal> AS TRUE
+</synopsis>
+
+    Note that the maximu number of variables defined
+    in <literal>DEFINE</literal> clause is 26.
+
+<synopsis>
+[ AFTER MATCH SKIP PAST LAST ROW | AFTER MATCH SKIP TO NEXT ROW ]
+PATTERN <replaceable class="parameter">pattern_variable_name</replaceable>[+] [, ...]
+DEFINE <replaceable class="parameter">definition_varible_name</replaceable> AS <replaceable class="parameter">expression</replaceable> [, ...]
+</synopsis>
+   </para>
+
    <para>
     The purpose of a <literal>WINDOW</literal> clause is to specify the
     behavior of <firstterm>window functions</firstterm> appearing in the query's
-- 
2.25.1


----Next_Part(Fri_Oct_25_13_04_53_2024_648)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="v23-0007-Row-pattern-recognition-patch-tests.patch"



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


end of thread, other threads:[~2024-10-25 03:56 UTC | newest]

Thread overview: 171+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v27 2/9] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v33 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v31 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v30 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v32 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v24 02/15] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v26 02/10] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v27 2/9] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v28 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v29 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v24 02/15] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v34 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v29 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v25 02/15] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v38 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v23 02/15] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v37 02/11] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2019-12-20 01:07 [PATCH v39 2/8] Add relisivm column to pg_class system catalog Yugo Nagata <[email protected]>
2024-10-25 03:56 [PATCH v23 6/8] Row pattern recognition patch (docs). Tatsuo Ishii <[email protected]>

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