From 6d68410e597a11d07c224501075d378795ce2970 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddy@enterprisedb.com>
Date: Fri, 2 Apr 2021 10:10:34 +0530
Subject: [PATCH v1] Emit warning when partitioned table's persistence is
 changed

Changing persistence setting(LOGGED/UNLOGGED) for a partitioned
table does not affect existing or future partitions. If required,
set the persistence setting for each partition separately. Perhaps
this could be improved.
---
 doc/src/sgml/ref/alter_table.sgml         |  5 ++++-
 src/backend/commands/tablecmds.c          | 20 ++++++++++++++++++++
 src/test/regress/expected/alter_table.out | 13 +++++++++++++
 src/test/regress/sql/alter_table.sql      | 10 ++++++++++
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index 07e37a6dc8..538e42a666 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -712,7 +712,10 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
      <para>
       This form changes the table from unlogged to logged or vice-versa
       (see <xref linkend="sql-createtable-unlogged"/>).  It cannot be applied
-      to a temporary table.
+      to a temporary table.  Changing persistence setting for a partitioned
+      table does not affect existing or future partitions. If required, set the
+      persistence setting for each partition separately. Perhaps this could be
+      improved.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 88a68a4697..b017c967cb 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4457,6 +4457,16 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("cannot change persistence setting twice")));
+			/*
+			 * Changing persistence setting for a partitioned table does not
+			 * affect existing or future partitions. If required, set the
+			 * persistence setting for each partition separately. XXX Perhaps
+			 * this could be improved someday.
+			 */
+			if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+				ereport(WARNING,
+						(errmsg("changing persistence setting for a partitioned table does not affect existing or future partitions"),
+						 errhint("If required, set the persistence setting for each partition separately.")));
 			tab->chgPersistence = ATPrepChangePersistence(rel, true);
 			/* force rewrite if necessary; see comment in ATRewriteTables */
 			if (tab->chgPersistence)
@@ -4472,6 +4482,16 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 						 errmsg("cannot change persistence setting twice")));
+			/*
+			 * Changing persistence setting for a partitioned table does not
+			 * affect existing or future partitions. If required, set the
+			 * persistence setting for each partition separately. XXX Perhaps
+			 * this could be improved someday.
+			 */
+			if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+				ereport(WARNING,
+						(errmsg("changing persistence setting for a partitioned table does not affect existing or future partitions"),
+						 errhint("If required, set the persistence setting for each partition separately.")));
 			tab->chgPersistence = ATPrepChangePersistence(rel, false);
 			/* force rewrite if necessary; see comment in ATRewriteTables */
 			if (tab->chgPersistence)
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index ec14b060a6..ff10aef087 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -3472,6 +3472,19 @@ ALTER TABLE logged1 SET UNLOGGED; -- silently do nothing
 DROP TABLE logged3;
 DROP TABLE logged2;
 DROP TABLE logged1;
+-- setting partitioned table's logged/unlogged ness has no effect on existing
+-- or future partitions, so we just emit a warning.
+CREATE TABLE part_logged_parent (key integer PRIMARY KEY, val text)
+	PARTITION BY RANGE (key);
+CREATE TABLE part_logged_child1 PARTITION OF part_logged_parent
+	FOR VALUES FROM (1) TO (10);
+ALTER TABLE part_logged_parent SET UNLOGGED; -- warning is emitted
+WARNING:  changing persistence setting for a partitioned table does not affect existing or future partitions
+HINT:  If required, set the persistence setting for each partition separately.
+ALTER TABLE part_logged_parent SET LOGGED; -- warning is emitted
+WARNING:  changing persistence setting for a partitioned table does not affect existing or future partitions
+HINT:  If required, set the persistence setting for each partition separately.
+DROP TABLE part_logged_parent;
 -- test ADD COLUMN IF NOT EXISTS
 CREATE TABLE test_add_column(c1 integer);
 \d test_add_column
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 7a9c9252dc..89fdbd2b88 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -2189,6 +2189,16 @@ DROP TABLE logged3;
 DROP TABLE logged2;
 DROP TABLE logged1;
 
+-- setting partitioned table's logged/unlogged ness has no effect on existing
+-- or future partitions, so we just emit a warning.
+CREATE TABLE part_logged_parent (key integer PRIMARY KEY, val text)
+	PARTITION BY RANGE (key);
+CREATE TABLE part_logged_child1 PARTITION OF part_logged_parent
+	FOR VALUES FROM (1) TO (10);
+ALTER TABLE part_logged_parent SET UNLOGGED; -- warning is emitted
+ALTER TABLE part_logged_parent SET LOGGED; -- warning is emitted
+DROP TABLE part_logged_parent;
+
 -- test ADD COLUMN IF NOT EXISTS
 CREATE TABLE test_add_column(c1 integer);
 \d test_add_column
-- 
2.25.1

