v1-0001-Fix-assert-failure-when-detach-partition.patch
application/octet-stream
Filename: v1-0001-Fix-assert-failure-when-detach-partition.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Fix assert failure when detach partition.
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_inherits.c | 26 | 0 |
| src/backend/commands/tablecmds.c | 21 | 0 |
| src/include/catalog/pg_inherits.h | 2 | 0 |
| src/test/regress/expected/partition_info.out | 13 | 0 |
| src/test/regress/sql/partition_info.sql | 15 | 0 |
From 40d43781c41359d2fc834827db55d8edd39710cf Mon Sep 17 00:00:00 2001
From: Tender Wang <tndrwang@gmail.com>
Date: Wed, 12 Jun 2024 13:29:10 +0800
Subject: [PATCH v1] Fix assert failure when detach partition.
---
src/backend/catalog/pg_inherits.c | 26 ++++++++++++++++++++
src/backend/commands/tablecmds.c | 21 ++++++++++++++++
src/include/catalog/pg_inherits.h | 2 ++
src/test/regress/expected/partition_info.out | 13 ++++++++++
src/test/regress/sql/partition_info.sql | 15 +++++++++++
5 files changed, 77 insertions(+)
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 836b4bfd89..c386863699 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -393,6 +393,32 @@ has_superclass(Oid relationId)
return result;
}
+/*
+ * get_superclass - returns this relation inherit tuple if it has
+ */
+HeapTuple
+get_superclass(Oid relationId)
+{
+ Relation catalog;
+ SysScanDesc scan;
+ ScanKeyData skey;
+ HeapTuple inhTup,
+ retval = NULL;
+
+ catalog = table_open(InheritsRelationId, AccessShareLock);
+ ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber,
+ F_OIDEQ, ObjectIdGetDatum(relationId));
+ scan = systable_beginscan(catalog, InheritsRelidSeqnoIndexId, true,
+ NULL, 1, &skey);
+ inhTup = systable_getnext(scan);
+ if (HeapTupleIsValid(inhTup))
+ retval = heap_copytuple(inhTup);
+
+ systable_endscan(scan);
+ table_close(catalog, AccessShareLock);
+
+ return retval;
+}
/*
* Given two type OIDs, determine whether the first is a complex type
* (class type) that inherits from the second.
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6adfd87614..a300676e14 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -19289,6 +19289,10 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent,
Oid idxid = lfirst_oid(cell);
Relation idx;
Oid constrOid;
+ HeapTuple parentTuple;
+ Oid parentIdxid;
+ Oid parentConstrOid;
+ Form_pg_inherits inhForm;
if (!has_superclass(idxid))
continue;
@@ -19296,15 +19300,32 @@ DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent,
Assert((IndexGetRelation(get_partition_parent(idxid, false), false) ==
RelationGetRelid(rel)));
+ /* Get inherit tuple */
+ parentTuple = get_superclass(idxid);
+ Assert(HeapTupleIsValid(parentTuple));
+ inhForm = (Form_pg_inherits) GETSTRUCT(parentTuple);
+ parentIdxid = inhForm->inhparent;
+
+ parentConstrOid = get_relation_idx_constraint_oid(RelationGetRelid(rel),
+ parentIdxid);
idx = index_open(idxid, AccessExclusiveLock);
IndexSetParentIndex(idx, InvalidOid);
+ /* Skip if there's no a constraint associated with parent index */
+ if (!OidIsValid(parentConstrOid))
+ {
+ heap_freetuple(parentTuple);
+ index_close(idx, NoLock);
+ continue;
+ }
+
/* If there's a constraint associated with the index, detach it too */
constrOid = get_relation_idx_constraint_oid(RelationGetRelid(partRel),
idxid);
if (OidIsValid(constrOid))
ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid);
+ heap_freetuple(parentTuple);
index_close(idx, NoLock);
}
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index b3da78c24b..d8855a1733 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -18,6 +18,7 @@
#ifndef PG_INHERITS_H
#define PG_INHERITS_H
+#include "access/htup.h"
#include "catalog/genbki.h"
#include "catalog/pg_inherits_d.h"
@@ -56,6 +57,7 @@ extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode,
List **numparents);
extern bool has_subclass(Oid relationId);
extern bool has_superclass(Oid relationId);
+extern HeapTuple get_superclass(Oid relationId);
extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId);
extern void StoreSingleInheritance(Oid relationId, Oid parentOid,
int32 seqNumber);
diff --git a/src/test/regress/expected/partition_info.out b/src/test/regress/expected/partition_info.out
index 42b6bc77ca..3f689989b9 100644
--- a/src/test/regress/expected/partition_info.out
+++ b/src/test/regress/expected/partition_info.out
@@ -275,6 +275,19 @@ SELECT pg_partition_root('ptif_normal_table');
(1 row)
DROP TABLE ptif_normal_table;
+-- If parent index doesn't have a constraint tuple
+-- detach partition should not fail.
+CREATE TABLE pt_ind_t (a int) PARTITION BY RANGE (a);
+CREATE TABLE pt_ind_tp (a int PRIMARY KEY);
+ALTER TABLE pt_ind_t ATTACH PARTITION pt_ind_tp FOR VALUES FROM (0) TO (1000);
+CREATE UNIQUE INDEX pt_a_idx ON pt_ind_t (a);
+ALTER INDEX pt_a_idx ATTACH PARTITION pt_ind_tp_pkey;
+ALTER TABLE pt_ind_t DETACH PARTITION pt_ind_tp;
+CREATE TABLE pt_indx_t (a int) PARTITION BY RANGE (a);
+CREATE TABLE pt_indx_tp (a int PRIMARY KEY);
+CREATE UNIQUE INDEX ptx_a_idx ON pt_indx_t (a);
+ALTER TABLE pt_indx_t ATTACH PARTITION pt_indx_tp FOR VALUES FROM (0) TO (1000);
+ALTER TABLE pt_indx_t DETACH PARTITION pt_indx_tp;
-- Various partitioning-related functions return empty/NULL if passed relations
-- of types that cannot be part of a partition tree; for example, views,
-- materialized views, legacy inheritance children or parents, etc.
diff --git a/src/test/regress/sql/partition_info.sql b/src/test/regress/sql/partition_info.sql
index b5060bec7f..a36f8db562 100644
--- a/src/test/regress/sql/partition_info.sql
+++ b/src/test/regress/sql/partition_info.sql
@@ -105,6 +105,21 @@ SELECT * FROM pg_partition_ancestors('ptif_normal_table');
SELECT pg_partition_root('ptif_normal_table');
DROP TABLE ptif_normal_table;
+-- If parent index doesn't have a constraint tuple
+-- detach partition should not fail.
+CREATE TABLE pt_ind_t (a int) PARTITION BY RANGE (a);
+CREATE TABLE pt_ind_tp (a int PRIMARY KEY);
+ALTER TABLE pt_ind_t ATTACH PARTITION pt_ind_tp FOR VALUES FROM (0) TO (1000);
+CREATE UNIQUE INDEX pt_a_idx ON pt_ind_t (a);
+ALTER INDEX pt_a_idx ATTACH PARTITION pt_ind_tp_pkey;
+ALTER TABLE pt_ind_t DETACH PARTITION pt_ind_tp;
+
+CREATE TABLE pt_indx_t (a int) PARTITION BY RANGE (a);
+CREATE TABLE pt_indx_tp (a int PRIMARY KEY);
+CREATE UNIQUE INDEX ptx_a_idx ON pt_indx_t (a);
+ALTER TABLE pt_indx_t ATTACH PARTITION pt_indx_tp FOR VALUES FROM (0) TO (1000);
+ALTER TABLE pt_indx_t DETACH PARTITION pt_indx_tp;
+
-- Various partitioning-related functions return empty/NULL if passed relations
-- of types that cannot be part of a partition tree; for example, views,
-- materialized views, legacy inheritance children or parents, etc.
--
2.34.1