Alvaro Herrera <alvherre@commandprompt.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 doselect '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 *
fromv;
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