aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/orindxpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/orindxpath.c')
-rw-r--r--src/backend/optimizer/path/orindxpath.c430
1 files changed, 228 insertions, 202 deletions
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index e040675e6ec..96408b78905 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* orindxpath.c--
- * Routines to find index paths that match a set of 'or' clauses
+ * Routines to find index paths that match a set of 'or' clauses
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.1.1.1 1996/07/09 06:21:36 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.2 1997/09/07 04:43:46 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,241 +31,267 @@
#include "parser/parsetree.h"
-static void best_or_subclause_indices(Query *root, Rel *rel, List *subclauses,
- List *indices, List *examined_indexids, Cost subcost, List *selectivities,
- List **indexids, Cost *cost, List **selecs);
-static void best_or_subclause_index(Query *root, Rel *rel, Expr *subclause,
- List *indices, int *indexid, Cost *cost, Cost *selec);
+static void
+best_or_subclause_indices(Query * root, Rel * rel, List * subclauses,
+ List * indices, List * examined_indexids, Cost subcost, List * selectivities,
+ List ** indexids, Cost * cost, List ** selecs);
+static void
+best_or_subclause_index(Query * root, Rel * rel, Expr * subclause,
+ List * indices, int *indexid, Cost * cost, Cost * selec);
-/*
+/*
* create-or-index-paths--
- * Creates index paths for indices that match 'or' clauses.
- *
+ * Creates index paths for indices that match 'or' clauses.
+ *
* 'rel' is the relation entry for which the paths are to be defined on
* 'clauses' is the list of available restriction clause nodes
- *
+ *
* Returns a list of these index path nodes.
- *
+ *
*/
-List *
-create_or_index_paths(Query *root,
- Rel *rel, List *clauses)
+List *
+create_or_index_paths(Query * root,
+ Rel * rel, List * clauses)
{
- List *t_list = NIL;
-
- if (clauses != NIL) {
- CInfo *clausenode = (CInfo *) (lfirst (clauses));
-
- /* Check to see if this clause is an 'or' clause, and, if so,
- * whether or not each of the subclauses within the 'or' clause has
- * been matched by an index (the 'Index field was set in
- * (match_or) if no index matches a given subclause, one of the
- * lists of index nodes returned by (get_index) will be 'nil').
- */
- if (valid_or_clause(clausenode) &&
- clausenode->indexids) {
- List *temp = NIL;
- List *index_list = NIL;
- bool index_flag = true;
-
- index_list = clausenode->indexids;
- foreach(temp,index_list) {
- if (!temp)
- index_flag = false;
- }
- if (index_flag) { /* used to be a lisp every function */
- IndexPath *pathnode = makeNode(IndexPath);
- List *indexids;
- Cost cost;
- List *selecs;
+ List *t_list = NIL;
+
+ if (clauses != NIL)
+ {
+ CInfo *clausenode = (CInfo *) (lfirst(clauses));
+
+ /*
+ * Check to see if this clause is an 'or' clause, and, if so,
+ * whether or not each of the subclauses within the 'or' clause
+ * has been matched by an index (the 'Index field was set in
+ * (match_or) if no index matches a given subclause, one of the
+ * lists of index nodes returned by (get_index) will be 'nil').
+ */
+ if (valid_or_clause(clausenode) &&
+ clausenode->indexids)
+ {
+ List *temp = NIL;
+ List *index_list = NIL;
+ bool index_flag = true;
+
+ index_list = clausenode->indexids;
+ foreach(temp, index_list)
+ {
+ if (!temp)
+ index_flag = false;
+ }
+ if (index_flag)
+ { /* used to be a lisp every function */
+ IndexPath *pathnode = makeNode(IndexPath);
+ List *indexids;
+ Cost cost;
+ List *selecs;
- best_or_subclause_indices(root,
- rel,
- clausenode->clause->args,
- clausenode->indexids,
- NIL,
- (Cost)0,
- NIL,
- &indexids,
- &cost,
- &selecs);
-
- pathnode->path.pathtype = T_IndexScan;
- pathnode->path.parent = rel;
- pathnode->indexqual =
- lcons(clausenode,NIL);
- pathnode->indexid = indexids;
- pathnode->path.path_cost = cost;
-
- /* copy clauseinfo list into path for expensive
- function processing -- JMH, 7/7/92 */
- pathnode->path.locclauseinfo =
- set_difference(clauses,
- copyObject((Node*)
- rel->clauseinfo));
-
-#if 0 /* fix xfunc */
- /* add in cost for expensive functions! -- JMH, 7/7/92 */
- if (XfuncMode != XFUNC_OFF) {
- ((Path*)pathnode)->path_cost +=
- xfunc_get_path_cost((Path)pathnode);
+ best_or_subclause_indices(root,
+ rel,
+ clausenode->clause->args,
+ clausenode->indexids,
+ NIL,
+ (Cost) 0,
+ NIL,
+ &indexids,
+ &cost,
+ &selecs);
+
+ pathnode->path.pathtype = T_IndexScan;
+ pathnode->path.parent = rel;
+ pathnode->indexqual =
+ lcons(clausenode, NIL);
+ pathnode->indexid = indexids;
+ pathnode->path.path_cost = cost;
+
+ /*
+ * copy clauseinfo list into path for expensive function
+ * processing -- JMH, 7/7/92
+ */
+ pathnode->path.locclauseinfo =
+ set_difference(clauses,
+ copyObject((Node *)
+ rel->clauseinfo));
+
+#if 0 /* fix xfunc */
+ /* add in cost for expensive functions! -- JMH, 7/7/92 */
+ if (XfuncMode != XFUNC_OFF)
+ {
+ ((Path *) pathnode)->path_cost +=
+ xfunc_get_path_cost((Path) pathnode);
+ }
+#endif
+ clausenode->selectivity = (Cost) floatVal(selecs);
+ t_list =
+ lcons(pathnode,
+ create_or_index_paths(root, rel, lnext(clauses)));
+ }
+ else
+ {
+ t_list = create_or_index_paths(root, rel, lnext(clauses));
+ }
}
-#endif
- clausenode->selectivity = (Cost)floatVal(selecs);
- t_list =
- lcons(pathnode,
- create_or_index_paths(root, rel,lnext(clauses)));
- } else {
- t_list = create_or_index_paths(root, rel,lnext(clauses));
- }
}
- }
- return(t_list);
+ return (t_list);
}
-/*
+/*
* best-or-subclause-indices--
- * Determines the best index to be used in conjunction with each subclause
- * of an 'or' clause and the cost of scanning a relation using these
- * indices. The cost is the sum of the individual index costs.
- *
+ * Determines the best index to be used in conjunction with each subclause
+ * of an 'or' clause and the cost of scanning a relation using these
+ * indices. The cost is the sum of the individual index costs.
+ *
* 'rel' is the node of the relation on which the index is defined
* 'subclauses' are the subclauses of the 'or' clause
* 'indices' are those index nodes that matched subclauses of the 'or'
- * clause
- * 'examined-indexids' is a list of those index ids to be used with
- * subclauses that have already been examined
+ * clause
+ * 'examined-indexids' is a list of those index ids to be used with
+ * subclauses that have already been examined
* 'subcost' is the cost of using the indices in 'examined-indexids'
* 'selectivities' is a list of the selectivities of subclauses that
- * have already been examined
- *
+ * have already been examined
+ *
* Returns a list of the indexids, cost, and selectivities of each
* subclause, e.g., ((i1 i2 i3) cost (s1 s2 s3)), where 'i' is an OID,
* 'cost' is a flonum, and 's' is a flonum.
*/
static void
-best_or_subclause_indices(Query *root,
- Rel *rel,
- List *subclauses,
- List *indices,
- List *examined_indexids,
- Cost subcost,
- List *selectivities,
- List **indexids, /* return value */
- Cost *cost, /* return value */
- List **selecs) /* return value */
+best_or_subclause_indices(Query * root,
+ Rel * rel,
+ List * subclauses,
+ List * indices,
+ List * examined_indexids,
+ Cost subcost,
+ List * selectivities,
+ List ** indexids, /* return value */
+ Cost * cost, /* return value */
+ List ** selecs) /* return value */
{
- if (subclauses==NIL) {
- *indexids = nreverse(examined_indexids);
- *cost = subcost;
- *selecs = nreverse(selectivities);
- } else {
- int best_indexid;
- Cost best_cost;
- Cost best_selec;
-
- best_or_subclause_index(root, rel, lfirst(subclauses), lfirst(indices),
- &best_indexid, &best_cost, &best_selec);
-
- best_or_subclause_indices(root,
- rel,
- lnext(subclauses),
- lnext(indices),
- lconsi(best_indexid, examined_indexids),
- subcost + best_cost,
- lcons(makeFloat(best_selec), selectivities),
- indexids,
- cost,
- selecs);
- }
- return;
-}
+ if (subclauses == NIL)
+ {
+ *indexids = nreverse(examined_indexids);
+ *cost = subcost;
+ *selecs = nreverse(selectivities);
+ }
+ else
+ {
+ int best_indexid;
+ Cost best_cost;
+ Cost best_selec;
+
+ best_or_subclause_index(root, rel, lfirst(subclauses), lfirst(indices),
+ &best_indexid, &best_cost, &best_selec);
-/*
+ best_or_subclause_indices(root,
+ rel,
+ lnext(subclauses),
+ lnext(indices),
+ lconsi(best_indexid, examined_indexids),
+ subcost + best_cost,
+ lcons(makeFloat(best_selec), selectivities),
+ indexids,
+ cost,
+ selecs);
+ }
+ return;
+}
+
+/*
* best-or-subclause-index--
- * Determines which is the best index to be used with a subclause of
- * an 'or' clause by estimating the cost of using each index and selecting
- * the least expensive.
- *
+ * Determines which is the best index to be used with a subclause of
+ * an 'or' clause by estimating the cost of using each index and selecting
+ * the least expensive.
+ *
* 'rel' is the node of the relation on which the index is defined
* 'subclause' is the subclause
* 'indices' is a list of index nodes that match the subclause
- *
+ *
* Returns a list (index-id index-subcost index-selectivity)
* (a fixnum, a fixnum, and a flonum respectively).
- *
+ *
*/
static void
-best_or_subclause_index(Query *root,
- Rel *rel,
- Expr *subclause,
- List *indices,
- int *retIndexid, /* return value */
- Cost *retCost, /* return value */
- Cost *retSelec) /* return value */
+best_or_subclause_index(Query * root,
+ Rel * rel,
+ Expr * subclause,
+ List * indices,
+ int *retIndexid, /* return value */
+ Cost * retCost, /* return value */
+ Cost * retSelec) /* return value */
{
- if (indices != NIL) {
- Datum value;
- int flag = 0;
- Cost subcost;
- Rel *index = (Rel *)lfirst (indices);
- AttrNumber attno = (get_leftop (subclause))->varattno ;
- Oid opno = ((Oper*)subclause->oper)->opno;
- bool constant_on_right = non_null((Expr*)get_rightop(subclause));
- float npages, selec;
- int subclause_indexid;
- Cost subclause_cost;
- Cost subclause_selec;
-
- if(constant_on_right) {
- value = ((Const*)get_rightop (subclause))->constvalue;
- } else {
- value = NameGetDatum("");
- }
- if(constant_on_right) {
- flag = (_SELEC_IS_CONSTANT_ ||_SELEC_CONSTANT_RIGHT_);
- } else {
- flag = _SELEC_CONSTANT_RIGHT_;
- }
- index_selectivity(lfirsti(index->relids),
- index->classlist,
- lconsi(opno,NIL),
- getrelid(lfirsti(rel->relids),
- root->rtable),
- lconsi(attno,NIL),
- lconsi(value,NIL),
- lconsi(flag,NIL),
- 1,
- &npages,
- &selec);
-
- subcost = cost_index((Oid) lfirsti(index->relids),
- (int)npages,
- (Cost)selec,
- rel->pages,
- rel->tuples,
- index->pages,
- index->tuples,
- false);
- best_or_subclause_index(root,
- rel,
- subclause,
- lnext(indices),
- &subclause_indexid,
- &subclause_cost,
- &subclause_selec);
+ if (indices != NIL)
+ {
+ Datum value;
+ int flag = 0;
+ Cost subcost;
+ Rel *index = (Rel *) lfirst(indices);
+ AttrNumber attno = (get_leftop(subclause))->varattno;
+ Oid opno = ((Oper *) subclause->oper)->opno;
+ bool constant_on_right = non_null((Expr *) get_rightop(subclause));
+ float npages,
+ selec;
+ int subclause_indexid;
+ Cost subclause_cost;
+ Cost subclause_selec;
- if (subclause_indexid==0 || subcost < subclause_cost) {
- *retIndexid = lfirsti(index->relids);
- *retCost = subcost;
- *retSelec = selec;
- } else {
- *retIndexid = 0;
- *retCost = 0.0;
- *retSelec = 0.0;
- }
- }
- return;
+ if (constant_on_right)
+ {
+ value = ((Const *) get_rightop(subclause))->constvalue;
+ }
+ else
+ {
+ value = NameGetDatum("");
+ }
+ if (constant_on_right)
+ {
+ flag = (_SELEC_IS_CONSTANT_ || _SELEC_CONSTANT_RIGHT_);
+ }
+ else
+ {
+ flag = _SELEC_CONSTANT_RIGHT_;
+ }
+ index_selectivity(lfirsti(index->relids),
+ index->classlist,
+ lconsi(opno, NIL),
+ getrelid(lfirsti(rel->relids),
+ root->rtable),
+ lconsi(attno, NIL),
+ lconsi(value, NIL),
+ lconsi(flag, NIL),
+ 1,
+ &npages,
+ &selec);
+
+ subcost = cost_index((Oid) lfirsti(index->relids),
+ (int) npages,
+ (Cost) selec,
+ rel->pages,
+ rel->tuples,
+ index->pages,
+ index->tuples,
+ false);
+ best_or_subclause_index(root,
+ rel,
+ subclause,
+ lnext(indices),
+ &subclause_indexid,
+ &subclause_cost,
+ &subclause_selec);
+
+ if (subclause_indexid == 0 || subcost < subclause_cost)
+ {
+ *retIndexid = lfirsti(index->relids);
+ *retCost = subcost;
+ *retSelec = selec;
+ }
+ else
+ {
+ *retIndexid = 0;
+ *retCost = 0.0;
+ *retSelec = 0.0;
+ }
+ }
+ return;
}