On Wed, Jun 11, 2014 at 7:24 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:

> Robert Haas <robertmh...@gmail.com> writes:
> > On Tue, Jun 10, 2014 at 7:19 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> >> Given the lack of previous complaints, I'm not sure this amounts to
> >> a back-patchable bug, but it does seem like something worth fixing
> >> going forward.
>
> > Agreed, although I'd be willing to see us slip it into 9.4.  It's
> > doubtful that anyone will get upset if their query plans change
> > between beta1 and beta2, but the same cannot be said for released
> > branches.
>
> After further thought about this I realized that there's another category
> of proof possibilities that is pretty simple to add while we're at it.
> Namely, once we've found that both subexpressions of the two operator
> clauses are equal(), we can use btree opclass relationships to prove that,
> say, "x < y implies x <= y" or "x < y refutes x > y", independently of
> just what x and y are.  (Well, they have to be immutable expressions, but
> we'd not get this far if they're not.)  We already had pretty nearly all
> of the machinery for that, but again it was only used for proving cases
> involving comparisons to constants.
>
> A little bit of refactoring later, I offer the attached draft patch.
> I'm thinking this is probably more than we want to slip into 9.4
> at this point, but I'll commit it to HEAD soon if there are not
> objections.
>
>                         regards, tom lane
>
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>
>
I applied Tom's patch to the latest HEAD
(e04a9ccd2ccd6e31cc4af6b08257a0a186d0fce8) and showed it to Brian. Looks to
solve the problem he originally reported

$ patch -p1 -i ../better-predicate-proofs-1.patch
(Stripping trailing CRs from patch.)
patching file src/backend/optimizer/util/predtest.c


$ /opt/pgsql_patch_review/bin/psql postgres
Timing is on.
Null display (null) is "«NULL»".
Expanded display (expanded) is used automatically.
psql (9.5devel)
Type "help" for help.

postgres=# CREATE OR REPLACE FUNCTION public.return_if_even(v_id integer)
returns integer
postgres-# LANGUAGE sql AS
postgres-# $$
postgres$# SELECT case when v_id % 2 = 1 then 0 else v_id end;
postgres$# $$;
CREATE FUNCTION
Time: 44.669 ms

postgres=# create table public.partial_functional_index_test as
postgres-# select id from generate_series(1,1000000) AS s(id);
SELECT 1000000
Time: 1037.993 ms

postgres=# create index partial_functional_idx ON
public.partial_functional_index_test
postgres-# USING btree ( public.return_if_even(id) )
postgres-# WHERE public.return_if_even(id) = id;
LOG:  sending cancel to blocking autovacuum PID 12521
DETAIL:  Process 12424 waits for ShareLock on relation 16385 of database
12217.
STATEMENT:  create index partial_functional_idx ON
public.partial_functional_index_test
    USING btree ( public.return_if_even(id) )
    WHERE public.return_if_even(id) = id;
ERROR:  canceling autovacuum task
CONTEXT:  automatic analyze of table
"postgres.public.partial_functional_index_test"
CREATE INDEX
Time: 1658.245 ms

postgres=# explain analyze select count(1) from
public.partial_functional_index_test where public.return_if_even(id) = id;
                                                                     QUERY
PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=4818.05..4818.06 rows=1 width=0) (actual
time=2503.851..2503.854 rows=1 loops=1)
   ->  Bitmap Heap Scan on partial_functional_index_test
(cost=82.67..4805.55 rows=5000 width=0) (actual time=43.724..1309.309
rows=500000 loops=1)
         Recheck Cond: (CASE WHEN ((id % 2) = 1) THEN 0 ELSE id END = id)
         Heap Blocks: exact=4425
         ->  Bitmap Index Scan on partial_functional_idx  (cost=0.00..81.42
rows=5000 width=0) (actual time=42.961..42.961 rows=500000 loops=1)
 Planning time: 4.245 ms
 Execution time: 2505.281 ms
(7 rows)

Time: 2515.344 ms
postgres=# explain analyze select count(1) from
public.partial_functional_index_test where id = public.return_if_even(id);
                                                                     QUERY
PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=4818.05..4818.06 rows=1 width=0) (actual
time=2483.862..2483.866 rows=1 loops=1)
   ->  Bitmap Heap Scan on partial_functional_index_test
(cost=82.67..4805.55 rows=5000 width=0) (actual time=40.704..1282.955
rows=500000 loops=1)
         Recheck Cond: (CASE WHEN ((id % 2) = 1) THEN 0 ELSE id END = id)
         Heap Blocks: exact=4425
         ->  Bitmap Index Scan on partial_functional_idx  (cost=0.00..81.42
rows=5000 width=0) (actual time=39.657..39.657 rows=500000 loops=1)
 Planning time: 0.127 ms
 Execution time: 2483.979 ms
(7 rows)


--
Keith Fiske
Database Administrator
OmniTI Computer Consulting, Inc.
http://www.keithf4.com

Reply via email to