@@ -41,7 +41,8 @@ typedef struct RangeQueryClause
41
41
42
42
static void addRangeClause (RangeQueryClause * * rqlist , Node * clause ,
43
43
bool varonleft , bool isLTsel , Selectivity s2 );
44
-
44
+ static RelOptInfo * find_relation_from_clauses (PlannerInfo * root ,
45
+ List * clauses );
45
46
46
47
/****************************************************************************
47
48
* ROUTINES TO COMPUTE SELECTIVITIES
@@ -101,14 +102,14 @@ clauselist_selectivity(PlannerInfo *root,
101
102
List * clauses ,
102
103
int varRelid ,
103
104
JoinType jointype ,
104
- SpecialJoinInfo * sjinfo ,
105
- RelOptInfo * rel )
105
+ SpecialJoinInfo * sjinfo )
106
106
{
107
107
Selectivity s1 = 1.0 ;
108
108
RangeQueryClause * rqlist = NULL ;
109
109
ListCell * l ;
110
110
Bitmapset * estimatedclauses = NULL ;
111
111
int listidx ;
112
+ RelOptInfo * rel ;
112
113
113
114
/*
114
115
* If there's exactly one clause, then extended statistics is futile at
@@ -117,7 +118,14 @@ clauselist_selectivity(PlannerInfo *root,
117
118
*/
118
119
if (list_length (clauses ) == 1 )
119
120
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 );
121
129
122
130
/*
123
131
* When a relation of RTE_RELATION is given as 'rel', we'll try to
@@ -164,7 +172,7 @@ clauselist_selectivity(PlannerInfo *root,
164
172
continue ;
165
173
166
174
/* 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 );
168
176
169
177
/*
170
178
* Check for being passed a RestrictInfo.
@@ -417,6 +425,39 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause,
417
425
* rqlist = rqelem ;
418
426
}
419
427
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
+
420
461
/*
421
462
* bms_is_subset_singleton
422
463
*
@@ -529,8 +570,7 @@ clause_selectivity(PlannerInfo *root,
529
570
Node * clause ,
530
571
int varRelid ,
531
572
JoinType jointype ,
532
- SpecialJoinInfo * sjinfo ,
533
- RelOptInfo * rel )
573
+ SpecialJoinInfo * sjinfo )
534
574
{
535
575
Selectivity s1 = 0.5 ; /* default for any unhandled clause type */
536
576
RestrictInfo * rinfo = NULL ;
@@ -650,8 +690,7 @@ clause_selectivity(PlannerInfo *root,
650
690
(Node * ) get_notclausearg ((Expr * ) clause ),
651
691
varRelid ,
652
692
jointype ,
653
- sjinfo ,
654
- rel );
693
+ sjinfo );
655
694
}
656
695
else if (and_clause (clause ))
657
696
{
@@ -660,8 +699,7 @@ clause_selectivity(PlannerInfo *root,
660
699
((BoolExpr * ) clause )-> args ,
661
700
varRelid ,
662
701
jointype ,
663
- sjinfo ,
664
- rel );
702
+ sjinfo );
665
703
}
666
704
else if (or_clause (clause ))
667
705
{
@@ -680,8 +718,7 @@ clause_selectivity(PlannerInfo *root,
680
718
(Node * ) lfirst (arg ),
681
719
varRelid ,
682
720
jointype ,
683
- sjinfo ,
684
- rel );
721
+ sjinfo );
685
722
686
723
s1 = s1 + s2 - s1 * s2 ;
687
724
}
@@ -774,8 +811,7 @@ clause_selectivity(PlannerInfo *root,
774
811
(Node * ) ((RelabelType * ) clause )-> arg ,
775
812
varRelid ,
776
813
jointype ,
777
- sjinfo ,
778
- rel );
814
+ sjinfo );
779
815
}
780
816
else if (IsA (clause , CoerceToDomain ))
781
817
{
@@ -784,8 +820,7 @@ clause_selectivity(PlannerInfo *root,
784
820
(Node * ) ((CoerceToDomain * ) clause )-> arg ,
785
821
varRelid ,
786
822
jointype ,
787
- sjinfo ,
788
- rel );
823
+ sjinfo );
789
824
}
790
825
else
791
826
{
0 commit comments