Re: [HACKERS] path toward faster partition pruning - Mailing list pgsql-hackers

From Amit Langote
Subject Re: [HACKERS] path toward faster partition pruning
Date
Msg-id 28dc6449-b0ee-be9f-b045-9dc8aa770238@lab.ntt.co.jp
Whole thread Raw
In response to Re: [HACKERS] path toward faster partition pruning  (Tomas Vondra <tomas.vondra@2ndquadrant.com>)
List pgsql-hackers
Thanks Tomas for the review.

On 2018/03/30 1:55, Tomas Vondra wrote:
> Hi,
> 
> I think there's a bug in generate_pruning_steps_from_opexprs, which does
> this for PARTITION_STRATEGY_HASH:
> 
> 
>     for_each_cell(lc1, lc)
>     {
>         pc = lfirst(lc1);
> 
>         /*
>          * Note that we pass nullkeys for step_nullkeys,
>          * because we need to tell hash partition bound search
>          * function which of the keys are NULL.
>          */
>         Assert(pc->op_strategy == HTEqualStrategyNumber);
>         pc_steps =
>                 get_steps_using_prefix(context,
>                                        HTEqualStrategyNumber,
>                                        pc->expr,
>                                        pc->cmpfn,
>                                        pc->keyno,
>                                        nullkeys,
>                                        prefix);
>     }
> 
>     opsteps = list_concat(opsteps, list_copy(pc_steps));
> 
> 
> Notice that the list_concat() is outside the for_each_cell loop. Doesn't
> that mean we fail to consider some of the clauses (all except the very
> last clause) for pruning? I haven't managed to come up with an example,
> but I haven't tried very hard.
> 
> FWIW I've noticed this because gcc complains that pg_steps might be used
> uninitialized:
> 
> partprune.c: In function ‘generate_partition_pruning_steps_internal’:
> partprune.c:992:16: warning: ‘pc_steps’ may be used uninitialized in
> this function [-Wmaybe-uninitialized]
>       opsteps = list_concat(opsteps, list_copy(pc_steps));
>                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> partprune.c:936:14: note: ‘pc_steps’ was declared here
>       List   *pc_steps;
>               ^~~~~~~~
> All of PostgreSQL successfully made. Ready to install.
> 
> 
> So even if it's not a bug, we probably need to fix the code somehow.

Yeah, the code needs to be fixed.  Although, it seems to me that in the
hash partitioning case, the loop would iterate at most once, at least if
the query didn't contain any Params.  That's because, at that point, there
cannot be multiple mutually AND'd equality clauses referring to the same
key.  For example, if there were in the original query and they contained
different values, we wouldn't get this far anyway as they would be reduced
to constant-false at an earlier planning stage.  If they all contained the
same value (e.g. key = 1 and key = 1::smallint and a = 1::int and a =
1::bigint), then only one of them will be left in rel->baserestrictinfo
anyway.  But we still need to have the loop because all of what I said
wouldn't happen if the clauses contained Params.  In that case, the result
would be determined at execution time.

I have fixed the code as you suggested and will post the fixed version
shortly after fixing the issues David reported.

Thanks,
Amit



pgsql-hackers by date:

Previous
From: David Steele
Date:
Subject: Re: [PATCH] Verify Checksums during Basebackups
Next
From: Kyotaro HORIGUCHI
Date:
Subject: Re: Question about WalSndWriteData