1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Make setrefs.c match by ressortgroupref even for plain Vars.

Previously, we skipped using search_indexed_tlist_for_sortgroupref()
if the tlist expression being sought in the child plan node was merely
a Var.  This is purely an optimization, based on the theory that
search_indexed_tlist_for_var() is faster, and one copy of a Var should
be as good as another.  However, the GROUPING SETS patch broke the
latter assumption: grouping columns containing the "same" Var can
sometimes have different outputs, as shown in the test case added here.
So do it the hard way whenever a ressortgroupref marking exists.

(If this seems like a bottleneck, we could imagine building a tlist index
data structure for ressortgroupref values, as we do for Vars.  But I'll
let that idea go until there's some evidence it's worthwhile.)

Back-patch to 9.6.  The problem also exists in 9.5 where GROUPING SETS
came in, but this patch is insufficient to resolve the problem in 9.5:
there is some obscure dependency on the upper-planner-pathification
work that happened in 9.6.  Given that this is such a weird corner case,
and no end users have complained about it, it doesn't seem worth the work
to develop a fix for 9.5.

Patch by me, per a report from Heikki Linnakangas.  (This does not fix
Heikki's original complaint, just the follow-on one.)

Discussion: https://postgr.es/m/aefc657e-edb2-64d5-6df1-a0828f6e9104@iki.fi
This commit is contained in:
Tom Lane
2017-10-26 12:17:40 -04:00
parent 74d2c0dbfd
commit 08f1e1f0a4
3 changed files with 43 additions and 4 deletions

View File

@ -1744,8 +1744,8 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
TargetEntry *tle = (TargetEntry *) lfirst(l);
Node *newexpr;
/* If it's a non-Var sort/group item, first try to match by sortref */
if (tle->ressortgroupref != 0 && !IsA(tle->expr, Var))
/* If it's a sort/group item, first try to match by sortref */
if (tle->ressortgroupref != 0)
{
newexpr = (Node *)
search_indexed_tlist_for_sortgroupref(tle->expr,
@ -2113,7 +2113,6 @@ search_indexed_tlist_for_non_var(Expr *node,
/*
* search_indexed_tlist_for_sortgroupref --- find a sort/group expression
* (which is assumed not to be just a Var)
*
* If a match is found, return a Var constructed to reference the tlist item.
* If no match, return NULL.
@ -2644,7 +2643,7 @@ is_converted_whole_row_reference(Node *node)
if (IsA(convexpr->arg, Var))
{
Var *var = castNode(Var, convexpr->arg);
Var *var = castNode(Var, convexpr->arg);
if (var->varattno == 0)
return true;