Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CBRD-23689] If both outer join and inner join are present, the optimizer cannot find the optimal join order. #2351

Merged
merged 6 commits into from
Jun 17, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 20 additions & 33 deletions src/optimizer/query_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,7 @@ qo_analyze_term (QO_TERM * term, int term_type)
case PT_XOR:
/* get segments from the expression itself */
qo_expr_segs (env, pt_expr, &lhs_segs);
QO_TERM_SET_FLAG (term, QO_TERM_OR_PRED);
shparkcubrid marked this conversation as resolved.
Show resolved Hide resolved
break;

/* the other operators that can not be used as term; error case */
Expand All @@ -2085,9 +2086,8 @@ qo_analyze_term (QO_TERM * term, int term_type)
else
{ /* if (pt_expr->or_next == NULL) */
/* term that consist of more than one predicates; do same as PT_OR */

qo_expr_segs (env, pt_expr, &lhs_segs);

QO_TERM_SET_FLAG (term, QO_TERM_OR_PRED);
} /* if (pt_expr->or_next == NULL) */

/* get nodes from segments */
Expand Down Expand Up @@ -2630,27 +2630,6 @@ qo_analyze_term (QO_TERM * term, int term_type)
QO_TERM_CLEAR_FLAG (term, QO_TERM_MERGEABLE_EDGE);
}
}
else
{
QO_NODE *node;

for (i = 0; i < env->nnodes; i++)
{
node = QO_ENV_NODE (env, i);

if (QO_NODE_IDX (node) >= QO_NODE_IDX (head_node) && QO_NODE_IDX (node) < QO_NODE_IDX (tail_node))
{
if (QO_NODE_PT_JOIN_TYPE (node) == PT_JOIN_LEFT_OUTER
|| QO_NODE_PT_JOIN_TYPE (node) == PT_JOIN_RIGHT_OUTER
|| QO_NODE_PT_JOIN_TYPE (node) == PT_JOIN_FULL_OUTER)
{
/* record explicit join dependecy */
bitset_union (&(QO_NODE_OUTER_DEP_SET (tail_node)), &(QO_NODE_OUTER_DEP_SET (node)));
bitset_add (&(QO_NODE_OUTER_DEP_SET (tail_node)), QO_NODE_IDX (node));
}
}
}
} /* else */
}

wrapup:
Expand Down Expand Up @@ -6117,7 +6096,7 @@ qo_discover_edges (QO_ENV * env)
static void
qo_classify_outerjoin_terms (QO_ENV * env)
{
bool is_null_padded;
bool is_null_padded, is_outerjoin;
int n, i, t;
BITSET_ITERATOR iter;
QO_NODE *node, *on_node;
Expand Down Expand Up @@ -6177,11 +6156,23 @@ qo_classify_outerjoin_terms (QO_ENV * env)
}

nidx_self = -1; /* init */
is_outerjoin = false;
for (t = bitset_iterate (&(QO_TERM_NODES (term)), &iter); t != -1; t = bitset_next_member (&iter))
{
node = QO_ENV_NODE (env, t);

nidx_self = MAX (nidx_self, QO_NODE_IDX (node));
if (QO_TERM_IS_FLAGED (term, QO_TERM_OR_PRED) && QO_NODE_IS_OUTER_JOIN (node))
{
is_outerjoin = true; /* for OR predicate */
}
shparkcubrid marked this conversation as resolved.
Show resolved Hide resolved
}
if (nidx_self != -1)
{
node = QO_ENV_NODE (env, nidx_self);
if (QO_NODE_IS_OUTER_JOIN (node))
{
is_outerjoin = true;
}
shparkcubrid marked this conversation as resolved.
Show resolved Hide resolved
}
QO_ASSERT (env, nidx_self < env->nnodes);

Expand Down Expand Up @@ -6225,7 +6216,7 @@ qo_classify_outerjoin_terms (QO_ENV * env)
}
else
{
if (QO_NODE_IS_OUTER_JOIN (node))
if (is_outerjoin)
{
QO_TERM_CLASS (term) = QO_TC_AFTER_JOIN;

Expand All @@ -6241,17 +6232,13 @@ qo_classify_outerjoin_terms (QO_ENV * env)
if (nidx_self >= 0)
{
node = QO_ENV_NODE (env, nidx_self);

if (QO_ON_COND_TERM (term))
if (is_outerjoin)
{
if (QO_NODE_IS_OUTER_JOIN (node))
if (QO_ON_COND_TERM (term))
{
QO_TERM_CLASS (term) = QO_TC_DURING_JOIN;
}
}
else
{
if (QO_NODE_IS_OUTER_JOIN (node))
else
{
QO_TERM_CLASS (term) = QO_TC_AFTER_JOIN;
}
Expand Down
1 change: 1 addition & 0 deletions src/optimizer/query_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ struct qo_term
#define QO_TERM_NON_IDX_SARG_COLL 32 /* not suitable for key range/filter */
#define QO_TERM_MULTI_COLL_PRED 64 /* multi column && in OP, (a,b) in .. */
#define QO_TERM_MULTI_COLL_CONST 128 /* multi column && have constant value, (a,1) in .. */
#define QO_TERM_OR_PRED 256 /* or predicate. e.g.) a=1 or b=2 */

#define QO_TERM_IS_FLAGED(t, f) (QO_TERM_FLAG(t) & (int) (f))
#define QO_TERM_SET_FLAG(t, f) QO_TERM_FLAG(t) |= (int) (f)
Expand Down
17 changes: 1 addition & 16 deletions src/optimizer/query_planner.c
Original file line number Diff line number Diff line change
Expand Up @@ -1932,21 +1932,7 @@ qo_iscan_cost (QO_PLAN * planp)
{
termp = QO_ENV_TERM (QO_NODE_ENV (nodep), t);

if (i == 0)
{ /* the first key-range term of the index scan */
sel *= QO_TERM_SELECTIVITY (termp);
}
else
{ /* apply heuristic factor */
if (QO_TERM_SELECTIVITY (termp) < 0.1)
{
sel *= QO_TERM_SELECTIVITY (termp) * pow ((double) n, 2);
}
else
{
sel *= QO_TERM_SELECTIVITY (termp);
}
}
sel *= QO_TERM_SELECTIVITY (termp);

/* check upper bound */
sel = MIN (sel, 1.0);
Expand All @@ -1959,7 +1945,6 @@ qo_iscan_cost (QO_PLAN * planp)
i++;
}
}
n--;
}

sel_limit = 0.0; /* init */
Expand Down