mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix bug lp:1001506
This is a backport of the (unchaged) fix for MySQL bug #11764372, 57197. Analysis: When the outer query finishes its main execution and computes GROUP BY, it needs to construct a new temporary table (and a corresponding JOIN) to execute the last DISTINCT operation. At this point JOIN::exec calls JOIN::join_free, which calls JOIN::cleanup -> TMP_TABLE_PARAM::cleanup for both the outer and the inner JOINs. The call to the inner TMP_TABLE_PARAM::cleanup sets copy_field = NULL, but not copy_field_end. The final execution phase that computes the DISTINCT invokes: evaluate_join_record -> end_write -> copy_funcs The last function copies the results of all functions into the temp table. copy_funcs walks over all functions in join->tmp_table_param.items_to_copy. In this case items_to_copy contains both assignments to user variables. The process of copying user variables invokes Item_func_set_user_var::check which in turn re-evaluates the arguments of the user variable assignment. This in turn triggers re-evaluation of the subquery, and ultimately copy_field. However, the previous call to TMP_TABLE_PARAM::cleanup for the subquery already set copy_field to NULL but not its copy_field_end. This results in a null pointer access, and a crash. Fix: Set copy_field_end and save_copy_field_end to null when deleting copy fields in TMP_TABLE_PARAM::cleanup().
This commit is contained in:
@ -16072,6 +16072,8 @@ copy_fields(TMP_TABLE_PARAM *param)
|
||||
Copy_field *ptr=param->copy_field;
|
||||
Copy_field *end=param->copy_field_end;
|
||||
|
||||
DBUG_ASSERT((ptr != NULL && end >= ptr) || (ptr == NULL && end == NULL));
|
||||
|
||||
for (; ptr != end; ptr++)
|
||||
(*ptr->do_copy)(ptr);
|
||||
|
||||
|
Reference in New Issue
Block a user