diff options
Diffstat (limited to 'src/backend/optimizer/plan')
| -rw-r--r-- | src/backend/optimizer/plan/createplan.c | 64 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/planagg.c | 3 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 3 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/subselect.c | 40 |
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 */ |
