summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan')
-rw-r--r--src/backend/optimizer/plan/createplan.c64
-rw-r--r--src/backend/optimizer/plan/planagg.c3
-rw-r--r--src/backend/optimizer/plan/setrefs.c3
-rw-r--r--src/backend/optimizer/plan/subselect.c40
4 files changed, 79 insertions, 31 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index c74125f1f7..f01114c673 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -105,7 +105,7 @@ static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
List *tidquals);
static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
Index scanrelid, Node *funcexpr, List *funccolnames,
- List *funccoltypes, List *funccoltypmods);
+ List *funccoltypes, List *funccoltypmods, List *funccolcollations);
static ValuesScan *make_valuesscan(List *qptlist, List *qpqual,
Index scanrelid, List *values_lists);
static CteScan *make_ctescan(List *qptlist, List *qpqual,
@@ -133,12 +133,13 @@ static MergeJoin *make_mergejoin(List *tlist,
List *joinclauses, List *otherclauses,
List *mergeclauses,
Oid *mergefamilies,
+ Oid *mergecollations,
int *mergestrategies,
bool *mergenullsfirst,
Plan *lefttree, Plan *righttree,
JoinType jointype);
static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
- AttrNumber *sortColIdx, Oid *sortOperators, bool *nullsFirst,
+ AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst,
double limit_tuples);
static Plan *prepare_sort_from_pathkeys(PlannerInfo *root,
Plan *lefttree, List *pathkeys,
@@ -146,6 +147,7 @@ static Plan *prepare_sort_from_pathkeys(PlannerInfo *root,
int *p_numsortkeys,
AttrNumber **p_sortColIdx,
Oid **p_sortOperators,
+ Oid **p_collations,
bool **p_nullsFirst);
static Material *make_material(Plan *lefttree);
@@ -671,6 +673,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
&node->numCols,
&node->sortColIdx,
&node->sortOperators,
+ &node->collations,
&node->nullsFirst);
/*
@@ -685,6 +688,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ Oid *collations;
bool *nullsFirst;
/* Build the child plan */
@@ -696,6 +700,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
&numsortkeys,
&sortColIdx,
&sortOperators,
+ &collations,
&nullsFirst);
/*
@@ -710,13 +715,15 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");
Assert(memcmp(sortOperators, node->sortOperators,
numsortkeys * sizeof(Oid)) == 0);
+ Assert(memcmp(collations, node->collations,
+ numsortkeys * sizeof(Oid)) == 0);
Assert(memcmp(nullsFirst, node->nullsFirst,
numsortkeys * sizeof(bool)) == 0);
/* Now, insert a Sort node if subplan isn't sufficiently ordered */
if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
subplan = (Plan *) make_sort(root, subplan, numsortkeys,
- sortColIdx, sortOperators, nullsFirst,
+ sortColIdx, sortOperators, collations, nullsFirst,
best_path->limit_tuples);
subplans = lappend(subplans, subplan);
@@ -1569,7 +1576,8 @@ create_functionscan_plan(PlannerInfo *root, Path *best_path,
rte->funcexpr,
rte->eref->colnames,
rte->funccoltypes,
- rte->funccoltypmods);
+ rte->funccoltypmods,
+ rte->funccolcollations);
copy_path_costsize(&scan_plan->scan.plan, best_path);
@@ -1847,6 +1855,7 @@ create_mergejoin_plan(PlannerInfo *root,
List *innerpathkeys;
int nClauses;
Oid *mergefamilies;
+ Oid *mergecollations;
int *mergestrategies;
bool *mergenullsfirst;
MergeJoin *join_plan;
@@ -1946,6 +1955,7 @@ create_mergejoin_plan(PlannerInfo *root,
nClauses = list_length(mergeclauses);
Assert(nClauses == list_length(best_path->path_mergeclauses));
mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));
+ mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));
mergestrategies = (int *) palloc(nClauses * sizeof(int));
mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));
@@ -2074,12 +2084,14 @@ create_mergejoin_plan(PlannerInfo *root,
/* pathkeys should match each other too (more debugging) */
if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
+ opathkey->pk_collation != ipathkey->pk_collation ||
opathkey->pk_strategy != ipathkey->pk_strategy ||
opathkey->pk_nulls_first != ipathkey->pk_nulls_first)
elog(ERROR, "left and right pathkeys do not match in mergejoin");
/* OK, save info for executor */
mergefamilies[i] = opathkey->pk_opfamily;
+ mergecollations[i] = opathkey->pk_collation;
mergestrategies[i] = opathkey->pk_strategy;
mergenullsfirst[i] = opathkey->pk_nulls_first;
i++;
@@ -2099,6 +2111,7 @@ create_mergejoin_plan(PlannerInfo *root,
otherclauses,
mergeclauses,
mergefamilies,
+ mergecollations,
mergestrategies,
mergenullsfirst,
outer_plan,
@@ -2528,6 +2541,7 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index)
/* Found a match */
result = makeVar(index->rel->relid, pos + 1,
exprType(lfirst(indexpr_item)), -1,
+ exprCollation(lfirst(indexpr_item)),
0);
return (Node *) result;
}
@@ -2881,7 +2895,8 @@ make_functionscan(List *qptlist,
Node *funcexpr,
List *funccolnames,
List *funccoltypes,
- List *funccoltypmods)
+ List *funccoltypmods,
+ List *funccolcollations)
{
FunctionScan *node = makeNode(FunctionScan);
Plan *plan = &node->scan.plan;
@@ -2896,6 +2911,7 @@ make_functionscan(List *qptlist,
node->funccolnames = funccolnames;
node->funccoltypes = funccoltypes;
node->funccoltypmods = funccoltypmods;
+ node->funccolcollations = funccolcollations;
return node;
}
@@ -3181,6 +3197,7 @@ make_mergejoin(List *tlist,
List *otherclauses,
List *mergeclauses,
Oid *mergefamilies,
+ Oid *mergecollations,
int *mergestrategies,
bool *mergenullsfirst,
Plan *lefttree,
@@ -3197,6 +3214,7 @@ make_mergejoin(List *tlist,
plan->righttree = righttree;
node->mergeclauses = mergeclauses;
node->mergeFamilies = mergefamilies;
+ node->mergeCollations = mergecollations;
node->mergeStrategies = mergestrategies;
node->mergeNullsFirst = mergenullsfirst;
node->join.jointype = jointype;
@@ -3214,7 +3232,7 @@ make_mergejoin(List *tlist,
*/
static Sort *
make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
- AttrNumber *sortColIdx, Oid *sortOperators, bool *nullsFirst,
+ AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst,
double limit_tuples)
{
Sort *node = makeNode(Sort);
@@ -3238,6 +3256,7 @@ make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
node->numCols = numCols;
node->sortColIdx = sortColIdx;
node->sortOperators = sortOperators;
+ node->collations = collations;
node->nullsFirst = nullsFirst;
return node;
@@ -3253,9 +3272,9 @@ make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
* max possible number of columns. Return value is the new column count.
*/
static int
-add_sort_column(AttrNumber colIdx, Oid sortOp, bool nulls_first,
+add_sort_column(AttrNumber colIdx, Oid sortOp, Oid coll, bool nulls_first,
int numCols, AttrNumber *sortColIdx,
- Oid *sortOperators, bool *nullsFirst)
+ Oid *sortOperators, Oid *collations, bool *nullsFirst)
{
int i;
@@ -3271,7 +3290,8 @@ add_sort_column(AttrNumber colIdx, Oid sortOp, bool nulls_first,
* opposite nulls direction is redundant.
*/
if (sortColIdx[i] == colIdx &&
- sortOperators[numCols] == sortOp)
+ sortOperators[numCols] == sortOp &&
+ collations[numCols] == coll)
{
/* Already sorting by this col, so extra sort key is useless */
return numCols;
@@ -3281,6 +3301,7 @@ add_sort_column(AttrNumber colIdx, Oid sortOp, bool nulls_first,
/* Add the column */
sortColIdx[numCols] = colIdx;
sortOperators[numCols] = sortOp;
+ collations[numCols] = coll;
nullsFirst[numCols] = nulls_first;
return numCols + 1;
}
@@ -3320,6 +3341,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
int *p_numsortkeys,
AttrNumber **p_sortColIdx,
Oid **p_sortOperators,
+ Oid **p_collations,
bool **p_nullsFirst)
{
List *tlist = lefttree->targetlist;
@@ -3327,6 +3349,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ Oid *collations;
bool *nullsFirst;
/*
@@ -3335,6 +3358,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
numsortkeys = list_length(pathkeys);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -3493,9 +3517,10 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
*/
numsortkeys = add_sort_column(tle->resno,
sortop,
+ pathkey->pk_collation,
pathkey->pk_nulls_first,
numsortkeys,
- sortColIdx, sortOperators, nullsFirst);
+ sortColIdx, sortOperators, collations, nullsFirst);
}
Assert(numsortkeys > 0);
@@ -3504,6 +3529,7 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
*p_numsortkeys = numsortkeys;
*p_sortColIdx = sortColIdx;
*p_sortOperators = sortOperators;
+ *p_collations = collations;
*p_nullsFirst = nullsFirst;
return lefttree;
@@ -3525,6 +3551,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ Oid *collations;
bool *nullsFirst;
/* Compute sort column info, and adjust lefttree as needed */
@@ -3533,11 +3560,12 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
&numsortkeys,
&sortColIdx,
&sortOperators,
+ &collations,
&nullsFirst);
/* Now build the Sort node */
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators, nullsFirst, limit_tuples);
+ sortColIdx, sortOperators, collations, nullsFirst, limit_tuples);
}
/*
@@ -3555,6 +3583,7 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ Oid *collations;
bool *nullsFirst;
/*
@@ -3563,6 +3592,7 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
numsortkeys = list_length(sortcls);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -3578,15 +3608,16 @@ make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
* redundantly.
*/
numsortkeys = add_sort_column(tle->resno, sortcl->sortop,
+ exprCollation((Node *) tle->expr),
sortcl->nulls_first,
numsortkeys,
- sortColIdx, sortOperators, nullsFirst);
+ sortColIdx, sortOperators, collations, nullsFirst);
}
Assert(numsortkeys > 0);
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators, nullsFirst, -1.0);
+ sortColIdx, sortOperators, collations, nullsFirst, -1.0);
}
/*
@@ -3614,6 +3645,7 @@ make_sort_from_groupcols(PlannerInfo *root,
int numsortkeys;
AttrNumber *sortColIdx;
Oid *sortOperators;
+ Oid *collations;
bool *nullsFirst;
/*
@@ -3622,6 +3654,7 @@ make_sort_from_groupcols(PlannerInfo *root,
numsortkeys = list_length(groupcls);
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
+ collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
numsortkeys = 0;
@@ -3637,16 +3670,17 @@ make_sort_from_groupcols(PlannerInfo *root,
* redundantly.
*/
numsortkeys = add_sort_column(tle->resno, grpcl->sortop,
+ exprCollation((Node *) tle->expr),
grpcl->nulls_first,
numsortkeys,
- sortColIdx, sortOperators, nullsFirst);
+ sortColIdx, sortOperators, collations, nullsFirst);
grpno++;
}
Assert(numsortkeys > 0);
return make_sort(root, lefttree, numsortkeys,
- sortColIdx, sortOperators, nullsFirst, -1.0);
+ sortColIdx, sortOperators, collations, nullsFirst, -1.0);
}
static Material *
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index dfbc624aa8..f885385296 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -561,7 +561,8 @@ make_agg_subplan(PlannerInfo *root, RelOptInfo *rel, PrivateMMAggInfo *info)
*/
info->param = SS_make_initplan_from_plan(&subroot, plan,
exprType((Node *) tle->expr),
- -1);
+ -1,
+ exprCollation((Node *) tle->expr));
/*
* Put the updated list of InitPlans back into the outer PlannerInfo.
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 02f5cabd25..867238ecc8 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -213,9 +213,11 @@ set_plan_references(PlannerGlobal *glob, Plan *plan,
newrte->funcexpr = NULL;
newrte->funccoltypes = NIL;
newrte->funccoltypmods = NIL;
+ newrte->funccolcollations = NIL;
newrte->values_lists = NIL;
newrte->ctecoltypes = NIL;
newrte->ctecoltypmods = NIL;
+ newrte->ctecolcollations = NIL;
glob->finalrtable = lappend(glob->finalrtable, newrte);
@@ -1119,6 +1121,7 @@ set_dummy_tlist_references(Plan *plan, int rtoffset)
tle->resno,
exprType((Node *) oldvar),
exprTypmod((Node *) oldvar),
+ exprCollation((Node *) oldvar),
0);
if (IsA(oldvar, Var))
{
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index febec1e15f..29eb9dced4 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -157,6 +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->location = -1;
return retval;
@@ -185,6 +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->location = -1;
return retval;
@@ -225,6 +227,7 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
retval->paramid = i;
retval->paramtype = agg->aggtype;
retval->paramtypmod = -1;
+ retval->paramcollation = agg->collid;
retval->location = -1;
return retval;
@@ -236,7 +239,7 @@ 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)
+generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)
{
Param *retval;
PlannerParamItem *pitem;
@@ -246,6 +249,7 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod)
retval->paramid = list_length(root->glob->paramlist);
retval->paramtype = paramtype;
retval->paramtypmod = paramtypmod;
+ retval->paramcollation = paramcollation;
retval->location = -1;
pitem = makeNode(PlannerParamItem);
@@ -270,7 +274,7 @@ SS_assign_special_param(PlannerInfo *root)
Param *param;
/* We generate a Param of datatype INTERNAL */
- param = generate_new_param(root, INTERNALOID, -1);
+ param = generate_new_param(root, INTERNALOID, -1, InvalidOid);
/* ... but the caller only cares about its ID */
return param->paramid;
}
@@ -278,13 +282,13 @@ 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(),
+ * 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.
*/
static void
-get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod)
+get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod, Oid *colcollation)
{
/* In cases such as EXISTS, tlist might be empty; arbitrarily use VOID */
if (plan->targetlist)
@@ -296,11 +300,13 @@ get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod)
{
*coltype = exprType((Node *) tent->expr);
*coltypmod = exprTypmod((Node *) tent->expr);
+ *colcollation = exprCollation((Node *) tent->expr);
return;
}
}
*coltype = VOIDOID;
*coltypmod = -1;
+ *colcollation = InvalidOid;
}
/*
@@ -470,7 +476,7 @@ build_subplan(PlannerInfo *root, Plan *plan, List *rtable, List *rowmarks,
splan->subLinkType = subLinkType;
splan->testexpr = NULL;
splan->paramIds = NIL;
- get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod);
+ get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod, &splan->firstColCollation);
splan->useHashTable = false;
splan->unknownEqFalse = unknownEqFalse;
splan->setParam = NIL;
@@ -523,7 +529,7 @@ build_subplan(PlannerInfo *root, Plan *plan, List *rtable, List *rowmarks,
Param *prm;
Assert(testexpr == NULL);
- prm = generate_new_param(root, BOOLOID, -1);
+ prm = generate_new_param(root, BOOLOID, -1, InvalidOid);
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
@@ -537,7 +543,8 @@ build_subplan(PlannerInfo *root, Plan *plan, List *rtable, List *rowmarks,
Assert(testexpr == NULL);
prm = generate_new_param(root,
exprType((Node *) te->expr),
- exprTypmod((Node *) te->expr));
+ exprTypmod((Node *) te->expr),
+ exprCollation((Node *) te->expr));
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
@@ -556,7 +563,8 @@ build_subplan(PlannerInfo *root, Plan *plan, List *rtable, List *rowmarks,
format_type_be(exprType((Node *) te->expr)));
prm = generate_new_param(root,
arraytype,
- exprTypmod((Node *) te->expr));
+ exprTypmod((Node *) te->expr),
+ exprCollation((Node *) te->expr));
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
@@ -708,7 +716,8 @@ generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds)
param = generate_new_param(root,
exprType((Node *) tent->expr),
- exprTypmod((Node *) tent->expr));
+ exprTypmod((Node *) tent->expr),
+ exprCollation((Node *) tent->expr));
result = lappend(result, param);
ids = lappend_int(ids, param->paramid);
}
@@ -964,7 +973,7 @@ SS_process_ctes(PlannerInfo *root)
splan->subLinkType = CTE_SUBLINK;
splan->testexpr = NULL;
splan->paramIds = NIL;
- get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod);
+ get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod, &splan->firstColCollation);
splan->useHashTable = false;
splan->unknownEqFalse = false;
splan->setParam = NIL;
@@ -999,7 +1008,7 @@ SS_process_ctes(PlannerInfo *root)
* Assign a param to represent the query output. We only really care
* about reserving a parameter ID number.
*/
- prm = generate_new_param(root, INTERNALOID, -1);
+ prm = generate_new_param(root, INTERNALOID, -1, InvalidOid);
splan->setParam = list_make1_int(prm->paramid);
/*
@@ -1565,7 +1574,8 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
oc = lnext(oc);
param = generate_new_param(root,
exprType(rightarg),
- exprTypmod(rightarg));
+ exprTypmod(rightarg),
+ exprCollation(rightarg));
tlist = lappend(tlist,
makeTargetEntry((Expr *) rightarg,
resno++,
@@ -2352,7 +2362,7 @@ finalize_primnode(Node *node, finalize_primnode_context *context)
*/
Param *
SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
- Oid resulttype, int32 resulttypmod)
+ Oid resulttype, int32 resulttypmod, Oid resultcollation)
{
SubPlan *node;
Param *prm;
@@ -2388,7 +2398,7 @@ 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);
+ 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);
@@ -2403,7 +2413,7 @@ SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
/*
* Make a Param that will be the subplan's output.
*/
- prm = generate_new_param(root, resulttype, resulttypmod);
+ prm = generate_new_param(root, resulttype, resulttypmod, resultcollation);
node->setParam = list_make1_int(prm->paramid);
/* Label the subplan for EXPLAIN purposes */