Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit97ddfc9

Browse files
committed
Ensure that EquivalenceClasses generated from ORDER BY keys contain proper
RelabelType nodes when the sort key is binary-compatible with the sortoperator rather than having exactly its input type. We did this correctlyfor index columns but not sort keys, leading to failure to notice thata varchar index matches an ORDER BY request. This requires a bit more workin make_sort_from_pathkeys, but not anyplace else that I can find.Per bug report and subsequent discussion.
1 parent65bd783 commit97ddfc9

File tree

2 files changed

+44
-23
lines changed

2 files changed

+44
-23
lines changed

‎src/backend/optimizer/path/pathkeys.c

Lines changed: 25 additions & 22 deletions
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.86 2007/10/27 05:45:43 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.87 2007/11/02 18:54:15 tgl Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -277,6 +277,30 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
277277
elog(ERROR,"could not find opfamilies for ordering operator %u",
278278
ordering_op);
279279

280+
/*
281+
* When dealing with binary-compatible opclasses, we have to ensure that
282+
* the exposed type of the expression tree matches the declared input
283+
* type of the opclass, except when that is a polymorphic type
284+
* (compare the behavior of parse_coerce.c). This ensures that we can
285+
* correctly match the indexkey or sortclause expression to other
286+
* expressions we find in the query, because arguments of ordinary
287+
* operator expressions will be cast that way. (We have to do this
288+
* for indexkeys because they are represented without any explicit
289+
* relabel in pg_index, and for sort clauses because the parser is
290+
* likewise cavalier about putting relabels on them.)
291+
*/
292+
if (exprType((Node*)expr)!=opcintype&&
293+
!IsPolymorphicType(opcintype))
294+
{
295+
/* Strip any existing RelabelType, and add a new one */
296+
while (expr&&IsA(expr,RelabelType))
297+
expr= (Expr*) ((RelabelType*)expr)->arg;
298+
expr= (Expr*)makeRelabelType(expr,
299+
opcintype,
300+
-1,
301+
COERCE_DONTCARE);
302+
}
303+
280304
/* Now find or create a matching EquivalenceClass */
281305
eclass=get_eclass_for_sort_expr(root,expr,opcintype,opfamilies);
282306

@@ -495,27 +519,6 @@ build_index_pathkeys(PlannerInfo *root,
495519
indexprs_item=lnext(indexprs_item);
496520
}
497521

498-
/*
499-
* When dealing with binary-compatible indexes, we have to ensure that
500-
* the exposed type of the expression tree matches the declared input
501-
* type of the opclass, except when that is a polymorphic type
502-
* (compare the behavior of parse_coerce.c). This ensures that we can
503-
* correctly match the indexkey expression to expressions we find in
504-
* the query, because arguments of operators that could match the
505-
* index will be cast likewise.
506-
*/
507-
if (exprType((Node*)indexkey)!=index->opcintype[i]&&
508-
!IsPolymorphicType(index->opcintype[i]))
509-
{
510-
/* Strip any existing RelabelType, and add a new one */
511-
while (indexkey&&IsA(indexkey,RelabelType))
512-
indexkey= (Expr*) ((RelabelType*)indexkey)->arg;
513-
indexkey= (Expr*)makeRelabelType(indexkey,
514-
index->opcintype[i],
515-
-1,
516-
COERCE_DONTCARE);
517-
}
518-
519522
/* OK, make a canonical pathkey for this sort key */
520523
cpathkey=make_pathkey_from_sortinfo(root,
521524
indexkey,

‎src/backend/optimizer/plan/createplan.c

Lines changed: 19 additions & 1 deletion
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.231 2007/05/21 17:57:34 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.232 2007/11/02 18:54:15 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -2756,12 +2756,30 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
27562756

27572757
if (em->em_is_const||em->em_is_child)
27582758
continue;
2759+
27592760
tle=tlist_member((Node*)em->em_expr,tlist);
27602761
if (tle)
27612762
{
27622763
pk_datatype=em->em_datatype;
27632764
break;/* found expr already in tlist */
27642765
}
2766+
2767+
/*
2768+
* 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).
2771+
*/
2772+
if (IsA(em->em_expr,RelabelType))
2773+
{
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+
}
2782+
}
27652783
}
27662784
if (!tle)
27672785
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp