diff options
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 96 |
1 files changed, 59 insertions, 37 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 95e46276f0a..dc38034104e 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -83,6 +83,15 @@ * joins, however, the selectivity is defined as the fraction of the left-hand * side relation's rows that are expected to have a match (ie, at least one * row with a TRUE result) in the right-hand side. + * + * For both oprrest and oprjoin functions, the operator's input collation OID + * (if any) is passed using the standard fmgr mechanism, so that the estimator + * function can fetch it with PG_GET_COLLATION(). Note, however, that all + * statistics in pg_statistic are currently built using the database's default + * collation. Thus, in most cases where we are looking at statistics, we + * should ignore the actual operator collation and use DEFAULT_COLLATION_OID. + * We expect that the error induced by doing this is usually not large enough + * to justify complicating matters. *---------- */ @@ -1097,6 +1106,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) Oid operator = PG_GETARG_OID(1); List *args = (List *) PG_GETARG_POINTER(2); int varRelid = PG_GETARG_INT32(3); + Oid collation = PG_GET_COLLATION(); VariableStatData vardata; Node *other; bool varonleft; @@ -1197,12 +1207,15 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) } /* - * Divide pattern into fixed prefix and remainder. XXX we have to assume - * default collation here, because we don't have access to the actual - * input collation for the operator. FIXME ... + * Divide pattern into fixed prefix and remainder. Unlike many of the + * other functions in this file, we use the pattern operator's actual + * collation for this step. This is not because we expect the collation + * to make a big difference in the selectivity estimate (it seldom would), + * but because we want to be sure we cache compiled regexps under the + * right cache key, so that they can be re-used at runtime. */ patt = (Const *) other; - pstatus = pattern_fixed_prefix(patt, ptype, DEFAULT_COLLATION_OID, + pstatus = pattern_fixed_prefix(patt, ptype, collation, &prefix, &rest); /* @@ -1847,18 +1860,20 @@ scalararraysel(PlannerInfo *root, elem_nulls[i], elmbyval)); if (is_join_clause) - s2 = DatumGetFloat8(FunctionCall5(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int16GetDatum(jointype), - PointerGetDatum(sjinfo))); + s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int16GetDatum(jointype), + PointerGetDatum(sjinfo))); else - s2 = DatumGetFloat8(FunctionCall4(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int32GetDatum(varRelid))); + s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int32GetDatum(varRelid))); if (useOr) { @@ -1912,18 +1927,20 @@ scalararraysel(PlannerInfo *root, */ args = list_make2(leftop, elem); if (is_join_clause) - s2 = DatumGetFloat8(FunctionCall5(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int16GetDatum(jointype), - PointerGetDatum(sjinfo))); + s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int16GetDatum(jointype), + PointerGetDatum(sjinfo))); else - s2 = DatumGetFloat8(FunctionCall4(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int32GetDatum(varRelid))); + s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int32GetDatum(varRelid))); if (useOr) { @@ -1962,18 +1979,20 @@ scalararraysel(PlannerInfo *root, dummyexpr->collation = clause->inputcollid; args = list_make2(leftop, dummyexpr); if (is_join_clause) - s2 = DatumGetFloat8(FunctionCall5(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int16GetDatum(jointype), - PointerGetDatum(sjinfo))); + s2 = DatumGetFloat8(FunctionCall5Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int16GetDatum(jointype), + PointerGetDatum(sjinfo))); else - s2 = DatumGetFloat8(FunctionCall4(&oprselproc, - PointerGetDatum(root), - ObjectIdGetDatum(operator), - PointerGetDatum(args), - Int32GetDatum(varRelid))); + s2 = DatumGetFloat8(FunctionCall4Coll(&oprselproc, + clause->inputcollid, + PointerGetDatum(root), + ObjectIdGetDatum(operator), + PointerGetDatum(args), + Int32GetDatum(varRelid))); s1 = useOr ? 0.0 : 1.0; /* @@ -2046,6 +2065,7 @@ rowcomparesel(PlannerInfo *root, { Selectivity s1; Oid opno = linitial_oid(clause->opnos); + Oid inputcollid = linitial_oid(clause->inputcollids); List *opargs; bool is_join_clause; @@ -2086,6 +2106,7 @@ rowcomparesel(PlannerInfo *root, /* Estimate selectivity for a join clause. */ s1 = join_selectivity(root, opno, opargs, + inputcollid, jointype, sjinfo); } @@ -2094,6 +2115,7 @@ rowcomparesel(PlannerInfo *root, /* Estimate selectivity for a restriction clause. */ s1 = restriction_selectivity(root, opno, opargs, + inputcollid, varRelid); } |