public inbox for [email protected]  
help / color / mirror / Atom feed
From: Dmitry Koval <[email protected]>
To: Alexander Korotkov <[email protected]>
Cc: Alexander Lakhin <[email protected]>
Cc: Robert Haas <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: Add SPLIT PARTITION/MERGE PARTITIONS commands
Date: Mon, 15 Apr 2024 18:26:56 +0300
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAPpHfdv-uR663BO6G2kRuLEQjob+UBHuD3iyXF+qGHXQFRN0-Q@mail.gmail.com>
References: <[email protected]>
	<[email protected]>
	<CAPpHfdtTgSdbzfcEz_mgVxh8VSDP=VfQ6r4T1n9SMT_impbDiA@mail.gmail.com>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<CAMbWs49c_7dT_oiP729b-JPRiDtTuDca3exN_cOZZwjGG-0bMA@mail.gmail.com>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<CAPpHfdv1ZkY9cPOqsLvDY9AA-fCYKHM4P07+-Mu+xq5o=daS6w@mail.gmail.com>
	<CA+TgmoYcjL+w2BQzku5iNXKR5fyxJMSP3avQta8xngioTX7D7A@mail.gmail.com>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<CAPpHfdv-uR663BO6G2kRuLEQjob+UBHuD3iyXF+qGHXQFRN0-Q@mail.gmail.com>

Hi!

> Please, find a my version of this fix attached.

Is it possible to make a small addition to the file v6-0001 ... .patch 
(see attachment)?

Most important:
1) Line 19:

+ mergePartName = makeRangeVar(cmd->name->schemaname, tmpRelName, -1);

(temporary table should use the same schema as the partition);

2) Lines 116-123:

+RESET search_path;
+
+-- Can't merge persistent partitions into a temporary partition
+ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
+
+SET search_path = pg_temp, public;

