From fc369280662c9183ccc50ac4ded144acadd84c15 Mon Sep 17 00:00:00 2001
From: Enrique Sanchez Cardoso <enriqueesanchz@gmail.com>
Date: Sun, 24 May 2026 14:40:39 +0200
Subject: [PATCH 3/4] Extend multicolumn MCV cap to partial IN/ANY matches

---
 src/backend/statistics/extended_stats.c |  5 +----
 src/backend/statistics/mcv.c            | 17 ++++++++++-------
 src/test/regress/expected/stats_ext.out |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index f8c38653bf9..da6f6315698 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -2016,10 +2016,7 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli
 												 mcv_basesel,
 												 mcv_totalsel);
 
-			/*
-			 * Cap to the least common MCV frequency when no MCV items
-			 * matched.
-			 */
+			/* Cap the contribution of values not found in the MCV. */
 			if (stat_sel > mcv_cap)
 				stat_sel = mcv_cap;
 
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 2e75f19d8bd..62761c58e33 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -1526,8 +1526,8 @@ pg_mcv_list_send(PG_FUNCTION_ARGS)
 
 /*
  * mcv_cap_multiplier
- *		Compute a multiplier for capping combined selectivity to the least
- *		common MCV frequency when no MCV items matched.
+ * 		Compute a multiplier for capping combined selectivity to the least
+ * 		common MCV frequency.
  *
  * Returns 0 if the cap should not be applied (unsupported clause types).
  * Returns >= 1 as the number of distinct value combinations the clauses
@@ -2105,6 +2105,7 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat,
 						   Selectivity *cap)
 {
 	int			i;
+	int64		matched_count = 0;
 	MCVList    *mcv;
 	Selectivity s = 0.0;
 	RangeTblEntry *rte = root->simple_rte_array[rel->relid];
@@ -2133,22 +2134,24 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat,
 		{
 			*basesel += mcv->items[i].base_frequency;
 			s += mcv->items[i].frequency;
+			matched_count++;
 		}
 	}
 
 	/*
-	 * When no MCV item matched and there is one equality clause per MCV
-	 * dimension, cap the selectivity to the least common MCV frequency. The
+	 * When there is one equality/IN clause per MCV dimension, cap the
+	 * contribution of value combinations not found in the MCV.  Each such
 	 * combination is not among the most common, so it can't be more frequent
 	 * than the least common tracked combination.
 	 */
-	if (s == 0.0 && mcv->ndimensions == list_length(clauses))
+	if (mcv->ndimensions == list_length(clauses))
 	{
 		int64		cap_mult = mcv_cap_multiplier(clauses);
+		int64		non_mcv_mult = cap_mult - matched_count;
 
-		if (cap_mult > 0)
+		if (non_mcv_mult > 0)
 		{
-			*cap = cap_mult * mcv->items[mcv->nitems - 1].frequency;
+			*cap = s + non_mcv_mult * mcv->items[mcv->nitems - 1].frequency;
 			CLAMP_PROBABILITY(*cap);
 		}
 	}
diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out
index 82ad9edb568..7ea244f7851 100644
--- a/src/test/regress/expected/stats_ext.out
+++ b/src/test/regress/expected/stats_ext.out
@@ -2969,7 +2969,7 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_cap WHERE a = 0 AND b = 0'
 SELECT * FROM check_estimated_rows('SELECT * FROM mcv_cap WHERE a = 0 AND b IN (0, 99)');
  estimated | actual 
 -----------+--------
-      5050 |    100
+       200 |    100
 (1 row)
 
 -- no MCV match
-- 
2.43.0

