aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/subselect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/subselect.c')
-rw-r--r--src/backend/optimizer/plan/subselect.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index a9649212f20..f2b586d19cc 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -157,7 +157,7 @@ replace_outer_var(PlannerInfo *root, Var *var)
retval->paramid = i;
retval->paramtype = var->vartype;
retval->paramtypmod = var->vartypmod;
- retval->paramcollation = var->varcollid;
+ retval->paramcollid = var->varcollid;
retval->location = -1;
return retval;
@@ -186,7 +186,7 @@ assign_nestloop_param(PlannerInfo *root, Var *var)
retval->paramid = i;
retval->paramtype = var->vartype;
retval->paramtypmod = var->vartypmod;
- retval->paramcollation = var->varcollid;
+ retval->paramcollid = var->varcollid;
retval->location = -1;
return retval;
@@ -227,7 +227,7 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
retval->paramid = i;
retval->paramtype = agg->aggtype;
retval->paramtypmod = -1;
- retval->paramcollation = agg->collid;
+ retval->paramcollid = agg->aggcollid;
retval->location = -1;
return retval;
@@ -239,7 +239,8 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
* This is used to allocate PARAM_EXEC slots for subplan outputs.
*/
static Param *
-generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)
+generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
+ Oid paramcollation)
{
Param *retval;
PlannerParamItem *pitem;
@@ -249,7 +250,7 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid para
retval->paramid = list_length(root->glob->paramlist);
retval->paramtype = paramtype;
retval->paramtypmod = paramtypmod;
- retval->paramcollation = paramcollation;
+ retval->paramcollid = paramcollation;
retval->location = -1;
pitem = makeNode(PlannerParamItem);
@@ -282,10 +283,11 @@ SS_assign_special_param(PlannerInfo *root)
/*
* Get the datatype of the first column of the plan's output.
*
- * This is stored for ARRAY_SUBLINK execution and for exprType()/exprTypmod()/exprCollation(),
- * which have no way to get at the plan associated with a SubPlan node.
- * We really only need the info for EXPR_SUBLINK and ARRAY_SUBLINK subplans,
- * but for consistency we save it always.
+ * This information is stored for ARRAY_SUBLINK execution and for
+ * exprType()/exprTypmod()/exprCollation(), which have no way to get at the
+ * plan associated with a SubPlan node. We really only need the info for
+ * EXPR_SUBLINK and ARRAY_SUBLINK subplans, but for consistency we save it
+ * always.
*/
static void
get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod, Oid *colcollation)
@@ -1395,13 +1397,15 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
List *leftargs,
*rightargs,
*opids,
+ *opcollations,
*newWhere,
*tlist,
*testlist,
*paramids;
ListCell *lc,
*rc,
- *oc;
+ *oc,
+ *cc;
AttrNumber resno;
/*
@@ -1465,7 +1469,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
* we aren't trying hard yet to ensure that we have only outer or only
* inner on each side; we'll check that if we get to the end.
*/
- leftargs = rightargs = opids = newWhere = NIL;
+ leftargs = rightargs = opids = opcollations = newWhere = NIL;
foreach(lc, (List *) whereClause)
{
OpExpr *expr = (OpExpr *) lfirst(lc);
@@ -1481,6 +1485,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
leftargs = lappend(leftargs, leftarg);
rightargs = lappend(rightargs, rightarg);
opids = lappend_oid(opids, expr->opno);
+ opcollations = lappend_oid(opcollations, expr->inputcollid);
continue;
}
if (contain_vars_of_level(rightarg, 1))
@@ -1497,6 +1502,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
leftargs = lappend(leftargs, rightarg);
rightargs = lappend(rightargs, leftarg);
opids = lappend_oid(opids, expr->opno);
+ opcollations = lappend_oid(opcollations, expr->inputcollid);
continue;
}
/* If no commutator, no chance to optimize the WHERE clause */
@@ -1565,16 +1571,17 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
*/
tlist = testlist = paramids = NIL;
resno = 1;
- /* there's no "for3" so we have to chase one of the lists manually */
- oc = list_head(opids);
- forboth(lc, leftargs, rc, rightargs)
+ /* there's no "forfour" so we have to chase one of the lists manually */
+ cc = list_head(opcollations);
+ forthree(lc, leftargs, rc, rightargs, oc, opids)
{
Node *leftarg = (Node *) lfirst(lc);
Node *rightarg = (Node *) lfirst(rc);
Oid opid = lfirst_oid(oc);
+ Oid opcollation = lfirst_oid(cc);
Param *param;
- oc = lnext(oc);
+ cc = lnext(cc);
param = generate_new_param(root,
exprType(rightarg),
exprTypmod(rightarg),
@@ -1586,7 +1593,8 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
false));
testlist = lappend(testlist,
make_opclause(opid, BOOLOID, false,
- (Expr *) leftarg, (Expr *) param));
+ (Expr *) leftarg, (Expr *) param,
+ InvalidOid, opcollation));
paramids = lappend_int(paramids, param->paramid);
}
@@ -2360,7 +2368,7 @@ finalize_primnode(Node *node, finalize_primnode_context *context)
/*
* SS_make_initplan_from_plan - given a plan tree, make it an InitPlan
*
- * The plan is expected to return a scalar value of the indicated type.
+ * The plan is expected to return a scalar value of the given type/collation.
* We build an EXPR_SUBLINK SubPlan node and put it into the initplan
* list for the current query level. A Param that represents the initplan's
* output is returned.
@@ -2369,7 +2377,8 @@ finalize_primnode(Node *node, finalize_primnode_context *context)
*/
Param *
SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
- Oid resulttype, int32 resulttypmod, Oid resultcollation)
+ Oid resulttype, int32 resulttypmod,
+ Oid resultcollation)
{
SubPlan *node;
Param *prm;
@@ -2405,7 +2414,8 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
*/
node = makeNode(SubPlan);
node->subLinkType = EXPR_SUBLINK;
- get_first_col_type(plan, &node->firstColType, &node->firstColTypmod, &node->firstColCollation);
+ get_first_col_type(plan, &node->firstColType, &node->firstColTypmod,
+ &node->firstColCollation);
node->plan_id = list_length(root->glob->subplans);
root->init_plans = lappend(root->init_plans, node);