pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Michael Paquier <michael@paquier.xyz>
To: Postgres hackers <pgsql-hackers@postgresql.org>
Subject: Assertion failure with ALTER TABLE ATTACH PARTITION with log_min_messages >= DEBUG1
Date: Fri, 5 Oct 2018 13:22:36 +0900
Message-ID: <20181005042236.GG1629@paquier.xyz> (raw)

Hi all,

Running installcheck on an instance with log_min_messages = DEBUG1, I
can bump into the following assertion failure:
#2  0x000056145231e82c in ExceptionalCondition
(conditionName=0x56145258ae0b "!(strvalue != ((void *)0))",
errorType=0x56145258adfb "FailedAssertion",
    fileName=0x56145258adf0 "snprintf.c", lineNumber=440) at assert.c:54
[...]
#7  0x000056145231f518 in errmsg (fmt=0x5614524dac60 "validating foreign
key constraint \"%s\"") at elog.c:796
#8  0x0000561451f6ab54 in validateForeignKeyConstraint (conname=0x0,
rel=0x7f12833ca750, pkrel=0x7f12833cc468, pkindOid=36449,
constraintOid=36466) at tablecmds.c:8566
#9  0x0000561451f61589 in ATRewriteTables (parsetree=0x561453bde5e0,
wqueue=0x7ffe8f1d55e8, lockmode=8) at tablecmds.c:4549

Looking at the stack trace there is this log in
validateForeignKeyConstraint:
ereport(DEBUG1,
        (errmsg("validating foreign key constraint \"%s\"", conname)));

However conname is set to NULL in this code path.

This test case allows to reproduce easily the failure:
CREATE TABLE fk_notpartitioned_pk (a int, b int, PRIMARY KEY (a, b));
CREATE TABLE fk_partitioned_fk (b int, a int) PARTITION BY RANGE (a, b);
CREATE TABLE fk_partitioned_fk_1 (b int, a int);
ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES
fk_notpartitioned_pk;
-- crash
ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR
  VALUES FROM (1,1) TO (2,2);

From what I can see the problem comes from CloneForeignKeyConstraint
which forgets to assign the constraint name when cloning the FK
definition.  While looking at the ATTACH PARTITION code, I have noticed
that a variable gets overridden, which is in my opinion bad style.  So
the problem is rather close to what Tom has fixed in 3d0f68dd it seems.

Attached is a patch for all that, with which installcheck-world passes
for me.  I am surprised this was not noticed before, the recent snprintf
stanza is nicely helping, and this would need to be back-patched down to
v11.

Thanks,
--
Michael

Attachments:

attach-partition-assert.patch (text/x-diff, 1.9K) download diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 6781b00c6e..2063abb8ae 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -574,6 +574,7 @@ CloneForeignKeyConstraints(Oid parentId, Oid relationId, List **cloned) fkconstraint = makeNode(Constraint); /* for now this is all we need */ + fkconstraint->conname = pstrdup(NameStr(constrForm->conname)); fkconstraint->fk_upd_action = constrForm->confupdtype; fkconstraint->fk_del_action = constrForm->confdeltype; fkconstraint->deferrable = constrForm->condeferrable; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c145385f84..7df1fc2a76 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -14275,21 +14275,21 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) RelationGetRelid(attachrel), &cloned); foreach(l, cloned) { - ClonedConstraint *cloned = lfirst(l); + ClonedConstraint *clonedcon = lfirst(l); NewConstraint *newcon; Relation clonedrel; AlteredTableInfo *parttab; - clonedrel = relation_open(cloned->relid, NoLock); + clonedrel = relation_open(clonedcon->relid, NoLock); parttab = ATGetQueueEntry(wqueue, clonedrel); newcon = (NewConstraint *) palloc0(sizeof(NewConstraint)); - newcon->name = cloned->constraint->conname; + newcon->name = clonedcon->constraint->conname; newcon->contype = CONSTR_FOREIGN; - newcon->refrelid = cloned->refrelid; - newcon->refindid = cloned->conindid; - newcon->conid = cloned->conid; - newcon->qual = (Node *) cloned->constraint; + newcon->refrelid = clonedcon->refrelid; + newcon->refindid = clonedcon->conindid; + newcon->conid = clonedcon->conid; + newcon->qual = (Node *) clonedcon->constraint; parttab->constraints = lappend(parttab->constraints, newcon);
signature.asc (application/pgp-signature, 832B) download

view thread (5+ messages)  latest in thread

Message-ID: <20181005042236.GG1629@paquier.xyz>
Permalink:  ../20181005042236.GG1629@paquier.xyz/
Also on:    postgresql.org/message-id/20181005042236.GG1629@paquier.xyz

 ·  · 

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: pgsql-hackers@postgresql.org
  Cc: michael@paquier.xyz
  Subject: Re: Assertion failure with ALTER TABLE ATTACH PARTITION with log_min_messages >= DEBUG1
  In-Reply-To: <20181005042236.GG1629@paquier.xyz>

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

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