mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-15391 Server crashes in JOIN::fix_all_splittings_in_plan or Assertion `join->best_read < double(1.79...e+308L)' failed
vers_setup_conds() used to AND all conditions on row_start/row_end columns and store it either in the WHERE clause or in the ON clause for some table. In some cases this caused ON clause to have conditions for tables that aren't part of that ON's join. Fixed to put a table's condition always in the ON clause of the corresponding table. Removed unnecessary ... `OR row_end IS NULL` clause, it's not needed in the ON clause. Simplified handling on PS and SP.
This commit is contained in:
@ -718,7 +718,7 @@ void vers_select_conds_t::print(String *str, enum_query_type query_type)
|
||||
}
|
||||
}
|
||||
|
||||
int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr)
|
||||
int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
DBUG_ENTER("SELECT_LEX::vers_setup_cond");
|
||||
#define newx new (thd->mem_root)
|
||||
@ -777,9 +777,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
||||
}
|
||||
}
|
||||
|
||||
COND** dst_cond= where_expr;
|
||||
COND* vers_cond= NULL;
|
||||
|
||||
for (table= tables; table; table= table->next_local)
|
||||
{
|
||||
if (!table->table || !table->table->versioned())
|
||||
@ -830,11 +827,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
||||
lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway
|
||||
}
|
||||
|
||||
if (table->on_expr)
|
||||
{
|
||||
dst_cond= &table->on_expr;
|
||||
}
|
||||
|
||||
const LEX_CSTRING *fstart= &table->table->vers_start_field()->field_name;
|
||||
const LEX_CSTRING *fend= &table->table->vers_end_field()->field_name;
|
||||
|
||||
@ -875,7 +867,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
||||
max_time.second_part= TIME_MAX_SECOND_PART;
|
||||
curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS);
|
||||
cond1= newx Item_func_eq(thd, row_end, curr);
|
||||
cond1= or_items(thd, cond1, newx Item_func_isnull(thd, row_end));
|
||||
break;
|
||||
case SYSTEM_TIME_AS_OF:
|
||||
cond1= newx Item_func_le(thd, row_start, vers_conditions.start.item);
|
||||
@ -938,43 +929,16 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
}
|
||||
vers_conditions.type= SYSTEM_TIME_ALL;
|
||||
|
||||
if (cond1)
|
||||
{
|
||||
vers_cond= and_items(thd,
|
||||
vers_cond,
|
||||
and_items(thd,
|
||||
cond2,
|
||||
cond1));
|
||||
if (table->is_view_or_derived())
|
||||
vers_cond= or_items(thd, vers_cond, newx Item_func_isnull(thd, row_end));
|
||||
cond1= and_items(thd, cond2, cond1);
|
||||
table->on_expr= and_items(thd, table->on_expr, cond1);
|
||||
}
|
||||
|
||||
table->vers_conditions.type= SYSTEM_TIME_ALL;
|
||||
} // for (table= tables; ...)
|
||||
|
||||
if (vers_cond)
|
||||
{
|
||||
COND *all_cond= and_items(thd, *dst_cond, vers_cond);
|
||||
bool from_where= dst_cond == where_expr;
|
||||
if (on_stmt_arena.arena_replaced())
|
||||
*dst_cond= all_cond;
|
||||
else
|
||||
thd->change_item_tree(dst_cond, all_cond);
|
||||
|
||||
if (from_where)
|
||||
{
|
||||
this->where= *dst_cond;
|
||||
this->where->top_level_item();
|
||||
}
|
||||
|
||||
// Invalidate current SP [#52, #422]
|
||||
if (thd->spcont)
|
||||
{
|
||||
DBUG_ASSERT(thd->spcont->m_sp);
|
||||
thd->spcont->m_sp->set_sp_cache_version(0);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
#undef newx
|
||||
}
|
||||
@ -1059,7 +1023,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
||||
}
|
||||
|
||||
/* System Versioning: handle FOR SYSTEM_TIME clause. */
|
||||
if (select_lex->vers_setup_conds(thd, tables_list, &conds) < 0)
|
||||
if (select_lex->vers_setup_conds(thd, tables_list) < 0)
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
@ -7533,7 +7497,7 @@ static int compare_embedding_subqueries(JOIN_TAB *jt1, JOIN_TAB *jt2)
|
||||
b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838
|
||||
c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0
|
||||
|
||||
As for subuqueries, this function must produce order that can be fed to
|
||||
As for subqueries, this function must produce order that can be fed to
|
||||
choose_initial_table_order().
|
||||
|
||||
@retval
|
||||
@ -7871,7 +7835,7 @@ greedy_search(JOIN *join,
|
||||
'best_read < DBL_MAX' means that optimizer managed to find
|
||||
some plan and updated 'best_positions' array accordingly.
|
||||
*/
|
||||
DBUG_ASSERT(join->best_read < DBL_MAX);
|
||||
DBUG_ASSERT(join->best_read < DBL_MAX);
|
||||
|
||||
if (size_remain <= search_depth)
|
||||
{
|
||||
@ -8629,7 +8593,7 @@ best_extension_by_limited_search(JOIN *join,
|
||||
/* Find the best access method from 's' to the current partial plan */
|
||||
POSITION loose_scan_pos;
|
||||
best_access_path(join, s, remaining_tables, idx, disable_jbuf,
|
||||
record_count, join->positions + idx, &loose_scan_pos);
|
||||
record_count, position, &loose_scan_pos);
|
||||
|
||||
/* Compute the cost of extending the plan with 's', avoid overflow */
|
||||
if (position->records_read < DBL_MAX / record_count)
|
||||
|
Reference in New Issue
Block a user