On Tue, Jun 14, 2016 at 4:48 PM, Amit Kapila <amit.kapil...@gmail.com>

> On Mon, Jun 13, 2016 at 8:11 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> >  I do
> > not share your confidence that using apply_projection_to_path within
> > create_grouping_paths is free of such a hazard.
> >
> Fair enough, let me try to explain the problem and someways to solve it in
> some more detail.  The main thing that got missed by me in the patch
> related to commit-04ae11f62 is that the partial path list of rel also needs
> to have a scanjoin_target. I was under assumption that
> create_grouping_paths will take care of assigning appropriate Path targets
> for the parallel paths generated by it.  If we see, create_grouping_paths()
> do take care of adding the appropriate path targets for the paths generated
> by that function.  However, it doesn't do anything for partial paths.   The
> patch sent by me yesterday [1] which was trying to assign
> partial_grouping_target to partial paths won't be the right fix, because
> (a) partial_grouping_target includes Aggregates (refer
> make_partialgroup_input_target) which we don't want for partial paths; (b)
> it is formed using grouping_target passed in function
> create_grouping_paths() whereas we need the path target formed from
> final_target for partial paths (as partial paths are scanjoin relations)
>  as is done for main path list (in grouping_planner(),  /* Forcibly apply
> that target to all the Paths for the scan/join rel.*/).   Now, I think we
> have following ways to solve it:
> (a) check whether the scanjoin_target contains any parallel-restricted
> clause before applying the same to partial path list in grouping_planner.
> However it could lead to duplicate checks in some cases for
> parallel-restricted clause, once in apply_projection_to_path() for main
> pathlist and then again before applying to partial paths.  I think we can
> avoid that by having an additional parameter in apply_projection_to_path()
> which can indicate if the check for parallel-safety is done inside that
> function and what is the result of same.
> (b) generate the appropriate scanjoin_target for partial path list in
> create_grouping_paths using final_target. However I think this might lead
> to some duplicate code in create_grouping_paths() as we might have to some
> thing similar to what we have done in grouping_planner for generating such
> a target.  I think if we want we can pass scanjoin_target to
> create_grouping_paths() as well.   Again, we have to check for
> parallel-safety for scanjoin_target before applying it to partial paths,
> but we need to do that only when grouped_rel is considered parallel-safe.
One more idea could be to have a flag (say parallel_safe) in PathTarget and
set it once we have ensured that the expressions in target doesn't contain
any parallel-restricted entry.  In
create_pathtarget()/set_pathtarget_cost_width(),  if the parallelmodeOK
flag is set, then we can evaluate target expressions for
parallel-restricted expressions and set the flag accordingly.  Now, this
has the benefit that we don't need to evaluate the expressions of targets
for parallel-restricted clauses again and again.  I think this way if the
flag is set once for final_target in grouping_planner, we don't need to
evaluate it again for other targets (grouping_target, scanjoin_target,
etc.) as those are derived from final_target.  Similarly, I think we need
to set ReplOptInfo->reltarget and others as required.

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

Reply via email to