diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execGrouping.c | 4 | ||||
-rw-r--r-- | src/backend/executor/execQual.c | 25 | ||||
-rw-r--r-- | src/backend/executor/execUtils.c | 7 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 8 | ||||
-rw-r--r-- | src/backend/executor/nodeAgg.c | 13 | ||||
-rw-r--r-- | src/backend/executor/nodeIndexscan.c | 2 | ||||
-rw-r--r-- | src/backend/executor/nodeMergeAppend.c | 5 | ||||
-rw-r--r-- | src/backend/executor/nodeMergejoin.c | 9 | ||||
-rw-r--r-- | src/backend/executor/nodeSubplan.c | 4 | ||||
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 10 |
10 files changed, 53 insertions, 34 deletions
diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index 1f02428a5b3..bfb8cbb303c 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -3,6 +3,10 @@ * execGrouping.c * executor utility routines for grouping, hashing, and aggregation * + * Note: we currently assume that equality and hashing functions are not + * collation-sensitive, so the code in this file has no support for passing + * collation settings through from callers. That may have to change someday. + * * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 5f0b58f43b7..80f08d8b92e 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -1202,12 +1202,12 @@ init_fcache(Oid foid, Oid input_collation, FuncExprState *fcache, /* Set up the primary fmgr lookup information */ fmgr_info_cxt(foid, &(fcache->func), fcacheCxt); - fmgr_info_set_collation(input_collation, &(fcache->func)); fmgr_info_set_expr((Node *) fcache->xprstate.expr, &(fcache->func)); /* Initialize the function call parameter struct as well */ InitFunctionCallInfoData(fcache->fcinfo_data, &(fcache->func), - list_length(fcache->args), NULL, NULL); + list_length(fcache->args), + input_collation, NULL, NULL); /* If function returns set, prepare expected tuple descriptor */ if (fcache->func.fn_retset && needDescForSets) @@ -1980,6 +1980,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr, returnsSet = fcache->func.fn_retset; InitFunctionCallInfoData(fcinfo, &(fcache->func), list_length(fcache->args), + fcache->fcinfo_data.fncollation, NULL, (Node *) &rsinfo); /* @@ -2017,7 +2018,7 @@ ExecMakeTableFunctionResult(ExprState *funcexpr, { /* Treat funcexpr as a generic expression */ direct_function_call = false; - InitFunctionCallInfoData(fcinfo, NULL, 0, NULL, NULL); + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); } /* @@ -3154,6 +3155,7 @@ ExecEvalRowCompare(RowCompareExprState *rstate, FunctionCallInfoData locfcinfo; InitFunctionCallInfoData(locfcinfo, &(rstate->funcs[i]), 2, + rstate->collations[i], NULL, NULL); locfcinfo.arg[0] = ExecEvalExpr(le, econtext, &locfcinfo.argnull[0], NULL); @@ -3234,7 +3236,9 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext, bool *isNull, ExprDoneCond *isDone) { Datum result = (Datum) 0; - MinMaxOp op = ((MinMaxExpr *) minmaxExpr->xprstate.expr)->op; + MinMaxExpr *minmax = (MinMaxExpr *) minmaxExpr->xprstate.expr; + Oid collation = minmax->inputcollid; + MinMaxOp op = minmax->op; FunctionCallInfoData locfcinfo; ListCell *arg; @@ -3242,7 +3246,8 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext, *isDone = ExprSingleResult; *isNull = true; /* until we get a result */ - InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, NULL, NULL); + InitFunctionCallInfoData(locfcinfo, &minmaxExpr->cfunc, 2, + collation, NULL, NULL); locfcinfo.argnull[0] = false; locfcinfo.argnull[1] = false; @@ -4115,7 +4120,6 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate, /* Set up the primary fmgr lookup information */ fmgr_info_cxt(acoerce->elemfuncid, &(astate->elemfunc), econtext->ecxt_per_query_memory); - /* Note: coercion functions are assumed to not use collation */ fmgr_info_set_expr((Node *) acoerce, &(astate->elemfunc)); } @@ -4124,9 +4128,11 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate, * * We pass on the desttypmod and isExplicit flags whether or not the * function wants them. + * + * Note: coercion functions are assumed to not use collation. */ InitFunctionCallInfoData(locfcinfo, &(astate->elemfunc), 3, - NULL, NULL); + InvalidOid, NULL, NULL); locfcinfo.arg[0] = PointerGetDatum(array); locfcinfo.arg[1] = Int32GetDatum(acoerce->resulttypmod); locfcinfo.arg[2] = BoolGetDatum(acoerce->isExplicit); @@ -4699,6 +4705,7 @@ ExecInitExpr(Expr *node, PlanState *parent) rstate->rargs = outlist; Assert(list_length(rcexpr->opfamilies) == nopers); rstate->funcs = (FmgrInfo *) palloc(nopers * sizeof(FmgrInfo)); + rstate->collations = (Oid *) palloc(nopers * sizeof(Oid)); i = 0; forthree(l, rcexpr->opnos, l2, rcexpr->opfamilies, l3, rcexpr->inputcollids) { @@ -4726,7 +4733,7 @@ ExecInitExpr(Expr *node, PlanState *parent) * does this code. */ fmgr_info(proc, &(rstate->funcs[i])); - fmgr_info_set_collation(inputcollid, &(rstate->funcs[i])); + rstate->collations[i] = inputcollid; i++; } state = (ExprState *) rstate; @@ -4786,8 +4793,6 @@ ExecInitExpr(Expr *node, PlanState *parent) * code. */ fmgr_info(typentry->cmp_proc, &(mstate->cfunc)); - fmgr_info_set_collation(minmaxexpr->inputcollid, - &(mstate->cfunc)); state = (ExprState *) mstate; } break; diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 0cbbe04d3bd..073ef8d23b3 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -1349,9 +1349,10 @@ index_recheck_constraint(Relation index, Oid *constr_procs, if (existing_isnull[i]) return false; - if (!DatumGetBool(OidFunctionCall2(constr_procs[i], - existing_values[i], - new_values[i]))) + if (!DatumGetBool(OidFunctionCall2Coll(constr_procs[i], + index->rd_indcollation[i], + existing_values[i], + new_values[i]))) return false; } diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 9c867bbae20..13946cab23d 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -127,7 +127,7 @@ static Node *sql_fn_param_ref(ParseState *pstate, ParamRef *pref); static List *init_execution_state(List *queryTree_list, SQLFunctionCachePtr fcache, bool lazyEvalOK); -static void init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK); +static void init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK); static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache); static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache); static void postquel_end(execution_state *es); @@ -363,7 +363,7 @@ init_execution_state(List *queryTree_list, * Initialize the SQLFunctionCache for a SQL function */ static void -init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK) +init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK) { Oid foid = finfo->fn_oid; Oid rettype; @@ -428,7 +428,7 @@ init_sql_fcache(FmgrInfo *finfo, bool lazyEvalOK) */ fcache->pinfo = prepare_sql_fn_parse_info(procedureTuple, finfo->fn_expr, - finfo->fn_collation); + collation); /* * And of course we need the function body text. @@ -798,7 +798,7 @@ fmgr_sql(PG_FUNCTION_ARGS) fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra; if (fcache == NULL) { - init_sql_fcache(fcinfo->flinfo, lazyEvalOK); + init_sql_fcache(fcinfo->flinfo, PG_GET_COLLATION(), lazyEvalOK); fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra; } eslist = fcache->func_state; diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 47555bab55b..13d77234801 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -130,6 +130,9 @@ typedef struct AggStatePerAggData FmgrInfo transfn; FmgrInfo finalfn; + /* Input collation derived for aggregate */ + Oid aggCollation; + /* number of sorting columns */ int numSortCols; @@ -430,6 +433,7 @@ advance_transition_function(AggState *aggstate, */ InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn), numArguments + 1, + peraggstate->aggCollation, (void *) aggstate, NULL); fcinfo->arg[0] = pergroupstate->transValue; fcinfo->argnull[0] = pergroupstate->transValueIsNull; @@ -597,6 +601,8 @@ process_ordered_aggregate_single(AggState *aggstate, /* * If DISTINCT mode, and not distinct from prior, skip it. + * + * Note: we assume equality functions don't care about collation. */ if (isDistinct && haveOldVal && @@ -737,6 +743,7 @@ finalize_aggregate(AggState *aggstate, FunctionCallInfoData fcinfo; InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1, + peraggstate->aggCollation, (void *) aggstate, NULL); fcinfo.arg[0] = pergroupstate->transValue; fcinfo.argnull[0] = pergroupstate->transValueIsNull; @@ -1676,16 +1683,16 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) &finalfnexpr); fmgr_info(transfn_oid, &peraggstate->transfn); - fmgr_info_set_collation(aggref->inputcollid, &peraggstate->transfn); fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn); if (OidIsValid(finalfn_oid)) { fmgr_info(finalfn_oid, &peraggstate->finalfn); - fmgr_info_set_collation(aggref->inputcollid, &peraggstate->finalfn); fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn); } + peraggstate->aggCollation = aggref->inputcollid; + get_typlenbyval(aggref->aggtype, &peraggstate->resulttypeLen, &peraggstate->resulttypeByVal); @@ -1833,8 +1840,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc); fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]); - fmgr_info_set_collation(aggref->inputcollid, - &peraggstate->equalfns[i]); i++; } Assert(i == numDistinctCols); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index d8e59ca39e5..dbc1467d5be 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -973,7 +973,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Index scanrelid, this_scan_key->sk_flags = SK_ROW_HEADER; this_scan_key->sk_attno = first_sub_key->sk_attno; this_scan_key->sk_strategy = rc->rctype; - /* sk_subtype, sk_func not used in a header */ + /* sk_subtype, sk_collation, sk_func not used in a header */ this_scan_key->sk_argument = PointerGetDatum(first_sub_key); } else if (IsA(clause, ScalarArrayOpExpr)) diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 4ebe0cbe033..43059664b93 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -327,8 +327,9 @@ heap_compare_slots(MergeAppendState *node, SlotNumber slot1, SlotNumber slot2) } else { - compare = DatumGetInt32(FunctionCall2(&scankey->sk_func, - datum1, datum2)); + compare = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func, + scankey->sk_collation, + datum1, datum2)); if (compare != 0) { if (scankey->sk_flags & SK_BT_DESC) diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index d6245e61874..208c0fb76ac 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -138,11 +138,12 @@ typedef struct MergeJoinClauseData /* * The comparison strategy in use, and the lookup info to let us call the - * btree comparison support function. + * btree comparison support function, and the collation to use. */ bool reverse; /* if true, negate the cmpfn's output */ bool nulls_first; /* if true, nulls sort low */ FmgrInfo cmpfinfo; + Oid collation; } MergeJoinClauseData; /* Result type for MJEvalOuterValues and MJEvalInnerValues */ @@ -242,7 +243,6 @@ MJExamineQuals(List *mergeclauses, /* Set up the fmgr lookup information */ fmgr_info(cmpproc, &(clause->cmpfinfo)); - fmgr_info_set_collation(collation, &(clause->cmpfinfo)); /* Fill the additional comparison-strategy flags */ if (opstrategy == BTLessStrategyNumber) @@ -254,6 +254,9 @@ MJExamineQuals(List *mergeclauses, clause->nulls_first = nulls_first; + /* ... and the collation too */ + clause->collation = collation; + iClause++; } @@ -429,7 +432,7 @@ MJCompare(MergeJoinState *mergestate) * OK to call the comparison function. */ InitFunctionCallInfoData(fcinfo, &(clause->cmpfinfo), 2, - NULL, NULL); + clause->collation, NULL, NULL); fcinfo.arg[0] = clause->ldatum; fcinfo.arg[1] = clause->rdatum; fcinfo.argnull[0] = false; diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 08a3017e614..4fcb66bbb03 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -831,8 +831,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* Lookup the equality function (potentially cross-type) */ fmgr_info(opexpr->opfuncid, &sstate->cur_eq_funcs[i - 1]); - fmgr_info_set_collation(opexpr->inputcollid, - &sstate->cur_eq_funcs[i - 1]); fmgr_info_set_expr((Node *) opexpr, &sstate->cur_eq_funcs[i - 1]); /* Look up the equality function for the RHS type */ @@ -841,8 +839,6 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) elog(ERROR, "could not find compatible hash operator for operator %u", opexpr->opno); fmgr_info(get_opcode(rhs_eq_oper), &sstate->tab_eq_funcs[i - 1]); - fmgr_info_set_collation(opexpr->inputcollid, - &sstate->tab_eq_funcs[i - 1]); /* Lookup the associated hash functions */ if (!get_op_hash_functions(opexpr->opno, diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 25d9298cefc..c90d40506f9 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -81,6 +81,8 @@ typedef struct WindowStatePerFuncData FmgrInfo flinfo; /* fmgr lookup data for window function */ + Oid winCollation; /* collation derived for window function */ + /* * We need the len and byval info for the result of each function in order * to know how to copy/delete values. @@ -289,6 +291,7 @@ advance_windowaggregate(WindowAggState *winstate, */ InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn), numArguments + 1, + perfuncstate->winCollation, (void *) winstate, NULL); fcinfo->arg[0] = peraggstate->transValue; fcinfo->argnull[0] = peraggstate->transValueIsNull; @@ -340,6 +343,7 @@ finalize_windowaggregate(WindowAggState *winstate, FunctionCallInfoData fcinfo; InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1, + perfuncstate->winCollation, (void *) winstate, NULL); fcinfo.arg[0] = peraggstate->transValue; fcinfo.argnull[0] = peraggstate->transValueIsNull; @@ -627,6 +631,7 @@ eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, */ InitFunctionCallInfoData(fcinfo, &(perfuncstate->flinfo), perfuncstate->numArguments, + perfuncstate->winCollation, (void *) perfuncstate->winobj, NULL); /* Just in case, make all the regular argument slots be null */ memset(fcinfo.argnull, true, perfuncstate->numArguments); @@ -1561,9 +1566,10 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, econtext->ecxt_per_query_memory); - fmgr_info_set_collation(wfunc->inputcollid, &perfuncstate->flinfo); fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); + perfuncstate->winCollation = wfunc->inputcollid; + get_typlenbyval(wfunc->wintype, &perfuncstate->resulttypeLen, &perfuncstate->resulttypeByVal); @@ -1801,13 +1807,11 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, &finalfnexpr); fmgr_info(transfn_oid, &peraggstate->transfn); - fmgr_info_set_collation(wfunc->inputcollid, &peraggstate->transfn); fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn); if (OidIsValid(finalfn_oid)) { fmgr_info(finalfn_oid, &peraggstate->finalfn); - fmgr_info_set_collation(wfunc->inputcollid, &peraggstate->finalfn); fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn); } |