Skip to content

Commit cbf5031

Browse files
committed
Tweak recognition of range-clause pairs so that 'var > $1 AND var < $2'
(ie, parameters instead of consts) will be treated as a range query. We do not know the actual selectivities involved, but it seems like a good idea to use a smaller estimate than we would use for two unrelated inequalities.
1 parent 6a68f42 commit cbf5031

File tree

1 file changed

+46
-37
lines changed

1 file changed

+46
-37
lines changed

src/backend/optimizer/path/clausesel.c

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.36 2000/05/30 00:49:46 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.37 2000/05/31 15:38:53 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -95,7 +95,7 @@ restrictlist_selectivity(Query *root,
9595
* directly as a 0..1 value but we need to convert losel to 1-losel before
9696
* interpreting it as a value. Then the available range is 1-losel to hisel.)
9797
* If the calculation yields zero or negative, however, we chicken out and
98-
* use the default interpretation; that probably means that one or both
98+
* use a default estimate; that probably means that one or both
9999
* selectivities is a default estimate rather than an actual range value.
100100
* Of course this is all very dependent on the behavior of
101101
* scalarltsel/scalargtsel; perhaps some day we can generalize the approach.
@@ -120,10 +120,12 @@ clauselist_selectivity(Query *root,
120120
Selectivity s2;
121121

122122
/*
123-
* See if it looks like a restriction clause with a constant. (If
124-
* it's not a constant we can't really trust the selectivity!) NB:
125-
* for consistency of results, this fragment of code had better
126-
* match what clause_selectivity() would do.
123+
* See if it looks like a restriction clause with a Const or Param
124+
* on one side. (Anything more complicated than that might not
125+
* behave in the simple way we are expecting.)
126+
*
127+
* NB: for consistency of results, this fragment of code had better
128+
* match what clause_selectivity() would do in the cases it handles.
127129
*/
128130
if (varRelid != 0 || NumRelids(clause) == 1)
129131
{
@@ -134,41 +136,48 @@ clauselist_selectivity(Query *root,
134136

135137
get_relattval(clause, varRelid,
136138
&relidx, &attno, &constval, &flag);
137-
if (relidx != 0 && (flag & SEL_CONSTANT))
139+
if (relidx != 0)
138140
{
139141
/* if get_relattval succeeded, it must be an opclause */
140-
Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
141-
RegProcedure oprrest = get_oprrest(opno);
142+
Var *other;
142143

143-
if (!oprrest)
144-
s2 = (Selectivity) 0.5;
145-
else
146-
s2 = restriction_selectivity(oprrest, opno,
147-
getrelid(relidx,
148-
root->rtable),
149-
attno,
150-
constval, flag);
151-
152-
/*
153-
* If we reach here, we have computed the same result that
154-
* clause_selectivity would, so we can just use s2 if it's
155-
* the wrong oprrest. But if it's the right oprrest, add
156-
* the clause to rqlist for later processing.
157-
*/
158-
switch (oprrest)
144+
other = (flag & SEL_RIGHT) ? get_rightop((Expr *) clause) :
145+
get_leftop((Expr *) clause);
146+
if (IsA(other, Const) || IsA(other, Param))
159147
{
160-
case F_SCALARLTSEL:
161-
addRangeClause(&rqlist, clause, flag, true, s2);
162-
break;
163-
case F_SCALARGTSEL:
164-
addRangeClause(&rqlist, clause, flag, false, s2);
165-
break;
166-
default:
167-
/* Just merge the selectivity in generically */
168-
s1 = s1 * s2;
169-
break;
148+
Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
149+
RegProcedure oprrest = get_oprrest(opno);
150+
151+
if (!oprrest)
152+
s2 = (Selectivity) 0.5;
153+
else
154+
s2 = restriction_selectivity(oprrest, opno,
155+
getrelid(relidx,
156+
root->rtable),
157+
attno,
158+
constval, flag);
159+
160+
/*
161+
* If we reach here, we have computed the same result that
162+
* clause_selectivity would, so we can just use s2 if it's
163+
* the wrong oprrest. But if it's the right oprrest, add
164+
* the clause to rqlist for later processing.
165+
*/
166+
switch (oprrest)
167+
{
168+
case F_SCALARLTSEL:
169+
addRangeClause(&rqlist, clause, flag, true, s2);
170+
break;
171+
case F_SCALARGTSEL:
172+
addRangeClause(&rqlist, clause, flag, false, s2);
173+
break;
174+
default:
175+
/* Just merge the selectivity in generically */
176+
s1 = s1 * s2;
177+
break;
178+
}
179+
continue; /* drop to loop bottom */
170180
}
171-
continue; /* drop to loop bottom */
172181
}
173182
}
174183
/* Not the right form, so treat it generically. */
@@ -374,7 +383,7 @@ clause_selectivity(Query *root,
374383
BooleanEqualOperator,
375384
getrelid(varno, root->rtable),
376385
((Var *) clause)->varattno,
377-
Int8GetDatum(true),
386+
BoolGetDatum(true),
378387
SEL_CONSTANT | SEL_RIGHT);
379388
/* an outer-relation bool var is taken as always true... */
380389
}

0 commit comments

Comments
 (0)