diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index e6d2c5cd80..83ac82a60a 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -49,7 +49,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.138 2005/03/06 22:15:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.139 2005/03/27 06:29:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -227,7 +227,6 @@ cost_nonsequential_access(double relpages) * but here we consider the cost of just one pass. * * 'root' is the query root - * 'baserel' is the base relation the index is for * 'index' is the index to be used * 'indexQuals' is the list of applicable qual clauses (implicit AND semantics) * 'is_injoin' is T if we are considering using the index scan as the inside @@ -243,11 +242,11 @@ cost_nonsequential_access(double relpages) */ void cost_index(Path *path, Query *root, - RelOptInfo *baserel, IndexOptInfo *index, List *indexQuals, bool is_injoin) { + RelOptInfo *baserel = index->rel; Cost startup_cost = 0; Cost run_cost = 0; Cost indexStartupCost; diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 9f5ab60337..324dad87c7 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.170 2005/03/26 23:29:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.171 2005/03/27 06:29:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -54,36 +54,31 @@ ((opclass) == BOOL_BTREE_OPS_OID || (opclass) == BOOL_HASH_OPS_OID) -static List *group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index); +static List *group_clauses_by_indexkey(IndexOptInfo *index); static List *group_clauses_by_indexkey_for_join(Query *root, - RelOptInfo *rel, IndexOptInfo *index, + IndexOptInfo *index, Relids outer_relids, JoinType jointype, bool isouterjoin); -static bool match_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, +static bool match_clause_to_indexcol(IndexOptInfo *index, int indexcol, Oid opclass, RestrictInfo *rinfo); -static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, +static bool match_join_clause_to_indexcol(IndexOptInfo *index, int indexcol, Oid opclass, RestrictInfo *rinfo); static Oid indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left); static bool pred_test_recurse(Node *clause, Node *predicate); static bool pred_test_simple_clause(Expr *predicate, Node *clause); -static Relids indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index); -static Path *make_innerjoin_index_path(Query *root, - RelOptInfo *rel, IndexOptInfo *index, +static Relids indexable_outerrelids(IndexOptInfo *index); +static Path *make_innerjoin_index_path(Query *root, IndexOptInfo *index, List *clausegroups); static bool match_index_to_operand(Node *operand, int indexcol, - RelOptInfo *rel, IndexOptInfo *index); -static bool match_boolean_index_clause(Node *clause, - int indexcol, - RelOptInfo *rel, + IndexOptInfo *index); +static bool match_boolean_index_clause(Node *clause, int indexcol, IndexOptInfo *index); static bool match_special_index_operator(Expr *clause, Oid opclass, bool indexkey_on_left); -static Expr *expand_boolean_index_clause(Node *clause, - int indexcol, - RelOptInfo *rel, +static Expr *expand_boolean_index_clause(Node *clause, int indexcol, IndexOptInfo *index); static List *expand_indexqual_condition(RestrictInfo *rinfo, Oid opclass); static List *prefix_quals(Node *leftop, Oid opclass, @@ -148,13 +143,13 @@ create_index_paths(Query *root, RelOptInfo *rel) * 1. Match the index against non-OR restriction clauses. (OR * clauses will be considered later by orindxpath.c.) */ - restrictclauses = group_clauses_by_indexkey(rel, index); + restrictclauses = group_clauses_by_indexkey(index); /* * 2. Compute pathkeys describing index's ordering, if any, then * see how many of them are actually useful for this query. */ - index_pathkeys = build_index_pathkeys(root, rel, index, + index_pathkeys = build_index_pathkeys(root, index, ForwardScanDirection); index_is_ordered = (index_pathkeys != NIL); useful_pathkeys = truncate_useless_pathkeys(root, rel, @@ -173,7 +168,7 @@ create_index_paths(Query *root, RelOptInfo *rel) useful_pathkeys != NIL || index->indpred != NIL) add_path(rel, (Path *) - create_index_path(root, rel, index, + create_index_path(root, index, restrictclauses, useful_pathkeys, index_is_ordered ? @@ -187,13 +182,13 @@ create_index_paths(Query *root, RelOptInfo *rel) */ if (index_is_ordered) { - index_pathkeys = build_index_pathkeys(root, rel, index, + index_pathkeys = build_index_pathkeys(root, index, BackwardScanDirection); useful_pathkeys = truncate_useless_pathkeys(root, rel, index_pathkeys); if (useful_pathkeys != NIL) add_path(rel, (Path *) - create_index_path(root, rel, index, + create_index_path(root, index, restrictclauses, useful_pathkeys, BackwardScanDirection)); @@ -207,7 +202,7 @@ create_index_paths(Query *root, RelOptInfo *rel) * joining purposes. We compute both per-index and * overall-for-relation sets. */ - join_outerrelids = indexable_outerrelids(rel, index); + join_outerrelids = indexable_outerrelids(index); index->outer_relids = join_outerrelids; all_join_outerrelids = bms_add_members(all_join_outerrelids, join_outerrelids); @@ -226,9 +221,6 @@ create_index_paths(Query *root, RelOptInfo *rel) * group_clauses_by_indexkey * Find restriction clauses that can be used with an index. * - * 'rel' is the node of the relation itself. - * 'index' is a index on 'rel'. - * * Returns a list of sublists of RestrictInfo nodes for clauses that can be * used with this index. Each sublist contains clauses that can be used * with one index key (in no particular order); the top list is ordered by @@ -243,10 +235,10 @@ create_index_paths(Query *root, RelOptInfo *rel) * Therefore, there are no empty sublists in the result. */ static List * -group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index) +group_clauses_by_indexkey(IndexOptInfo *index) { List *clausegroup_list = NIL; - List *restrictinfo_list = rel->baserestrictinfo; + List *restrictinfo_list = index->rel->baserestrictinfo; int indexcol = 0; Oid *classes = index->classlist; @@ -263,8 +255,7 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); - if (match_clause_to_indexcol(rel, - index, + if (match_clause_to_indexcol(index, indexcol, curClass, rinfo)) @@ -302,8 +293,7 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index) * will already have been generated for it.) */ static List * -group_clauses_by_indexkey_for_join(Query *root, - RelOptInfo *rel, IndexOptInfo *index, +group_clauses_by_indexkey_for_join(Query *root, IndexOptInfo *index, Relids outer_relids, JoinType jointype, bool isouterjoin) { @@ -327,7 +317,7 @@ group_clauses_by_indexkey_for_join(Query *root, * to get rid of a non-join clause if it appears after a join * clause it is redundant with. */ - foreach(l, rel->baserestrictinfo) + foreach(l, index->rel->baserestrictinfo) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); @@ -335,8 +325,7 @@ group_clauses_by_indexkey_for_join(Query *root, if (isouterjoin && rinfo->is_pushed_down) continue; - if (match_clause_to_indexcol(rel, - index, + if (match_clause_to_indexcol(index, indexcol, curClass, rinfo)) @@ -347,7 +336,7 @@ group_clauses_by_indexkey_for_join(Query *root, numsources = (clausegroup != NIL) ? 1 : 0; /* Look for joinclauses that are usable with given outer_relids */ - foreach(l, rel->joininfo) + foreach(l, index->rel->joininfo) { JoinInfo *joininfo = (JoinInfo *) lfirst(l); bool jfoundhere = false; @@ -364,8 +353,7 @@ group_clauses_by_indexkey_for_join(Query *root, if (isouterjoin && rinfo->is_pushed_down) continue; - if (match_join_clause_to_indexcol(rel, - index, + if (match_join_clause_to_indexcol(index, indexcol, curClass, rinfo)) @@ -434,9 +422,7 @@ group_clauses_by_indexkey_for_join(Query *root, * restriction clause as qpquals. FIXME someday. */ List * -group_clauses_by_indexkey_for_or(RelOptInfo *rel, - IndexOptInfo *index, - Expr *orsubclause) +group_clauses_by_indexkey_for_or(IndexOptInfo *index, Expr *orsubclause) { List *clausegroup_list = NIL; bool matched = false; @@ -452,8 +438,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel, /* Try to match the OR subclause to the index key */ if (IsA(orsubclause, RestrictInfo)) { - if (match_clause_to_indexcol(rel, index, - indexcol, curClass, + if (match_clause_to_indexcol(index, indexcol, curClass, (RestrictInfo *) orsubclause)) { clausegroup = lappend(clausegroup, orsubclause); @@ -467,8 +452,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel, RestrictInfo *subsubclause = (RestrictInfo *) lfirst(item); if (IsA(subsubclause, RestrictInfo) && - match_clause_to_indexcol(rel, index, - indexcol, curClass, + match_clause_to_indexcol(index, indexcol, curClass, subsubclause)) { clausegroup = lappend(clausegroup, subsubclause); @@ -486,12 +470,11 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel, */ if (clausegroup == NIL) { - foreach(item, rel->baserestrictinfo) + foreach(item, index->rel->baserestrictinfo) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(item); - if (match_clause_to_indexcol(rel, index, - indexcol, curClass, + if (match_clause_to_indexcol(index, indexcol, curClass, rinfo)) clausegroup = lappend(clausegroup, rinfo); } @@ -539,8 +522,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel, * For boolean indexes, it is also possible to match the clause directly * to the indexkey; or perhaps the clause is (NOT indexkey). * - * 'rel' is the relation of interest. - * 'index' is an index on 'rel'. + * 'index' is the index of interest. * 'indexcol' is a column number of 'index' (counting from 0). * 'opclass' is the corresponding operator class. * 'rinfo' is the clause to be tested (as a RestrictInfo node). @@ -551,8 +533,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel, * responsibility of higher-level routines to cope with those. */ static bool -match_clause_to_indexcol(RelOptInfo *rel, - IndexOptInfo *index, +match_clause_to_indexcol(IndexOptInfo *index, int indexcol, Oid opclass, RestrictInfo *rinfo) @@ -564,8 +545,7 @@ match_clause_to_indexcol(RelOptInfo *rel, /* First check for boolean-index cases. */ if (IsBooleanOpclass(opclass)) { - if (match_boolean_index_clause((Node *) clause, - indexcol, rel, index)) + if (match_boolean_index_clause((Node *) clause, indexcol, index)) return true; } @@ -582,7 +562,7 @@ match_clause_to_indexcol(RelOptInfo *rel, * (constant operator indexkey). Anything that is a "pseudo constant" * expression will do. */ - if (match_index_to_operand(leftop, indexcol, rel, index) && + if (match_index_to_operand(leftop, indexcol, index) && is_pseudo_constant_clause_relids(rightop, rinfo->right_relids)) { if (is_indexable_operator(clause, opclass, true)) @@ -597,7 +577,7 @@ match_clause_to_indexcol(RelOptInfo *rel, return false; } - if (match_index_to_operand(rightop, indexcol, rel, index) && + if (match_index_to_operand(rightop, indexcol, index) && is_pseudo_constant_clause_relids(leftop, rinfo->left_relids)) { if (is_indexable_operator(clause, opclass, false)) @@ -638,8 +618,7 @@ match_clause_to_indexcol(RelOptInfo *rel, * expressions like (a.f1 OP (b.f2 OP a.f3)); that's not processable by * an indexscan nestloop join, whereas (a.f1 OP (b.f2 OP c.f3)) is. * - * 'rel' is the relation of interest. - * 'index' is an index on 'rel'. + * 'index' is the index of interest. * 'indexcol' is a column number of 'index' (counting from 0). * 'opclass' is the corresponding operator class. * 'rinfo' is the clause to be tested (as a RestrictInfo node). @@ -650,8 +629,7 @@ match_clause_to_indexcol(RelOptInfo *rel, * responsibility of higher-level routines to cope with those. */ static bool -match_join_clause_to_indexcol(RelOptInfo *rel, - IndexOptInfo *index, +match_join_clause_to_indexcol(IndexOptInfo *index, int indexcol, Oid opclass, RestrictInfo *rinfo) @@ -674,25 +652,25 @@ match_join_clause_to_indexcol(RelOptInfo *rel, * none of the indexed relation's vars and contains no volatile * functions. */ - if (match_index_to_operand(leftop, indexcol, rel, index)) + if (match_index_to_operand(leftop, indexcol, index)) { Relids othervarnos = rinfo->right_relids; bool isIndexable; isIndexable = - !bms_overlap(rel->relids, othervarnos) && + !bms_overlap(index->rel->relids, othervarnos) && !contain_volatile_functions(rightop) && is_indexable_operator(clause, opclass, true); return isIndexable; } - if (match_index_to_operand(rightop, indexcol, rel, index)) + if (match_index_to_operand(rightop, indexcol, index)) { Relids othervarnos = rinfo->left_relids; bool isIndexable; isIndexable = - !bms_overlap(rel->relids, othervarnos) && + !bms_overlap(index->rel->relids, othervarnos) && !contain_volatile_functions(leftop) && is_indexable_operator(clause, opclass, false); return isIndexable; @@ -1423,16 +1401,14 @@ pred_test_simple_clause(Expr *predicate, Node *clause) * indexable_outerrelids * Finds all other relids that participate in any indexable join clause * for the specified index. Returns a set of relids. - * - * 'rel' is the relation for which 'index' is defined */ static Relids -indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) +indexable_outerrelids(IndexOptInfo *index) { Relids outer_relids = NULL; ListCell *l; - foreach(l, rel->joininfo) + foreach(l, index->rel->joininfo) { JoinInfo *joininfo = (JoinInfo *) lfirst(l); bool match_found = false; @@ -1455,8 +1431,7 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) { Oid curClass = classes[0]; - if (match_join_clause_to_indexcol(rel, - index, + if (match_join_clause_to_indexcol(index, indexcol, curClass, rinfo)) @@ -1614,7 +1589,6 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, /* find useful clauses for this index and outerjoin set */ clausegroups = group_clauses_by_indexkey_for_join(root, - rel, index, index_outer_relids, jointype, @@ -1622,8 +1596,7 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, if (clausegroups) { /* make the path */ - path = make_innerjoin_index_path(root, rel, index, - clausegroups); + path = make_innerjoin_index_path(root, index, clausegroups); } /* Cache the result --- whether positive or negative */ @@ -1661,15 +1634,16 @@ best_inner_indexscan(Query *root, RelOptInfo *rel, * Create an index path node for a path to be used as an inner * relation in a nestloop join. * - * 'rel' is the relation for which 'index' is defined + * 'index' is the index of interest * 'clausegroups' is a list of lists of RestrictInfos that can use 'index' */ static Path * make_innerjoin_index_path(Query *root, - RelOptInfo *rel, IndexOptInfo *index, + IndexOptInfo *index, List *clausegroups) { IndexPath *pathnode = makeNode(IndexPath); + RelOptInfo *rel = index->rel; List *indexquals, *allclauses; @@ -1686,7 +1660,7 @@ make_innerjoin_index_path(Query *root, pathnode->path.pathkeys = NIL; /* Convert clauses to indexquals the executor can handle */ - indexquals = expand_indexqual_conditions(rel, index, clausegroups); + indexquals = expand_indexqual_conditions(index, clausegroups); /* Flatten the clausegroups list to produce indexclauses list */ allclauses = flatten_clausegroups_list(clausegroups); @@ -1729,7 +1703,7 @@ make_innerjoin_index_path(Query *root, /* Like costsize.c, force estimate to be at least one row */ pathnode->rows = clamp_row_est(pathnode->rows); - cost_index(&pathnode->path, root, rel, index, indexquals, true); + cost_index(&pathnode->path, root, index, indexquals, true); return (Path *) pathnode; } @@ -1798,13 +1772,11 @@ make_expr_from_indexclauses(List *indexclauses) * * operand: the nodetree to be compared to the index * indexcol: the column number of the index (counting from 0) - * rel: the parent relation * index: the index of interest */ static bool match_index_to_operand(Node *operand, int indexcol, - RelOptInfo *rel, IndexOptInfo *index) { int indkey; @@ -1825,7 +1797,7 @@ match_index_to_operand(Node *operand, * Simple index column; operand must be a matching Var. */ if (operand && IsA(operand, Var) && - rel->relid == ((Var *) operand)->varno && + index->rel->relid == ((Var *) operand)->varno && indkey == ((Var *) operand)->varattno) return true; } @@ -1933,17 +1905,16 @@ match_index_to_operand(Node *operand, static bool match_boolean_index_clause(Node *clause, int indexcol, - RelOptInfo *rel, IndexOptInfo *index) { /* Direct match? */ - if (match_index_to_operand(clause, indexcol, rel, index)) + if (match_index_to_operand(clause, indexcol, index)) return true; /* NOT clause? */ if (not_clause(clause)) { if (match_index_to_operand((Node *) get_notclausearg((Expr *) clause), - indexcol, rel, index)) + indexcol, index)) return true; } /* @@ -1958,7 +1929,7 @@ match_boolean_index_clause(Node *clause, if (btest->booltesttype == IS_TRUE || btest->booltesttype == IS_FALSE) if (match_index_to_operand((Node *) btest->arg, - indexcol, rel, index)) + indexcol, index)) return true; } return false; @@ -2135,7 +2106,7 @@ match_special_index_operator(Expr *clause, Oid opclass, * someday --- tgl 7/00) */ List * -expand_indexqual_conditions(RelOptInfo *rel, IndexOptInfo *index, List *clausegroups) +expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) { List *resultquals = NIL; ListCell *clausegroup_item; @@ -2162,7 +2133,6 @@ expand_indexqual_conditions(RelOptInfo *rel, IndexOptInfo *index, List *clausegr boolqual = expand_boolean_index_clause((Node *) rinfo->clause, indexcol, - rel, index); if (boolqual) { @@ -2199,11 +2169,10 @@ expand_indexqual_conditions(RelOptInfo *rel, IndexOptInfo *index, List *clausegr static Expr * expand_boolean_index_clause(Node *clause, int indexcol, - RelOptInfo *rel, IndexOptInfo *index) { /* Direct match? */ - if (match_index_to_operand(clause, indexcol, rel, index)) + if (match_index_to_operand(clause, indexcol, index)) { /* convert to indexkey = TRUE */ return make_opclause(BooleanEqualOperator, BOOLOID, false, @@ -2216,7 +2185,7 @@ expand_boolean_index_clause(Node *clause, Node *arg = (Node *) get_notclausearg((Expr *) clause); /* It must have matched the indexkey */ - Assert(match_index_to_operand(arg, indexcol, rel, index)); + Assert(match_index_to_operand(arg, indexcol, index)); /* convert to indexkey = FALSE */ return make_opclause(BooleanEqualOperator, BOOLOID, false, (Expr *) arg, @@ -2228,7 +2197,7 @@ expand_boolean_index_clause(Node *clause, Node *arg = (Node *) btest->arg; /* It must have matched the indexkey */ - Assert(match_index_to_operand(arg, indexcol, rel, index)); + Assert(match_index_to_operand(arg, indexcol, index)); if (btest->booltesttype == IS_TRUE) { /* convert to indexkey = TRUE */ diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c index 1cda19c8fa..0843bb6ea8 100644 --- a/src/backend/optimizer/path/orindxpath.c +++ b/src/backend/optimizer/path/orindxpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.66 2005/03/26 23:29:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.67 2005/03/27 06:29:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -383,7 +383,7 @@ best_or_subclause_index(Query *root, } /* Collect index clauses usable with this index */ - indexclauses = group_clauses_by_indexkey_for_or(rel, index, subclause); + indexclauses = group_clauses_by_indexkey_for_or(index, subclause); /* * Ignore index if it doesn't match the subclause at all; except @@ -398,9 +398,9 @@ best_or_subclause_index(Query *root, continue; /* Convert clauses to indexquals the executor can handle */ - indexquals = expand_indexqual_conditions(rel, index, indexclauses); + indexquals = expand_indexqual_conditions(index, indexclauses); - cost_index(&subclause_path, root, rel, index, indexquals, false); + cost_index(&subclause_path, root, index, indexquals, false); if (!found || subclause_path.total_cost < *retTotalCost) { diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index d2c6de54dd..0e23045fef 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -11,7 +11,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.64 2005/01/23 02:21:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.65 2005/03/27 06:29:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -648,7 +648,6 @@ get_cheapest_fractional_path_for_pathkeys(List *paths, */ List * build_index_pathkeys(Query *root, - RelOptInfo *rel, IndexOptInfo *index, ScanDirection scandir) { @@ -675,7 +674,8 @@ build_index_pathkeys(Query *root, if (*indexkeys != 0) { /* simple index column */ - indexkey = (Node *) find_indexkey_var(root, rel, *indexkeys); + indexkey = (Node *) find_indexkey_var(root, index->rel, + *indexkeys); } else { diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index d1b94c483a..f4a76a9b3b 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.176 2005/03/10 23:21:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.177 2005/03/27 06:29:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -65,16 +65,13 @@ static void fix_indxqual_references(List *indexquals, IndexPath *index_path, List **indxstrategy, List **indxsubtype, List **indxlossy); -static void fix_indxqual_sublist(List *indexqual, - Relids baserelids, int baserelid, - IndexOptInfo *index, +static void fix_indxqual_sublist(List *indexqual, IndexOptInfo *index, List **fixed_quals, List **strategy, List **subtype, List **lossy); -static Node *fix_indxqual_operand(Node *node, int baserelid, - IndexOptInfo *index, - Oid *opclass); +static Node *fix_indxqual_operand(Node *node, IndexOptInfo *index, + Oid *opclass); static List *get_switched_clauses(List *clauses, Relids outerrelids); static List *order_qual_clauses(Query *root, List *clauses); static void copy_path_costsize(Plan *dest, Path *src); @@ -1179,8 +1176,6 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path, List **indxsubtype, List **indxlossy) { - Relids baserelids = index_path->path.parent->relids; - int baserelid = index_path->path.parent->relid; List *index_info = index_path->indexinfo; ListCell *iq, *ii; @@ -1198,7 +1193,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path, List *subtype; List *lossy; - fix_indxqual_sublist(indexqual, baserelids, baserelid, index, + fix_indxqual_sublist(indexqual, index, &fixed_qual, &strategy, &subtype, &lossy); *fixed_indexquals = lappend(*fixed_indexquals, fixed_qual); *indxstrategy = lappend(*indxstrategy, strategy); @@ -1222,9 +1217,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path, * the integer list of lossiness flags (1/0) */ static void -fix_indxqual_sublist(List *indexqual, - Relids baserelids, int baserelid, - IndexOptInfo *index, +fix_indxqual_sublist(List *indexqual, IndexOptInfo *index, List **fixed_quals, List **strategy, List **subtype, @@ -1265,7 +1258,7 @@ fix_indxqual_sublist(List *indexqual, * the clause. The indexkey should be the side that refers to * (only) the base relation. */ - if (!bms_equal(rinfo->left_relids, baserelids)) + if (!bms_equal(rinfo->left_relids, index->rel->relids)) CommuteClause(newclause); /* @@ -1273,7 +1266,6 @@ fix_indxqual_sublist(List *indexqual, * indexkey operand as needed, and get the index opclass. */ linitial(newclause->args) = fix_indxqual_operand(linitial(newclause->args), - baserelid, index, &opclass); @@ -1295,8 +1287,7 @@ fix_indxqual_sublist(List *indexqual, } static Node * -fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index, - Oid *opclass) +fix_indxqual_operand(Node *node, IndexOptInfo *index, Oid *opclass) { /* * We represent index keys by Var nodes having the varno of the base @@ -1316,7 +1307,7 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index, node = (Node *) ((RelabelType *) node)->arg; if (IsA(node, Var) && - ((Var *) node)->varno == baserelid) + ((Var *) node)->varno == index->rel->relid) { /* Try to match against simple index columns */ int varatt = ((Var *) node)->varattno; @@ -1353,7 +1344,7 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index, if (equal(node, indexkey)) { /* Found a match */ - result = makeVar(baserelid, pos + 1, + result = makeVar(index->rel->relid, pos + 1, exprType(lfirst(indexpr_item)), -1, 0); /* return the correct opclass, too */ diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 53b2197edd..b6b0cc505f 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.113 2005/03/26 23:29:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.114 2005/03/27 06:29:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -417,8 +417,7 @@ create_seqscan_path(Query *root, RelOptInfo *rel) * create_index_path * Creates a path node for an index scan. * - * 'rel' is the parent rel - * 'index' is an index on 'rel' + * 'index' is a usable index. * 'restriction_clauses' is a list of lists of RestrictInfo nodes * to be used as index qual conditions in the scan. * 'pathkeys' describes the ordering of the path. @@ -430,7 +429,6 @@ create_seqscan_path(Query *root, RelOptInfo *rel) */ IndexPath * create_index_path(Query *root, - RelOptInfo *rel, IndexOptInfo *index, List *restriction_clauses, List *pathkeys, @@ -440,11 +438,11 @@ create_index_path(Query *root, List *indexquals; pathnode->path.pathtype = T_IndexScan; - pathnode->path.parent = rel; + pathnode->path.parent = index->rel; pathnode->path.pathkeys = pathkeys; /* Convert clauses to indexquals the executor can handle */ - indexquals = expand_indexqual_conditions(rel, index, restriction_clauses); + indexquals = expand_indexqual_conditions(index, restriction_clauses); /* Flatten the clause-groups list to produce indexclauses list */ restriction_clauses = flatten_clausegroups_list(restriction_clauses); @@ -466,9 +464,9 @@ create_index_path(Query *root, * The number of rows is the same as the parent rel's estimate, since * this isn't a join inner indexscan. */ - pathnode->rows = rel->rows; + pathnode->rows = index->rel->rows; - cost_index(&pathnode->path, root, rel, index, indexquals, false); + cost_index(&pathnode->path, root, index, indexquals, false); return pathnode; } diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index c9679a19e2..6099211ba4 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.101 2005/03/24 19:14:49 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.102 2005/03/27 06:29:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -124,6 +124,7 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel) info = makeNode(IndexOptInfo); info->indexoid = index->indexrelid; + info->rel = rel; info->ncolumns = ncolumns = index->indnatts; /* diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index b5c024df31..4698e4d8cb 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.103 2005/02/21 06:43:04 neilc Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.104 2005/03/27 06:29:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -253,6 +253,7 @@ typedef struct IndexOptInfo NodeTag type; Oid indexoid; /* OID of the index relation */ + RelOptInfo *rel; /* back-link to index's table */ /* statistics from pg_class */ BlockNumber pages; /* number of disk pages in index */ diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index 6fc3487a90..9e379dd0c4 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.62 2004/12/31 22:03:36 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.63 2005/03/27 06:29:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,10 +50,8 @@ extern bool enable_mergejoin; extern bool enable_hashjoin; extern double clamp_row_est(double nrows); -extern void cost_seqscan(Path *path, Query *root, - RelOptInfo *baserel); -extern void cost_index(Path *path, Query *root, - RelOptInfo *baserel, IndexOptInfo *index, +extern void cost_seqscan(Path *path, Query *root, RelOptInfo *baserel); +extern void cost_index(Path *path, Query *root, IndexOptInfo *index, List *indexQuals, bool is_injoin); extern void cost_tidscan(Path *path, Query *root, RelOptInfo *baserel, List *tideval); diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 1efa654649..44e9b087b3 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.56 2004/12/31 22:03:36 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.57 2005/03/27 06:29:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,7 +28,7 @@ extern void set_cheapest(RelOptInfo *parent_rel); extern void add_path(RelOptInfo *parent_rel, Path *new_path); extern Path *create_seqscan_path(Query *root, RelOptInfo *rel); -extern IndexPath *create_index_path(Query *root, RelOptInfo *rel, +extern IndexPath *create_index_path(Query *root, IndexOptInfo *index, List *restriction_clauses, List *pathkeys, diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index d159e1ecf4..28c44444d7 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.79 2005/03/26 23:29:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.80 2005/03/27 06:29:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,11 +38,9 @@ extern void debug_print_rel(Query *root, RelOptInfo *rel); extern void create_index_paths(Query *root, RelOptInfo *rel); extern Path *best_inner_indexscan(Query *root, RelOptInfo *rel, Relids outer_relids, JoinType jointype); -extern List *group_clauses_by_indexkey_for_or(RelOptInfo *rel, - IndexOptInfo *index, +extern List *group_clauses_by_indexkey_for_or(IndexOptInfo *index, Expr *orsubclause); -extern List *expand_indexqual_conditions(RelOptInfo *rel, - IndexOptInfo *index, +extern List *expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups); extern void check_partial_indexes(Query *root, RelOptInfo *rel); extern bool pred_test(List *predicate_list, List *restrictinfo_list); @@ -108,8 +106,7 @@ extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths, List *pathkeys, double fraction); -extern List *build_index_pathkeys(Query *root, RelOptInfo *rel, - IndexOptInfo *index, +extern List *build_index_pathkeys(Query *root, IndexOptInfo *index, ScanDirection scandir); extern List *build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery);