diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 53 | ||||
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 10 | ||||
-rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 42 | ||||
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 16 | ||||
-rw-r--r-- | src/backend/optimizer/util/restrictinfo.c | 14 |
5 files changed, 78 insertions, 57 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index b9ccc770a43..c2fe837db65 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.150 2003/12/18 00:22:12 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.151 2003/12/30 23:53:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -64,9 +64,11 @@ static List *group_clauses_by_indexkey_for_join(Query *root, Relids outer_relids, JoinType jointype, bool isouterjoin); static bool match_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, - int indexcol, Oid opclass, Expr *clause); + int indexcol, Oid opclass, + Expr *clause, RestrictInfo *rinfo); static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, - int indexcol, Oid opclass, Expr *clause); + int indexcol, Oid opclass, + RestrictInfo *rinfo); static Oid indexable_operator(Expr *clause, Oid opclass, bool indexkey_on_left); static bool pred_test(List *predicate_list, List *restrictinfo_list, @@ -374,14 +376,14 @@ match_or_subclause_to_indexkey(RelOptInfo *rel, foreach(item, ((BoolExpr *) clause)->args) { if (match_clause_to_indexcol(rel, index, 0, opclass, - lfirst(item))) + lfirst(item), NULL)) return true; } return false; } else return match_clause_to_indexcol(rel, index, 0, opclass, - clause); + clause, NULL); } /*---------- @@ -445,7 +447,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, if (match_clause_to_indexcol(rel, index, indexcol, curClass, - subsubclause)) + subsubclause, NULL)) FastConc(&clausegroup, expand_indexqual_condition(subsubclause, curClass)); @@ -453,7 +455,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, } else if (match_clause_to_indexcol(rel, index, indexcol, curClass, - orsubclause)) + orsubclause, NULL)) FastConc(&clausegroup, expand_indexqual_condition(orsubclause, curClass)); @@ -470,7 +472,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, if (match_clause_to_indexcol(rel, index, indexcol, curClass, - rinfo->clause)) + rinfo->clause, rinfo)) FastConc(&clausegroup, expand_indexqual_condition(rinfo->clause, curClass)); @@ -550,7 +552,8 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index) index, indexcol, curClass, - rinfo->clause)) + rinfo->clause, + rinfo)) FastAppend(&clausegroup, rinfo); } @@ -625,7 +628,8 @@ group_clauses_by_indexkey_for_join(Query *root, index, indexcol, curClass, - rinfo->clause)) + rinfo->clause, + rinfo)) FastAppend(&clausegroup, rinfo); } @@ -654,7 +658,7 @@ group_clauses_by_indexkey_for_join(Query *root, index, indexcol, curClass, - rinfo->clause)) + rinfo)) { FastAppend(&clausegroup, rinfo); if (!jfoundhere) @@ -726,6 +730,7 @@ group_clauses_by_indexkey_for_join(Query *root, * 'indexcol' is a column number of 'index' (counting from 0). * 'opclass' is the corresponding operator class. * 'clause' is the clause to be tested. + * 'rinfo' is the clause's RestrictInfo, if available (NULL if not). * * Returns true if the clause can be used with this index key. * @@ -737,7 +742,8 @@ match_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, int indexcol, Oid opclass, - Expr *clause) + Expr *clause, + RestrictInfo *rinfo) { Node *leftop, *rightop; @@ -754,9 +760,13 @@ match_clause_to_indexcol(RelOptInfo *rel, * Check for clauses of the form: (indexkey operator constant) or * (constant operator indexkey). Anything that is a "pseudo constant" * expression will do. + * + * If we have the RestrictInfo available, we can make a more efficient + * test for pseudo-constness. */ if (match_index_to_operand(leftop, indexcol, rel, index) && - is_pseudo_constant_clause(rightop)) + (rinfo ? is_pseudo_constant_clause_relids(rightop, rinfo->right_relids) + : is_pseudo_constant_clause(rightop))) { if (is_indexable_operator(clause, opclass, true)) return true; @@ -771,7 +781,8 @@ match_clause_to_indexcol(RelOptInfo *rel, } if (match_index_to_operand(rightop, indexcol, rel, index) && - is_pseudo_constant_clause(leftop)) + (rinfo ? is_pseudo_constant_clause_relids(leftop, rinfo->left_relids) + : is_pseudo_constant_clause(leftop))) { if (is_indexable_operator(clause, opclass, false)) return true; @@ -813,7 +824,7 @@ match_clause_to_indexcol(RelOptInfo *rel, * 'index' is an index on 'rel'. * 'indexcol' is a column number of 'index' (counting from 0). * 'opclass' is the corresponding operator class. - * 'clause' is the clause to be tested. + * 'rinfo' is the clause to be tested (as a RestrictInfo node). * * Returns true if the clause can be used with this index key. * @@ -825,8 +836,9 @@ match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, int indexcol, Oid opclass, - Expr *clause) + RestrictInfo *rinfo) { + Expr *clause = rinfo->clause; Node *leftop, *rightop; @@ -846,27 +858,25 @@ match_join_clause_to_indexcol(RelOptInfo *rel, */ if (match_index_to_operand(leftop, indexcol, rel, index)) { - Relids othervarnos = pull_varnos(rightop); + Relids othervarnos = rinfo->right_relids; bool isIndexable; isIndexable = !bms_overlap(rel->relids, othervarnos) && !contain_volatile_functions(rightop) && is_indexable_operator(clause, opclass, true); - bms_free(othervarnos); return isIndexable; } if (match_index_to_operand(rightop, indexcol, rel, index)) { - Relids othervarnos = pull_varnos(leftop); + Relids othervarnos = rinfo->left_relids; bool isIndexable; isIndexable = !bms_overlap(rel->relids, othervarnos) && !contain_volatile_functions(leftop) && is_indexable_operator(clause, opclass, false); - bms_free(othervarnos); return isIndexable; } @@ -1351,7 +1361,6 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) foreach(j, joininfo->jinfo_restrictinfo) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(j); - Expr *clause = rinfo->clause; int indexcol = 0; Oid *classes = index->classlist; @@ -1363,7 +1372,7 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) index, indexcol, curClass, - clause)) + rinfo)) { match_found = true; break; diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 5b95ec7c4dd..91cd0ab22a5 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.83 2003/11/29 19:51:50 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.84 2003/12/30 23:53:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -690,7 +690,7 @@ hash_inner_and_outer(Query *root, { RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i); - if (restrictinfo->left_relids == NULL || + if (!restrictinfo->canjoin || restrictinfo->hashjoinoperator == InvalidOid) continue; /* not hashjoinable */ @@ -809,12 +809,12 @@ select_mergejoin_clauses(RelOptInfo *joinrel, switch (jointype) { case JOIN_RIGHT: - if (restrictinfo->left_relids == NULL || + if (!restrictinfo->canjoin || restrictinfo->mergejoinoperator == InvalidOid) return NIL; /* not mergejoinable */ break; case JOIN_FULL: - if (restrictinfo->left_relids == NULL || + if (!restrictinfo->canjoin || restrictinfo->mergejoinoperator == InvalidOid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -826,7 +826,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel, } } - if (restrictinfo->left_relids == NULL || + if (!restrictinfo->canjoin || restrictinfo->mergejoinoperator == InvalidOid) continue; /* not mergejoinable */ diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 5612430a390..3da001e997a 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.93 2003/11/29 19:51:50 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.94 2003/12/30 23:53:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -380,12 +380,13 @@ distribute_qual_to_rels(Query *root, Node *clause, bool can_be_equijoin; restrictinfo->clause = (Expr *) clause; + restrictinfo->canjoin = false; /* set below, if join clause */ + restrictinfo->left_relids = NULL; + restrictinfo->right_relids = NULL; restrictinfo->subclauseindices = NIL; restrictinfo->eval_cost.startup = -1; /* not computed until * needed */ restrictinfo->this_selec = -1; /* not computed until needed */ - restrictinfo->left_relids = NULL; /* set below, if join clause */ - restrictinfo->right_relids = NULL; restrictinfo->mergejoinoperator = InvalidOid; restrictinfo->left_sortop = InvalidOid; restrictinfo->right_sortop = InvalidOid; @@ -510,6 +511,15 @@ distribute_qual_to_rels(Query *root, Node *clause, restrictinfo->ispusheddown = ispusheddown || !bms_equal(relids, qualscope); + /* + * If it's a binary opclause, set up left/right relids info. + */ + if (is_opclause(clause) && length(((OpExpr *) clause)->args) == 2) + { + restrictinfo->left_relids = pull_varnos(get_leftop((Expr *) clause)); + restrictinfo->right_relids = pull_varnos(get_rightop((Expr *) clause)); + } + switch (bms_membership(relids)) { case BMS_SINGLETON: @@ -562,18 +572,11 @@ distribute_qual_to_rels(Query *root, Node *clause, */ if (is_opclause(clause) && length(((OpExpr *) clause)->args) == 2) { - Relids left_relids; - Relids right_relids; - - left_relids = pull_varnos(get_leftop((Expr *) clause)); - right_relids = pull_varnos(get_rightop((Expr *) clause)); - if (!bms_is_empty(left_relids) && - !bms_is_empty(right_relids) && - !bms_overlap(left_relids, right_relids)) - { - restrictinfo->left_relids = left_relids; - restrictinfo->right_relids = right_relids; - } + if (!bms_is_empty(restrictinfo->left_relids) && + !bms_is_empty(restrictinfo->right_relids) && + !bms_overlap(restrictinfo->left_relids, + restrictinfo->right_relids)) + restrictinfo->canjoin = true; } /* @@ -814,13 +817,14 @@ qual_is_redundant(Query *root, List *equalexprs; bool someadded; - newleft = get_leftop(restrictinfo->clause); - newright = get_rightop(restrictinfo->clause); - /* Never redundant unless vars appear on both sides */ - if (!contain_var_clause(newleft) || !contain_var_clause(newright)) + if (bms_is_empty(restrictinfo->left_relids) || + bms_is_empty(restrictinfo->right_relids)) return false; + newleft = get_leftop(restrictinfo->clause); + newright = get_rightop(restrictinfo->clause); + /* * Set cached pathkeys. NB: it is okay to do this now because this * routine is only invoked while we are generating implied equalities. diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index d6f0bb3ad2e..35efa6bc630 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.157 2003/12/28 21:57:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.158 2003/12/30 23:53:15 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -812,6 +812,20 @@ is_pseudo_constant_clause(Node *clause) } /* + * is_pseudo_constant_clause_relids + * Same as above, except caller already has available the var membership + * of the clause; this lets us avoid the contain_var_clause() scan. + */ +bool +is_pseudo_constant_clause_relids(Node *clause, Relids relids) +{ + if (bms_is_empty(relids) && + !contain_volatile_functions(clause)) + return true; + return false; +} + +/* * pull_constant_clauses * Scan through a list of qualifications and separate "constant" quals * from those that are not. diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index 2ae122e92a9..f77966a2262 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.20 2003/11/29 19:51:51 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.21 2003/12/30 23:53:15 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -227,15 +227,9 @@ join_clause_is_redundant(Query *root, if (redundant) { - /* - * It looks redundant, now check for "var = const" case. If - * left_relids/right_relids are set, then there are definitely - * vars on both sides; else we must check the hard way. - */ - if (rinfo->left_relids) - return true; /* var = var, so redundant */ - if (contain_var_clause(get_leftop(rinfo->clause)) && - contain_var_clause(get_rightop(rinfo->clause))) + /* It looks redundant, but check for "var = const" case */ + if (!bms_is_empty(rinfo->left_relids) && + !bms_is_empty(rinfo->right_relids)) return true; /* var = var, so redundant */ /* else var = const, not redundant */ } |