From b8fb29126fdc6083bf2d020fc5e55f3cb9ad050d Mon Sep 17 00:00:00 2001
From: houzj <houzj.fnst@cn.fujitsu.com>
Date: Thu, 18 Feb 2021 11:17:35 +0800
Subject: [PATCH] reloption parallel parallel_dml_enabled test and doc

Test and documentation updates for reloption parallel_dml_enabled.
---
 doc/src/sgml/ref/alter_table.sgml             |  2 +-
 doc/src/sgml/ref/create_table.sgml            | 27 +++++++++++++++++
 src/test/regress/expected/insert_parallel.out | 42 ++++++++++++++++++++++++---
 src/test/regress/sql/insert_parallel.sql      | 34 +++++++++++++++++++---
 4 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index c25ef5a..ecb0470 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -722,7 +722,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
      <para>
       <literal>SHARE UPDATE EXCLUSIVE</literal> lock will be taken for
       fillfactor, toast and autovacuum storage parameters, as well as the
-      planner parameter <varname>parallel_workers</varname>.
+      planner parameter <varname>parallel_workers</varname> and <varname>parallel_dml_enabled</varname>.
      </para>
     </listitem>
    </varlistentry>
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 569f4c9..f402174 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -1408,6 +1408,33 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     </listitem>
    </varlistentry>
 
+   <varlistentry id="reloption-parallel-dml-enabled" xreflabel="parallel_dml_enabled">
+    <term><literal>parallel_dml_enabled</literal> (<type>boolean</type>)
+     <indexterm>
+     <primary><varname>parallel_dml_enabled</varname> storage parameter</primary>
+    </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Enables or disables the query planner's use of parallel DML for
+      this table. When enabled (and provided that
+      <xref linkend="guc-enable-parallel-dml"/> is also <literal>true</literal>),
+      the planner performs additional parallel-safety checks on the table's
+      attributes and indexes, in order to determine if it's safe to use a
+      parallel plan for table-modification. The default is
+      <literal>true</literal>.
+      In cases such as when the table has a large number of partitions, and
+      particularly also when that table uses a parallel-unsafe feature that
+      prevents parallelism, the overhead of these checks may become prohibitively
+      high. To address this potential overhead in these cases, this option can be
+      used to disable the use of parallel DML for this table.
+      Note that if the target table of the parallel DML is partitioned, the
+      <literal>parallel_dml_enabled</literal> option values of the partitions are
+      ignored.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled">
     <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>)
     <indexterm>
diff --git a/src/test/regress/expected/insert_parallel.out b/src/test/regress/expected/insert_parallel.out
index 73330ef..997d8b5 100644
--- a/src/test/regress/expected/insert_parallel.out
+++ b/src/test/regress/expected/insert_parallel.out
@@ -70,13 +70,13 @@ set max_parallel_workers_per_gather=4;
 create table para_insert_p1 (
 	unique1		int4	PRIMARY KEY,
 	stringu1	name
-);
+) with (parallel_dml_enabled = off);
 create table para_insert_f1 (
 	unique1		int4	REFERENCES para_insert_p1(unique1),
 	stringu1	name
 );
 --
--- Test INSERT with underlying query when enable_parallel_dml=off.
+-- Test INSERT with underlying query when enable_parallel_dml=off and reloption.parallel_dml_enabled=off.
 -- (should create plan with serial INSERT + SELECT)
 --
 explain(costs off) insert into para_insert_p1 select unique1, stringu1 from tenk1;
@@ -87,10 +87,25 @@ explain(costs off) insert into para_insert_p1 select unique1, stringu1 from tenk
 (2 rows)
 
 --
--- Enable parallel dml
+-- Enable guc option enable_parallel_dml
 --
 set enable_parallel_dml = on;
 --
+-- Test INSERT with underlying query when enable_parallel_dml=on and reloption.parallel_dml_enabled=off.
+-- (should create plan with serial INSERT + SELECT)
+--
+explain(costs off) insert into para_insert_p1 select unique1, stringu1 from tenk1;
+        QUERY PLAN        
+--------------------------
+ Insert on para_insert_p1
+   ->  Seq Scan on tenk1
+(2 rows)
+
+--
+-- Enable reloption parallel_dml_enabled
+--
+alter table para_insert_p1 set (parallel_dml_enabled = on);
+--
 -- Test INSERT with underlying query.
 -- (should create plan with parallel INSERT+SELECT, Gather parent node)
 --
@@ -868,9 +883,28 @@ truncate testdef;
 --
 -- Test INSERT into partition with underlying query.
 --
-create table parttable1 (a int, b name) partition by range (a);
+create table parttable1 (a int, b name) partition by range (a) with (parallel_dml_enabled=off);
 create table parttable1_1 partition of parttable1 for values from (0) to (5000);
 create table parttable1_2 partition of parttable1 for values from (5000) to (10000);
+--
+-- Test INSERT into partition when reloption.parallel_dml_enabled=off
+-- (should not create a parallel plan)
+--
+explain (costs off) insert into parttable1 select unique1,stringu1 from tenk1;
+       QUERY PLAN        
+-------------------------
+ Insert on parttable1
+   ->  Seq Scan on tenk1
+(2 rows)
+
+--
+-- Enable reloption parallel_dml_enabled
+--
+alter table parttable1 set (parallel_dml_enabled = on);
+--
+-- Test INSERT into partition when reloption.parallel_dml_enabled=off
+-- (should create a parallel plan)
+--
 explain (costs off) insert into parttable1 select unique1,stringu1 from tenk1;
                QUERY PLAN               
 ----------------------------------------
diff --git a/src/test/regress/sql/insert_parallel.sql b/src/test/regress/sql/insert_parallel.sql
index eba30d2..8cb439b 100644
--- a/src/test/regress/sql/insert_parallel.sql
+++ b/src/test/regress/sql/insert_parallel.sql
@@ -87,7 +87,7 @@ set max_parallel_workers_per_gather=4;
 create table para_insert_p1 (
 	unique1		int4	PRIMARY KEY,
 	stringu1	name
-);
+) with (parallel_dml_enabled = off);
 
 create table para_insert_f1 (
 	unique1		int4	REFERENCES para_insert_p1(unique1),
@@ -95,17 +95,28 @@ create table para_insert_f1 (
 );
 
 --
--- Test INSERT with underlying query when enable_parallel_dml=off.
+-- Test INSERT with underlying query when enable_parallel_dml=off and reloption.parallel_dml_enabled=off.
 -- (should create plan with serial INSERT + SELECT)
 --
 explain(costs off) insert into para_insert_p1 select unique1, stringu1 from tenk1;
 
 --
--- Enable parallel dml
+-- Enable guc option enable_parallel_dml
 --
 set enable_parallel_dml = on;
 
 --
+-- Test INSERT with underlying query when enable_parallel_dml=on and reloption.parallel_dml_enabled=off.
+-- (should create plan with serial INSERT + SELECT)
+--
+explain(costs off) insert into para_insert_p1 select unique1, stringu1 from tenk1;
+
+--
+-- Enable reloption parallel_dml_enabled
+--
+alter table para_insert_p1 set (parallel_dml_enabled = on);
+
+--
 -- Test INSERT with underlying query.
 -- (should create plan with parallel INSERT+SELECT, Gather parent node)
 --
@@ -359,10 +370,25 @@ truncate testdef;
 --
 -- Test INSERT into partition with underlying query.
 --
-create table parttable1 (a int, b name) partition by range (a);
+create table parttable1 (a int, b name) partition by range (a) with (parallel_dml_enabled=off);
 create table parttable1_1 partition of parttable1 for values from (0) to (5000);
 create table parttable1_2 partition of parttable1 for values from (5000) to (10000);
 
+--
+-- Test INSERT into partition when reloption.parallel_dml_enabled=off
+-- (should not create a parallel plan)
+--
+explain (costs off) insert into parttable1 select unique1,stringu1 from tenk1;
+
+--
+-- Enable reloption parallel_dml_enabled
+--
+alter table parttable1 set (parallel_dml_enabled = on);
+
+--
+-- Test INSERT into partition when reloption.parallel_dml_enabled=on
+-- (should create a parallel plan)
+--
 explain (costs off) insert into parttable1 select unique1,stringu1 from tenk1;
 insert into parttable1 select unique1,stringu1 from tenk1;
 select count(*) from parttable1_1;
-- 
2.7.2.windows.1

