Commit be6c38b9 authored by Tom Lane's avatar Tom Lane

Adjust the definition of RestrictInfo's left_relids and right_relids

fields: now they are valid whenever the clause is a binary opclause,
not only when it is a potential join clause (there is a new boolean
field canjoin to signal the latter condition).  This lets us avoid
recomputing the relid sets over and over while examining indexes.
Still more work to do to make this as useful as it could be, because
there are places that could use the info but don't have access to the
RestrictInfo node.
parent 5e545151
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.269 2003/11/29 19:51:49 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.270 2003/12/30 23:53:14 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1169,11 +1169,12 @@ _copyRestrictInfo(RestrictInfo *from) ...@@ -1169,11 +1169,12 @@ _copyRestrictInfo(RestrictInfo *from)
COPY_NODE_FIELD(clause); COPY_NODE_FIELD(clause);
COPY_SCALAR_FIELD(ispusheddown); COPY_SCALAR_FIELD(ispusheddown);
COPY_SCALAR_FIELD(canjoin);
COPY_BITMAPSET_FIELD(left_relids);
COPY_BITMAPSET_FIELD(right_relids);
COPY_NODE_FIELD(subclauseindices); /* XXX probably bad */ COPY_NODE_FIELD(subclauseindices); /* XXX probably bad */
COPY_SCALAR_FIELD(eval_cost); COPY_SCALAR_FIELD(eval_cost);
COPY_SCALAR_FIELD(this_selec); COPY_SCALAR_FIELD(this_selec);
COPY_BITMAPSET_FIELD(left_relids);
COPY_BITMAPSET_FIELD(right_relids);
COPY_SCALAR_FIELD(mergejoinoperator); COPY_SCALAR_FIELD(mergejoinoperator);
COPY_SCALAR_FIELD(left_sortop); COPY_SCALAR_FIELD(left_sortop);
COPY_SCALAR_FIELD(right_sortop); COPY_SCALAR_FIELD(right_sortop);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.210 2003/11/29 19:51:49 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.211 2003/12/30 23:53:14 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -563,16 +563,9 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b) ...@@ -563,16 +563,9 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
COMPARE_SCALAR_FIELD(ispusheddown); COMPARE_SCALAR_FIELD(ispusheddown);
/* /*
* We ignore subclauseindices, eval_cost, this_selec, * We ignore all the remaining fields, since they may not be set yet,
* left/right_relids, left/right_pathkey, and left/right_bucketsize, * and should be derivable from the clause anyway.
* since they may not be set yet, and should be derivable from the
* clause anyway. Probably it's not really necessary to compare any
* of these remaining fields ...
*/ */
COMPARE_SCALAR_FIELD(mergejoinoperator);
COMPARE_SCALAR_FIELD(left_sortop);
COMPARE_SCALAR_FIELD(right_sortop);
COMPARE_SCALAR_FIELD(hashjoinoperator);
return true; return true;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.222 2003/11/29 19:51:49 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.223 2003/12/30 23:53:14 tgl Exp $
* *
* NOTES * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
...@@ -1074,9 +1074,10 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node) ...@@ -1074,9 +1074,10 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node)
/* NB: this isn't a complete set of fields */ /* NB: this isn't a complete set of fields */
WRITE_NODE_FIELD(clause); WRITE_NODE_FIELD(clause);
WRITE_BOOL_FIELD(ispusheddown); WRITE_BOOL_FIELD(ispusheddown);
WRITE_NODE_FIELD(subclauseindices); WRITE_BOOL_FIELD(canjoin);
WRITE_BITMAPSET_FIELD(left_relids); WRITE_BITMAPSET_FIELD(left_relids);
WRITE_BITMAPSET_FIELD(right_relids); WRITE_BITMAPSET_FIELD(right_relids);
WRITE_NODE_FIELD(subclauseindices);
WRITE_OID_FIELD(mergejoinoperator); WRITE_OID_FIELD(mergejoinoperator);
WRITE_OID_FIELD(left_sortop); WRITE_OID_FIELD(left_sortop);
WRITE_OID_FIELD(right_sortop); WRITE_OID_FIELD(right_sortop);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -64,9 +64,11 @@ static List *group_clauses_by_indexkey_for_join(Query *root,
Relids outer_relids, Relids outer_relids,
JoinType jointype, bool isouterjoin); JoinType jointype, bool isouterjoin);
static bool match_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index, 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, 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, static Oid indexable_operator(Expr *clause, Oid opclass,
bool indexkey_on_left); bool indexkey_on_left);
static bool pred_test(List *predicate_list, List *restrictinfo_list, static bool pred_test(List *predicate_list, List *restrictinfo_list,
...@@ -374,14 +376,14 @@ match_or_subclause_to_indexkey(RelOptInfo *rel, ...@@ -374,14 +376,14 @@ match_or_subclause_to_indexkey(RelOptInfo *rel,
foreach(item, ((BoolExpr *) clause)->args) foreach(item, ((BoolExpr *) clause)->args)
{ {
if (match_clause_to_indexcol(rel, index, 0, opclass, if (match_clause_to_indexcol(rel, index, 0, opclass,
lfirst(item))) lfirst(item), NULL))
return true; return true;
} }
return false; return false;
} }
else else
return match_clause_to_indexcol(rel, index, 0, opclass, return match_clause_to_indexcol(rel, index, 0, opclass,
clause); clause, NULL);
} }
/*---------- /*----------
...@@ -445,7 +447,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, ...@@ -445,7 +447,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
if (match_clause_to_indexcol(rel, index, if (match_clause_to_indexcol(rel, index,
indexcol, curClass, indexcol, curClass,
subsubclause)) subsubclause, NULL))
FastConc(&clausegroup, FastConc(&clausegroup,
expand_indexqual_condition(subsubclause, expand_indexqual_condition(subsubclause,
curClass)); curClass));
...@@ -453,7 +455,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, ...@@ -453,7 +455,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
} }
else if (match_clause_to_indexcol(rel, index, else if (match_clause_to_indexcol(rel, index,
indexcol, curClass, indexcol, curClass,
orsubclause)) orsubclause, NULL))
FastConc(&clausegroup, FastConc(&clausegroup,
expand_indexqual_condition(orsubclause, expand_indexqual_condition(orsubclause,
curClass)); curClass));
...@@ -470,7 +472,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel, ...@@ -470,7 +472,7 @@ extract_or_indexqual_conditions(RelOptInfo *rel,
if (match_clause_to_indexcol(rel, index, if (match_clause_to_indexcol(rel, index,
indexcol, curClass, indexcol, curClass,
rinfo->clause)) rinfo->clause, rinfo))
FastConc(&clausegroup, FastConc(&clausegroup,
expand_indexqual_condition(rinfo->clause, expand_indexqual_condition(rinfo->clause,
curClass)); curClass));
...@@ -550,7 +552,8 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index) ...@@ -550,7 +552,8 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
index, index,
indexcol, indexcol,
curClass, curClass,
rinfo->clause)) rinfo->clause,
rinfo))
FastAppend(&clausegroup, rinfo); FastAppend(&clausegroup, rinfo);
} }
...@@ -625,7 +628,8 @@ group_clauses_by_indexkey_for_join(Query *root, ...@@ -625,7 +628,8 @@ group_clauses_by_indexkey_for_join(Query *root,
index, index,
indexcol, indexcol,
curClass, curClass,
rinfo->clause)) rinfo->clause,
rinfo))
FastAppend(&clausegroup, rinfo); FastAppend(&clausegroup, rinfo);
} }
...@@ -654,7 +658,7 @@ group_clauses_by_indexkey_for_join(Query *root, ...@@ -654,7 +658,7 @@ group_clauses_by_indexkey_for_join(Query *root,
index, index,
indexcol, indexcol,
curClass, curClass,
rinfo->clause)) rinfo))
{ {
FastAppend(&clausegroup, rinfo); FastAppend(&clausegroup, rinfo);
if (!jfoundhere) if (!jfoundhere)
...@@ -726,6 +730,7 @@ group_clauses_by_indexkey_for_join(Query *root, ...@@ -726,6 +730,7 @@ group_clauses_by_indexkey_for_join(Query *root,
* 'indexcol' is a column number of 'index' (counting from 0). * 'indexcol' is a column number of 'index' (counting from 0).
* 'opclass' is the corresponding operator class. * 'opclass' is the corresponding operator class.
* 'clause' is the clause to be tested. * '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. * Returns true if the clause can be used with this index key.
* *
...@@ -737,7 +742,8 @@ match_clause_to_indexcol(RelOptInfo *rel, ...@@ -737,7 +742,8 @@ match_clause_to_indexcol(RelOptInfo *rel,
IndexOptInfo *index, IndexOptInfo *index,
int indexcol, int indexcol,
Oid opclass, Oid opclass,
Expr *clause) Expr *clause,
RestrictInfo *rinfo)
{ {
Node *leftop, Node *leftop,
*rightop; *rightop;
...@@ -754,9 +760,13 @@ match_clause_to_indexcol(RelOptInfo *rel, ...@@ -754,9 +760,13 @@ match_clause_to_indexcol(RelOptInfo *rel,
* Check for clauses of the form: (indexkey operator constant) or * Check for clauses of the form: (indexkey operator constant) or
* (constant operator indexkey). Anything that is a "pseudo constant" * (constant operator indexkey). Anything that is a "pseudo constant"
* expression will do. * 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) && 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)) if (is_indexable_operator(clause, opclass, true))
return true; return true;
...@@ -771,7 +781,8 @@ match_clause_to_indexcol(RelOptInfo *rel, ...@@ -771,7 +781,8 @@ match_clause_to_indexcol(RelOptInfo *rel,
} }
if (match_index_to_operand(rightop, indexcol, rel, index) && 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)) if (is_indexable_operator(clause, opclass, false))
return true; return true;
...@@ -813,7 +824,7 @@ match_clause_to_indexcol(RelOptInfo *rel, ...@@ -813,7 +824,7 @@ match_clause_to_indexcol(RelOptInfo *rel,
* 'index' is an index on 'rel'. * 'index' is an index on 'rel'.
* 'indexcol' is a column number of 'index' (counting from 0). * 'indexcol' is a column number of 'index' (counting from 0).
* 'opclass' is the corresponding operator class. * '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. * Returns true if the clause can be used with this index key.
* *
...@@ -825,8 +836,9 @@ match_join_clause_to_indexcol(RelOptInfo *rel, ...@@ -825,8 +836,9 @@ match_join_clause_to_indexcol(RelOptInfo *rel,
IndexOptInfo *index, IndexOptInfo *index,
int indexcol, int indexcol,
Oid opclass, Oid opclass,
Expr *clause) RestrictInfo *rinfo)
{ {
Expr *clause = rinfo->clause;
Node *leftop, Node *leftop,
*rightop; *rightop;
...@@ -846,27 +858,25 @@ match_join_clause_to_indexcol(RelOptInfo *rel, ...@@ -846,27 +858,25 @@ match_join_clause_to_indexcol(RelOptInfo *rel,
*/ */
if (match_index_to_operand(leftop, indexcol, rel, index)) if (match_index_to_operand(leftop, indexcol, rel, index))
{ {
Relids othervarnos = pull_varnos(rightop); Relids othervarnos = rinfo->right_relids;
bool isIndexable; bool isIndexable;
isIndexable = isIndexable =
!bms_overlap(rel->relids, othervarnos) && !bms_overlap(rel->relids, othervarnos) &&
!contain_volatile_functions(rightop) && !contain_volatile_functions(rightop) &&
is_indexable_operator(clause, opclass, true); is_indexable_operator(clause, opclass, true);
bms_free(othervarnos);
return isIndexable; return isIndexable;
} }
if (match_index_to_operand(rightop, indexcol, rel, index)) if (match_index_to_operand(rightop, indexcol, rel, index))
{ {
Relids othervarnos = pull_varnos(leftop); Relids othervarnos = rinfo->left_relids;
bool isIndexable; bool isIndexable;
isIndexable = isIndexable =
!bms_overlap(rel->relids, othervarnos) && !bms_overlap(rel->relids, othervarnos) &&
!contain_volatile_functions(leftop) && !contain_volatile_functions(leftop) &&
is_indexable_operator(clause, opclass, false); is_indexable_operator(clause, opclass, false);
bms_free(othervarnos);
return isIndexable; return isIndexable;
} }
...@@ -1351,7 +1361,6 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) ...@@ -1351,7 +1361,6 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index)
foreach(j, joininfo->jinfo_restrictinfo) foreach(j, joininfo->jinfo_restrictinfo)
{ {
RestrictInfo *rinfo = (RestrictInfo *) lfirst(j); RestrictInfo *rinfo = (RestrictInfo *) lfirst(j);
Expr *clause = rinfo->clause;
int indexcol = 0; int indexcol = 0;
Oid *classes = index->classlist; Oid *classes = index->classlist;
...@@ -1363,7 +1372,7 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index) ...@@ -1363,7 +1372,7 @@ indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index)
index, index,
indexcol, indexcol,
curClass, curClass,
clause)) rinfo))
{ {
match_found = true; match_found = true;
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -690,7 +690,7 @@ hash_inner_and_outer(Query *root,
{ {
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i); RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
if (restrictinfo->left_relids == NULL || if (!restrictinfo->canjoin ||
restrictinfo->hashjoinoperator == InvalidOid) restrictinfo->hashjoinoperator == InvalidOid)
continue; /* not hashjoinable */ continue; /* not hashjoinable */
...@@ -809,12 +809,12 @@ select_mergejoin_clauses(RelOptInfo *joinrel, ...@@ -809,12 +809,12 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
switch (jointype) switch (jointype)
{ {
case JOIN_RIGHT: case JOIN_RIGHT:
if (restrictinfo->left_relids == NULL || if (!restrictinfo->canjoin ||
restrictinfo->mergejoinoperator == InvalidOid) restrictinfo->mergejoinoperator == InvalidOid)
return NIL; /* not mergejoinable */ return NIL; /* not mergejoinable */
break; break;
case JOIN_FULL: case JOIN_FULL:
if (restrictinfo->left_relids == NULL || if (!restrictinfo->canjoin ||
restrictinfo->mergejoinoperator == InvalidOid) restrictinfo->mergejoinoperator == InvalidOid)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
...@@ -826,7 +826,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel, ...@@ -826,7 +826,7 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
} }
} }
if (restrictinfo->left_relids == NULL || if (!restrictinfo->canjoin ||
restrictinfo->mergejoinoperator == InvalidOid) restrictinfo->mergejoinoperator == InvalidOid)
continue; /* not mergejoinable */ continue; /* not mergejoinable */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -380,12 +380,13 @@ distribute_qual_to_rels(Query *root, Node *clause,
bool can_be_equijoin; bool can_be_equijoin;
restrictinfo->clause = (Expr *) clause; restrictinfo->clause = (Expr *) clause;
restrictinfo->canjoin = false; /* set below, if join clause */
restrictinfo->left_relids = NULL;
restrictinfo->right_relids = NULL;
restrictinfo->subclauseindices = NIL; restrictinfo->subclauseindices = NIL;
restrictinfo->eval_cost.startup = -1; /* not computed until restrictinfo->eval_cost.startup = -1; /* not computed until
* needed */ * needed */
restrictinfo->this_selec = -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->mergejoinoperator = InvalidOid;
restrictinfo->left_sortop = InvalidOid; restrictinfo->left_sortop = InvalidOid;
restrictinfo->right_sortop = InvalidOid; restrictinfo->right_sortop = InvalidOid;
...@@ -510,6 +511,15 @@ distribute_qual_to_rels(Query *root, Node *clause, ...@@ -510,6 +511,15 @@ distribute_qual_to_rels(Query *root, Node *clause,
restrictinfo->ispusheddown = ispusheddown || !bms_equal(relids, restrictinfo->ispusheddown = ispusheddown || !bms_equal(relids,
qualscope); 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)) switch (bms_membership(relids))
{ {
case BMS_SINGLETON: case BMS_SINGLETON:
...@@ -562,18 +572,11 @@ distribute_qual_to_rels(Query *root, Node *clause, ...@@ -562,18 +572,11 @@ distribute_qual_to_rels(Query *root, Node *clause,
*/ */
if (is_opclause(clause) && length(((OpExpr *) clause)->args) == 2) if (is_opclause(clause) && length(((OpExpr *) clause)->args) == 2)
{ {
Relids left_relids; if (!bms_is_empty(restrictinfo->left_relids) &&
Relids right_relids; !bms_is_empty(restrictinfo->right_relids) &&
!bms_overlap(restrictinfo->left_relids,
left_relids = pull_varnos(get_leftop((Expr *) clause)); restrictinfo->right_relids))
right_relids = pull_varnos(get_rightop((Expr *) clause)); restrictinfo->canjoin = true;
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;
}
} }
/* /*
...@@ -814,13 +817,14 @@ qual_is_redundant(Query *root, ...@@ -814,13 +817,14 @@ qual_is_redundant(Query *root,
List *equalexprs; List *equalexprs;
bool someadded; bool someadded;
newleft = get_leftop(restrictinfo->clause);
newright = get_rightop(restrictinfo->clause);
/* Never redundant unless vars appear on both sides */ /* 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; 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 * Set cached pathkeys. NB: it is okay to do this now because this
* routine is only invoked while we are generating implied equalities. * routine is only invoked while we are generating implied equalities.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -811,6 +811,20 @@ is_pseudo_constant_clause(Node *clause) ...@@ -811,6 +811,20 @@ is_pseudo_constant_clause(Node *clause)
return false; return false;
} }
/*
* 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 * pull_constant_clauses
* Scan through a list of qualifications and separate "constant" quals * Scan through a list of qualifications and separate "constant" quals
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -227,15 +227,9 @@ join_clause_is_redundant(Query *root,
if (redundant) if (redundant)
{ {
/* /* It looks redundant, but check for "var = const" case */
* It looks redundant, now check for "var = const" case. If if (!bms_is_empty(rinfo->left_relids) &&
* left_relids/right_relids are set, then there are definitely !bms_is_empty(rinfo->right_relids))
* 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)))
return true; /* var = var, so redundant */ return true; /* var = var, so redundant */
/* else var = const, not redundant */ /* else var = const, not redundant */
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.87 2003/12/28 21:57:37 tgl Exp $ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.88 2003/12/30 23:53:15 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -596,6 +596,19 @@ typedef struct RestrictInfo ...@@ -596,6 +596,19 @@ typedef struct RestrictInfo
bool ispusheddown; /* TRUE if clause was pushed down in level */ bool ispusheddown; /* TRUE if clause was pushed down in level */
/*
* This flag is set true if the clause looks potentially useful as a
* merge or hash join clause, that is if it is a binary opclause with
* nonoverlapping sets of relids referenced in the left and right sides.
* (Whether the operator is actually merge or hash joinable isn't
* checked, however.)
*/
bool canjoin;
/* These fields are set for any binary opclause: */
Relids left_relids; /* relids in left side of clause */
Relids right_relids; /* relids in right side of clause */
/* only used if clause is an OR clause: */ /* only used if clause is an OR clause: */
List *subclauseindices; /* indexes matching subclauses */ List *subclauseindices; /* indexes matching subclauses */
/* subclauseindices is a List of Lists of IndexOptInfos */ /* subclauseindices is a List of Lists of IndexOptInfos */
...@@ -604,15 +617,6 @@ typedef struct RestrictInfo ...@@ -604,15 +617,6 @@ typedef struct RestrictInfo
QualCost eval_cost; /* eval cost of clause; -1 if not yet set */ QualCost eval_cost; /* eval cost of clause; -1 if not yet set */
Selectivity this_selec; /* selectivity; -1 if not yet set */ Selectivity this_selec; /* selectivity; -1 if not yet set */
/*
* If the clause looks useful for joining --- that is, it is a binary
* opclause with nonoverlapping sets of relids referenced in the left
* and right sides --- then these two fields are set to sets of the
* referenced relids. Otherwise they are both NULL.
*/
Relids left_relids; /* relids in left side of join clause */
Relids right_relids; /* relids in right side of join clause */
/* valid if clause is mergejoinable, else InvalidOid: */ /* valid if clause is mergejoinable, else InvalidOid: */
Oid mergejoinoperator; /* copy of clause operator */ Oid mergejoinoperator; /* copy of clause operator */
Oid left_sortop; /* leftside sortop needed for mergejoin */ Oid left_sortop; /* leftside sortop needed for mergejoin */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.69 2003/11/29 22:41:07 pgsql Exp $ * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.70 2003/12/30 23:53:15 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -54,6 +54,7 @@ extern bool contain_volatile_functions(Node *clause); ...@@ -54,6 +54,7 @@ extern bool contain_volatile_functions(Node *clause);
extern bool contain_nonstrict_functions(Node *clause); extern bool contain_nonstrict_functions(Node *clause);
extern bool is_pseudo_constant_clause(Node *clause); extern bool is_pseudo_constant_clause(Node *clause);
extern bool is_pseudo_constant_clause_relids(Node *clause, Relids relids);
extern List *pull_constant_clauses(List *quals, List **constantQual); extern List *pull_constant_clauses(List *quals, List **constantQual);
extern bool has_distinct_on_clause(Query *query); extern bool has_distinct_on_clause(Query *query);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment