From: | Mathieu De Zutter <mathieu(at)dezutter(dot)org> |
---|---|
To: | pgsql-general(at)postgresql(dot)org |
Subject: | Constraint exclusion issue |
Date: | 2010-01-16 18:02:30 |
Message-ID: | d4468d971001161002h7ecbe245md79bef34363048be@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Hi,
I'm trying to make constraint exclusion work correctly in a query with
only one parameter, but I have some issues.
Please have a look at the scenario below and tell me how I can improve it.
Thanks!
-- I create an inheritance relationship with a check constraint in the child
shs-dev=# create table parent (c char, n integer);
CREATE TABLE
shs-dev=# create table child1 ( ) inherits (parent);
CREATE TABLE
shs-dev=# alter table child1 add check (c = 'a');
ALTER TABLE
-- I query on a row containing both attributes, and pgsql 8.4
correctly skips the child table because of the constraint
shs-dev=# explain select * from parent where (c,n) = ('b',0);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Result (cost=0.00..39.10 rows=1 width=12)
-> Append (cost=0.00..39.10 rows=1 width=12)
-> Seq Scan on parent (cost=0.00..39.10 rows=1 width=12)
Filter: ((c = 'b'::bpchar) AND (n = 0))
-- Ok, lets see if I can parameterize this with only one parameter... NO!
shs-dev=# explain select * from parent where (c,n) = '("b",0)';
ERROR: input of anonymous composite types is not implemented
-- I create a type so it's not anonymous anymore
shs-dev=# create type y as (c char, n integer);
CREATE TYPE
-- But pgsql forgets about the constraint now :(
shs-dev=# explain select * from parent where (c,n)::y = '("b",0)'::y;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..78.20 rows=20 width=12)
-> Append (cost=0.00..78.20 rows=20 width=12)
-> Seq Scan on parent (cost=0.00..39.10 rows=10 width=12)
Filter: (ROW(c, n)::y = '(b,0)'::y)
-> Seq Scan on child1 parent (cost=0.00..39.10 rows=10 width=12)
Filter: (ROW(c, n)::y = '(b,0)'::y)
-- This is OK (but has two parameters, I want only one)
shs-dev=# explain select * from parent where ((c,n)::y).c = 'b' and
((c,n)::y).n = 0;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Result (cost=0.00..39.10 rows=1 width=12)
-> Append (cost=0.00..39.10 rows=1 width=12)
-> Seq Scan on parent (cost=0.00..39.10 rows=1 width=12)
Filter: ((c = 'b'::bpchar) AND (n = 0))
-- This isn't OK
shs-dev=# explain select * from parent where ((c,n)::y).c =
('("b",0)'::y).c and ((c,n)::y).n = ('("b",0)'::y).n;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..78.20 rows=2 width=12)
-> Append (cost=0.00..78.20 rows=2 width=12)
-> Seq Scan on parent (cost=0.00..39.10 rows=1 width=12)
Filter: ((c = ('(b,0)'::y).c) AND (n = ('(b,0)'::y).n))
-> Seq Scan on child1 parent (cost=0.00..39.10 rows=1 width=12)
Filter: ((c = ('(b,0)'::y).c) AND (n = ('(b,0)'::y).n))
-- So the problem seems to be that the 'b' value cannot be deduced in
time for the constraint exclusion to do its job.
--
Regards,
Mathieu
From | Date | Subject | |
---|---|---|---|
Next Message | Scott Marlowe | 2010-01-16 18:26:02 | Re: Constraint exclusion issue |
Previous Message | Dimitri Fontaine | 2010-01-16 16:15:32 | Re: Avoid transaction abot if/when constraint violated |