Commit 949984be authored by Michael Widenius's avatar Michael Widenius

Fixed lp:828514 "Assertion `! is_set()' failed in...

Fixed lp:828514 "Assertion `! is_set()' failed in Diagnostics_area::set_ok_status with derived table + subquery + concurrent DML"


sql/item_subselect.cc:
  Added check of error condtions (safety)
sql/sql_join_cache.cc:
  Added DBUG to some functions.
  Added error checking for calls to check_match(); This fixed the bug.
sql/sql_select.cc:
  Moved variable assignment to be close to where it's used (cleanup)
parent 429a5557
...@@ -2973,7 +2973,7 @@ int subselect_single_select_engine::exec() ...@@ -2973,7 +2973,7 @@ int subselect_single_select_engine::exec()
executed= 1; executed= 1;
thd->where= save_where; thd->where= save_where;
thd->lex->current_select= save_select; thd->lex->current_select= save_select;
DBUG_RETURN(join->error||thd->is_fatal_error); DBUG_RETURN(join->error || thd->is_fatal_error || thd->is_error());
} }
thd->where= save_where; thd->where= save_where;
thd->lex->current_select= save_select; thd->lex->current_select= save_select;
...@@ -4578,7 +4578,8 @@ int subselect_hash_sj_engine::exec() ...@@ -4578,7 +4578,8 @@ int subselect_hash_sj_engine::exec()
/* The subquery should be optimized, and materialized only once. */ /* The subquery should be optimized, and materialized only once. */
DBUG_ASSERT(materialize_join->optimized && !is_materialized); DBUG_ASSERT(materialize_join->optimized && !is_materialized);
materialize_join->exec(); materialize_join->exec();
if ((res= test(materialize_join->error || thd->is_fatal_error))) if ((res= test(materialize_join->error || thd->is_fatal_error ||
thd->is_error())))
goto err; goto err;
/* /*
......
...@@ -2021,6 +2021,7 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) ...@@ -2021,6 +2021,7 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last)
JOIN_TAB *tab; JOIN_TAB *tab;
enum_nested_loop_state rc= NESTED_LOOP_OK; enum_nested_loop_state rc= NESTED_LOOP_OK;
bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join(); bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
DBUG_ENTER("JOIN_CACHE::join_records");
if (outer_join_first_inner && !join_tab->first_unmatched) if (outer_join_first_inner && !join_tab->first_unmatched)
join_tab->not_null_compl= TRUE; join_tab->not_null_compl= TRUE;
...@@ -2102,7 +2103,8 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) ...@@ -2102,7 +2103,8 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last)
finish: finish:
restore_last_record(); restore_last_record();
reset(TRUE); reset(TRUE);
return rc; DBUG_PRINT("exit", ("rc: %d", rc));
DBUG_RETURN(rc);
} }
...@@ -2164,10 +2166,11 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) ...@@ -2164,10 +2166,11 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
join_tab->table->null_row= 0; join_tab->table->null_row= 0;
bool check_only_first_match= join_tab->check_only_first_match(); bool check_only_first_match= join_tab->check_only_first_match();
bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join(); bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
DBUG_ENTER("JOIN_CACHE::join_matching_records");
/* Return at once if there are no records in the join buffer */ /* Return at once if there are no records in the join buffer */
if (!records) if (!records)
return NESTED_LOOP_OK; DBUG_RETURN(NESTED_LOOP_OK);
/* /*
When joining we read records from the join buffer back into record buffers. When joining we read records from the join buffer back into record buffers.
...@@ -2241,7 +2244,7 @@ finish: ...@@ -2241,7 +2244,7 @@ finish:
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR; rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
finish2: finish2:
join_tab_scan->close(); join_tab_scan->close();
return rc; DBUG_RETURN(rc);
} }
...@@ -2323,6 +2326,7 @@ bool JOIN_CACHE::set_match_flag_if_none(JOIN_TAB *first_inner, ...@@ -2323,6 +2326,7 @@ bool JOIN_CACHE::set_match_flag_if_none(JOIN_TAB *first_inner,
enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr) enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
{ {
enum_nested_loop_state rc= NESTED_LOOP_OK; enum_nested_loop_state rc= NESTED_LOOP_OK;
DBUG_ENTER("JOIN_CACHE::generate_full_extensions");
/* /*
Check whether the extended partial join record meets Check whether the extended partial join record meets
...@@ -2340,16 +2344,18 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr) ...@@ -2340,16 +2344,18 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{ {
reset(TRUE); reset(TRUE);
return rc; DBUG_RETURN(rc);
} }
} }
if (res == -1) if (res == -1)
{ {
rc= NESTED_LOOP_ERROR; rc= NESTED_LOOP_ERROR;
return rc; DBUG_RETURN(rc);
} }
} }
return rc; else if (join->thd->is_error())
rc= NESTED_LOOP_ERROR;
DBUG_RETURN(rc);
} }
...@@ -2374,16 +2380,20 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr) ...@@ -2374,16 +2380,20 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
RETURN VALUE RETURN VALUE
TRUE there is a match TRUE there is a match
FALSE there is no match FALSE there is no match
In this case the caller must also check thd->is_error() to see
if there was a fatal error for the query.
*/ */
inline bool JOIN_CACHE::check_match(uchar *rec_ptr) inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
{ {
/* Check whether pushdown conditions are satisfied */ /* Check whether pushdown conditions are satisfied */
DBUG_ENTER("JOIN_CACHE:check_match");
if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0) if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
return FALSE; DBUG_RETURN(FALSE);
if (!join_tab->is_last_inner_table()) if (!join_tab->is_last_inner_table())
return TRUE; DBUG_RETURN(TRUE);
/* /*
This is the last inner table of an outer join, This is the last inner table of an outer join,
...@@ -2396,7 +2406,7 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr) ...@@ -2396,7 +2406,7 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
set_match_flag_if_none(first_inner, rec_ptr); set_match_flag_if_none(first_inner, rec_ptr);
if (first_inner->check_only_first_match() && if (first_inner->check_only_first_match() &&
!join_tab->first_inner) !join_tab->first_inner)
return TRUE; DBUG_RETURN(TRUE);
/* /*
This is the first match for the outer table row. This is the first match for the outer table row.
The function set_match_flag_if_none has turned the flag The function set_match_flag_if_none has turned the flag
...@@ -2410,13 +2420,12 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr) ...@@ -2410,13 +2420,12 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
for (JOIN_TAB *tab= first_inner; tab <= join_tab; tab++) for (JOIN_TAB *tab= first_inner; tab <= join_tab; tab++)
{ {
if (tab->select && tab->select->skip_record(join->thd) <= 0) if (tab->select && tab->select->skip_record(join->thd) <= 0)
return FALSE; DBUG_RETURN(FALSE);
} }
} }
while ((first_inner= first_inner->first_upper) && while ((first_inner= first_inner->first_upper) &&
first_inner->last_inner == join_tab); first_inner->last_inner == join_tab);
DBUG_RETURN(TRUE);
return TRUE;
} }
...@@ -2451,10 +2460,11 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last) ...@@ -2451,10 +2460,11 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
ulonglong cnt; ulonglong cnt;
enum_nested_loop_state rc= NESTED_LOOP_OK; enum_nested_loop_state rc= NESTED_LOOP_OK;
bool is_first_inner= join_tab == join_tab->first_unmatched; bool is_first_inner= join_tab == join_tab->first_unmatched;
DBUG_ENTER("JOIN_CACHE::join_null_complements");
/* Return at once if there are no records in the join buffer */ /* Return at once if there are no records in the join buffer */
if (!records) if (!records)
return NESTED_LOOP_OK; DBUG_RETURN(NESTED_LOOP_OK);
cnt= records - (is_key_access() ? 0 : test(skip_last)); cnt= records - (is_key_access() ? 0 : test(skip_last));
...@@ -2484,7 +2494,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last) ...@@ -2484,7 +2494,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
} }
finish: finish:
return rc; DBUG_RETURN(rc);
} }
......
...@@ -2385,7 +2385,6 @@ JOIN::exec() ...@@ -2385,7 +2385,6 @@ JOIN::exec()
thd_proc_info(thd, "Copying to group table"); thd_proc_info(thd, "Copying to group table");
DBUG_PRINT("info", ("%s", thd->proc_info)); DBUG_PRINT("info", ("%s", thd->proc_info));
tmp_error= -1;
if (curr_join != this) if (curr_join != this)
{ {
if (sum_funcs2) if (sum_funcs2)
...@@ -2410,6 +2409,7 @@ JOIN::exec() ...@@ -2410,6 +2409,7 @@ JOIN::exec()
JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables; JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
first_tab->sorted= test(first_tab->loosescan_match_tab); first_tab->sorted= test(first_tab->loosescan_match_tab);
} }
tmp_error= -1;
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) || if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0))) 0)))
...@@ -14839,10 +14839,12 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) ...@@ -14839,10 +14839,12 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
{ {
enum_nested_loop_state rc; enum_nested_loop_state rc;
JOIN_CACHE *cache= join_tab->cache; JOIN_CACHE *cache= join_tab->cache;
DBUG_ENTER("sub_select_cache"); DBUG_ENTER("sub_select_cache");
/* This function cannot be called if join_tab has no associated join buffer */ /*
This function cannot be called if join_tab has no associated join
buffer
*/
DBUG_ASSERT(cache != NULL); DBUG_ASSERT(cache != NULL);
join_tab->cache->reset_join(join); join_tab->cache->reset_join(join);
......
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