@@ -41,7 +41,8 @@ typedef struct RangeQueryClause
4141
4242static void addRangeClause (RangeQueryClause * * rqlist , Node * clause ,
4343 bool varonleft , bool isLTsel , Selectivity s2 );
44-
44+ static RelOptInfo * find_relation_from_clauses (PlannerInfo * root ,
45+ List * clauses );
4546
4647/****************************************************************************
4748 * ROUTINES TO COMPUTE SELECTIVITIES
@@ -101,14 +102,14 @@ clauselist_selectivity(PlannerInfo *root,
101102 List * clauses ,
102103 int varRelid ,
103104 JoinType jointype ,
104- SpecialJoinInfo * sjinfo ,
105- RelOptInfo * rel )
105+ SpecialJoinInfo * sjinfo )
106106{
107107 Selectivity s1 = 1.0 ;
108108 RangeQueryClause * rqlist = NULL ;
109109 ListCell * l ;
110110 Bitmapset * estimatedclauses = NULL ;
111111 int listidx ;
112+ RelOptInfo * rel ;
112113
113114 /*
114115 * If there's exactly one clause, then extended statistics is futile at
@@ -117,7 +118,14 @@ clauselist_selectivity(PlannerInfo *root,
117118 */
118119 if (list_length (clauses ) == 1 )
119120 return clause_selectivity (root , (Node * ) linitial (clauses ),
120- varRelid , jointype , sjinfo , rel );
121+ varRelid , jointype , sjinfo );
122+
123+ /*
124+ * Determine if these clauses reference a single relation. If so we might
125+ * like to try applying any extended statistics which exist on it.
126+ * Called many time during joins, so must return NULL quickly if not.
127+ */
128+ rel = find_relation_from_clauses (root , clauses );
121129
122130 /*
123131 * When a relation of RTE_RELATION is given as 'rel', we'll try to
@@ -164,7 +172,7 @@ clauselist_selectivity(PlannerInfo *root,
164172 continue ;
165173
166174 /* Always compute the selectivity using clause_selectivity */
167- s2 = clause_selectivity (root , clause , varRelid , jointype , sjinfo , rel );
175+ s2 = clause_selectivity (root , clause , varRelid , jointype , sjinfo );
168176
169177 /*
170178 * Check for being passed a RestrictInfo.
@@ -417,6 +425,39 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause,
417425 * rqlist = rqelem ;
418426}
419427
428+ /*
429+ * find_relation_from_clauses
430+ * Process each clause in 'clauses' and determine if all clauses
431+ * reference only a single relation. If so return that relation,
432+ * otherwise return NULL.
433+ */
434+ static RelOptInfo *
435+ find_relation_from_clauses (PlannerInfo * root , List * clauses )
436+ {
437+ ListCell * l ;
438+ int relid ;
439+ int lastrelid = 0 ;
440+
441+ foreach (l , clauses )
442+ {
443+ RestrictInfo * rinfo = (RestrictInfo * ) lfirst (l );
444+
445+ if (bms_get_singleton_member (rinfo -> clause_relids , & relid ))
446+ {
447+ if (lastrelid != 0 && relid != lastrelid )
448+ return NULL ; /* relation not the same as last one */
449+ lastrelid = relid ;
450+ }
451+ else
452+ return NULL ; /* multiple relations in clause */
453+ }
454+
455+ if (lastrelid != 0 )
456+ return find_base_rel (root , lastrelid );
457+
458+ return NULL ; /* no clauses */
459+ }
460+
420461/*
421462 * bms_is_subset_singleton
422463 *
@@ -529,8 +570,7 @@ clause_selectivity(PlannerInfo *root,
529570 Node * clause ,
530571 int varRelid ,
531572 JoinType jointype ,
532- SpecialJoinInfo * sjinfo ,
533- RelOptInfo * rel )
573+ SpecialJoinInfo * sjinfo )
534574{
535575 Selectivity s1 = 0.5 ; /* default for any unhandled clause type */
536576 RestrictInfo * rinfo = NULL ;
@@ -650,8 +690,7 @@ clause_selectivity(PlannerInfo *root,
650690 (Node * ) get_notclausearg ((Expr * ) clause ),
651691 varRelid ,
652692 jointype ,
653- sjinfo ,
654- rel );
693+ sjinfo );
655694 }
656695 else if (and_clause (clause ))
657696 {
@@ -660,8 +699,7 @@ clause_selectivity(PlannerInfo *root,
660699 ((BoolExpr * ) clause )-> args ,
661700 varRelid ,
662701 jointype ,
663- sjinfo ,
664- rel );
702+ sjinfo );
665703 }
666704 else if (or_clause (clause ))
667705 {
@@ -680,8 +718,7 @@ clause_selectivity(PlannerInfo *root,
680718 (Node * ) lfirst (arg ),
681719 varRelid ,
682720 jointype ,
683- sjinfo ,
684- rel );
721+ sjinfo );
685722
686723 s1 = s1 + s2 - s1 * s2 ;
687724 }
@@ -774,8 +811,7 @@ clause_selectivity(PlannerInfo *root,
774811 (Node * ) ((RelabelType * ) clause )-> arg ,
775812 varRelid ,
776813 jointype ,
777- sjinfo ,
778- rel );
814+ sjinfo );
779815 }
780816 else if (IsA (clause , CoerceToDomain ))
781817 {
@@ -784,8 +820,7 @@ clause_selectivity(PlannerInfo *root,
784820 (Node * ) ((CoerceToDomain * ) clause )-> arg ,
785821 varRelid ,
786822 jointype ,
787- sjinfo ,
788- rel );
823+ sjinfo );
789824 }
790825 else
791826 {
0 commit comments