Re: PostgreSQL 8.3.4 reproducible crash

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
Cc: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>, dmitry(at)koterov(dot)ru, pgsql-hackers(at)postgresql(dot)org
Subject: Re: PostgreSQL 8.3.4 reproducible crash
Date: 2008-12-10 19:12:43
Message-ID: 5702.1228936363@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Alvaro Herrera <alvherre(at)commandprompt(dot)com> writes:
> I think the right fix is to ensure that ActiveSnapshot is set.

The proximate cause is certainly lack of a snapshot, but I think there
might be some other interesting issues here too. The crash comes when
the SQL-language domain check function demands a snapshot --- but if
you do
select '1'::bug1.domain;
it works fine! The reason for the discrepancy is that parse_coerce.c
handles a coercion to a domain by coercing the literal to the underlying
type (int4 in this case) and then setting up a *runtime* domain coercion
using a CoerceToDomain expression node. So in that case the domain
check doesn't occur till runtime when a snapshot will be available.
But in the crashing case we simply invoke record_in, which invokes
domain_in, which invokes the SQL function.

So there seem to be a couple of things we might want to do:

1. Ensure that a snapshot is set before doing parse analysis of any
non-utility command. (We *must* not set a snap before LOCK or a
transaction control command, and it seems best to not do it for any
utility command.) One issue here is that this would change the behavior
for mixed utility and non-utility commands in a single query string;
though I'm not sure how much that matters.

2. Treat coercion to a record type as being something that should occur
at runtime, ie build a RowExpr instead of a constant. This would
produce more uniform behavior in terms of when domain constraints get
applied.

I think the core issue is really whether it is important to postpone
domain constraint checks. Consider something like

create domain d as int;
create view v as select '-1'::d;
alter domain d add constraint "c" check (value > 0);
select * from v;

Right now you get an error at the SELECT, but that seems a bit
surprising. It's even more surprising that the CREATE still works if
you made the constraint first. And a novice might reasonably wonder why
the domain check is postponed when the underlying type's checks occur
instantly --- for example, this fails outright:
create view v as select 'z'::d;

So this is all a bit odd to start with, and then on top of that we have
the issue that the check timing changes if you put the domain inside a
record.

Comments?

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2008-12-10 19:30:31 Re: PostgreSQL 8.3.4 reproducible crash
Previous Message Bruce Momjian 2008-12-10 19:04:15 Re: Updates of SE-PostgreSQL 8.4devel patches (r1268)