summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2016-06-13 16:59:25 +0000
committerTom Lane2016-06-13 16:59:25 +0000
commit89d53515e53ea080029894939118365b647489b3 (patch)
tree6d8839cba676d636270e49ad5c7ca4a9bc42b432
parentcd9b4f24ce5f24de5112392d5a9db3a8d4208115 (diff)
In planner.c, avoid assuming that all PathTargets have sortgrouprefs.
The struct definition for PathTarget specifies that a NULL sortgrouprefs pointer means no sortgroupref labels. While it's likely that there should always be at least one labeled column in the places that were unconditionally fetching through the pointer, it seems wiser to adhere to the data structure specification and test first. Add a macro to make this convenient. Per experimentation with running the regression tests with a very small parallelization threshold --- the crash I observed may well represent a bug elsewhere, but still this coding was not very robust. Report: <20756.1465834072@sss.pgh.pa.us>
-rw-r--r--src/backend/optimizer/plan/planner.c10
-rw-r--r--src/include/nodes/relation.h4
2 files changed, 9 insertions, 5 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 54c04404361..07b925e74c5 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -4222,7 +4222,7 @@ make_group_input_target(PlannerInfo *root, PathTarget *final_target)
foreach(lc, final_target->exprs)
{
Expr *expr = (Expr *) lfirst(lc);
- Index sgref = final_target->sortgrouprefs[i];
+ Index sgref = get_pathtarget_sortgroupref(final_target, i);
if (sgref && parse->groupClause &&
get_sortgroupref_clause_noerr(sgref, parse->groupClause) != NULL)
@@ -4304,7 +4304,7 @@ make_partialgroup_input_target(PlannerInfo *root, PathTarget *final_target)
foreach(lc, final_target->exprs)
{
Expr *expr = (Expr *) lfirst(lc);
- Index sgref = final_target->sortgrouprefs[i];
+ Index sgref = get_pathtarget_sortgroupref(final_target, i);
if (sgref && parse->groupClause &&
get_sortgroupref_clause_noerr(sgref, parse->groupClause) != NULL)
@@ -4556,7 +4556,7 @@ make_window_input_target(PlannerInfo *root,
foreach(lc, final_target->exprs)
{
Expr *expr = (Expr *) lfirst(lc);
- Index sgref = final_target->sortgrouprefs[i];
+ Index sgref = get_pathtarget_sortgroupref(final_target, i);
/*
* Don't want to deconstruct window clauses or GROUP BY items. (Note
@@ -4757,7 +4757,7 @@ make_sort_input_target(PlannerInfo *root,
* only be Vars anyway. There don't seem to be any cases where it
* would be worth the trouble to double-check.
*/
- if (final_target->sortgrouprefs[i] == 0)
+ if (get_pathtarget_sortgroupref(final_target, i) == 0)
{
/*
* Check for SRF or volatile functions. Check the SRF case first
@@ -4847,7 +4847,7 @@ make_sort_input_target(PlannerInfo *root,
postponable_cols = lappend(postponable_cols, expr);
else
add_column_to_pathtarget(input_target, expr,
- final_target->sortgrouprefs[i]);
+ get_pathtarget_sortgroupref(final_target, i));
i++;
}
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index cafd6962298..a4892cbae59 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -783,6 +783,10 @@ typedef struct PathTarget
int width; /* estimated avg width of result tuples */
} PathTarget;
+/* Convenience macro to get a sort/group refno from a PathTarget */
+#define get_pathtarget_sortgroupref(target, colno) \
+ ((target)->sortgrouprefs ? (target)->sortgrouprefs[colno] : (Index) 0)
+
/*
* ParamPathInfo