From 29b57d6f7ce027cd327d0b0708b3597a6dde2851 Mon Sep 17 00:00:00 2001 From: "ZizhuanLiu(X-MAN)" <44973863@qq.com> Date: Wed, 19 Aug 2026 14:21:02 +0800 Subject: [PATCH v3] Fix var_eq_const: sum selectivity of all matching MCV When the column statistics have deterministic collation and the constant has non-deterministic collation. discussion: https://www.postgresql.org/message-id/flat/tencent_A15A9D89A86F2E4B086ABA462578B9B64307@qq.com commitfest: https://commitfest.postgresql.org/patch/7075/ --- src/backend/utils/adt/selfuncs.c | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index e27ec9e..fae28f6 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -413,6 +413,7 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, AttStatsSlot sslot; bool match = false; int i; + double sumcommon = 0.0; /* * Is the constant "=" to any of the column's most common values? @@ -427,6 +428,9 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, { LOCAL_FCINFO(fcinfo, 2); FmgrInfo eqproc; + pg_locale_t sta_locale = 0; + pg_locale_t const_locale = 0; + bool scan_all_values = false; fmgr_info(opfuncoid, &eqproc); @@ -446,6 +450,11 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, else fcinfo->args[0].value = constval; + sta_locale = pg_newlocale_from_collation(sslot.stacoll); + const_locale = pg_newlocale_from_collation(collation); + scan_all_values = (!const_locale->deterministic && sta_locale->deterministic); + selec = 0.0; + for (i = 0; i < sslot.nvalues; i++) { Datum fresult; @@ -459,8 +468,21 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, if (!fcinfo->isnull && DatumGetBool(fresult)) { match = true; - break; + if (scan_all_values == false) + { + selec = sslot.numbers[i]; + break; + } + else + /* + * When the column statistics have deterministic collation while + * the constant has non-deterministic collation, scan all statistical + * entries and accumulate selectivity for matching items. + */ + selec += sslot.numbers[i]; } + + sumcommon += sslot.numbers[i]; } } else @@ -469,26 +491,15 @@ var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, i = 0; /* keep compiler quiet */ } - if (match) - { - /* - * Constant is "=" to this common value. We know selectivity - * exactly (or as exactly as ANALYZE could calculate it, anyway). - */ - selec = sslot.numbers[i]; - } - else + if (match == false) { /* * Comparison is against a constant that is neither NULL nor any * of the common values. Its selectivity cannot be more than * this: */ - double sumcommon = 0.0; double otherdistinct; - for (i = 0; i < sslot.nnumbers; i++) - sumcommon += sslot.numbers[i]; selec = 1.0 - sumcommon - nullfrac; CLAMP_PROBABILITY(selec); -- 2.43.0