summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 36015ea6c4b..b47ef466dc1 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -22,7 +22,6 @@
#include "access/stratnum.h"
#include "access/sysattr.h"
#include "catalog/pg_class.h"
-#include "catalog/pg_operator.h"
#include "foreign/fdwapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
@@ -172,8 +171,8 @@ static Plan *prepare_sort_from_pathkeys(PlannerInfo *root,
Oid **p_sortOperators,
Oid **p_collations,
bool **p_nullsFirst);
-static EquivalenceMember *find_ec_member_for_expr(EquivalenceClass *ec,
- Expr *tlexpr,
+static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec,
+ TargetEntry *tle,
Relids relids);
static Material *make_material(Plan *lefttree);
@@ -1325,36 +1324,35 @@ create_indexscan_plan(PlannerInfo *root,
}
/*
- * If there are ORDER BY expressions, look up the sort operators for
- * their datatypes.
+ * If there are ORDER BY expressions, look up the sort operators for their
+ * result datatypes.
*/
- if (best_path->path.pathkeys && indexorderbys)
+ if (indexorderbys)
{
ListCell *pathkeyCell,
*exprCell;
/*
- * PathKey contains pointer to the equivalence class, but that's not
- * enough because we need the expression's datatype to look up the
- * sort operator in the operator family. We have to dig out the
- * equivalence member for the datatype.
+ * PathKey contains OID of the btree opfamily we're sorting by, but
+ * that's not quite enough because we need the expression's datatype
+ * to look up the sort operator in the operator family.
*/
+ Assert(list_length(best_path->path.pathkeys) == list_length(indexorderbys));
forboth(pathkeyCell, best_path->path.pathkeys, exprCell, indexorderbys)
{
PathKey *pathkey = (PathKey *) lfirst(pathkeyCell);
- Expr *expr = (Expr *) lfirst(exprCell);
- EquivalenceMember *em;
-
- /* Find equivalence member for the order by expression */
- em = find_ec_member_for_expr(pathkey->pk_eclass, expr, NULL);
+ Node *expr = (Node *) lfirst(exprCell);
+ Oid exprtype = exprType(expr);
+ Oid sortop;
/* Get sort operator from opfamily */
- indexorderbyops =
- lappend_oid(indexorderbyops,
- get_opfamily_member(pathkey->pk_opfamily,
- em->em_datatype,
- em->em_datatype,
- pathkey->pk_strategy));
+ sortop = get_opfamily_member(pathkey->pk_opfamily,
+ exprtype,
+ exprtype,
+ pathkey->pk_strategy);
+ if (!OidIsValid(sortop))
+ elog(ERROR, "failed to find sort operator for ORDER BY expression");
+ indexorderbyops = lappend_oid(indexorderbyops, sortop);
}
}
@@ -4100,7 +4098,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]);
if (tle)
{
- em = find_ec_member_for_expr(ec, tle->expr, relids);
+ em = find_ec_member_for_tle(ec, tle, relids);
if (em)
{
/* found expr at right place in tlist */
@@ -4131,7 +4129,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
foreach(j, tlist)
{
tle = (TargetEntry *) lfirst(j);
- em = find_ec_member_for_expr(ec, tle->expr, relids);
+ em = find_ec_member_for_tle(ec, tle, relids);
if (em)
{
/* found expr already in tlist */
@@ -4252,21 +4250,23 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
}
/*
- * find_ec_member_for_expr
- * Locate an EquivalenceClass member matching the given expression, if any
+ * find_ec_member_for_tle
+ * Locate an EquivalenceClass member matching the given TLE, if any
*
* Child EC members are ignored unless they match 'relids'.
*/
static EquivalenceMember *
-find_ec_member_for_expr(EquivalenceClass *ec,
- Expr *expr,
- Relids relids)
+find_ec_member_for_tle(EquivalenceClass *ec,
+ TargetEntry *tle,
+ Relids relids)
{
+ Expr *tlexpr;
ListCell *lc;
/* We ignore binary-compatible relabeling on both ends */
- while (expr && IsA(expr, RelabelType))
- expr = ((RelabelType *) expr)->arg;
+ tlexpr = tle->expr;
+ while (tlexpr && IsA(tlexpr, RelabelType))
+ tlexpr = ((RelabelType *) tlexpr)->arg;
foreach(lc, ec->ec_members)
{
@@ -4292,7 +4292,7 @@ find_ec_member_for_expr(EquivalenceClass *ec,
while (emexpr && IsA(emexpr, RelabelType))
emexpr = ((RelabelType *) emexpr)->arg;
- if (equal(emexpr, expr))
+ if (equal(emexpr, tlexpr))
return em;
}