Skip to content

Commit bd310e0

Browse files
committed
Bug#20487336: Assert 'length > 0 && keyparts != 0' in calc_length_and_keyparts
Preliminary patch: Refactor TABLE_LIST::sj_on_expr: Rename member to m_sj_cond (it is indeed a condition). Add setter set_sj_cond() and getter sj_cond().
1 parent f28d8d8 commit bd310e0

File tree

5 files changed

+51
-35
lines changed

5 files changed

+51
-35
lines changed

sql/aggregate_check.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,13 +1028,13 @@ void Group_check::find_fd_in_joined_table(List<TABLE_LIST> *join_list)
10281028
TABLE_LIST *table;
10291029
while ((table= li++))
10301030
{
1031-
if (table->sj_on_expr)
1031+
if (table->sj_cond())
10321032
{
10331033
/*
10341034
We can ignore this nest as:
1035-
- the subquery's WHERE was copied to sj_on_expr
1035+
- the subquery's WHERE was copied to the semi-join condition
10361036
- so where the IN equalities
1037-
- sj_on_expr is also present in the parent nest's join condition or in
1037+
- sj_cond() is also present in the parent nest's join condition or in
10381038
the query block's WHERE condition, which we check somewhere else.
10391039
Note that columns from sj-inner tables can help only as "intermediate
10401040
link" in the graph of functional dependencies, as they are neither in

sql/sql_lex.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2886,7 +2886,7 @@ static void print_table_array(THD *thd, String *str, TABLE_LIST **table,
28862886
}
28872887
else if (curr->straight)
28882888
str->append(STRING_WITH_LEN(" straight_join "));
2889-
else if (curr->sj_on_expr)
2889+
else if (curr->sj_cond())
28902890
str->append(STRING_WITH_LEN(" semi join "));
28912891
else
28922892
str->append(STRING_WITH_LEN(" join "));
@@ -2952,12 +2952,12 @@ static void print_join(THD *thd,
29522952
not a semi-join nest. This is necessary because "A SEMIJOIN B" is not the
29532953
same as "B SEMIJOIN A".
29542954
*/
2955-
if ((*table)->sj_on_expr)
2955+
if ((*table)->sj_cond())
29562956
{
29572957
TABLE_LIST **end= table + non_const_tables;
29582958
for (TABLE_LIST **t2= table; t2!=end; t2++)
29592959
{
2960-
if (!(*t2)->sj_on_expr)
2960+
if (!(*t2)->sj_cond())
29612961
{
29622962
TABLE_LIST *tmp= *t2;
29632963
*t2= *table;

sql/sql_optimizer.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4317,7 +4317,7 @@ uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
43174317
if ((nested_join= table->nested_join))
43184318
{
43194319
// We should have either a join condition or a semi-join condition
4320-
DBUG_ASSERT((table->join_cond() == NULL) == (table->sj_on_expr != NULL));
4320+
DBUG_ASSERT((table->join_cond() == NULL) == (table->sj_cond() != NULL));
43214321

43224322
nested_join->nj_map= 0;
43234323
nested_join->nj_total= 0;
@@ -4332,7 +4332,7 @@ uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
43324332
nested_join->nj_map= (nested_join_map) 1 << first_unused++;
43334333
nested_join->nj_total= nested_join->join_list.elements;
43344334
}
4335-
else if (table->sj_on_expr)
4335+
else if (table->sj_cond())
43364336
{
43374337
NESTED_JOIN *const outer_nest=
43384338
table->embedding ? table->embedding->nested_join : NULL;
@@ -4981,7 +4981,7 @@ bool JOIN::extract_const_tables()
49814981
*/
49824982
extract_method= extract_no_table;
49834983
}
4984-
else if (tl->embedding && tl->embedding->sj_on_expr)
4984+
else if (tl->embedding && tl->embedding->sj_cond())
49854985
{
49864986
/*
49874987
Table belongs to a semi-join.
@@ -5182,7 +5182,7 @@ bool JOIN::extract_func_dependent_tables()
51825182
if (eq_part.is_prefix(table->key_info[key].user_defined_key_parts) &&
51835183
!table->fulltext_searched && // 1
51845184
!tl->outer_join_nest() && // 2
5185-
!(tl->embedding && tl->embedding->sj_on_expr) && // 3
5185+
!(tl->embedding && tl->embedding->sj_cond()) && // 3
51865186
!(tab->join_cond() && tab->join_cond()->is_expensive()) &&// 4
51875187
!(table->file->ha_table_flags() & HA_BLOCK_CONST_TABLE)) // 5
51885188
{
@@ -5303,7 +5303,7 @@ bool JOIN::estimate_rowcount()
53035303
TABLE_LIST *const tl= tab->table_ref;
53045304
if (!tab->const_keys.is_clear_all() && // (1)
53055305
(!tl->embedding || // (2)
5306-
(tl->embedding && tl->embedding->sj_on_expr))) // (3)
5306+
(tl->embedding && tl->embedding->sj_cond()))) // (3)
53075307
{
53085308
/*
53095309
This call fills tab->quick() with the best QUICK access method
@@ -5323,7 +5323,7 @@ bool JOIN::estimate_rowcount()
53235323
*/
53245324
if (records == 0 &&
53255325
tab->table()->reginfo.impossible_range &&
5326-
(!(tl->embedding && tl->embedding->sj_on_expr)))
5326+
(!(tl->embedding && tl->embedding->sj_cond())))
53275327
{
53285328
/*
53295329
Impossible WHERE condition or join condition
@@ -5388,7 +5388,7 @@ void JOIN::set_semijoin_embedding()
53885388
{
53895389
for (TABLE_LIST *tl= tab->table_ref; tl->embedding; tl= tl->embedding)
53905390
{
5391-
if (tl->embedding->sj_on_expr)
5391+
if (tl->embedding->sj_cond())
53925392
{
53935393
tab->emb_sj_nest= tl->embedding;
53945394
break;
@@ -6137,7 +6137,7 @@ static bool pull_out_semijoin_tables(JOIN *join)
61376137
add("functionally_dependent", true);
61386138
/*
61396139
Pulling a table out of uncorrelated subquery in general makes
6140-
makes it correlated. See the NOTE to this function.
6140+
it correlated. See the NOTE to this function.
61416141
*/
61426142
sj_nest->nested_join->sj_corr_tables|= tbl->map();
61436143
sj_nest->nested_join->sj_depends_on|= tbl->map();
@@ -6432,7 +6432,7 @@ merge_key_fields(Key_field *start, Key_field *new_fields, Key_field *end,
64326432
static uint get_semi_join_select_list_index(Item_field *item_field)
64336433
{
64346434
TABLE_LIST *emb_sj_nest= item_field->table_ref->embedding;
6435-
if (emb_sj_nest && emb_sj_nest->sj_on_expr)
6435+
if (emb_sj_nest && emb_sj_nest->sj_cond())
64366436
{
64376437
List<Item> &items= emb_sj_nest->nested_join->sj_inner_exprs;
64386438
List_iterator<Item> it(items);

sql/sql_resolver.cc

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ SELECT_LEX::simplify_joins(THD *thd,
14041404
the corresponding join condition is added to JC.
14051405
*/
14061406
if (simplify_joins(thd, &nested_join->join_list,
1407-
false, in_sj || table->sj_on_expr,
1407+
false, in_sj || table->sj_cond(),
14081408
&join_cond, changelog))
14091409
DBUG_RETURN(true);
14101410

@@ -1417,7 +1417,7 @@ SELECT_LEX::simplify_joins(THD *thd,
14171417
nested_join->used_tables= (table_map) 0;
14181418
nested_join->not_null_tables=(table_map) 0;
14191419
if (simplify_joins(thd, &nested_join->join_list, top,
1420-
in_sj || table->sj_on_expr, cond, changelog))
1420+
in_sj || table->sj_cond(), cond, changelog))
14211421
DBUG_RETURN(true);
14221422
used_tables= nested_join->used_tables;
14231423
not_null_tables= nested_join->not_null_tables;
@@ -1549,7 +1549,7 @@ SELECT_LEX::simplify_joins(THD *thd,
15491549
while ((table= li++))
15501550
{
15511551
nested_join= table->nested_join;
1552-
if (table->sj_on_expr && !in_sj)
1552+
if (table->sj_cond() && !in_sj)
15531553
{
15541554
/*
15551555
If this is a semi-join that is not contained within another semi-join,
@@ -1635,9 +1635,10 @@ bool SELECT_LEX::record_join_nest_info(List<TABLE_LIST> *tables)
16351635
This assignment is required in case pull_out_semijoin_tables()
16361636
is not called.
16371637
*/
1638-
if (table->sj_on_expr)
1638+
if (table->sj_cond())
16391639
table->sj_inner_tables= table->nested_join->used_tables;
1640-
if (table->sj_on_expr && sj_nests.push_back(table))
1640+
1641+
if (table->sj_cond() && sj_nests.push_back(table))
16411642
DBUG_RETURN(true);
16421643

16431644
if (table->join_cond())
@@ -1998,15 +1999,17 @@ SELECT_LEX::convert_subquery_to_semijoin(Item_exists_subselect *subq_pred)
19981999
correlated tables to sj_corr_tables.
19992000
*/
20002001
nested_join->sj_corr_tables= subq_pred->used_tables();
2002+
20012003
/*
20022004
sj_depends_on contains the set of outer tables referred in the
20032005
subquery's WHERE clause as well as tables referred in the IN predicate's
20042006
left-hand side.
20052007
*/
20062008
nested_join->sj_depends_on= subq_pred->used_tables() |
20072009
in_subq_pred->left_expr->used_tables();
2008-
/* Put the subquery's WHERE into semi-join's condition. */
2009-
sj_nest->sj_on_expr= subq_select->where_cond();
2010+
2011+
// Put the subquery's WHERE into semi-join's condition.
2012+
Item *sj_cond= subq_select->where_cond();
20102013

20112014
/*
20122015
Create the IN-equalities and inject them into semi-join's ON condition.
@@ -2058,8 +2061,8 @@ SELECT_LEX::convert_subquery_to_semijoin(Item_exists_subselect *subq_pred)
20582061
if (item_eq == NULL)
20592062
DBUG_RETURN(true); /* purecov: inspected */
20602063

2061-
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
2062-
if (sj_nest->sj_on_expr == NULL)
2064+
sj_cond= and_items(sj_cond, item_eq);
2065+
if (sj_cond == NULL)
20632066
DBUG_RETURN(true); /* purecov: inspected */
20642067
}
20652068
else
@@ -2076,18 +2079,21 @@ SELECT_LEX::convert_subquery_to_semijoin(Item_exists_subselect *subq_pred)
20762079
if (item_eq == NULL)
20772080
DBUG_RETURN(true); /* purecov: inspected */
20782081

2079-
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
2080-
if (sj_nest->sj_on_expr == NULL)
2082+
sj_cond= and_items(sj_cond, item_eq);
2083+
if (sj_cond == NULL)
20812084
DBUG_RETURN(true); /* purecov: inspected */
20822085
}
20832086
}
2084-
/* Fix the created equality and AND */
2087+
// Fix the created equality and AND
20852088

20862089
Opt_trace_array sj_on_trace(&thd->opt_trace,
20872090
"evaluating_constant_semijoin_conditions");
2088-
sj_nest->sj_on_expr->top_level_item();
2089-
if (sj_nest->sj_on_expr->fix_fields(thd, &sj_nest->sj_on_expr))
2091+
sj_cond->top_level_item();
2092+
if (sj_cond->fix_fields(thd, &sj_cond))
20902093
DBUG_RETURN(true); /* purecov: inspected */
2094+
2095+
// Attach semi-join condition to semi-join nest
2096+
sj_nest->set_sj_cond(sj_cond);
20912097
}
20922098

20932099
// Unlink the subquery's query expression:
@@ -2114,21 +2120,21 @@ SELECT_LEX::convert_subquery_to_semijoin(Item_exists_subselect *subq_pred)
21142120
repoint_contexts_of_join_nests(subq_select->top_join_list);
21152121

21162122
// Update table map for the semi-join condition
2117-
sj_nest->sj_on_expr->fix_after_pullout(this, subq_select);
2123+
sj_nest->sj_cond()->fix_after_pullout(this, subq_select);
21182124

21192125
// Update table map for semi-join nest's WHERE condition and join conditions
21202126
fix_tables_after_pullout(this, subq_select,
21212127
&sj_nest->nested_join->join_list, 0);
21222128

21232129
//TODO fix QT_
21242130
DBUG_EXECUTE("where",
2125-
print_where(sj_nest->sj_on_expr,"SJ-EXPR", QT_ORDINARY););
2131+
print_where(sj_nest->sj_cond(),"SJ-COND", QT_ORDINARY););
21262132

21272133
if (emb_tbl_nest)
21282134
{
21292135
// Inject semi-join condition into parent's join condition
21302136
emb_tbl_nest->set_join_cond(and_items(emb_tbl_nest->join_cond(),
2131-
sj_nest->sj_on_expr));
2137+
sj_nest->sj_cond()));
21322138
if (emb_tbl_nest->join_cond() == NULL)
21332139
DBUG_RETURN(true);
21342140
emb_tbl_nest->join_cond()->top_level_item();
@@ -2140,7 +2146,7 @@ SELECT_LEX::convert_subquery_to_semijoin(Item_exists_subselect *subq_pred)
21402146
else
21412147
{
21422148
// Inject semi-join condition into parent's WHERE condition
2143-
m_where_cond= and_items(m_where_cond, sj_nest->sj_on_expr);
2149+
m_where_cond= and_items(m_where_cond, sj_nest->sj_cond());
21442150
if (m_where_cond == NULL)
21452151
DBUG_RETURN(true);
21462152
m_where_cond->top_level_item();

sql/table.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,16 @@ struct TABLE_LIST
17041704
}
17051705
Item **join_cond_optim_ref() { return &m_join_cond_optim; }
17061706

1707+
/// Get the semi-join condition for a semi-join nest, NULL otherwise
1708+
Item *sj_cond() const { return m_sj_cond; }
1709+
1710+
/// Set the semi-join condition for a semi-join nest
1711+
void set_sj_cond(Item *cond)
1712+
{
1713+
DBUG_ASSERT(m_sj_cond == NULL);
1714+
m_sj_cond= cond;
1715+
}
1716+
17071717
/// Merge tables from a query block into a nested join structure
17081718
bool merge_underlying_tables(class st_select_lex *select);
17091719

@@ -2017,7 +2027,7 @@ struct TABLE_LIST
20172027
{
20182028
if (!embedding)
20192029
return NULL;
2020-
if (embedding->sj_on_expr)
2030+
if (embedding->sj_cond())
20212031
return embedding->embedding;
20222032
return embedding;
20232033
}
@@ -2115,8 +2125,8 @@ struct TABLE_LIST
21152125
once for all executions of a prepared statement).
21162126
*/
21172127
Item *m_join_cond;
2128+
Item *m_sj_cond; ///< Synthesized semijoin condition
21182129
public:
2119-
Item *sj_on_expr; /* Synthesized semijoin condition */
21202130
/*
21212131
(Valid only for semi-join nests) Bitmap of tables that are within the
21222132
semi-join (this is different from bitmap of all nest's children because

0 commit comments

Comments
 (0)