(Alexandr Lakhin's test for using of pg_temp schema explicitly).


The rest of the changes in v6_afterfix.diff are not very important and 
can be ignored.

-- 
With best regards,
Dmitry Koval

Postgres Professional: http://postgrespro.com
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c6ce7b94d9..bce5e39b64 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -21130,6 +21130,7 @@ moveSplitTableRows(Relation rel, Relation splitRel, List *partlist, List *newPar
  *
  * Emulates command: CREATE [TEMP] TABLE <newPartName> (LIKE <modelRelName>
  * INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)
+ * Function locks created relation in AccessExclusiveLock mode and returns it.
  */
 static Relation
 createPartitionTable(Relation rel, RangeVar *newPartName, RangeVar *modelRelName,
@@ -21500,8 +21501,7 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	{
 		/* Create partition table with generated temparary name. */
 		sprintf(tmpRelName, "merge-%u-%X-tmp", RelationGetRelid(rel), MyProcPid);
-		mergePartName = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
-									 tmpRelName, -1);
+		mergePartName = makeRangeVar(cmd->name->schemaname, tmpRelName, -1);
 	}
 
 	newPartRel = createPartitionTable(rel,
diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out
index b1d0b50b0b..0a4022f714 100644
--- a/src/test/regress/expected/partition_merge.out
+++ b/src/test/regress/expected/partition_merge.out
@@ -793,23 +793,58 @@ SELECT indexname FROM pg_indexes WHERE tablename = 'tp_1_2';
 
 DROP TABLE t;
 --
--- Try creating a partition in the temporary schema.
+-- Try mixing permanent and temporary partitions.
 --
 SET search_path = public, pg_temp;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+ oid | relpersistence 
+-----+----------------
+ t   | p
+(1 row)
+
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+  oid   |        pg_get_expr         | relpersistence 
+--------+----------------------------+----------------
+ tp_0_1 | FOR VALUES FROM (0) TO (1) | p
+ tp_1_2 | FOR VALUES FROM (1) TO (2) | p
+(2 rows)
+
 SET search_path = pg_temp, public;
 -- Can't merge persistent partitions into a temporary partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
 ERROR:  cannot create a temporary relation as partition of permanent relation "t"
+RESET search_path;
+-- Can't merge persistent partitions into a temporary partition
+ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
+ERROR:  cannot create a temporary relation as partition of permanent relation "t"
 DROP TABLE t;
-DROP TAble tp_0_2;
-ERROR:  table "tp_0_2" does not exist
+SET search_path = pg_temp, public;
 BEGIN;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+ oid | relpersistence 
+-----+----------------
+ t   | t
+(1 row)
+
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+  oid   |        pg_get_expr         | relpersistence 
+--------+----------------------------+----------------
+ tp_0_1 | FOR VALUES FROM (0) TO (1) | t
+ tp_1_2 | FOR VALUES FROM (1) TO (2) | t
+(2 rows)
+
 SET search_path = public, pg_temp;
 -- Can't merge temporary partitions into a persistent partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql
index 2d55e0f5a3..56adcf4bfc 100644
--- a/src/test/regress/sql/partition_merge.sql
+++ b/src/test/regress/sql/partition_merge.sql
@@ -484,25 +484,43 @@ SELECT indexname FROM pg_indexes WHERE tablename = 'tp_1_2';
 DROP TABLE t;
 
 --
--- Try creating a partition in the temporary schema.
+-- Try mixing permanent and temporary partitions.
 --
 SET search_path = public, pg_temp;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
 
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+
 SET search_path = pg_temp, public;
 
 -- Can't merge persistent partitions into a temporary partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
+
+RESET search_path;
+
+-- Can't merge persistent partitions into a temporary partition
+ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
 DROP TABLE t;
-DROP TAble tp_0_2;
+
+SET search_path = pg_temp, public;
 
 BEGIN;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
 
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+
 SET search_path = public, pg_temp;
 
 -- Can't merge temporary partitions into a persistent partition


Attachments:

  [text/plain] v6_afterfix.diff (6.2K, ../[email protected]/2-v6_afterfix.diff)
  download | inline diff:
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c6ce7b94d9..bce5e39b64 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -21130,6 +21130,7 @@ moveSplitTableRows(Relation rel, Relation splitRel, List *partlist, List *newPar
  *
  * Emulates command: CREATE [TEMP] TABLE <newPartName> (LIKE <modelRelName>
  * INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY)
+ * Function locks created relation in AccessExclusiveLock mode and returns it.
  */
 static Relation
 createPartitionTable(Relation rel, RangeVar *newPartName, RangeVar *modelRelName,
@@ -21500,8 +21501,7 @@ ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	{
 		/* Create partition table with generated temparary name. */
 		sprintf(tmpRelName, "merge-%u-%X-tmp", RelationGetRelid(rel), MyProcPid);
-		mergePartName = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
-									 tmpRelName, -1);
+		mergePartName = makeRangeVar(cmd->name->schemaname, tmpRelName, -1);
 	}
 
 	newPartRel = createPartitionTable(rel,
diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out
index b1d0b50b0b..0a4022f714 100644
--- a/src/test/regress/expected/partition_merge.out
+++ b/src/test/regress/expected/partition_merge.out
@@ -793,23 +793,58 @@ SELECT indexname FROM pg_indexes WHERE tablename = 'tp_1_2';
 
 DROP TABLE t;
 --
--- Try creating a partition in the temporary schema.
+-- Try mixing permanent and temporary partitions.
 --
 SET search_path = public, pg_temp;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+ oid | relpersistence 
+-----+----------------
+ t   | p
+(1 row)
+
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+  oid   |        pg_get_expr         | relpersistence 
+--------+----------------------------+----------------
+ tp_0_1 | FOR VALUES FROM (0) TO (1) | p
+ tp_1_2 | FOR VALUES FROM (1) TO (2) | p
+(2 rows)
+
 SET search_path = pg_temp, public;
 -- Can't merge persistent partitions into a temporary partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
 ERROR:  cannot create a temporary relation as partition of permanent relation "t"
+RESET search_path;
+-- Can't merge persistent partitions into a temporary partition
+ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
+ERROR:  cannot create a temporary relation as partition of permanent relation "t"
 DROP TABLE t;
-DROP TAble tp_0_2;
-ERROR:  table "tp_0_2" does not exist
+SET search_path = pg_temp, public;
 BEGIN;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+ oid | relpersistence 
+-----+----------------
+ t   | t
+(1 row)
+
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+  oid   |        pg_get_expr         | relpersistence 
+--------+----------------------------+----------------
+ tp_0_1 | FOR VALUES FROM (0) TO (1) | t
+ tp_1_2 | FOR VALUES FROM (1) TO (2) | t
+(2 rows)
+
 SET search_path = public, pg_temp;
 -- Can't merge temporary partitions into a persistent partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql
index 2d55e0f5a3..56adcf4bfc 100644
--- a/src/test/regress/sql/partition_merge.sql
+++ b/src/test/regress/sql/partition_merge.sql
@@ -484,25 +484,43 @@ SELECT indexname FROM pg_indexes WHERE tablename = 'tp_1_2';
 DROP TABLE t;
 
 --
--- Try creating a partition in the temporary schema.
+-- Try mixing permanent and temporary partitions.
 --
 SET search_path = public, pg_temp;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
 
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+
 SET search_path = pg_temp, public;
 
 -- Can't merge persistent partitions into a temporary partition
 ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
+
+RESET search_path;
+
+-- Can't merge persistent partitions into a temporary partition
+ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
 DROP TABLE t;
-DROP TAble tp_0_2;
+
+SET search_path = pg_temp, public;
 
 BEGIN;
 CREATE TABLE t (i int) PARTITION BY RANGE (i);
 CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
 CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
 
+SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
+SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
+  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
+  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
+  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
+
 SET search_path = public, pg_temp;
 
 -- Can't merge temporary partitions into a persistent partition


view thread (48+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Add SPLIT PARTITION/MERGE PARTITIONS commands
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

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