On 12 May 2016 at 07:04, Robert Haas <robertmh...@gmail.com> wrote: > On Wed, May 11, 2016 at 1:57 PM, Robert Haas <robertmh...@gmail.com> wrote: >> I don't immediately understand what's going wrong here. It looks to >> me like make_group_input_target() already called, and that worked OK, >> but now make_partialgroup_input_target() is failing using more-or-less >> the same logic. Presumably that's because make_group_input_target() >> was called on final_target as returned by create_pathtarget(root, >> tlist), but make_partialgroup_input_target() is being called on >> grouping_target, which I'm guessing came from >> make_window_input_target, which somehow lacks sortgroupref labeling. >> But I don't immediately see how that would happen, so there's >> obviously something I'm missing here. > > So, it turns out you can reproduce this bug pretty easily without > force_parallel_mode, like this: > > alter table int4_tbl set (parallel_degree = 4); > SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42; > > Or you can just a query that involves a window function on a table > large enough for parallelism to be considered: > > SELECT SUM(COUNT(aid)) OVER () FROM pgbench_accounts; > > The crash goes way if the target list involves at least one plain > column that uses no aggregate or window function, because then the > PathTarget list has a sortgrouprefs array. Trivial fix patch > attached, although some more review from you (Tom Lane, PathTarget > inventor and planner whiz) and David Rowley (author of this function) > would be appreciated in case there are deeper issues here.
The problem is make_group_input_target() only calls add_column_to_pathtarget() (which allocates this array) when there's a GROUP BY, otherwise it just appends to the non_group_col list. Since your query has no GROUP BY it means that add_column_to_pathtarget() is never called with a non-zero sortgroupref. It looks like Tom has intended that PathTarget->sortgrouprefs can be NULL going by both the comment /* corresponding sort/group refnos, or 0 */, and the coding inside add_column_to_pathtarget(), which does not allocate the array if given a 0 sortgroupref. It looks like make_sort_input_target(), make_window_input_target() and make_group_input_target() all get away without this check because they're all using final_target, which was built by make_pathtarget_from_tlist() which *always* allocates the sortgrouprefs array, even if it's left filled with zeros. It might be better if this was all consistent. Perhaps it would be worth modifying make_pathtarget_from_tlist() to only allocate the sortgrouprefs array if there's any non-zero tle->ressortgroupref, then modify the other make_*_input_target() functions to handle a NULL array, similar to the fix that's in your patch. This saves an allocation which is likely much more expensive than the NULL check later. Alternatively add_column_to_pathtarget() could be modified to allocate the array even if sortgroupref is zero. I think consistency is good here, as if this had been consistent this would not be a bug. -- David Rowley http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services