Fixing inheritance merge behavior in ALTER TABLE ADD CONSTRAINT

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Cc: Benedikt Grundmann <bgrundmann(at)janestreet(dot)com>
Subject: Fixing inheritance merge behavior in ALTER TABLE ADD CONSTRAINT
Date: 2016-10-07 21:09:46
Message-ID: 22108.1475874586@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I've been looking into the misbehavior complained of here:
https://www.postgresql.org/message-id/CADbMkNPT-Jz5PRSQ4RbUASYAjocV_KHUWapR%2Bg8fNvhUAyRpxA%40mail.gmail.com

I originally thought this was pg_dump's fault, but I now think it's not,
or at least that changing the backend's behavior would be a superior
solution. The problem can be described thus:

create table parent(f1 int);
create table child() inherits(parent);
alter table parent add constraint inh_check check(f1 > 0) not valid;
alter table child add constraint inh_check check(f1 > 0) not valid;

The above sequence fails with
ERROR: constraint "inh_check" for relation "child" already exists
However, if you swap the order of the two ALTER ADD commands, it succeeds,
with the second ALTER instead saying
NOTICE: merging constraint "inh_check" with inherited definition
In that case you end up with a child constraint marked as having both
local origin (conislocal=true) and inherited origin (coninhcount=1).
This is the situation that Benedikt's example has, and the problem is
for pg_dump to restore this state.

Now, pg_dump needs to issue separate commands along these lines to restore
NOT VALID constraints, because it has to copy data into the tables before
adding the constraints. (Otherwise, if any rows not satisfying the
constraint are still in the table, the restore would fail.) The problem
from pg_dump's viewpoint is that there's nothing particularly guaranteeing
that the two ALTERs will be issued in the "right" order. Absent other
considerations, it'll tend to issue the ALTERs in alphabetical order,
which means dumping this example exactly as given will work, but not so
much if the table names are like "foo" and "foo_child".

We could possibly try to fix this by adding dependencies, but the
dependencies would have to say that the parent table's constraint depends
on the child table's constraint, which seems pretty weird.

What seems like a saner answer to me is to change the backend so that it
will accept these ALTER commands in either order, with the same end state.
The reason it throws an error now, IMO, is just so that blindly issuing
the same ALTER ADD CONSTRAINT twice will fail. But we could deal with
that by saying that it's okay as long as the initially-targeted constraint
doesn't already have conislocal = true.

While I was poking at this, I came across a second problem in the same
area, which is that this succeeds:

alter table child add constraint inh_check check(f1 > 0) not valid;
alter table parent add constraint inh_check check(f1 > 0);

After that, you have a parent constraint that claims to be valid and
inheritable, but nonetheless there might be rows in a child table
that don't meet the constraint. That is BAD. It would break planner
deductions that depend on believing that check constraints hold for
all rows emitted by an inherited table scan. (I'm not certain whether
there are any affected cases right now, but it's certainly plausible
that there might be such in future.) Whatever you think of the other
situation, we need to disallow this.

The attached proposed patch (sans test cases as yet) deals with both
of these things, and doesn't change the results of any existing regression
test cases.

I'm inclined to treat this as a bug and back-patch it as far as we
allow NOT VALID check constraints, which seems to be 9.2.

Comments?

regards, tom lane

Attachment Content-Type Size
fix-alter-add-constraint-with-inheritance.patch text/x-diff 5.6 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2016-10-07 21:12:45 Re: Our "fallback" atomics implementation doesn't actually work
Previous Message Heikki Linnakangas 2016-10-07 20:58:45 Re: Illegal SJIS mapping