aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-05-20 20:28:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-05-20 20:28:20 +0000
commitbe03eb25f34c9c95c400504ef76c8abe0081d09f (patch)
treeca3b081710826485bdaaad375b80e82f5a7fd611 /src/backend/optimizer/path
parent5d53389cfe5ecacadda12f3a777a642605278e49 (diff)
downloadpostgresql-be03eb25f34c9c95c400504ef76c8abe0081d09f.tar.gz
postgresql-be03eb25f34c9c95c400504ef76c8abe0081d09f.zip
Modify optimizer data structures so that IndexOptInfo lists built for
create_index_paths are not immediately discarded, but are available for subsequent planner work. This allows avoiding redundant syscache lookups in several places. Change interface to operator selectivity estimation procedures to allow faster and more flexible estimation. Initdb forced due to change of pg_proc entries for selectivity functions!
Diffstat (limited to 'src/backend/optimizer/path')
-rw-r--r--src/backend/optimizer/path/allpaths.c69
-rw-r--r--src/backend/optimizer/path/clausesel.c123
-rw-r--r--src/backend/optimizer/path/costsize.c4
-rw-r--r--src/backend/optimizer/path/indxpath.c14
-rw-r--r--src/backend/optimizer/path/joinrels.c8
-rw-r--r--src/backend/optimizer/path/orindxpath.c40
6 files changed, 110 insertions, 148 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 243ff7c5a72..afb3259e736 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.73 2001/05/08 17:25:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.74 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,8 +35,8 @@ static void set_base_rel_pathlists(Query *root);
static void set_plain_rel_pathlist(Query *root, RelOptInfo *rel,
RangeTblEntry *rte);
static void set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
- RangeTblEntry *rte,
- List *inheritlist);
+ Index rti, RangeTblEntry *rte,
+ List *inheritlist);
static RelOptInfo *make_one_rel_by_joins(Query *root, int levels_needed,
List *initial_rels);
@@ -69,7 +69,7 @@ make_one_rel(Query *root)
rel = make_fromexpr_rel(root, root->jointree);
/*
- * The result should join all the query's rels.
+ * The result should join all the query's base rels.
*/
Assert(length(rel->relids) == length(root->base_rel_list));
@@ -190,10 +190,11 @@ set_base_rel_pathlists(Query *root)
/* Select cheapest path (pretty easy in this case...) */
set_cheapest(rel);
}
- else if ((inheritlist = expand_inherted_rtentry(root, rti)) != NIL)
+ else if ((inheritlist = expand_inherted_rtentry(root, rti, true))
+ != NIL)
{
/* Relation is root of an inheritance tree, process specially */
- set_inherited_rel_pathlist(root, rel, rte, inheritlist);
+ set_inherited_rel_pathlist(root, rel, rti, rte, inheritlist);
}
else
{
@@ -210,8 +211,6 @@ set_base_rel_pathlists(Query *root)
static void
set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte)
{
- List *indices = find_secondary_indexes(rte->relid);
-
/* Mark rel with estimated output rows, width, etc */
set_baserel_size_estimates(root, rel);
@@ -230,13 +229,9 @@ set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte)
create_tidscan_paths(root, rel);
/* Consider index paths for both simple and OR index clauses */
- create_index_paths(root, rel, indices);
+ create_index_paths(root, rel);
- /*
- * Note: create_or_index_paths depends on create_index_paths to have
- * marked OR restriction clauses with relevant indices; this is why it
- * doesn't need to be given the list of indices.
- */
+ /* create_index_paths must be done before create_or_index_paths */
create_or_index_paths(root, rel, rel->baserestrictinfo);
/* Now find the cheapest of the paths for this rel */
@@ -248,14 +243,26 @@ set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte)
* Build access paths for a inheritance tree rooted at rel
*
* inheritlist is a list of RT indexes of all tables in the inheritance tree,
- * including the parent itself. Note we will not come here unless there's
- * at least one child in addition to the parent.
+ * including a duplicate of the parent itself. Note we will not come here
+ * unless there's at least one child in addition to the parent.
+ *
+ * NOTE: the passed-in rel and RTE will henceforth represent the appended
+ * result of the whole inheritance tree. The members of inheritlist represent
+ * the individual tables --- in particular, the inheritlist member that is a
+ * duplicate of the parent RTE represents the parent table alone.
+ * We will generate plans to scan the individual tables that refer to
+ * the inheritlist RTEs, whereas Vars elsewhere in the plan tree that
+ * refer to the original RTE are taken to refer to the append output.
+ * In particular, this means we have separate RelOptInfos for the parent
+ * table and for the append output, which is a good thing because they're
+ * not the same size.
*/
static void
-set_inherited_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte,
+set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
+ Index rti, RangeTblEntry *rte,
List *inheritlist)
{
- int parentRTindex = lfirsti(rel->relids);
+ int parentRTindex = rti;
Oid parentOID = rte->relid;
List *subpaths = NIL;
List *il;
@@ -268,7 +275,15 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte,
elog(ERROR, "SELECT FOR UPDATE is not supported for inherit queries");
/*
- * Recompute size estimates for whole inheritance tree
+ * The executor will check the parent table's access permissions when it
+ * examines the parent's inheritlist entry. There's no need to check
+ * twice, so turn off access check bits in the original RTE.
+ */
+ rte->checkForRead = false;
+ rte->checkForWrite = false;
+
+ /*
+ * Initialize to compute size estimates for whole inheritance tree
*/
rel->rows = 0;
rel->width = 0;
@@ -289,21 +304,17 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte,
/*
* Make a RelOptInfo for the child so we can do planning. Do NOT
- * attach the RelOptInfo to the query's base_rel_list, however.
- *
- * NOTE: when childRTindex == parentRTindex, we create a second
- * RelOptInfo for the same relation. This RelOptInfo will
- * represent the parent table alone, whereas the original
- * RelOptInfo represents the union of the inheritance tree
- * members.
+ * attach the RelOptInfo to the query's base_rel_list, however,
+ * since the child is not part of the main join tree. Instead,
+ * the child RelOptInfo is added to other_rel_list.
*/
- childrel = make_base_rel(root, childRTindex);
+ childrel = build_other_rel(root, childRTindex);
/*
* Copy the parent's targetlist and restriction quals to the
- * child, with attribute-number adjustment if needed. We don't
+ * child, with attribute-number adjustment as needed. We don't
* bother to copy the join quals, since we can't do any joining
- * here.
+ * of the individual tables.
*/
childrel->targetlist = (List *)
adjust_inherited_attrs((Node *) rel->targetlist,
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))
{
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index dddca240e95..b4379e4b39b 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.73 2001/05/09 23:13:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.74 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -773,7 +773,7 @@ estimate_hash_bucketsize(Query *root, Var *var)
if (relid == InvalidOid)
return 0.1;
- rel = get_base_rel(root, var->varno);
+ rel = find_base_rel(root, var->varno);
if (rel->tuples <= 0.0 || rel->rows <= 0.0)
return 0.1; /* ensure we can divide below */
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index ca19465c897..a5f5bb151da 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.104 2001/03/23 04:49:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.105 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -127,18 +127,15 @@ static Const *string_to_const(const char *str, Oid datatype);
* consideration in nested-loop joins.
*
* 'rel' is the relation for which we want to generate index paths
- * 'indices' is a list of available indexes for 'rel'
*/
void
-create_index_paths(Query *root,
- RelOptInfo *rel,
- List *indices)
+create_index_paths(Query *root, RelOptInfo *rel)
{
List *restrictinfo_list = rel->baserestrictinfo;
List *joininfo_list = rel->joininfo;
List *ilist;
- foreach(ilist, indices)
+ foreach(ilist, rel->indexlist)
{
IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
List *restrictclauses;
@@ -1435,10 +1432,10 @@ index_innerjoin(Query *root, RelOptInfo *rel, IndexOptInfo *index,
/*
* Note that we are making a pathnode for a single-scan indexscan;
- * therefore, both indexid and indexqual should be single-element
+ * therefore, both indexinfo and indexqual should be single-element
* lists.
*/
- pathnode->indexid = makeListi1(index->indexoid);
+ pathnode->indexinfo = makeList1(index);
pathnode->indexqual = makeList1(indexquals);
/* We don't actually care what order the index scans in ... */
@@ -2030,7 +2027,6 @@ find_operator(const char *opname, Oid datatype)
static Datum
string_to_datum(const char *str, Oid datatype)
{
-
/*
* We cheat a little by assuming that textin() will do for bpchar and
* varchar constants too...
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 929a977112d..3bde257a37e 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.52 2001/03/22 03:59:35 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.53 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -332,7 +332,7 @@ make_rels_by_clauseless_joins(Query *root,
/*
* make_jointree_rel
- * Find or build a RelOptInfojoin rel representing a specific
+ * Find or build a RelOptInfo join rel representing a specific
* jointree item. For JoinExprs, we only consider the construction
* path that corresponds exactly to what the user wrote.
*/
@@ -343,7 +343,7 @@ make_jointree_rel(Query *root, Node *jtnode)
{
int varno = ((RangeTblRef *) jtnode)->rtindex;
- return get_base_rel(root, varno);
+ return build_base_rel(root, varno);
}
else if (IsA(jtnode, FromExpr))
{
@@ -402,7 +402,7 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
* Find or build the join RelOptInfo, and compute the restrictlist
* that goes with this particular joining.
*/
- joinrel = get_join_rel(root, rel1, rel2, jointype, &restrictlist);
+ joinrel = build_join_rel(root, rel1, rel2, jointype, &restrictlist);
/*
* Consider paths using each rel as both outer and inner.
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index d4e467c3e04..25cbc3e4fa2 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.42 2001/01/24 19:42:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/orindxpath.c,v 1.43 2001/05/20 20:28:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,8 +26,8 @@ static void best_or_subclause_indices(Query *root, RelOptInfo *rel,
IndexPath *pathnode);
static void best_or_subclause_index(Query *root, RelOptInfo *rel,
Expr *subclause, List *indices,
+ IndexOptInfo **retIndexInfo,
List **retIndexQual,
- Oid *retIndexid,
Cost *retStartupCost,
Cost *retTotalCost);
@@ -122,14 +122,14 @@ create_or_index_paths(Query *root,
* of an 'or' clause and the cost of scanning a relation using these
* indices. The cost is the sum of the individual index costs, since
* the executor will perform a scan for each subclause of the 'or'.
+ * Returns a list of IndexOptInfo nodes, one per scan.
*
- * This routine also creates the indexqual and indexid lists that will
- * be needed by the executor. The indexqual list has one entry for each
- * scan of the base rel, which is a sublist of indexqual conditions to
- * apply in that scan. The implicit semantics are AND across each sublist
- * of quals, and OR across the toplevel list (note that the executor
- * takes care not to return any single tuple more than once). The indexid
- * list gives the OID of the index to be used in each scan.
+ * This routine also creates the indexqual list that will be needed by
+ * the executor. The indexqual list has one entry for each scan of the base
+ * rel, which is a sublist of indexqual conditions to apply in that scan.
+ * The implicit semantics are AND across each sublist of quals, and OR across
+ * the toplevel list (note that the executor takes care not to return any
+ * single tuple more than once).
*
* 'rel' is the node of the relation on which the indexes are defined
* 'subclauses' are the subclauses of the 'or' clause
@@ -138,9 +138,9 @@ create_or_index_paths(Query *root,
* 'pathnode' is the IndexPath node being built.
*
* Results are returned by setting these fields of the passed pathnode:
+ * 'indexinfo' gets a list of the index IndexOptInfo nodes, one per scan
* 'indexqual' gets the constructed indexquals for the path (a list
* of sublists of clauses, one sublist per scan of the base rel)
- * 'indexid' gets a list of the index OIDs for each scan of the rel
* 'startup_cost' and 'total_cost' get the complete path costs.
*
* 'startup_cost' is the startup cost for the first index scan only;
@@ -161,28 +161,28 @@ best_or_subclause_indices(Query *root,
{
List *slist;
+ pathnode->indexinfo = NIL;
pathnode->indexqual = NIL;
- pathnode->indexid = NIL;
pathnode->path.startup_cost = 0;
pathnode->path.total_cost = 0;
foreach(slist, subclauses)
{
Expr *subclause = lfirst(slist);
+ IndexOptInfo *best_indexinfo;
List *best_indexqual;
- Oid best_indexid;
Cost best_startup_cost;
Cost best_total_cost;
best_or_subclause_index(root, rel, subclause, lfirst(indices),
- &best_indexqual, &best_indexid,
+ &best_indexinfo, &best_indexqual,
&best_startup_cost, &best_total_cost);
- Assert(best_indexid != InvalidOid);
+ Assert(best_indexinfo != NULL);
+ pathnode->indexinfo = lappend(pathnode->indexinfo, best_indexinfo);
pathnode->indexqual = lappend(pathnode->indexqual, best_indexqual);
- pathnode->indexid = lappendi(pathnode->indexid, best_indexid);
- if (slist == subclauses)/* first scan? */
+ if (slist == subclauses) /* first scan? */
pathnode->path.startup_cost = best_startup_cost;
pathnode->path.total_cost += best_total_cost;
@@ -199,8 +199,8 @@ best_or_subclause_indices(Query *root,
* 'rel' is the node of the relation on which the index is defined
* 'subclause' is the OR subclause being considered
* 'indices' is a list of IndexOptInfo nodes that match the subclause
+ * '*retIndexInfo' gets the IndexOptInfo of the best index
* '*retIndexQual' gets a list of the indexqual conditions for the best index
- * '*retIndexid' gets the OID of the best index
* '*retStartupCost' gets the startup cost of a scan with that index
* '*retTotalCost' gets the total cost of a scan with that index
*/
@@ -209,8 +209,8 @@ best_or_subclause_index(Query *root,
RelOptInfo *rel,
Expr *subclause,
List *indices,
+ IndexOptInfo **retIndexInfo, /* return value */
List **retIndexQual, /* return value */
- Oid *retIndexid, /* return value */
Cost *retStartupCost, /* return value */
Cost *retTotalCost) /* return value */
{
@@ -218,8 +218,8 @@ best_or_subclause_index(Query *root,
List *ilist;
/* if we don't match anything, return zeros */
+ *retIndexInfo = NULL;
*retIndexQual = NIL;
- *retIndexid = InvalidOid;
*retStartupCost = 0;
*retTotalCost = 0;
@@ -238,8 +238,8 @@ best_or_subclause_index(Query *root,
if (first_time || subclause_path.total_cost < *retTotalCost)
{
+ *retIndexInfo = index;
*retIndexQual = indexqual;
- *retIndexid = index->indexoid;
*retStartupCost = subclause_path.startup_cost;
*retTotalCost = subclause_path.total_cost;
first_time = false;