Teach convert_subquery_pathkeys() to handle the case where the
subquery's pathkey is a RelabelType applied to something that appears in the subquery's output; for example where the subquery returns a varchar Var and the sort order is shown as that Var coerced to text. This comes up because varchar doesn't have its own sort operator. Per example from Peter Hardman.
This commit is contained in:
parent
4e1bdcaabf
commit
144b0ae8ee
@ -11,7 +11,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.77 2006/07/14 14:52:20 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.78 2006/08/17 17:02:49 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1059,26 +1059,61 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
{
|
{
|
||||||
PathKeyItem *sub_item = (PathKeyItem *) lfirst(j);
|
PathKeyItem *sub_item = (PathKeyItem *) lfirst(j);
|
||||||
Node *sub_key = sub_item->key;
|
Node *sub_key = sub_item->key;
|
||||||
|
Expr *rtarg;
|
||||||
ListCell *k;
|
ListCell *k;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We handle two cases: the sub_pathkey key can be either an exact
|
||||||
|
* match for a targetlist entry, or a RelabelType of a targetlist
|
||||||
|
* entry. (The latter case is worth extra code because it arises
|
||||||
|
* frequently in connection with varchar fields.)
|
||||||
|
*/
|
||||||
|
if (IsA(sub_key, RelabelType))
|
||||||
|
rtarg = ((RelabelType *) sub_key)->arg;
|
||||||
|
else
|
||||||
|
rtarg = NULL;
|
||||||
|
|
||||||
foreach(k, sub_tlist)
|
foreach(k, sub_tlist)
|
||||||
{
|
{
|
||||||
TargetEntry *tle = (TargetEntry *) lfirst(k);
|
TargetEntry *tle = (TargetEntry *) lfirst(k);
|
||||||
|
Node *outer_expr;
|
||||||
if (!tle->resjunk &&
|
|
||||||
equal(tle->expr, sub_key))
|
|
||||||
{
|
|
||||||
/* Found a representation for this sub_key */
|
|
||||||
Var *outer_var;
|
|
||||||
PathKeyItem *outer_item;
|
PathKeyItem *outer_item;
|
||||||
int score;
|
int score;
|
||||||
|
|
||||||
outer_var = makeVar(rel->relid,
|
/* resjunk items aren't visible to outer query */
|
||||||
|
if (tle->resjunk)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (equal(tle->expr, sub_key))
|
||||||
|
{
|
||||||
|
/* Exact match */
|
||||||
|
outer_expr = (Node *)
|
||||||
|
makeVar(rel->relid,
|
||||||
tle->resno,
|
tle->resno,
|
||||||
exprType((Node *) tle->expr),
|
exprType((Node *) tle->expr),
|
||||||
exprTypmod((Node *) tle->expr),
|
exprTypmod((Node *) tle->expr),
|
||||||
0);
|
0);
|
||||||
outer_item = makePathKeyItem((Node *) outer_var,
|
}
|
||||||
|
else if (rtarg && equal(tle->expr, rtarg))
|
||||||
|
{
|
||||||
|
/* Match after discarding RelabelType */
|
||||||
|
outer_expr = (Node *)
|
||||||
|
makeVar(rel->relid,
|
||||||
|
tle->resno,
|
||||||
|
exprType((Node *) tle->expr),
|
||||||
|
exprTypmod((Node *) tle->expr),
|
||||||
|
0);
|
||||||
|
outer_expr = (Node *)
|
||||||
|
makeRelabelType((Expr *) outer_expr,
|
||||||
|
((RelabelType *) sub_key)->resulttype,
|
||||||
|
((RelabelType *) sub_key)->resulttypmod,
|
||||||
|
((RelabelType *) sub_key)->relabelformat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Found a representation for this sub_key */
|
||||||
|
outer_item = makePathKeyItem(outer_expr,
|
||||||
sub_item->sortop,
|
sub_item->sortop,
|
||||||
true);
|
true);
|
||||||
/* score = # of mergejoin peers */
|
/* score = # of mergejoin peers */
|
||||||
@ -1094,7 +1129,6 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we couldn't find a representation of this sub_pathkey, we're
|
* If we couldn't find a representation of this sub_pathkey, we're
|
||||||
|
Loading…
x
Reference in New Issue
Block a user