aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/clausesel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/clausesel.c')
-rw-r--r--src/backend/optimizer/path/clausesel.c123
1 files changed, 39 insertions, 84 deletions
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 2699b56cb37..78407fb833a 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -8,13 +8,15 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.43 2001/03/23 04:49:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.44 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/pg_operator.h"
+#include "catalog/pg_type.h"
+#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/plancat.h"
@@ -24,6 +26,12 @@
#include "utils/lsyscache.h"
+/* note that pg_type.h hardwires size of bool as 1 ... duplicate it */
+#define MAKEBOOLCONST(val,isnull) \
+ ((Node *) makeConst(BOOLOID, 1, (Datum) (val), \
+ (isnull), true, false, false))
+
+
/*
* Data structure for accumulating info about possible range-query
* clause pairs in clauselist_selectivity.
@@ -39,7 +47,7 @@ typedef struct RangeQueryClause
} RangeQueryClause;
static void addRangeClause(RangeQueryClause **rqlist, Node *clause,
- int flag, bool isLTsel, Selectivity s2);
+ bool varonleft, bool isLTsel, Selectivity s2);
static Selectivity clause_selectivity(Query *root,
Node *clause,
int varRelid);
@@ -131,35 +139,24 @@ clauselist_selectivity(Query *root,
* match what clause_selectivity() would do in the cases it
* handles.
*/
- if (varRelid != 0 || NumRelids(clause) == 1)
+ if (is_opclause(clause) &&
+ (varRelid != 0 || NumRelids(clause) == 1))
{
- int relidx;
- AttrNumber attno;
- Datum constval;
- int flag;
-
- get_relattval(clause, varRelid,
- &relidx, &attno, &constval, &flag);
- if (relidx != 0)
+ Expr *expr = (Expr *) clause;
+
+ if (length(expr->args) == 2)
{
- /* if get_relattval succeeded, it must be an opclause */
- Var *other;
+ bool varonleft = true;
- other = (flag & SEL_RIGHT) ? get_rightop((Expr *) clause) :
- get_leftop((Expr *) clause);
- if (is_pseudo_constant_clause((Node *) other))
+ if (is_pseudo_constant_clause(lsecond(expr->args)) ||
+ (varonleft = false,
+ is_pseudo_constant_clause(lfirst(expr->args))))
{
- Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
+ Oid opno = ((Oper *) expr->oper)->opno;
RegProcedure oprrest = get_oprrest(opno);
- if (!oprrest)
- s2 = (Selectivity) 0.5;
- else
- s2 = restriction_selectivity(oprrest, opno,
- getrelid(relidx,
- root->rtable),
- attno,
- constval, flag);
+ s2 = restriction_selectivity(root, opno,
+ expr->args, varRelid);
/*
* If we reach here, we have computed the same result
@@ -171,10 +168,12 @@ clauselist_selectivity(Query *root,
switch (oprrest)
{
case F_SCALARLTSEL:
- addRangeClause(&rqlist, clause, flag, true, s2);
+ addRangeClause(&rqlist, clause,
+ varonleft, true, s2);
break;
case F_SCALARGTSEL:
- addRangeClause(&rqlist, clause, flag, false, s2);
+ addRangeClause(&rqlist, clause,
+ varonleft, false, s2);
break;
default:
/* Just merge the selectivity in generically */
@@ -220,7 +219,7 @@ clauselist_selectivity(Query *root,
* No data available --- use a default estimate that
* is small, but not real small.
*/
- s2 = 0.01;
+ s2 = 0.005;
}
else
{
@@ -259,14 +258,13 @@ clauselist_selectivity(Query *root,
*/
static void
addRangeClause(RangeQueryClause **rqlist, Node *clause,
- int flag, bool isLTsel, Selectivity s2)
+ bool varonleft, bool isLTsel, Selectivity s2)
{
RangeQueryClause *rqelem;
Node *var;
bool is_lobound;
- /* get_relattval sets flag&SEL_RIGHT if the var is on the LEFT. */
- if (flag & SEL_RIGHT)
+ if (varonleft)
{
var = (Node *) get_leftop((Expr *) clause);
is_lobound = !isLTsel; /* x < something is high bound */
@@ -405,12 +403,12 @@ clause_selectivity(Query *root,
* is equivalent to the clause reln.attribute = 't', so we
* compute the selectivity as if that is what we have.
*/
- s1 = restriction_selectivity(F_EQSEL,
+ s1 = restriction_selectivity(root,
BooleanEqualOperator,
- rte->relid,
- var->varattno,
- BoolGetDatum(true),
- SEL_CONSTANT | SEL_RIGHT);
+ makeList2(var,
+ MAKEBOOLCONST(true,
+ false)),
+ varRelid);
}
}
}
@@ -486,57 +484,14 @@ clause_selectivity(Query *root,
if (is_join_clause)
{
/* Estimate selectivity for a join clause. */
- RegProcedure oprjoin = get_oprjoin(opno);
-
- /*
- * if the oprjoin procedure is missing for whatever reason,
- * use a selectivity of 0.5
- */
- if (!oprjoin)
- s1 = (Selectivity) 0.5;
- else
- {
- int relid1,
- relid2;
- AttrNumber attno1,
- attno2;
- Oid reloid1,
- reloid2;
-
- get_rels_atts(clause, &relid1, &attno1, &relid2, &attno2);
- reloid1 = relid1 ? getrelid(relid1, root->rtable) : InvalidOid;
- reloid2 = relid2 ? getrelid(relid2, root->rtable) : InvalidOid;
- s1 = join_selectivity(oprjoin, opno,
- reloid1, attno1,
- reloid2, attno2);
- }
+ s1 = join_selectivity(root, opno,
+ ((Expr *) clause)->args);
}
else
{
/* Estimate selectivity for a restriction clause. */
- RegProcedure oprrest = get_oprrest(opno);
-
- /*
- * if the oprrest procedure is missing for whatever reason,
- * use a selectivity of 0.5
- */
- if (!oprrest)
- s1 = (Selectivity) 0.5;
- else
- {
- int relidx;
- AttrNumber attno;
- Datum constval;
- int flag;
- Oid reloid;
-
- get_relattval(clause, varRelid,
- &relidx, &attno, &constval, &flag);
- reloid = relidx ? getrelid(relidx, root->rtable) : InvalidOid;
- s1 = restriction_selectivity(oprrest, opno,
- reloid, attno,
- constval, flag);
- }
+ s1 = restriction_selectivity(root, opno,
+ ((Expr *) clause)->args, varRelid);
}
}
else if (is_funcclause(clause))
@@ -555,7 +510,7 @@ clause_selectivity(Query *root,
/*
* Just for the moment! FIX ME! - vadim 02/04/98
*/
- s1 = 1.0;
+ s1 = (Selectivity) 0.5;
}
else if (IsA(clause, RelabelType))
{