[MDEV-31647] Stack looping and SIGSEGV in Item_args::walk_args on UPDATE Created: 2023-07-08  Updated: 2023-12-14

Status: Open
Project: MariaDB Server
Component/s: Data Manipulation - Update, Optimizer
Affects Version/s: 10.4, 10.5, 10.6, 10.9, 10.10, 10.11, 11.0, 11.1
Fix Version/s: 10.4, 10.5, 10.6, 10.11, 11.0, 11.1

Type: Bug Priority: Critical
Reporter: Roel Van de Paar Assignee: Yuchen Pei
Resolution: Unresolved Votes: 0
Labels: stack-looping

Issue Links:
Relates
relates to MDEV-22534 Trivial correlation detection/removal... In Review

 Description   

--source include/have_innodb.inc
CREATE TABLE c (c INT, c2 INT) ENGINE=InnoDB;
UPDATE c SET c=0 WHERE c=(SELECT 1 FROM (SELECT * FROM (SELECT 1) AS v1 JOIN c HAVING c=1) AS v2 NATURAL JOIN c) ORDER BY LAST_VALUE (c2) OVER (ORDER BY c2);

Leads to:

11.1.2 3883eb63dc5e663558571c33d086c9fd3aa0cf8f (Debug)

Core was generated by `/test/MD220623-mariadb-11.1.2-linux-x86_64-dbg/bin/mariadbd --no-defaults --cor'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000559a05d4c44b in Item_args::walk_args (arg=0x1505280a7a40, 
    walk_subquery=true, processor=<optimized out>, this=0x150528025b70)
    at /test/11.1_dbg/sql/item.h:2794
 
warning: Source file is more recent than executable.
2794	      if (args[i]->walk(processor, walk_subquery, arg))
[Current thread is 1 (Thread 0x15059c0c5640 (LWP 2549356))]
(gdb) bt
#0  0x0000559a05d4c44b in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794
#1  Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#2  0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#3  0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
#4  Item_func_or_sum::walk (this=0x1505280257b0, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#5  0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794
#6  Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#7  0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#8  0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
#9  Item_func_or_sum::walk (this=0x1505280257b0, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#10 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794
#11 Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#12 0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#13 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
#14 Item_func_or_sum::walk (this=0x1505280257b0, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#15 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794
#16 Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#17 0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#18 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
#19 Item_func_or_sum::walk (this=0x1505280257b0, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#20 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794
#21 Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#22 0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#23 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
... stack looping ...
#986 Item_func_or_sum::walk (this=0x150528025af8, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#987 0x0000559a05dc6680 in Item_ref::walk (this=0x150528032a90, processor=&virtual Item::register_field_in_read_map(void*), walk_subquery=<optimized out>, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5699
#988 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025828) at /test/11.1_dbg/sql/item.h:2794
#989 Item_func_or_sum::walk (this=0x1505280257b0, processor=<optimized out>, walk_subquery=true, arg=0x1505280a7a40) at /test/11.1_dbg/sql/item.h:5493
#990 0x0000559a05d4c451 in Item_args::walk_args (arg=0x1505280a7a40, walk_subquery=true, processor=<optimized out>, this=0x150528025b70) at /test/11.1_dbg/sql/item.h:2794

Bug confirmed present in:
MariaDB: 10.4.31 (dbg), 10.4.31 (opt), 10.5.22 (dbg), 10.5.22 (opt), 10.6.15 (dbg), 10.6.15 (opt), 10.9.8 (dbg), 10.9.8 (opt), 10.10.6 (dbg), 10.10.6 (opt), 10.11.5 (dbg), 10.11.5 (opt), 11.0.3 (dbg), 11.0.3 (opt), 11.1.2 (dbg), 11.1.2 (opt)

Bug (or feature/syntax) confirmed not present in:
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.40 (dbg), 8.0.33 (dbg), 8.0.33 (opt)



 Comments   
Comment by Sergei Petrunia [ 2023-10-24 ]

We saw similar stack looping with Item_ref in MDEV-22534. Maybe, this one is related.

Comment by Yuchen Pei [ 2023-10-31 ]

This looks different from MDEV-22534. The cycle was both formed (1)
and walked (2) during the final stage of exec, inside
AGGR_OP::end_send (see below). I'm not sure what's going on, but the
Item_field "c.c2" referenced by an Item_aggregate_ref "c.c2", in the
Item_sum_last_value "last_value(c.c2)", in the Item_window_func
"last_value(c.c2) over ( order by c.c2)" was substituted to be the
Item_window_func, forming a cycle.

11.0 be24e75229a4496e525677149c8a116a3ff4b372

// inside AGGR_OP::end_send():
  // Update ref array
  join_tab->join->set_items_ref_array(*join_tab->ref_array); // (1)
  bool keep_last_filesort_result = join_tab->filesort ? false : true;
  if (join_tab->window_funcs_step)
  {
    if (join_tab->window_funcs_step->exec(join, keep_last_filesort_result)) // (2)
      return NESTED_LOOP_ERROR;
  }

When the cycle is walked:

Item_func_or_sum::walk > Item_ref::walk > Item_args::walk_args > Item_args::walk_args > Item_func_or_sum::walk > find_all_keys > filesort > create_sort_index > Window_funcs_computation::exec > AGGR_OP::end_send > sub_select_postjoin_aggr > sub_select > do_select > JOIN::exec > mysql_select > mysql_multi_update > mysql_parse > dispatch_command > do_command > handle_one_connection > pfs_spawn_thread

When the cycle was formed:

JOIN::copy_ref_ptr_array > JOIN::set_items_ref_array > AGGR_OP::end_send > sub_select_postjoin_aggr > sub_select > do_select > JOIN::exec > mysql_select > mysql_multi_update > mysql_parse > dispatch_command > do_command > handle_one_connection > pfs_spawn_thread

The source array was created (ref_pointer_array below) in a call
to change_refs_to_tmp_fields, during optimize stage:

change_refs_to_tmp_fields > JOIN::make_aggr_tables_info > JOIN::optimize_inner > JOIN::optimize > mysql_multi_update > mysql_execute_command > dispatch_command > do_command > do_handle_one_connection > pfs_spawn_thread

11.0 be24e75229a4496e525677149c8a116a3ff4b372

static bool
change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
			  List<Item> &res_selected_fields,
			  List<Item> &res_all_fields, uint elements,
			  List<Item> &all_fields)
{
//  [... 6 lines elided]
  for (i= 0; (item= it++); i++)
  {
//  [... 10 lines elided]
    ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
      new_item;
  }
//  [... 7 lines elided]
}

All this makes it look like it's caused by different problems as the
cycle in MDEV-22534.

Generated at Thu Feb 08 10:25:26 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.