Skip to content

Commit

Permalink
[CBRD-25335] Problem where nodes without a join relationship are conn…
Browse files Browse the repository at this point in the history
…ected and incorrect results are output. (#5170)

http://jira.cubrid.org/browse/CBRD-25335

Fix so that dummy_join_term is not generated when a node has a join predicate.
as-is
 add dummy_join_term for ANSI node without join term for previous node.
to-be
 add dummy_join_term for ANSI node without join term.

In the case of right outer join, dependency is set on the entire preceding table connected by ANSI join. and Remove the right_dep_set that is no longer needed.
  • Loading branch information
shparkcubrid authored and mhoh3963 committed Aug 6, 2024
1 parent 4e06329 commit d29a35a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 39 deletions.
50 changes: 20 additions & 30 deletions src/optimizer/query_graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ qo_optimize_helper (QO_ENV * env)
QO_TERM *term;
QO_NODE *node, *p_node;
BITSET nodeset;
int n;
int n, k;

parser = QO_ENV_PARSER (env);
tree = QO_ENV_PT_TREE (env);
Expand Down Expand Up @@ -517,12 +517,7 @@ qo_optimize_helper (QO_ENV * env)
if (QO_TERM_CLASS (term) == QO_TC_JOIN)
{
QO_ASSERT (env, QO_ON_COND_TERM (term));

n = QO_TERM_LOCATION (term);
if (QO_NODE_LOCATION (QO_TERM_HEAD (term)) == n - 1 && QO_NODE_LOCATION (QO_TERM_TAIL (term)) == n)
{
bitset_add (&nodeset, QO_NODE_IDX (QO_TERM_TAIL (term)));
}
bitset_add (&nodeset, QO_NODE_IDX (QO_TERM_TAIL (term)));
}

conj->next = next;
Expand All @@ -540,19 +535,30 @@ qo_optimize_helper (QO_ENV * env)
conj->next = next;
}

/* check join-edge for ansi(explicit) join */
for (n = 1; n < env->nnodes; n++)
{
node = QO_ENV_NODE (env, n);

/* check join-edge for explicit join */
if (QO_NODE_PT_JOIN_TYPE (node) != PT_JOIN_NONE && QO_NODE_PT_JOIN_TYPE (node) != PT_JOIN_CROSS
&& !BITSET_MEMBER (nodeset, n))
/* In case of ansi join without join-edge, a dummy join term is added to maintain the outer join. */
if (QO_NODE_IS_ANSI_JOIN (node) && !BITSET_MEMBER (nodeset, n))
{
p_node = QO_ENV_NODE (env, n - 1);
(void) qo_add_dummy_join_term (env, p_node, node);
/* Is it safe to pass node[n-1] as head node? Yes, because the sequence of QO_NODEs corresponds to the
* sequence of PT_SPEC list
*/
}

/* set dep set for right outer join */
if (QO_NODE_PT_JOIN_TYPE (node) == PT_JOIN_RIGHT_OUTER)
{
/* In the case of right outer join, dependency is set on the entire preceding table connected by ANSI join. */
k = n - 1;
p_node = QO_ENV_NODE (env, k);
QO_ADD_OUTER_DEP_SET (node, p_node);

while (k > 0 && QO_NODE_IS_ANSI_JOIN (p_node))
{
p_node = QO_ENV_NODE (env, --k);
QO_ADD_OUTER_DEP_SET (node, p_node);
}
}
}

Expand Down Expand Up @@ -1920,11 +1926,9 @@ qo_add_dummy_join_term (QO_ENV * env, QO_NODE * p_node, QO_NODE * on_node)
{
case PT_JOIN_INNER:
QO_TERM_JOIN_TYPE (term) = JOIN_INNER;
QO_ADD_RIGHT_DEP_SET (on_node, p_node);
break;
case PT_JOIN_LEFT_OUTER:
QO_TERM_JOIN_TYPE (term) = JOIN_LEFT;
QO_ADD_RIGHT_DEP_SET (on_node, p_node);
for (i = 0; i < env->nterms; i++)
{
temp_term = QO_ENV_TERM (env, i);
Expand All @@ -1942,9 +1946,7 @@ qo_add_dummy_join_term (QO_ENV * env, QO_NODE * p_node, QO_NODE * on_node)
break;
case PT_JOIN_RIGHT_OUTER:
QO_TERM_JOIN_TYPE (term) = JOIN_RIGHT;
QO_ADD_RIGHT_DEP_SET (on_node, p_node);
QO_ADD_OUTER_DEP_SET (on_node, p_node);
QO_ADD_RIGHT_TO_OUTER (on_node, p_node);
break;
case PT_JOIN_FULL_OUTER: /* not used */
QO_TERM_JOIN_TYPE (term) = JOIN_OUTER;
Expand Down Expand Up @@ -2661,15 +2663,12 @@ qo_analyze_term (QO_TERM * term, int term_type)
if (QO_NODE_PT_JOIN_TYPE (on_node) == PT_JOIN_LEFT_OUTER)
{
QO_TERM_JOIN_TYPE (term) = JOIN_LEFT;
QO_ADD_RIGHT_DEP_SET (on_node, head_node);
QO_ADD_OUTER_DEP_SET (on_node, head_node);
}
else if (QO_NODE_PT_JOIN_TYPE (on_node) == PT_JOIN_RIGHT_OUTER)
{
QO_TERM_JOIN_TYPE (term) = JOIN_RIGHT;
QO_ADD_RIGHT_DEP_SET (on_node, head_node);
QO_ADD_OUTER_DEP_SET (on_node, head_node);
QO_ADD_RIGHT_TO_OUTER (on_node, head_node);
}
else if (QO_NODE_PT_JOIN_TYPE (on_node) == PT_JOIN_FULL_OUTER)
{ /* not used */
Expand All @@ -2678,7 +2677,6 @@ qo_analyze_term (QO_TERM * term, int term_type)
else if (QO_NODE_PT_JOIN_TYPE (on_node) == PT_JOIN_INNER)
{
QO_TERM_JOIN_TYPE (term) = JOIN_INNER;
QO_ADD_RIGHT_DEP_SET (on_node, head_node);
}
}
else
Expand Down Expand Up @@ -8202,7 +8200,6 @@ qo_node_clear (QO_ENV * env, int idx)
bitset_init (&(QO_NODE_SUBQUERIES (node)), env);
bitset_init (&(QO_NODE_SEGS (node)), env);
bitset_init (&(QO_NODE_OUTER_DEP_SET (node)), env);
bitset_init (&(QO_NODE_RIGHT_DEP_SET (node)), env);

QO_NODE_HINT (node) = PT_HINT_NONE;
}
Expand All @@ -8221,7 +8218,6 @@ qo_node_free (QO_NODE * node)
bitset_delset (&(QO_NODE_SEGS (node)));
bitset_delset (&(QO_NODE_SUBQUERIES (node)));
bitset_delset (&(QO_NODE_OUTER_DEP_SET (node)));
bitset_delset (&(QO_NODE_RIGHT_DEP_SET (node)));
qo_free_class_info (QO_NODE_ENV (node), QO_NODE_INFO (node));
if (QO_NODE_INDEXES (node))
{
Expand Down Expand Up @@ -8342,12 +8338,6 @@ qo_node_dump (QO_NODE * node, FILE * f)
bitset_print (&(QO_NODE_DEP_SET (node)), f);
fputs (")", f);
}
if (!bitset_is_empty (&(QO_NODE_RIGHT_DEP_SET (node))))
{
fputs (" (right-dep-set ", f);
bitset_print (&(QO_NODE_RIGHT_DEP_SET (node)), f);
fputs (")", f);
}

fprintf (f, " (loc %d)", entity->info.spec.location);
}
Expand Down
16 changes: 7 additions & 9 deletions src/optimizer/query_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@ struct qo_node
/* NULL if no USING INDEX clause in the query */

BITSET outer_dep_set; /* outer join dependency; to preserve join sequence */
BITSET right_dep_set; /* outer join dependency for right outer join; to preserve join sequence */
PT_HINT_ENUM hint; /* hint comment contained in given */
bool sargable; /* whether sargs are applicable to this node */
bool sort_limit_candidate; /* whether this node is a candidate for a SORT_LIMIT plan */
Expand All @@ -395,7 +394,6 @@ struct qo_node
#define QO_NODE_USING_INDEX(node) (node)->using_index

#define QO_NODE_OUTER_DEP_SET(node) (node)->outer_dep_set
#define QO_NODE_RIGHT_DEP_SET(node) (node)->right_dep_set
#define QO_NODE_SARGABLE(node) (node)->sargable

#define QO_NODE_NAME(node) (node)->class_name
Expand Down Expand Up @@ -424,17 +422,17 @@ struct qo_node
QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_RIGHT_OUTER || \
QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_FULL_OUTER)

#define QO_NODE_IS_ANSI_JOIN(node) \
(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 || \
QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_NATURAL || \
QO_NODE_PT_JOIN_TYPE(node) == PT_JOIN_INNER)

#define QO_ADD_OUTER_DEP_SET(tail,head) \
bitset_union (&(QO_NODE_OUTER_DEP_SET (tail)), &(QO_NODE_OUTER_DEP_SET (head))); \
bitset_add (&(QO_NODE_OUTER_DEP_SET (tail)), QO_NODE_IDX (head));

#define QO_ADD_RIGHT_DEP_SET(tail,head) \
bitset_union (&(QO_NODE_RIGHT_DEP_SET (tail)), &(QO_NODE_RIGHT_DEP_SET (head))); \
bitset_add (&(QO_NODE_RIGHT_DEP_SET (tail)), QO_NODE_IDX (head));

#define QO_ADD_RIGHT_TO_OUTER(tail,head) \
bitset_union (&(QO_NODE_OUTER_DEP_SET (tail)), &(QO_NODE_RIGHT_DEP_SET (head)));

struct qo_segment
{
/*
Expand Down

0 comments on commit d29a35a

Please sign in to comment.