pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feed[PATCH v2] WIP: don't let constraint indexes attach to raw indexes
1+ messages / 1 participants
[nested] [flat]
* [PATCH v2] WIP: don't let constraint indexes attach to raw indexes
@ 2024-06-28 11:16 Alvaro Herrera <alvherre@alvh.no-ip.org>
0 siblings, 0 replies; 1+ messages in thread
From: Alvaro Herrera @ 2024-06-28 11:16 UTC (permalink / raw)
Probably for master only, since we probably don't want to prohibit
working behavior in backbranches. In backbranches we'll have to cope
with the possibility that a hierarchy such as the one being forbidded
here already exists. We may also want to do something about this during
pg_upgrade.
---
src/backend/commands/indexcmds.c | 24 ++++++++++++++++-----
src/backend/commands/tablecmds.c | 37 +++++++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 8 deletions(-)
inline patch 1: src/backend/commands/indexcmds.c, src/backend/commands/tablecmds.c (+53/-8 lines) download inline-1.patch
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 309389e20d..50205b9bdb 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1378,7 +1378,11 @@ DefineIndex(Oid tableId,
parentIndex->rd_opfamily,
attmap))
{
- Oid cldConstrOid = InvalidOid;
+ Oid cldConstrOid;
+
+ cldConstrOid =
+ get_relation_idx_constraint_oid(childRelid,
+ cldidxid);
/*
* Found a match.
@@ -1387,19 +1391,29 @@ DefineIndex(Oid tableId,
* because of a constraint, then the child needs to
* have a constraint also, so look for one. If there
* is no such constraint, this index is no good, so
- * keep looking.
+ * keep looking. On the other hand, if the index that
+ * exists on the child _is_ a constraint but this one
+ * isn't, then we shouldn't match them. XXX should we
+ * instead choose to ignore the index?
*/
if (createdConstraintId != InvalidOid)
{
- cldConstrOid =
- get_relation_idx_constraint_oid(childRelid,
- cldidxid);
if (cldConstrOid == InvalidOid)
{
index_close(cldidx, lockmode);
continue;
}
}
+ else if (OidIsValid(cldConstrOid))
+ ereport(ERROR,
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("can't create index on partitioned table \"%s\" matching constraint \"%s\" on partition \"%s\"",
+ RelationGetRelationName(rel),
+ get_constraint_name(cldConstrOid),
+ RelationGetRelationName(childrel)),
+ errhint("You can create the index on ONLY \"%s\", or create a constraint instead.",
+ RelationGetRelationName(rel)));
+
/* Attach index to parent and we're done. */
IndexSetParentIndex(cldidx, indexRelationId);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 66cda26a25..8cb9893e5d 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -18757,6 +18757,10 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel)
idxRel->rd_opfamily,
attmap))
{
+ cldConstrOid =
+ get_relation_idx_constraint_oid(RelationGetRelid(attachrel),
+ cldIdxId);
+
/*
* If this index is being created in the parent because of a
* constraint, then the child needs to have a constraint also,
@@ -18765,9 +18769,6 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel)
*/
if (OidIsValid(constraintOid))
{
- cldConstrOid =
- get_relation_idx_constraint_oid(RelationGetRelid(attachrel),
- cldIdxId);
/* no dice */
if (!OidIsValid(cldConstrOid))
continue;
@@ -18777,6 +18778,22 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel)
get_constraint_type(cldConstrOid))
continue;
}
+ else
+ {
+ /*
+ * If the parent does *not* have a constraint, then the
+ * child must also not have one. Otherwise, things can get
+ * ugly by detach time.
+ */
+
+ if (OidIsValid(cldConstrOid))
+ ereport(ERROR,
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("can't attach partition \"%s\" with constraint \"%s\" that matches non-constraint index \"%s\"",
+ RelationGetRelationName(attachrel),
+ get_constraint_name(cldConstrOid),
+ RelationGetRelationName(idxRel)));
+ }
/* bingo. */
IndexSetParentIndex(attachrelIdxRels[i], idx);
@@ -19726,6 +19743,20 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
RelationGetRelationName(parentTbl),
RelationGetRelationName(partIdx))));
}
+ else
+ {
+ Oid constroid;
+
+ constroid = get_relation_idx_constraint_oid(RelationGetRelid(partTbl),
+ partIdxId);
+
+ if (OidIsValid(constroid))
+ ereport(ERROR,
+ errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("can't attach constraint-supporting index \"%s\" to non-constraint index \"%s\"",
+ get_constraint_name(constroid),
+ RelationGetRelationName(partIdx)));
+ }
/* All good -- do it */
IndexSetParentIndex(partIdx, RelationGetRelid(parentIdx));
--
2.39.2
--q72ne4r752oxakpn--
^ permalink raw reply [nested|flat] 1+ messages in thread
only message in thread
Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-06-28 11:16 [PATCH v2] WIP: don't let constraint indexes attach to raw indexes Alvaro Herrera <alvherre@alvh.no-ip.org>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox