aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
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;