aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
authorAndrew Gierth <rhodiumtoad@postgresql.org>2018-03-21 10:42:04 +0000
committerAndrew Gierth <rhodiumtoad@postgresql.org>2018-03-21 11:39:28 +0000
commitd2d79887eadff72c339a072ef693bb6016651d30 (patch)
treedc777dcbe00114aef09beeb6bdc2eea6524202b7 /src/backend/optimizer/plan/planner.c
parentaea7c17e86e99a7ed4da489b3df2b5493b5e5e95 (diff)
downloadpostgresql-d2d79887eadff72c339a072ef693bb6016651d30.tar.gz
postgresql-d2d79887eadff72c339a072ef693bb6016651d30.zip
Repair crash with unsortable grouping sets.
If there were multiple grouping sets, none of them empty, all of which were unsortable, then an oversight in consider_groupingsets_paths led to a null pointer dereference. Fix, and add a regression test for this case. Per report from Dang Minh Huong, though I didn't use their patch. Backpatch to 10.x where hashed grouping sets were added.
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index b452da02042..85805ff5c70 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -3997,7 +3997,28 @@ consider_groupingsets_paths(PlannerInfo *root,
Assert(can_hash);
- if (pathkeys_contained_in(root->group_pathkeys, path->pathkeys))
+ /*
+ * If the input is coincidentally sorted usefully (which can happen
+ * even if is_sorted is false, since that only means that our caller
+ * has set up the sorting for us), then save some hashtable space by
+ * making use of that. But we need to watch out for degenerate cases:
+ *
+ * 1) If there are any empty grouping sets, then group_pathkeys might
+ * be NIL if all non-empty grouping sets are unsortable. In this case,
+ * there will be a rollup containing only empty groups, and the
+ * pathkeys_contained_in test is vacuously true; this is ok.
+ *
+ * XXX: the above relies on the fact that group_pathkeys is generated
+ * from the first rollup. If we add the ability to consider multiple
+ * sort orders for grouping input, this assumption might fail.
+ *
+ * 2) If there are no empty sets and only unsortable sets, then the
+ * rollups list will be empty (and thus l_start == NULL), and
+ * group_pathkeys will be NIL; we must ensure that the vacuously-true
+ * pathkeys_contain_in test doesn't cause us to crash.
+ */
+ if (l_start != NULL &&
+ pathkeys_contained_in(root->group_pathkeys, path->pathkeys))
{
unhashed_rollup = lfirst_node(RollupData, l_start);
exclude_groups = unhashed_rollup->numGroups;