Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1be0601

Browse files
committed
Last week's patch for make_sort_from_pathkeys wasn't good enough: it has
to be able to discard top-level RelabelType nodes on *both* sides of the equivalence-class-to-target-list comparison, since make_pathkey_from_sortinfo might either add or remove a RelabelType. Also fix the latter to do the removal case cleanly. Per example from Peter.
1 parent f1528b5 commit 1be0601

File tree

4 files changed

+50
-23
lines changed

4 files changed

+50
-23
lines changed

src/backend/optimizer/path/pathkeys.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.87 2007/11/02 18:54:15 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.88 2007/11/08 19:25:37 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -292,13 +292,14 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
292292
if (exprType((Node *) expr) != opcintype &&
293293
!IsPolymorphicType(opcintype))
294294
{
295-
/* Strip any existing RelabelType, and add a new one */
295+
/* Strip any existing RelabelType, and add a new one if needed */
296296
while (expr && IsA(expr, RelabelType))
297297
expr = (Expr *) ((RelabelType *) expr)->arg;
298-
expr = (Expr *) makeRelabelType(expr,
299-
opcintype,
300-
-1,
301-
COERCE_DONTCARE);
298+
if (exprType((Node *) expr) != opcintype)
299+
expr = (Expr *) makeRelabelType(expr,
300+
opcintype,
301+
-1,
302+
COERCE_DONTCARE);
302303
}
303304

304305
/* Now find or create a matching EquivalenceClass */

src/backend/optimizer/plan/createplan.c

+12-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.232 2007/11/02 18:54:15 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.233 2007/11/08 19:25:37 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -2738,7 +2738,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
27382738
/*
27392739
* We can sort by any non-constant expression listed in the pathkey's
27402740
* EquivalenceClass. For now, we take the first one that corresponds
2741-
* to an available Var in the tlist. If there isn't any, use the first
2741+
* to an available item in the tlist. If there isn't any, use the first
27422742
* one that is an expression in the input's vars. (The non-const
27432743
* restriction only matters if the EC is below_outer_join; but if it
27442744
* isn't, it won't contain consts anyway, else we'd have discarded
@@ -2766,24 +2766,21 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
27662766

27672767
/*
27682768
* We can also use it if the pathkey expression is a relabel
2769-
* of the tlist entry. This is needed for binary-compatible
2770-
* cases (cf. make_pathkey_from_sortinfo).
2769+
* of the tlist entry, or vice versa. This is needed for
2770+
* binary-compatible cases (cf. make_pathkey_from_sortinfo).
2771+
* We prefer an exact match, though, so we do the basic
2772+
* search first.
27712773
*/
2772-
if (IsA(em->em_expr, RelabelType))
2774+
tle = tlist_member_ignore_relabel((Node *) em->em_expr, tlist);
2775+
if (tle)
27732776
{
2774-
Expr *rtarg = ((RelabelType *) em->em_expr)->arg;
2775-
2776-
tle = tlist_member((Node *) rtarg, tlist);
2777-
if (tle)
2778-
{
2779-
pk_datatype = em->em_datatype;
2780-
break; /* found expr already in tlist */
2781-
}
2777+
pk_datatype = em->em_datatype;
2778+
break; /* found expr already in tlist */
27822779
}
27832780
}
27842781
if (!tle)
27852782
{
2786-
/* No matching Var; look for a computable expression */
2783+
/* No matching tlist item; look for a computable expression */
27872784
Expr *sortexpr = NULL;
27882785

27892786
foreach(j, pathkey->pk_eclass->ec_members)
@@ -2798,7 +2795,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
27982795
exprvars = pull_var_clause((Node *) sortexpr, false);
27992796
foreach(k, exprvars)
28002797
{
2801-
if (!tlist_member(lfirst(k), tlist))
2798+
if (!tlist_member_ignore_relabel(lfirst(k), tlist))
28022799
break;
28032800
}
28042801
list_free(exprvars);

src/backend/optimizer/util/tlist.c

+29-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.74 2007/01/05 22:19:33 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.75 2007/11/08 19:25:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -44,6 +44,34 @@ tlist_member(Node *node, List *targetlist)
4444
return NULL;
4545
}
4646

47+
/*
48+
* tlist_member_ignore_relabel
49+
* Same as above, except that we ignore top-level RelabelType nodes
50+
* while checking for a match. This is needed for some scenarios
51+
* involving binary-compatible sort operations.
52+
*/
53+
TargetEntry *
54+
tlist_member_ignore_relabel(Node *node, List *targetlist)
55+
{
56+
ListCell *temp;
57+
58+
while (node && IsA(node, RelabelType))
59+
node = (Node *) ((RelabelType *) node)->arg;
60+
61+
foreach(temp, targetlist)
62+
{
63+
TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
64+
Expr *tlexpr = tlentry->expr;
65+
66+
while (tlexpr && IsA(tlexpr, RelabelType))
67+
tlexpr = ((RelabelType *) tlexpr)->arg;
68+
69+
if (equal(node, tlexpr))
70+
return tlentry;
71+
}
72+
return NULL;
73+
}
74+
4775
/*
4876
* flatten_tlist
4977
* Create a target list that only contains unique variables.

src/include/optimizer/tlist.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.45 2007/01/05 22:19:56 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.46 2007/11/08 19:25:37 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -18,6 +18,7 @@
1818

1919

2020
extern TargetEntry *tlist_member(Node *node, List *targetlist);
21+
extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist);
2122

2223
extern List *flatten_tlist(List *tlist);
2324
extern List *add_to_flat_tlist(List *tlist, List *vars);

0 commit comments

Comments
 (0)