From 26ea36f62cc30ffb44524e8bfa703ae28d2fef76 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@2ndquadrant.com>
Date: Thu, 12 Nov 2020 02:53:45 +0100
Subject: [PATCH 2/4] WIP: don't use extended statistics twice

---
 src/backend/optimizer/path/clausesel.c | 112 ++++++++++++++++++-------
 1 file changed, 80 insertions(+), 32 deletions(-)

diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index bbe9591aff..215c5db9fd 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -45,6 +45,22 @@ static void addRangeClause(RangeQueryClause **rqlist, Node *clause,
 static RelOptInfo *find_single_rel_for_clauses(PlannerInfo *root,
 											   List *clauses);
 
+static Selectivity
+clause_selectivity_internal(PlannerInfo *root,
+							Node *clause,
+							int varRelid,
+							JoinType jointype,
+							SpecialJoinInfo *sjinfo,
+							bool use_extended_stats);
+
+static Selectivity
+clauselist_selectivity_internal(PlannerInfo *root,
+								List *clauses,
+								int varRelid,
+								JoinType jointype,
+								SpecialJoinInfo *sjinfo,
+								bool use_extended_stats);
+
 /****************************************************************************
  *		ROUTINES TO COMPUTE SELECTIVITIES
  ****************************************************************************/
@@ -71,6 +87,18 @@ clauselist_selectivity(PlannerInfo *root,
 					   int varRelid,
 					   JoinType jointype,
 					   SpecialJoinInfo *sjinfo)
+{
+	return clauselist_selectivity_internal(root, clauses, varRelid,
+										   jointype, sjinfo, true);
+}
+
+static Selectivity
+clauselist_selectivity_internal(PlannerInfo *root,
+								List *clauses,
+								int varRelid,
+								JoinType jointype,
+								SpecialJoinInfo *sjinfo,
+								bool use_extended_stats)
 {
 	Selectivity s1 = 1.0;
 	RelOptInfo *rel;
@@ -81,7 +109,7 @@ clauselist_selectivity(PlannerInfo *root,
 	 * it has extended statistics, try to apply those.
 	 */
 	rel = find_single_rel_for_clauses(root, clauses);
-	if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
+	if (use_extended_stats && rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
 	{
 		/*
 		 * Estimate as many clauses as possible using extended statistics.
@@ -126,7 +154,8 @@ clauselist_selectivity_or(PlannerInfo *root,
 						  List *clauses,
 						  int varRelid,
 						  JoinType jointype,
-						  SpecialJoinInfo *sjinfo)
+						  SpecialJoinInfo *sjinfo,
+						  bool use_extended_stats)
 {
 	Selectivity	s = 0.0;
 	RelOptInfo *rel;
@@ -137,7 +166,7 @@ clauselist_selectivity_or(PlannerInfo *root,
 	 * it has extended statistics, try to apply those.
 	 */
 	rel = find_single_rel_for_clauses(root, clauses);
-	if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
+	if (use_extended_stats && rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL)
 	{
 		/*
 		 * Estimate as many clauses as possible using extended statistics.
@@ -221,8 +250,8 @@ clauselist_selectivity_simple(PlannerInfo *root,
 	 * relevant.
 	 */
 	if (list_length(clauses) == 1 && bms_is_empty(estimatedclauses))
-		return clause_selectivity(root, (Node *) linitial(clauses),
-								  varRelid, jointype, sjinfo);
+		return clause_selectivity_internal(root, (Node *) linitial(clauses),
+										   varRelid, jointype, sjinfo, false);
 
 	/*
 	 * Anything that doesn't look like a potential rangequery clause gets
@@ -246,7 +275,8 @@ clauselist_selectivity_simple(PlannerInfo *root,
 			continue;
 
 		/* Always compute the selectivity using clause_selectivity */
-		s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo);
+		s2 = clause_selectivity_internal(root, clause, varRelid,
+										 jointype, sjinfo, false);
 
 		/*
 		 * Check for being passed a RestrictInfo.
@@ -453,11 +483,12 @@ clauselist_selectivity_simple_or(PlannerInfo *root,
 		if (bms_is_member(listidx, estimatedclauses))
 			continue;
 
-		s2 = clause_selectivity(root,
-								(Node *) lfirst(lc),
-								varRelid,
-								jointype,
-								sjinfo);
+		s2 = clause_selectivity_internal(root,
+										 (Node *) lfirst(lc),
+										 varRelid,
+										 jointype,
+										 sjinfo,
+										 false);
 
 		s = s + s2 - s * s2;
 	}
@@ -716,6 +747,18 @@ clause_selectivity(PlannerInfo *root,
 				   int varRelid,
 				   JoinType jointype,
 				   SpecialJoinInfo *sjinfo)
+{
+	return clause_selectivity_internal(root, clause, varRelid,
+									   jointype, sjinfo, true);
+}
+
+static Selectivity
+clause_selectivity_internal(PlannerInfo *root,
+							Node *clause,
+							int varRelid,
+							JoinType jointype,
+							SpecialJoinInfo *sjinfo,
+							bool use_extended_stats)
 {
 	Selectivity s1 = 0.5;		/* default for any unhandled clause type */
 	RestrictInfo *rinfo = NULL;
@@ -831,20 +874,22 @@ clause_selectivity(PlannerInfo *root,
 	else if (is_notclause(clause))
 	{
 		/* inverse of the selectivity of the underlying clause */
-		s1 = 1.0 - clause_selectivity(root,
-									  (Node *) get_notclausearg((Expr *) clause),
-									  varRelid,
-									  jointype,
-									  sjinfo);
+		s1 = 1.0 - clause_selectivity_internal(root,
+											   (Node *) get_notclausearg((Expr *) clause),
+											   varRelid,
+											   jointype,
+											   sjinfo,
+											   use_extended_stats);
 	}
 	else if (is_andclause(clause))
 	{
 		/* share code with clauselist_selectivity() */
-		s1 = clauselist_selectivity(root,
-									((BoolExpr *) clause)->args,
-									varRelid,
-									jointype,
-									sjinfo);
+		s1 = clauselist_selectivity_internal(root,
+											 ((BoolExpr *) clause)->args,
+											 varRelid,
+											 jointype,
+											 sjinfo,
+											 use_extended_stats);
 	}
 	else if (is_orclause(clause))
 	{
@@ -856,7 +901,8 @@ clause_selectivity(PlannerInfo *root,
 									   ((BoolExpr *) clause)->args,
 									   varRelid,
 									   jointype,
-									   sjinfo);
+									   sjinfo,
+									   use_extended_stats);
 	}
 	else if (is_opclause(clause) || IsA(clause, DistinctExpr))
 	{
@@ -957,20 +1003,22 @@ clause_selectivity(PlannerInfo *root,
 	else if (IsA(clause, RelabelType))
 	{
 		/* Not sure this case is needed, but it can't hurt */
-		s1 = clause_selectivity(root,
-								(Node *) ((RelabelType *) clause)->arg,
-								varRelid,
-								jointype,
-								sjinfo);
+		s1 = clause_selectivity_internal(root,
+										 (Node *) ((RelabelType *) clause)->arg,
+										 varRelid,
+										 jointype,
+										 sjinfo,
+										 use_extended_stats);
 	}
 	else if (IsA(clause, CoerceToDomain))
 	{
 		/* Not sure this case is needed, but it can't hurt */
-		s1 = clause_selectivity(root,
-								(Node *) ((CoerceToDomain *) clause)->arg,
-								varRelid,
-								jointype,
-								sjinfo);
+		s1 = clause_selectivity_internal(root,
+										 (Node *) ((CoerceToDomain *) clause)->arg,
+										 varRelid,
+										 jointype,
+										 sjinfo,
+										 use_extended_stats);
 	}
 	else
 	{
-- 
2.26.2

