Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-30052

Crash with a query containing nested WINDOW clauses

Details

    Description

      Setting this to critical due to use-after-poison in sql/sql_list.h (ref ASAN output in first comment below), as well as the code location (opt_subselect.cc) and the code in crashes on (total_key_length += inner->max_length).

      CREATE TABLE t (c INT) ENGINE=InnoDB;
      UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN ((SELECT * FROM (SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v3 AS (PARTITION BY c))))));
      

      Leads to:

      10.11.2 8283948846740a22f96bbe7bccf250708406d5d9 (Debug)

      Core was generated by `/test/MD171122-mariadb-10.11.2-linux-x86_64-dbg/bin/mysqld --no-defaults --core'.
      Program terminated with signal SIGSEGV, Segmentation fault.
      #0  subquery_types_allow_materialization (thd=thd@entry=0x1463c4000d48, 
          in_subs=in_subs@entry=0x1463c4028708)
          at /test/10.11_dbg/sql/opt_subselect.cc:891
      891	    total_key_length += inner->max_length;
      [Current thread is 1 (Thread 0x1463f8912700 (LWP 3156269))]
      (gdb) bt
      #0  subquery_types_allow_materialization (thd=thd@entry=0x1463c4000d48, in_subs=in_subs@entry=0x1463c4028708) at /test/10.11_dbg/sql/opt_subselect.cc:891
      #1  0x000056489b07a4e6 in is_materialization_applicable (thd=thd@entry=0x1463c4000d48, in_subs=in_subs@entry=0x1463c4028708, child_select=child_select@entry=0x1463c4014068) at /test/10.11_dbg/sql/sql_lex.h:1651
      #2  0x000056489b07ab8b in check_and_do_in_subquery_rewrites (join=join@entry=0x1463c4029ef8) at /test/10.11_dbg/sql/opt_subselect.cc:755
      #3  0x000056489af4049a in JOIN::prepare (this=0x1463c4029ef8, tables_init=<optimized out>, conds_init=<optimized out>, og_num=<optimized out>, order_init=<optimized out>, skip_order_by=skip_order_by@entry=false, group_init=<optimized out>, having_init=<optimized out>, proc_param_init=<optimized out>, select_lex_arg=<optimized out>, unit_arg=<optimized out>) at /test/10.11_dbg/sql/sql_select.cc:1565
      #4  0x000056489b2bd33d in subselect_single_select_engine::prepare (this=0x1463c4028900, thd=0x1463c4000d48) at /test/10.11_dbg/sql/sql_lex.h:1368
      #5  0x000056489b2bc80b in Item_subselect::fix_fields (this=this@entry=0x1463c4028708, thd_param=thd_param@entry=0x1463c4000d48, ref=ref@entry=0x1463c4028968) at /test/10.11_dbg/sql/item_subselect.cc:295
      #6  0x000056489b2bcc50 in Item_in_subselect::fix_fields (this=0x1463c4028708, thd_arg=0x1463c4000d48, ref=0x1463c4028968) at /test/10.11_dbg/sql/item_subselect.cc:3545
      #7  0x000056489af102e7 in Item::fix_fields_if_needed (ref=<optimized out>, thd=0x1463c4000d48, this=0x1463c4028708) at /test/10.11_dbg/sql/item.h:1164
      #8  Item::fix_fields_if_needed_for_scalar (ref=<optimized out>, thd=0x1463c4000d48, this=0x1463c4028708) at /test/10.11_dbg/sql/item.h:1156
      #9  Item::fix_fields_if_needed_for_order_by (ref=<optimized out>, thd=0x1463c4000d48, this=0x1463c4028708) at /test/10.11_dbg/sql/item.h:1164
      #10 find_order_in_list (thd=thd@entry=0x1463c4000d48, ref_pointer_array=<optimized out>, tables=tables@entry=0x1463c4013330, order=order@entry=0x1463c4028958, fields=@0x1463f8910cf0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463f8910cf0, elements = 0}, <No data fields>}, all_fields=@0x1463c4029a28: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463c4029a28, elements = 0}, <No data fields>}, is_group_field=false, add_to_all_fields=true, from_window_spec=false) at /test/10.11_dbg/sql/sql_select.cc:25730
      #11 0x000056489af3bd31 in setup_order (thd=thd@entry=0x1463c4000d48, ref_pointer_array=<optimized out>, tables=tables@entry=0x1463c4013330, fields=@0x1463f8910cf0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463f8910cf0, elements = 0}, <No data fields>}, all_fields=@0x1463c4029a28: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463c4029a28, elements = 0}, <No data fields>}, order=0x1463c4028958, from_window_spec=false) at /test/10.11_dbg/sql/sql_select.cc:25777
      #12 0x000056489af3fccd in setup_without_group (reserved=<optimized out>, hidden_group_fields=0x1463c40299d7, win_funcs=<optimized out>, win_specs=<optimized out>, group=<optimized out>, order=<optimized out>, conds=0x1463c4029b10, all_fields=@0x1463c4029a28: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463c4029a28, elements = 0}, <No data fields>}, fields=<optimized out>, leaves=<optimized out>, tables=<optimized out>, ref_pointer_array=<optimized out>, thd=<optimized out>) at /test/10.11_dbg/sql/sql_select.cc:888
      #13 JOIN::prepare (this=this@entry=0x1463c4029690, tables_init=tables_init@entry=0x1463c4013330, conds_init=conds_init@entry=0x1463c4013dc0, og_num=og_num@entry=1, order_init=order_init@entry=0x1463c4028958, skip_order_by=skip_order_by@entry=false, group_init=<optimized out>, having_init=<optimized out>, proc_param_init=<optimized out>, select_lex_arg=<optimized out>, unit_arg=<optimized out>) at /test/10.11_dbg/sql/sql_select.cc:1465
      #14 0x000056489af5650c in mysql_select (thd=thd@entry=0x1463c4000d48, tables=tables@entry=0x1463c4013330, fields=@0x1463f8910cf0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x56489c459f00 <end_of_list>, last = 0x1463f8910cf0, elements = 0}, <No data fields>}, conds=conds@entry=0x1463c4013dc0, og_num=1, order=0x1463c4028958, group=0x0, having=0x0, proc_param=0x0, select_options=37383395344512, result=0x1463c4029580, unit=0x1463c4004f88, select_lex=0x1463c40057b8) at /test/10.11_dbg/sql/sql_select.cc:5056
      #15 0x000056489afcf16b in mysql_multi_update (thd=thd@entry=0x1463c4000d48, table_list=0x1463c4013330, fields=fields@entry=0x1463c4005a58, values=values@entry=0x1463c4005e88, conds=0x1463c4013dc0, options=0, handle_duplicates=DUP_ERROR, ignore=false, unit=0x1463c4004f88, select_lex=0x1463c40057b8, result=0x1463f8910ed0) at /test/10.11_dbg/sql/sql_update.cc:1980
      #16 0x000056489aed18c8 in mysql_execute_command (thd=thd@entry=0x1463c4000d48, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.11_dbg/sql/sql_parse.cc:4489
      #17 0x000056489aebe606 in mysql_parse (thd=thd@entry=0x1463c4000d48, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x1463f8911300) at /test/10.11_dbg/sql/sql_parse.cc:7998
      #18 0x000056489aecbb41 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x1463c4000d48, packet=packet@entry=0x1463c400adf9 "UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN ((SELECT * FROM (SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v3 AS (PARTITION BY c))))))", packet_length=packet_length@entry=178, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_class.h:1346
      #19 0x000056489aecdf7f in do_command (thd=0x1463c4000d48, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_parse.cc:1407
      #20 0x000056489b028763 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x56489d9a6fb8, put_in_cache=put_in_cache@entry=true) at /test/10.11_dbg/sql/sql_connect.cc:1416
      #21 0x000056489b028c32 in handle_one_connection (arg=0x56489d9a6fb8) at /test/10.11_dbg/sql/sql_connect.cc:1318
      #22 0x000014641159c609 in start_thread (arg=<optimized out>) at pthread_create.c:477
      #23 0x0000146411188133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
      

      Bug confirmed present in:
      MariaDB: 10.3.37 (dbg), 10.4.27 (dbg), 10.5.18 (dbg), 10.6.10 (dbg), 10.7.6 (dbg), 10.8.5 (dbg), 10.9.3 (dbg), 10.10.2 (dbg), 10.11.2 (dbg)

      Bug (or feature/syntax) confirmed not present in:
      MariaDB: 10.3.37 (opt), 10.4.27 (opt), 10.5.18 (opt), 10.6.10 (opt), 10.7.6 (opt), 10.8.5 (opt), 10.9.3 (opt), 10.10.2 (opt), 10.11.2 (opt)
      MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.38 (dbg), 5.7.38 (opt), 8.0.29 (dbg), 8.0.29 (opt)

      Attachments

        Issue Links

          Activity

            ASAN Sees use-after-poison

            10.11.0 fe1f8f2c6b6f3b8e3383168225f9ae7853028947 (Optimized, UBASAN)

            ==3243144==ERROR: AddressSanitizer: use-after-poison on address 0x6290000887b0 at pc 0x55f7a34ef836 bp 0x14cfbfdb91e0 sp 0x14cfbfdb91d0
            READ of size 8 at 0x6290000887b0 thread T16
                #0 0x55f7a34ef835 in base_list_iterator::next() /test/10.11_opt_san/sql/sql_list.h:431
                #1 0x55f7a34ef835 in List_iterator<Item>::operator++(int) /test/10.11_opt_san/sql/sql_list.h:596
                #2 0x55f7a34ef835 in subquery_types_allow_materialization /test/10.11_opt_san/sql/opt_subselect.cc:888
                #3 0x55f7a34f069a in is_materialization_applicable(THD*, Item_in_subselect*, st_select_lex*) /test/10.11_opt_san/sql/opt_subselect.cc:521
                #4 0x55f7a34f2d25 in check_and_do_in_subquery_rewrites(JOIN*) /test/10.11_opt_san/sql/opt_subselect.cc:755
                #5 0x55f7a2db7f6e in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/10.11_opt_san/sql/sql_select.cc:1556
                #6 0x55f7a48acec4 in subselect_single_select_engine::prepare(THD*) /test/10.11_opt_san/sql/item_subselect.cc:3930
                #7 0x55f7a48a5ad5 in Item_subselect::fix_fields(THD*, Item**) /test/10.11_opt_san/sql/item_subselect.cc:295
                #8 0x55f7a48a8d3c in Item_in_subselect::fix_fields(THD*, Item**) /test/10.11_opt_san/sql/item_subselect.cc:3589
                #9 0x55f7a2bacd1e in Item::fix_fields_if_needed(THD*, Item**) /test/10.11_opt_san/sql/item.h:1144
                #10 0x55f7a2bacd1e in Item::fix_fields_if_needed_for_scalar(THD*, Item**) /test/10.11_opt_san/sql/item.h:1148
                #11 0x55f7a2bacd1e in Item::fix_fields_if_needed_for_order_by(THD*, Item**) /test/10.11_opt_san/sql/item.h:1156
                #12 0x55f7a2bacd1e in find_order_in_list /test/10.11_opt_san/sql/sql_select.cc:25677
                #13 0x55f7a2cb5e34 in setup_order(THD*, Bounds_checked_array<Item*>, TABLE_LIST*, List<Item>&, List<Item>&, st_order*, bool) /test/10.11_opt_san/sql/sql_select.cc:25724
                #14 0x55f7a2db5b3d in setup_without_group /test/10.11_opt_san/sql/sql_select.cc:900
                #15 0x55f7a2db5b3d in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/10.11_opt_san/sql/sql_select.cc:1456
                #16 0x55f7a2dc3fd6 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/10.11_opt_san/sql/sql_select.cc:5045
                #17 0x55f7a30ea947 in mysql_multi_update(THD*, TABLE_LIST*, List<Item>*, List<Item>*, Item*, unsigned long long, enum_duplicates, bool, st_select_lex_unit*, st_select_lex*, multi_update**) /test/10.11_opt_san/sql/sql_update.cc:1980
                #18 0x55f7a2a1faa5 in mysql_execute_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:4487
                #19 0x55f7a29a4500 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_opt_san/sql/sql_parse.cc:8035
                #20 0x55f7a29f90ff in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_opt_san/sql/sql_parse.cc:1894
                #21 0x55f7a2a043fd in do_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:1407
                #22 0x55f7a32ed4cd in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1418
                #23 0x55f7a32efb3c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1312
                #24 0x14cfe2fe1608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
                #25 0x14cfe2256132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)
             
            0x6290000887b0 is located 5552 bytes inside of 16400-byte region [0x629000087200,0x62900008b210)
            allocated by thread T16 here:
                #0 0x55f7a2178a08 in __interceptor_malloc (/test/UBASAN_MD010922-mariadb-10.11.0-linux-x86_64-opt/bin/mariadbd+0x79c3a08)
                #1 0x55f7a6668824 in my_malloc /test/10.11_opt_san/mysys/my_malloc.c:90
                #2 0x55f7a6644600 in root_alloc /test/10.11_opt_san/mysys/my_alloc.c:66
                #3 0x55f7a6644600 in reset_root_defaults /test/10.11_opt_san/mysys/my_alloc.c:243
                #4 0x55f7a269663c in THD::init_for_queries() /test/10.11_opt_san/sql/sql_class.cc:1385
                #5 0x55f7a32e7ee3 in prepare_new_connection_state(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1240
                #6 0x55f7a32e9717 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1333
                #7 0x55f7a32e9717 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1322
                #8 0x55f7a32ec509 in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1408
                #9 0x55f7a32efb3c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1312
                #10 0x14cfe2fe1608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
             
            Thread T16 created by T0 here:
                #0 0x55f7a20a5a45 in pthread_create (/test/UBASAN_MD010922-mariadb-10.11.0-linux-x86_64-opt/bin/mariadbd+0x78f0a45)
                #1 0x55f7a21c8f83 in create_thread_to_handle_connection(CONNECT*) /test/10.11_opt_san/sql/mysqld.cc:6018
                #2 0x55f7a21da00f in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/10.11_opt_san/sql/mysqld.cc:6139
                #3 0x55f7a21db037 in handle_connections_sockets() /test/10.11_opt_san/sql/mysqld.cc:6263
                #4 0x55f7a21ddf94 in mysqld_main(int, char**) /test/10.11_opt_san/sql/mysqld.cc:5913
                #5 0x14cfe215b082 in __libc_start_main ../csu/libc-start.c:308
             
            SUMMARY: AddressSanitizer: use-after-poison /test/10.11_opt_san/sql/sql_list.h:431 in base_list_iterator::next()
            Shadow bytes around the buggy address:
              0x0c52800090a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c52800090b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c52800090c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 f7 00 00
              0x0c52800090d0: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c52800090e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            =>0x0c52800090f0: 00 00 00 00 f7 f7[f7]f7 00 00 00 00 00 00 00 00
              0x0c5280009100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            Shadow byte legend (one shadow byte represents 8 application bytes):
              Addressable:           00
              Partially addressable: 01 02 03 04 05 06 07
              Heap left redzone:       fa
              Freed heap region:       fd
              Stack left redzone:      f1
              Stack mid redzone:       f2
              Stack right redzone:     f3
              Stack after return:      f5
              Stack use after scope:   f8
              Global redzone:          f9
              Global init order:       f6
              Poisoned by user:        f7
              Container overflow:      fc
              Array cookie:            ac
              Intra object redzone:    bb
              ASan internal:           fe
              Left alloca redzone:     ca
              Right alloca redzone:    cb
              Shadow gap:              cc
            

            Roel Roel Van de Paar added a comment - ASAN Sees use-after-poison 10.11.0 fe1f8f2c6b6f3b8e3383168225f9ae7853028947 (Optimized, UBASAN) ==3243144==ERROR: AddressSanitizer: use-after-poison on address 0x6290000887b0 at pc 0x55f7a34ef836 bp 0x14cfbfdb91e0 sp 0x14cfbfdb91d0 READ of size 8 at 0x6290000887b0 thread T16 #0 0x55f7a34ef835 in base_list_iterator::next() /test/10.11_opt_san/sql/sql_list.h:431 #1 0x55f7a34ef835 in List_iterator<Item>::operator++(int) /test/10.11_opt_san/sql/sql_list.h:596 #2 0x55f7a34ef835 in subquery_types_allow_materialization /test/10.11_opt_san/sql/opt_subselect.cc:888 #3 0x55f7a34f069a in is_materialization_applicable(THD*, Item_in_subselect*, st_select_lex*) /test/10.11_opt_san/sql/opt_subselect.cc:521 #4 0x55f7a34f2d25 in check_and_do_in_subquery_rewrites(JOIN*) /test/10.11_opt_san/sql/opt_subselect.cc:755 #5 0x55f7a2db7f6e in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/10.11_opt_san/sql/sql_select.cc:1556 #6 0x55f7a48acec4 in subselect_single_select_engine::prepare(THD*) /test/10.11_opt_san/sql/item_subselect.cc:3930 #7 0x55f7a48a5ad5 in Item_subselect::fix_fields(THD*, Item**) /test/10.11_opt_san/sql/item_subselect.cc:295 #8 0x55f7a48a8d3c in Item_in_subselect::fix_fields(THD*, Item**) /test/10.11_opt_san/sql/item_subselect.cc:3589 #9 0x55f7a2bacd1e in Item::fix_fields_if_needed(THD*, Item**) /test/10.11_opt_san/sql/item.h:1144 #10 0x55f7a2bacd1e in Item::fix_fields_if_needed_for_scalar(THD*, Item**) /test/10.11_opt_san/sql/item.h:1148 #11 0x55f7a2bacd1e in Item::fix_fields_if_needed_for_order_by(THD*, Item**) /test/10.11_opt_san/sql/item.h:1156 #12 0x55f7a2bacd1e in find_order_in_list /test/10.11_opt_san/sql/sql_select.cc:25677 #13 0x55f7a2cb5e34 in setup_order(THD*, Bounds_checked_array<Item*>, TABLE_LIST*, List<Item>&, List<Item>&, st_order*, bool) /test/10.11_opt_san/sql/sql_select.cc:25724 #14 0x55f7a2db5b3d in setup_without_group /test/10.11_opt_san/sql/sql_select.cc:900 #15 0x55f7a2db5b3d in JOIN::prepare(TABLE_LIST*, Item*, unsigned int, st_order*, bool, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) /test/10.11_opt_san/sql/sql_select.cc:1456 #16 0x55f7a2dc3fd6 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/10.11_opt_san/sql/sql_select.cc:5045 #17 0x55f7a30ea947 in mysql_multi_update(THD*, TABLE_LIST*, List<Item>*, List<Item>*, Item*, unsigned long long, enum_duplicates, bool, st_select_lex_unit*, st_select_lex*, multi_update**) /test/10.11_opt_san/sql/sql_update.cc:1980 #18 0x55f7a2a1faa5 in mysql_execute_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:4487 #19 0x55f7a29a4500 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_opt_san/sql/sql_parse.cc:8035 #20 0x55f7a29f90ff in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_opt_san/sql/sql_parse.cc:1894 #21 0x55f7a2a043fd in do_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:1407 #22 0x55f7a32ed4cd in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1418 #23 0x55f7a32efb3c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1312 #24 0x14cfe2fe1608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477 #25 0x14cfe2256132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)   0x6290000887b0 is located 5552 bytes inside of 16400-byte region [0x629000087200,0x62900008b210) allocated by thread T16 here: #0 0x55f7a2178a08 in __interceptor_malloc (/test/UBASAN_MD010922-mariadb-10.11.0-linux-x86_64-opt/bin/mariadbd+0x79c3a08) #1 0x55f7a6668824 in my_malloc /test/10.11_opt_san/mysys/my_malloc.c:90 #2 0x55f7a6644600 in root_alloc /test/10.11_opt_san/mysys/my_alloc.c:66 #3 0x55f7a6644600 in reset_root_defaults /test/10.11_opt_san/mysys/my_alloc.c:243 #4 0x55f7a269663c in THD::init_for_queries() /test/10.11_opt_san/sql/sql_class.cc:1385 #5 0x55f7a32e7ee3 in prepare_new_connection_state(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1240 #6 0x55f7a32e9717 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1333 #7 0x55f7a32e9717 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1322 #8 0x55f7a32ec509 in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1408 #9 0x55f7a32efb3c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1312 #10 0x14cfe2fe1608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477   Thread T16 created by T0 here: #0 0x55f7a20a5a45 in pthread_create (/test/UBASAN_MD010922-mariadb-10.11.0-linux-x86_64-opt/bin/mariadbd+0x78f0a45) #1 0x55f7a21c8f83 in create_thread_to_handle_connection(CONNECT*) /test/10.11_opt_san/sql/mysqld.cc:6018 #2 0x55f7a21da00f in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/10.11_opt_san/sql/mysqld.cc:6139 #3 0x55f7a21db037 in handle_connections_sockets() /test/10.11_opt_san/sql/mysqld.cc:6263 #4 0x55f7a21ddf94 in mysqld_main(int, char**) /test/10.11_opt_san/sql/mysqld.cc:5913 #5 0x14cfe215b082 in __libc_start_main ../csu/libc-start.c:308   SUMMARY: AddressSanitizer: use-after-poison /test/10.11_opt_san/sql/sql_list.h:431 in base_list_iterator::next() Shadow bytes around the buggy address: 0x0c52800090a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c52800090b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c52800090c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 f7 00 00 0x0c52800090d0: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c52800090e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c52800090f0: 00 00 00 00 f7 f7[f7]f7 00 00 00 00 00 00 00 00 0x0c5280009100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc
            elenst Elena Stepanova added a comment - - edited

            It looks identical to (at least) MDEV-29359.

            elenst Elena Stepanova added a comment - - edited It looks identical to (at least) MDEV-29359 .
            Johnston Rex Johnston added a comment -

            Still puzzling over this one. Valgrind tells me this.

            ==22054== Thread 33:
            ==22054== Invalid read of size 8
            ==22054==    at 0x9B88AB: base_list_iterator::next_fast() (sql_list.h:443)
            ==22054==    by 0x9F5BB8: List_iterator_fast<Item>::operator++(int) (sql_list.h:620)
            ==22054==    by 0xBF8927: JOIN::eval_select_list_used_tables() (sql_select.cc:13203)
            ==22054==    by 0xBA0588: JOIN::optimize_inner() (sql_select.cc:2113)
            ==22054==    by 0xB9F9ED: JOIN::optimize() (sql_select.cc:1871)
            ==22054==    by 0xB063EC: st_select_lex::optimize_unflattened_subqueries(bool) (sql_lex.cc:4905)
            ==22054==    by 0xD85DF6: JOIN::optimize_constant_subqueries() (opt_subselect.cc:5689)
            ==22054==    by 0xBA09CF: JOIN::optimize_inner() (sql_select.cc:2194)
            ==22054==    by 0xB9F9ED: JOIN::optimize() (sql_select.cc:1871)
            ==22054==    by 0xBAB5AA: mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:5096)
            ==22054==    by 0xB9A7D1: handle_select(THD*, LEX*, select_result*, unsigned long long) (sql_select.cc:581)
            ==22054==    by 0xB44AEE: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:6263)
            ==22054==  Address 0x3b64e958 is 56 bytes inside a block of size 64 alloc'd
            ==22054==    at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
            ==22054==    by 0x18B620F: my_malloc (my_malloc.c:90)
            ==22054==    by 0x18A69D9: alloc_root (my_alloc.c:287)
            ==22054==    by 0x9B85EA: Sql_alloc::operator new(unsigned long, st_mem_root*) (sql_alloc.h:37)
            ==22054==    by 0x9B87AF: base_list::push_back(void*, st_mem_root*) (sql_list.h:195)
            ==22054==    by 0xA05504: List<Item>::push_back(Item*, st_mem_root*) (sql_list.h:505)
            ==22054==    by 0xB03607: st_select_lex::add_item_to_list(THD*, Item*) (sql_lex.cc:3473)
            ==22054==    by 0xB251F4: add_item_to_list(THD*, Item*) (sql_class.h:7373)
            ==22054==    by 0xE47393: MYSQLparse(THD*) (sql_yacc.yy:8958)
            ==22054==    by 0xB4EC2B: parse_sql(THD*, Parser_state*, Object_creation_ctx*, bool) (sql_parse.cc:10390)
            ==22054==    by 0xB492B8: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:7950)
            ==22054==    by 0xB3640D: dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) (sql_parse.cc:1894)
            ==22054== 
            ==22054== (action on error) vgdb me ... 
            

            Which makes no sense at all. It looks like the memory allocation metadata is corrupted.

            Johnston Rex Johnston added a comment - Still puzzling over this one. Valgrind tells me this. ==22054== Thread 33: ==22054== Invalid read of size 8 ==22054== at 0x9B88AB: base_list_iterator::next_fast() (sql_list.h:443) ==22054== by 0x9F5BB8: List_iterator_fast<Item>::operator++(int) (sql_list.h:620) ==22054== by 0xBF8927: JOIN::eval_select_list_used_tables() (sql_select.cc:13203) ==22054== by 0xBA0588: JOIN::optimize_inner() (sql_select.cc:2113) ==22054== by 0xB9F9ED: JOIN::optimize() (sql_select.cc:1871) ==22054== by 0xB063EC: st_select_lex::optimize_unflattened_subqueries(bool) (sql_lex.cc:4905) ==22054== by 0xD85DF6: JOIN::optimize_constant_subqueries() (opt_subselect.cc:5689) ==22054== by 0xBA09CF: JOIN::optimize_inner() (sql_select.cc:2194) ==22054== by 0xB9F9ED: JOIN::optimize() (sql_select.cc:1871) ==22054== by 0xBAB5AA: mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:5096) ==22054== by 0xB9A7D1: handle_select(THD*, LEX*, select_result*, unsigned long long) (sql_select.cc:581) ==22054== by 0xB44AEE: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:6263) ==22054== Address 0x3b64e958 is 56 bytes inside a block of size 64 alloc'd ==22054== at 0x483877F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==22054== by 0x18B620F: my_malloc (my_malloc.c:90) ==22054== by 0x18A69D9: alloc_root (my_alloc.c:287) ==22054== by 0x9B85EA: Sql_alloc::operator new(unsigned long, st_mem_root*) (sql_alloc.h:37) ==22054== by 0x9B87AF: base_list::push_back(void*, st_mem_root*) (sql_list.h:195) ==22054== by 0xA05504: List<Item>::push_back(Item*, st_mem_root*) (sql_list.h:505) ==22054== by 0xB03607: st_select_lex::add_item_to_list(THD*, Item*) (sql_lex.cc:3473) ==22054== by 0xB251F4: add_item_to_list(THD*, Item*) (sql_class.h:7373) ==22054== by 0xE47393: MYSQLparse(THD*) (sql_yacc.yy:8958) ==22054== by 0xB4EC2B: parse_sql(THD*, Parser_state*, Object_creation_ctx*, bool) (sql_parse.cc:10390) ==22054== by 0xB492B8: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:7950) ==22054== by 0xB3640D: dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) (sql_parse.cc:1894) ==22054== ==22054== (action on error) vgdb me ... Which makes no sense at all. It looks like the memory allocation metadata is corrupted.

            Johnston The Valgrind stack matches the ASAN stack for the first two frames. Does the ASAN trace above highlight where the issue is located?

            Roel Roel Van de Paar added a comment - Johnston The Valgrind stack matches the ASAN stack for the first two frames. Does the ASAN trace above highlight where the issue is located?
            Roel Roel Van de Paar added a comment - - edited

            Whilst the use-after-poison issue was discovered while inside the base_list_iterator class def in sql/sql_list.h (at line 431);

              inline void *next(void)
              {
                prev=el;
                current= *el;
                el= &current->next;
                return current->info;    // << Here, line 431
              }
            

            The original memory allocation for this thread was done by thread T16, which was started itself by the main mysqld_main thread (T0), using this code in reset_root_defaults in mysys/my_alloc.c line 243:

                  /* Allocate new prealloc block and add it to the end of free list */
                  if ((mem= (USED_MEM *) root_alloc(mem_root, size, &alloced_size,
                                                    MYF(MY_WME))))
                  {
                    mem->size= alloced_size;
                    mem->left= alloced_size - ALIGN_SIZE(sizeof(USED_MEM));
                    mem->next= *prev;
                    *prev= mem_root->pre_alloc= mem;
                    TRASH_MEM(mem);
                  }
            

            As per the ASAN trace. However, interestingly, we see this at the top of that code:

            #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG))
            

            Showing that using/not using Valgrind will lead to different outcomes here. Additionally, and a little strange, there is this "in-between" #endif preprocessor directive near the end of the function code block (i.e. is it in the right place?):

              }
              else
            #endif
                mem_root->pre_alloc= 0;
             
              DBUG_VOID_RETURN;
            }
            

            This function in particular (also in combination with having Valgrind turned on/off) may warrant further research.

            Roel Roel Van de Paar added a comment - - edited Whilst the use-after-poison issue was discovered while inside the base_list_iterator class def in sql/sql_list.h (at line 431); inline void *next( void ) { prev=el; current= *el; el= &current->next; return current->info; // << Here, line 431 } The original memory allocation for this thread was done by thread T16, which was started itself by the main mysqld_main thread (T0), using this code in reset_root_defaults in mysys/my_alloc.c line 243: /* Allocate new prealloc block and add it to the end of free list */ if ((mem= (USED_MEM *) root_alloc(mem_root, size, &alloced_size, MYF(MY_WME)))) { mem->size= alloced_size; mem->left= alloced_size - ALIGN_SIZE( sizeof (USED_MEM)); mem->next= *prev; *prev= mem_root->pre_alloc= mem; TRASH_MEM(mem); } As per the ASAN trace. However, interestingly, we see this at the top of that code: #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) Showing that using/not using Valgrind will lead to different outcomes here. Additionally, and a little strange, there is this "in-between" #endif preprocessor directive near the end of the function code block (i.e. is it in the right place?): } else #endif mem_root->pre_alloc= 0;   DBUG_VOID_RETURN; } This function in particular (also in combination with having Valgrind turned on/off) may warrant further research.

            inner->max_length in subquery_types_allow_materialization looks to be corrupted

            Program terminated with signal SIGSEGV, Segmentation fault.
            #0  subquery_types_allow_materialization (thd=thd@entry=0x14d220000d48, in_subs=in_subs@entry=0x14d220028708)
                at /test/10.11_dbg/sql/opt_subselect.cc:891
            891	    total_key_length += inner->max_length;
            [Current thread is 1 (Thread 0x14d2690c4700 (LWP 1491502))]
            (gdb) p total_key_length
            $1 = 0
            (gdb) p inner->max_length
            Cannot access memory at address 0x8f8f8f8f8f8f8f97
            

            Roel Roel Van de Paar added a comment - inner->max_length in subquery_types_allow_materialization looks to be corrupted Program terminated with signal SIGSEGV, Segmentation fault. #0 subquery_types_allow_materialization (thd=thd@entry=0x14d220000d48, in_subs=in_subs@entry=0x14d220028708) at /test/10.11_dbg/sql/opt_subselect.cc:891 891 total_key_length += inner->max_length; [Current thread is 1 (Thread 0x14d2690c4700 (LWP 1491502))] (gdb) p total_key_length $1 = 0 (gdb) p inner->max_length Cannot access memory at address 0x8f8f8f8f8f8f8f97
            Johnston Rex Johnston added a comment - - edited

            It's poisoned memory by a free() in removing a redundant group by clause in subquery.

            (gdb) p select_lex->first_inner_unit()->first_select()->join->fields_list
            $27 = (List<Item> &) @0x2edb1310: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x2edb0fa0, last = 0x2edb0fa0, elements = 1}, <No data fields>}
            (gdb) monitor get_vbits  0x2edb0fa0 10
            00000000 00000000 0000
             
            |
            V
             
            (gdb) monitor get_vbits  0x2edb0fa0 10
            ________ ________ ____
            Address 0x2EDB0FA0 len 10 has 10 bytes unaddressable
            

            The offending piece of code is in remove_redundant_subquery_clauses()

                    /*
                      Remove from the JOIN::all_fields list any reference to the elements
                      of the eliminated GROUP BY list unless it is 'in_field_list'.
                      This is needed in order not to confuse JOIN::make_aggr_tables_info()
                      when it constructs different structure for execution phase.
            	*/
                    List_iterator<Item> li(subq_select_lex->join->all_fields);
            	Item *item;
                    while ((item= li++))
            	{
                      if (item == *ord->item)
            	    li.remove();
            	}
            

            Will fix when I figure out how.

            Johnston Rex Johnston added a comment - - edited It's poisoned memory by a free() in removing a redundant group by clause in subquery. (gdb) p select_lex->first_inner_unit()->first_select()->join->fields_list $27 = (List<Item> &) @0x2edb1310: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x2edb0fa0, last = 0x2edb0fa0, elements = 1}, <No data fields>} (gdb) monitor get_vbits 0x2edb0fa0 10 00000000 00000000 0000   | V   (gdb) monitor get_vbits 0x2edb0fa0 10 ________ ________ ____ Address 0x2EDB0FA0 len 10 has 10 bytes unaddressable The offending piece of code is in remove_redundant_subquery_clauses() /* Remove from the JOIN::all_fields list any reference to the elements of the eliminated GROUP BY list unless it is 'in_field_list'. This is needed in order not to confuse JOIN::make_aggr_tables_info() when it constructs different structure for execution phase. */ List_iterator<Item> li(subq_select_lex->join->all_fields); Item *item; while ((item= li++)) { if (item == *ord->item) li.remove(); } Will fix when I figure out how.

            Great going

            Roel Roel Van de Paar added a comment - Great going
            Johnston Rex Johnston added a comment -

            Hi Igor,
            I was given this MDEV to look at by Sergei P. Looks like it's your code, I have no idea whether this is the right thing to do. Just guessing.
            Cheers, Rex

            Johnston Rex Johnston added a comment - Hi Igor, I was given this MDEV to look at by Sergei P. Looks like it's your code, I have no idea whether this is the right thing to do. Just guessing. Cheers, Rex
            Johnston Rex Johnston added a comment -

            and this still crashes...

            PREPARE FOO from "UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN ((SELECT * FROM (SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v3 AS (PARTITION BY c))))))";
            EXECUTE FOO;

            Johnston Rex Johnston added a comment - and this still crashes... PREPARE FOO from "UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN ((SELECT * FROM (SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v3 AS (PARTITION BY c))))))"; EXECUTE FOO;
            Roel Roel Van de Paar added a comment - - edited

            Found an additional testcase for use-after-poison in base_list_iterator::next to test with.

            CREATE TABLE x (x TEXT);
            SELECT (x=(SELECT x FROM x WHERE (x,x) NOT IN (SELECT''* x * 1,''FROM x WINDOW x AS (PARTITION BY x ORDER BY x ^ (SELECT 1 FROM x AS x WHERE x GROUP BY 1,x WINDOW x AS (PARTITION BY x ORDER BY (1))) ^ x RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING))) * 1^ 1 IN (-1,0,1,0,''/ x=x + CASE x WHEN TRUE THEN 0 ELSE 1 END OR x=x OR x=x)),''/ 1 AS x FROM x WINDOW x AS (PARTITION BY x ORDER BY (SELECT 1 FROM x WHERE x GROUP BY (x=(SELECT x FROM x WHERE (x,x) NOT IN (SELECT 1)) * 1^ 1 IN (-1,0,1,0,''/ x=x + CASE WHEN TRUE THEN 0 ELSE 1 END OR x=x OR x=x)),x WINDOW x AS (PARTITION BY x ORDER BY (1))) RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING);
            

            Roel Roel Van de Paar added a comment - - edited Found an additional testcase for use-after-poison in base_list_iterator::next to test with. CREATE TABLE x (x TEXT); SELECT (x=( SELECT x FROM x WHERE (x,x) NOT IN ( SELECT '' * x * 1, '' FROM x WINDOW x AS (PARTITION BY x ORDER BY x ^ ( SELECT 1 FROM x AS x WHERE x GROUP BY 1,x WINDOW x AS (PARTITION BY x ORDER BY (1))) ^ x RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING))) * 1^ 1 IN (-1,0,1,0, '' / x=x + CASE x WHEN TRUE THEN 0 ELSE 1 END OR x=x OR x=x)), '' / 1 AS x FROM x WINDOW x AS (PARTITION BY x ORDER BY ( SELECT 1 FROM x WHERE x GROUP BY (x=( SELECT x FROM x WHERE (x,x) NOT IN ( SELECT 1)) * 1^ 1 IN (-1,0,1,0, '' / x=x + CASE WHEN TRUE THEN 0 ELSE 1 END OR x=x OR x=x)),x WINDOW x AS (PARTITION BY x ORDER BY (1))) RANGE BETWEEN 1 FOLLOWING AND 1 FOLLOWING);

            Additional testcase with a very different stack, 10.4+ only, and a different ASAN use-after-poison in sql/sql_list.h

            CREATE TABLE t (c INT);
            SET SESSION optimizer_switch='materialization=OFF';
            UPDATE t SET c=1 WHERE c='' ORDER BY 1=(1 IN ((SELECT * FROM (SELECT * FROM t) AS v3 NATURAL JOIN t AS v2 NATURAL JOIN t AS v4 GROUP BY c WINDOW v5 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v6 AS (PARTITION BY c))))));
            

            Leads to:

            10.11.2 70be59913c90e93fe5136d6f6df03c4254aa515d (Debug)

            Core was generated by `/test/MD070123-mariadb-10.11.2-linux-x86_64-dbg/bin/mysqld --no-defaults --core'.
            Program terminated with signal SIGSEGV, Segmentation fault.
            #0  JOIN::eval_select_list_used_tables (this=0x14b870035148)
                at /test/10.11_dbg/sql/sql_select.cc:13195
            [Current thread is 1 (Thread 0x14b897147640 (LWP 2601256))]
            (gdb) bt
            #0  JOIN::eval_select_list_used_tables (this=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:13195
            #1  JOIN::optimize_inner (this=this@entry=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:2112
            #2  0x00005636942443aa in JOIN::optimize (this=this@entry=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:1870
            #3  0x000056369419066a in st_select_lex::optimize_unflattened_subqueries (this=0x14b8700057c8, const_only=const_only@entry=true) at /test/10.11_dbg/sql/sql_lex.cc:4907
            #4  0x000056369436b32b in JOIN::optimize_constant_subqueries (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/opt_subselect.cc:5689
            #5  0x0000563694242f3e in JOIN::optimize_inner (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/sql_select.cc:2193
            #6  0x00005636942443aa in JOIN::optimize (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/sql_select.cc:1870
            #7  0x000056369424449a in mysql_select (thd=thd@entry=0x14b870000d58, tables=tables@entry=0x14b870013390, fields=@0x14b897145d10: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5636956a6f00 <end_of_list>, last = 0x14b897145d10, elements = 0}, <No data fields>}, conds=conds@entry=0x14b870013e18, og_num=1, order=0x14b87002adb0, group=0x0, having=0x0, proc_param=0x0, select_options=37383395344512, result=0x14b8700346f0, unit=0x14b870004f98, select_lex=0x14b8700057c8) at /test/10.11_dbg/sql/sql_select.cc:5066
            #8  0x00005636942b980b in mysql_multi_update (thd=thd@entry=0x14b870000d58, table_list=0x14b870013390, fields=fields@entry=0x14b870005a68, values=values@entry=0x14b870005ea0, conds=0x14b870013e18, options=0, handle_duplicates=DUP_ERROR, ignore=false, unit=0x14b870004f98, select_lex=0x14b8700057c8, result=0x14b897145f00) at /test/10.11_dbg/sql/sql_update.cc:1980
            #9  0x00005636941bcfa8 in mysql_execute_command (thd=thd@entry=0x14b870000d58, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.11_dbg/sql/sql_parse.cc:4491
            #10 0x00005636941c2c7a in mysql_parse (thd=thd@entry=0x14b870000d58, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14b8971462c0) at /test/10.11_dbg/sql/sql_parse.cc:8000
            #11 0x00005636941c4e0e in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14b870000d58, packet=packet@entry=0x14b87000ae09 "UPDATE t SET c=1 WHERE c='' ORDER BY 1=(1 IN ((SELECT * FROM (SELECT * FROM t) AS v3 NATURAL JOIN t AS v2 NATURAL JOIN t AS v4 GROUP BY c WINDOW v5 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v6 A"..., packet_length=packet_length@entry=223, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_class.h:243
            #12 0x00005636941c6c67 in do_command (thd=0x14b870000d58, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_parse.cc:1407
            #13 0x0000563694310d30 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x563697323838, put_in_cache=put_in_cache@entry=true) at /test/10.11_dbg/sql/sql_connect.cc:1416
            #14 0x0000563694310f8f in handle_one_connection (arg=0x563697323838) at /test/10.11_dbg/sql/sql_connect.cc:1318
            #15 0x000014b8c7a62b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
            #16 0x000014b8c7af4a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
            

            10.11.2 70be59913c90e93fe5136d6f6df03c4254aa515d (Optimized, UBASAN)

            ==2670205==ERROR: AddressSanitizer: use-after-poison on address 0x6290000888c0 at pc 0x5622357f717c bp 0x147d5641d9f0 sp 0x147d5641d9e0
            READ of size 8 at 0x6290000888c0 thread T13
                #0 0x5622357f717b in base_list_iterator::next_fast() /test/10.11_opt_san/sql/sql_list.h:443
                #1 0x5622357f717b in List_iterator_fast<Item>::operator++(int) /test/10.11_opt_san/sql/sql_list.h:620
                #2 0x5622357f717b in JOIN::eval_select_list_used_tables() /test/10.11_opt_san/sql/sql_select.cc:13193
                #3 0x5622357f717b in JOIN::optimize_inner() /test/10.11_opt_san/sql/sql_select.cc:2112
                #4 0x5622357fb2a0 in JOIN::optimize() /test/10.11_opt_san/sql/sql_select.cc:1870
                #5 0x562235291342 in st_select_lex::optimize_unflattened_subqueries(bool) /test/10.11_opt_san/sql/sql_lex.cc:4907
                #6 0x562235f675e7 in JOIN::optimize_constant_subqueries() /test/10.11_opt_san/sql/opt_subselect.cc:5689
                #7 0x5622357f01a0 in JOIN::optimize_inner() /test/10.11_opt_san/sql/sql_select.cc:2193
                #8 0x5622357fb2a0 in JOIN::optimize() /test/10.11_opt_san/sql/sql_select.cc:1870
                #9 0x5622357fb936 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/10.11_opt_san/sql/sql_select.cc:5066
                #10 0x562235b16be7 in mysql_multi_update(THD*, TABLE_LIST*, List<Item>*, List<Item>*, Item*, unsigned long long, enum_duplicates, bool, st_select_lex_unit*, st_select_lex*, multi_update**) /test/10.11_opt_san/sql/sql_update.cc:1980
                #11 0x562235404878 in mysql_execute_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:4491
                #12 0x562235420d82 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_opt_san/sql/sql_parse.cc:8000
                #13 0x56223542e7e5 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_opt_san/sql/sql_parse.cc:1894
                #14 0x562235437f40 in do_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:1407
                #15 0x562235d1471c in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1416
                #16 0x562235d16d1c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1318
                #17 0x147d78315b42 in start_thread nptl/pthread_create.c:442
                #18 0x147d783a79ff  (/lib/x86_64-linux-gnu/libc.so.6+0x1269ff)
             
            0x6290000888c0 is located 5824 bytes inside of 16400-byte region [0x629000087200,0x62900008b210)
            allocated by thread T13 here:
                #0 0x562234b4c887 in malloc (/test/UBASAN_MD070123-mariadb-10.11.2-linux-x86_64-opt/bin/mariadbd+0x7a20887)
                #1 0x562238f71d14 in my_malloc /test/10.11_opt_san/mysys/my_malloc.c:90
                #2 0x562238f4ce2b in root_alloc /test/10.11_opt_san/mysys/my_alloc.c:66
                #3 0x562238f4ce2b in reset_root_defaults /test/10.11_opt_san/mysys/my_alloc.c:243
                #4 0x56223508d24e in THD::init_for_queries() /test/10.11_opt_san/sql/sql_class.cc:1387
                #5 0x562235d0f24e in prepare_new_connection_state(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1245
                #6 0x562235d10b37 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1339
                #7 0x562235d10b37 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1328
                #8 0x562235d137b7 in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1406
                #9 0x562235d16d1c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1318
                #10 0x147d78315b42 in start_thread nptl/pthread_create.c:442
             
            Thread T13 created by T0 here:
                #0 0x562234af06c5 in pthread_create (/test/UBASAN_MD070123-mariadb-10.11.2-linux-x86_64-opt/bin/mariadbd+0x79c46c5)
                #1 0x562234ba4cfe in create_thread_to_handle_connection(CONNECT*) /test/10.11_opt_san/sql/mysqld.cc:6102
                #2 0x562234bb712f in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/10.11_opt_san/sql/mysqld.cc:6223
                #3 0x562234bb80b7 in handle_connections_sockets() /test/10.11_opt_san/sql/mysqld.cc:6347
                #4 0x562234bbb11d in mysqld_main(int, char**) /test/10.11_opt_san/sql/mysqld.cc:5997
                #5 0x147d782aad8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
             
            SUMMARY: AddressSanitizer: use-after-poison /test/10.11_opt_san/sql/sql_list.h:443 in base_list_iterator::next_fast()
            Shadow bytes around the buggy address:
              0x0c52800090c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c52800090d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c52800090e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f7
              0x0c52800090f0: 00 00 f7 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            =>0x0c5280009110: 00 00 00 00 00 00 f7 f7[f7]f7 00 00 00 00 00 00
              0x0c5280009120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c5280009160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            Shadow byte legend (one shadow byte represents 8 application bytes):
              Addressable:           00
              Partially addressable: 01 02 03 04 05 06 07
              Heap left redzone:       fa
              Freed heap region:       fd
              Stack left redzone:      f1
              Stack mid redzone:       f2
              Stack right redzone:     f3
              Stack after return:      f5
              Stack use after scope:   f8
              Global redzone:          f9
              Global init order:       f6
              Poisoned by user:        f7
              Container overflow:      fc
              Array cookie:            ac
              Intra object redzone:    bb
              ASan internal:           fe
              Left alloca redzone:     ca
              Right alloca redzone:    cb
              Shadow gap:              cc
            ==2670205==ABORTING
            

            Bug confirmed present in:
            MariaDB: 10.4.28 (dbg), 10.5.19 (dbg), 10.6.12 (dbg), 10.7.8 (dbg), 10.8.7 (dbg), 10.9.5 (dbg), 10.10.3 (dbg), 10.11.2 (dbg)

            Bug (or feature/syntax) confirmed not present in:
            MariaDB: 10.3.38 (dbg), 10.3.38 (opt), 10.4.28 (opt), 10.5.19 (opt), 10.6.12 (opt), 10.7.8 (opt), 10.8.7 (opt), 10.9.5 (opt), 10.10.3 (opt), 10.11.2 (opt)
            MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.40 (dbg), 5.7.40 (opt), 8.0.31 (dbg), 8.0.31 (opt)

            Roel Roel Van de Paar added a comment - Additional testcase with a very different stack, 10.4+ only, and a different ASAN use-after-poison in sql/sql_list.h CREATE TABLE t (c INT ); SET SESSION optimizer_switch= 'materialization=OFF' ; UPDATE t SET c=1 WHERE c= '' ORDER BY 1=(1 IN (( SELECT * FROM ( SELECT * FROM t) AS v3 NATURAL JOIN t AS v2 NATURAL JOIN t AS v4 GROUP BY c WINDOW v5 AS ( ORDER BY ( SELECT * FROM t GROUP BY c WINDOW v6 AS (PARTITION BY c)))))); Leads to: 10.11.2 70be59913c90e93fe5136d6f6df03c4254aa515d (Debug) Core was generated by `/test/MD070123-mariadb-10.11.2-linux-x86_64-dbg/bin/mysqld --no-defaults --core'. Program terminated with signal SIGSEGV, Segmentation fault. #0 JOIN::eval_select_list_used_tables (this=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:13195 [Current thread is 1 (Thread 0x14b897147640 (LWP 2601256))] (gdb) bt #0 JOIN::eval_select_list_used_tables (this=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:13195 #1 JOIN::optimize_inner (this=this@entry=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:2112 #2 0x00005636942443aa in JOIN::optimize (this=this@entry=0x14b870035148) at /test/10.11_dbg/sql/sql_select.cc:1870 #3 0x000056369419066a in st_select_lex::optimize_unflattened_subqueries (this=0x14b8700057c8, const_only=const_only@entry=true) at /test/10.11_dbg/sql/sql_lex.cc:4907 #4 0x000056369436b32b in JOIN::optimize_constant_subqueries (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/opt_subselect.cc:5689 #5 0x0000563694242f3e in JOIN::optimize_inner (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/sql_select.cc:2193 #6 0x00005636942443aa in JOIN::optimize (this=this@entry=0x14b870034800) at /test/10.11_dbg/sql/sql_select.cc:1870 #7 0x000056369424449a in mysql_select (thd=thd@entry=0x14b870000d58, tables=tables@entry=0x14b870013390, fields=@0x14b897145d10: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5636956a6f00 <end_of_list>, last = 0x14b897145d10, elements = 0}, <No data fields>}, conds=conds@entry=0x14b870013e18, og_num=1, order=0x14b87002adb0, group=0x0, having=0x0, proc_param=0x0, select_options=37383395344512, result=0x14b8700346f0, unit=0x14b870004f98, select_lex=0x14b8700057c8) at /test/10.11_dbg/sql/sql_select.cc:5066 #8 0x00005636942b980b in mysql_multi_update (thd=thd@entry=0x14b870000d58, table_list=0x14b870013390, fields=fields@entry=0x14b870005a68, values=values@entry=0x14b870005ea0, conds=0x14b870013e18, options=0, handle_duplicates=DUP_ERROR, ignore=false, unit=0x14b870004f98, select_lex=0x14b8700057c8, result=0x14b897145f00) at /test/10.11_dbg/sql/sql_update.cc:1980 #9 0x00005636941bcfa8 in mysql_execute_command (thd=thd@entry=0x14b870000d58, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.11_dbg/sql/sql_parse.cc:4491 #10 0x00005636941c2c7a in mysql_parse (thd=thd@entry=0x14b870000d58, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x14b8971462c0) at /test/10.11_dbg/sql/sql_parse.cc:8000 #11 0x00005636941c4e0e in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x14b870000d58, packet=packet@entry=0x14b87000ae09 "UPDATE t SET c=1 WHERE c='' ORDER BY 1=(1 IN ((SELECT * FROM (SELECT * FROM t) AS v3 NATURAL JOIN t AS v2 NATURAL JOIN t AS v4 GROUP BY c WINDOW v5 AS (ORDER BY (SELECT * FROM t GROUP BY c WINDOW v6 A"..., packet_length=packet_length@entry=223, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_class.h:243 #12 0x00005636941c6c67 in do_command (thd=0x14b870000d58, blocking=blocking@entry=true) at /test/10.11_dbg/sql/sql_parse.cc:1407 #13 0x0000563694310d30 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x563697323838, put_in_cache=put_in_cache@entry=true) at /test/10.11_dbg/sql/sql_connect.cc:1416 #14 0x0000563694310f8f in handle_one_connection (arg=0x563697323838) at /test/10.11_dbg/sql/sql_connect.cc:1318 #15 0x000014b8c7a62b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442 #16 0x000014b8c7af4a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 10.11.2 70be59913c90e93fe5136d6f6df03c4254aa515d (Optimized, UBASAN) ==2670205==ERROR: AddressSanitizer: use-after-poison on address 0x6290000888c0 at pc 0x5622357f717c bp 0x147d5641d9f0 sp 0x147d5641d9e0 READ of size 8 at 0x6290000888c0 thread T13 #0 0x5622357f717b in base_list_iterator::next_fast() /test/10.11_opt_san/sql/sql_list.h:443 #1 0x5622357f717b in List_iterator_fast<Item>::operator++(int) /test/10.11_opt_san/sql/sql_list.h:620 #2 0x5622357f717b in JOIN::eval_select_list_used_tables() /test/10.11_opt_san/sql/sql_select.cc:13193 #3 0x5622357f717b in JOIN::optimize_inner() /test/10.11_opt_san/sql/sql_select.cc:2112 #4 0x5622357fb2a0 in JOIN::optimize() /test/10.11_opt_san/sql/sql_select.cc:1870 #5 0x562235291342 in st_select_lex::optimize_unflattened_subqueries(bool) /test/10.11_opt_san/sql/sql_lex.cc:4907 #6 0x562235f675e7 in JOIN::optimize_constant_subqueries() /test/10.11_opt_san/sql/opt_subselect.cc:5689 #7 0x5622357f01a0 in JOIN::optimize_inner() /test/10.11_opt_san/sql/sql_select.cc:2193 #8 0x5622357fb2a0 in JOIN::optimize() /test/10.11_opt_san/sql/sql_select.cc:1870 #9 0x5622357fb936 in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/10.11_opt_san/sql/sql_select.cc:5066 #10 0x562235b16be7 in mysql_multi_update(THD*, TABLE_LIST*, List<Item>*, List<Item>*, Item*, unsigned long long, enum_duplicates, bool, st_select_lex_unit*, st_select_lex*, multi_update**) /test/10.11_opt_san/sql/sql_update.cc:1980 #11 0x562235404878 in mysql_execute_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:4491 #12 0x562235420d82 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_opt_san/sql/sql_parse.cc:8000 #13 0x56223542e7e5 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_opt_san/sql/sql_parse.cc:1894 #14 0x562235437f40 in do_command(THD*, bool) /test/10.11_opt_san/sql/sql_parse.cc:1407 #15 0x562235d1471c in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1416 #16 0x562235d16d1c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1318 #17 0x147d78315b42 in start_thread nptl/pthread_create.c:442 #18 0x147d783a79ff (/lib/x86_64-linux-gnu/libc.so.6+0x1269ff)   0x6290000888c0 is located 5824 bytes inside of 16400-byte region [0x629000087200,0x62900008b210) allocated by thread T13 here: #0 0x562234b4c887 in malloc (/test/UBASAN_MD070123-mariadb-10.11.2-linux-x86_64-opt/bin/mariadbd+0x7a20887) #1 0x562238f71d14 in my_malloc /test/10.11_opt_san/mysys/my_malloc.c:90 #2 0x562238f4ce2b in root_alloc /test/10.11_opt_san/mysys/my_alloc.c:66 #3 0x562238f4ce2b in reset_root_defaults /test/10.11_opt_san/mysys/my_alloc.c:243 #4 0x56223508d24e in THD::init_for_queries() /test/10.11_opt_san/sql/sql_class.cc:1387 #5 0x562235d0f24e in prepare_new_connection_state(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1245 #6 0x562235d10b37 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1339 #7 0x562235d10b37 in thd_prepare_connection(THD*) /test/10.11_opt_san/sql/sql_connect.cc:1328 #8 0x562235d137b7 in do_handle_one_connection(CONNECT*, bool) /test/10.11_opt_san/sql/sql_connect.cc:1406 #9 0x562235d16d1c in handle_one_connection /test/10.11_opt_san/sql/sql_connect.cc:1318 #10 0x147d78315b42 in start_thread nptl/pthread_create.c:442   Thread T13 created by T0 here: #0 0x562234af06c5 in pthread_create (/test/UBASAN_MD070123-mariadb-10.11.2-linux-x86_64-opt/bin/mariadbd+0x79c46c5) #1 0x562234ba4cfe in create_thread_to_handle_connection(CONNECT*) /test/10.11_opt_san/sql/mysqld.cc:6102 #2 0x562234bb712f in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/10.11_opt_san/sql/mysqld.cc:6223 #3 0x562234bb80b7 in handle_connections_sockets() /test/10.11_opt_san/sql/mysqld.cc:6347 #4 0x562234bbb11d in mysqld_main(int, char**) /test/10.11_opt_san/sql/mysqld.cc:5997 #5 0x147d782aad8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58   SUMMARY: AddressSanitizer: use-after-poison /test/10.11_opt_san/sql/sql_list.h:443 in base_list_iterator::next_fast() Shadow bytes around the buggy address: 0x0c52800090c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c52800090d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c52800090e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f7 0x0c52800090f0: 00 00 f7 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c5280009110: 00 00 00 00 00 00 f7 f7[f7]f7 00 00 00 00 00 00 0x0c5280009120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5280009160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==2670205==ABORTING Bug confirmed present in: MariaDB: 10.4.28 (dbg), 10.5.19 (dbg), 10.6.12 (dbg), 10.7.8 (dbg), 10.8.7 (dbg), 10.9.5 (dbg), 10.10.3 (dbg), 10.11.2 (dbg) Bug (or feature/syntax) confirmed not present in: MariaDB: 10.3.38 (dbg), 10.3.38 (opt), 10.4.28 (opt), 10.5.19 (opt), 10.6.12 (opt), 10.7.8 (opt), 10.8.7 (opt), 10.9.5 (opt), 10.10.3 (opt), 10.11.2 (opt) MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.40 (dbg), 5.7.40 (opt), 8.0.31 (dbg), 8.0.31 (opt)
            Johnston Rex Johnston added a comment -

            Hi Sergei. I returned to this after Roel added new test cases.

            Johnston Rex Johnston added a comment - Hi Sergei. I returned to this after Roel added new test cases.
            Roel Roel Van de Paar added a comment - - edited

            I keep running into this bug in various ways. New UniqueID with this testcase

            CREATE TABLE t (c INT);
            SET SESSION optimizer_trace=1;
            UPDATE t SET c=1 WHERE c IN (SELECT * FROM t AS c NATURAL JOIN t WINDOW c AS (PARTITION BY 1 BETWEEN (SELECT 1 GROUP BY c WINDOW c AS (PARTITION BY c)) AND 1));
            

            SIGSEGV|st_select_lex::print|opt_trace_print_expanded_query|JOIN::prepare|subselect_single_select_engine::prepare
            

            Please verify this testcase after a fix found, as it may touch on another bug also (given the optimizer_trace setting requirement)

            Roel Roel Van de Paar added a comment - - edited I keep running into this bug in various ways. New UniqueID with this testcase CREATE TABLE t (c INT ); SET SESSION optimizer_trace=1; UPDATE t SET c=1 WHERE c IN ( SELECT * FROM t AS c NATURAL JOIN t WINDOW c AS (PARTITION BY 1 BETWEEN ( SELECT 1 GROUP BY c WINDOW c AS (PARTITION BY c)) AND 1)); SIGSEGV|st_select_lex::print|opt_trace_print_expanded_query|JOIN::prepare|subselect_single_select_engine::prepare Please verify this testcase after a fix found, as it may touch on another bug also (given the optimizer_trace setting requirement)

            Debugging the original testcase...

            The code in remove_redundant_subquery_clauses() removes elements from
            subq_select_lex->join->all_fields:

                    
                    /*
                      Remove from the JOIN::all_fields list any reference to the elements
                      of the eliminated GROUP BY list unless it is 'in_field_list'.
                      This is needed in order not to confuse JOIN::make_aggr_tables_info()
                      when it constructs different structure for execution phase.
            	*/
                    List_iterator<Item> li(subq_select_lex->join->all_fields);
            	Item *item;
                    while ((item= li++))
            	{
                      if (item == *ord->item)
            	    li.remove();
            	}
            

            While doing that, it corrupts subq_select_lex->item_list: immediately after the li.remove() call above one, one gets:

            (gdb) p subq_select_lex->item_list
            $88 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x7fff78015598, last = 0x7fff78015598, elements = 1}, <No data fields>}
             
            (gdb) p subq_select_lex->item_list->first[0]
            $89 = {<Sql_alloc> = {<No data fields>}, next = 0x8f8f8f8f8f8f8f8f, info = 0x8f8f8f8f8f8f8f8f}
            

            I'm not sure how this happens if these two are separate lists?

            psergei Sergei Petrunia added a comment - Debugging the original testcase... The code in remove_redundant_subquery_clauses() removes elements from subq_select_lex->join->all_fields : /* Remove from the JOIN::all_fields list any reference to the elements of the eliminated GROUP BY list unless it is 'in_field_list'. This is needed in order not to confuse JOIN::make_aggr_tables_info() when it constructs different structure for execution phase. */ List_iterator<Item> li(subq_select_lex->join->all_fields); Item *item; while ((item= li++)) { if (item == *ord->item) li. remove (); } While doing that, it corrupts subq_select_lex->item_list : immediately after the li.remove() call above one, one gets: (gdb) p subq_select_lex->item_list $88 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x7fff78015598, last = 0x7fff78015598, elements = 1}, <No data fields>}   (gdb) p subq_select_lex->item_list->first[0] $89 = {<Sql_alloc> = {<No data fields>}, next = 0x8f8f8f8f8f8f8f8f, info = 0x8f8f8f8f8f8f8f8f} I'm not sure how this happens if these two are separate lists?
            psergei Sergei Petrunia added a comment - - edited

            ... they are not. item_list is the suffix of all_fields. Note the $PTR here:

            (gdb) p subq_select_lex->join->all_fields
            $98 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x7fff6c02b610, last = $PTR, elements = 2}, <No data fields>}
            (gdb) p subq_select_lex->item_list
            $99 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = $PTR, last = $PTR, elements = 1}, <No data fields>}
            (gdb) p subq_select_lex->join->all_fields.first[0]
            $100 = {<Sql_alloc> = {<No data fields>}, next = $PTR, info = 0x7fff6c018988}
            

            List contents:

            (gdb) p subq_select_lex->join->all_fields.elem(0)
            $102 = (Item_singlerow_subselect *) 0x7fff6c018988
            (gdb) p subq_select_lex->join->all_fields.elem(1)
            $103 = (Item_field *) 0x7fff6c02aa30
            

            psergei Sergei Petrunia added a comment - - edited ... they are not. item_list is the suffix of all_fields . Note the $PTR here: (gdb) p subq_select_lex->join->all_fields $98 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x7fff6c02b610, last = $PTR, elements = 2}, <No data fields>} (gdb) p subq_select_lex->item_list $99 = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = $PTR, last = $PTR, elements = 1}, <No data fields>} (gdb) p subq_select_lex->join->all_fields.first[0] $100 = {<Sql_alloc> = {<No data fields>}, next = $PTR, info = 0x7fff6c018988} List contents: (gdb) p subq_select_lex->join->all_fields.elem(0) $102 = (Item_singlerow_subselect *) 0x7fff6c018988 (gdb) p subq_select_lex->join->all_fields.elem(1) $103 = (Item_field *) 0x7fff6c02aa30

            Take-away from the optimizer call: the observed "list sharing" is known and it was like that for a very long time.

            psergei Sergei Petrunia added a comment - Take-away from the optimizer call: the observed "list sharing" is known and it was like that for a very long time.
            Johnston Rex Johnston added a comment - PR updated after information from sanja details here https://github.com/MariaDB/server/commit/da51a117e1271b2ac821571a45849ffa04d8be2a#diff-16fd8e507582e428d933bc7ee3984394eab544410785220b536ab964d4e9e084

            Note: MDEV-29359 is fixed by the fix for this bug. MDEV-28515 (linked to MDEV-29359) is not fixed by fix for this bug.

            psergei Sergei Petrunia added a comment - Note: MDEV-29359 is fixed by the fix for this bug. MDEV-28515 (linked to MDEV-29359 ) is not fixed by fix for this bug.

            Johnston, the patch technically works, but I see some flaws:

            • why put the test in insert_select.test ? The failure is caused by the code which handles IN subqueries... I don't see how the INSERT part is necessary...
            • There is a more efficient way to check if we've reached the part of the list which we should not touch...
            • Some of the "discoveries" made while investigating this deserve code comments, I think...
            psergei Sergei Petrunia added a comment - Johnston , the patch technically works, but I see some flaws: why put the test in insert_select.test ? The failure is caused by the code which handles IN subqueries... I don't see how the INSERT part is necessary... There is a more efficient way to check if we've reached the part of the list which we should not touch... Some of the "discoveries" made while investigating this deserve code comments, I think...
            psergei Sergei Petrunia added a comment - - edited

            Addressed all of the above in: https://github.com/MariaDB/server/commit/436abf9253d4f54e8a2c7400c33d65790b9e620c
            sanja, could you please review?

            psergei Sergei Petrunia added a comment - - edited Addressed all of the above in: https://github.com/MariaDB/server/commit/436abf9253d4f54e8a2c7400c33d65790b9e620c sanja , could you please review?

            sanja, one question that is still not clear to me: If the select list entry was NOT added by GROUP BY code, why does the ORDER structure have ord->in_field_list==false ? Is this correct? (It's hard for me to tell, because there's no exact definition of what in_field_list means).

            And do we need the check for (!in_field_list) after this patch?

            psergei Sergei Petrunia added a comment - sanja , one question that is still not clear to me: If the select list entry was NOT added by GROUP BY code, why does the ORDER structure have ord->in_field_list==false ? Is this correct? (It's hard for me to tell, because there's no exact definition of what in_field_list means). And do we need the check for (!in_field_list) after this patch?

            Let's execute the query:

            UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN ((SELECT * FROM (SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS (ORDER BY (SELECT * FROM t tt GROUP BY c WINDOW v3 AS (PARTITION BY c))))));
            

            The cause of the problem can seen here:

            (gdb) p thd->lex->all_selects_list
            $122 = (SELECT_LEX *) 0x7fff90016990
            (gdb) p dbug_print_select((SELECT_LEX *) 0x7fff90016990)
            $123 = 0x555557581b40 <dbug_item_print_buf> "select `*` from test.t tt group by c"
            (gdb) p ((SELECT_LEX *) 0x7fff90016990)->group_list
            $124 = {<Sql_alloc> = {<No data fields>}, elements = 1, first = 0x7fff90017eb0, next = 0x7fff90017eb0}
            (gdb) p ((SELECT_LEX *) 0x7fff90016990)->next_select_in_list()
            $125 = (st_select_lex *) 0x7fff90014d38
            (gdb) p dbug_print_select((st_select_lex *) 0x7fff90014d38)
            $126 = 0x555557581b40 <dbug_item_print_buf> "select t.c AS c from test.t"
            (gdb) p ((st_select_lex *) 0x7fff90014d38)->next_select_in_list()
            $127 = (st_select_lex *) 0x7fff90014018
            (gdb) p dbug_print_select((st_select_lex *) 0x7fff90014018)
            $128 = 0x555557581b40 <dbug_item_print_buf> "select `*` from (select t.c AS c from test.t) v1 group by c"
            (gdb) p ((st_select_lex *) 0x7fff90014018)->group_list
            $129 = {<Sql_alloc> = {<No data fields>}, elements = 1, first = 0x7fff90017eb0, next = 0x7fff90017eb0}
            

            Here we see that two different selects:

            select `*` from (select t.c AS c from test.t) v1 group by c
            select `*` from test.t tt group by c
            

            share the same group_list.
            We have this when starting to execute mysql_derived_prepare() for the derived table v1 called indirectly from Multiupdate_prelocking_strategy::handle_end()

            igor Igor Babaev (Inactive) added a comment - Let's execute the query: UPDATE t SET c=1 WHERE c=2 ORDER BY (1 IN (( SELECT * FROM ( SELECT * FROM t) AS v1 GROUP BY c WINDOW v2 AS ( ORDER BY ( SELECT * FROM t tt GROUP BY c WINDOW v3 AS (PARTITION BY c)))))); The cause of the problem can seen here: (gdb) p thd->lex->all_selects_list $122 = (SELECT_LEX *) 0x7fff90016990 (gdb) p dbug_print_select((SELECT_LEX *) 0x7fff90016990) $123 = 0x555557581b40 <dbug_item_print_buf> "select `*` from test.t tt group by c" (gdb) p ((SELECT_LEX *) 0x7fff90016990)->group_list $124 = {<Sql_alloc> = {<No data fields>}, elements = 1, first = 0x7fff90017eb0, next = 0x7fff90017eb0} (gdb) p ((SELECT_LEX *) 0x7fff90016990)->next_select_in_list() $125 = (st_select_lex *) 0x7fff90014d38 (gdb) p dbug_print_select((st_select_lex *) 0x7fff90014d38) $126 = 0x555557581b40 <dbug_item_print_buf> "select t.c AS c from test.t" (gdb) p ((st_select_lex *) 0x7fff90014d38)->next_select_in_list() $127 = (st_select_lex *) 0x7fff90014018 (gdb) p dbug_print_select((st_select_lex *) 0x7fff90014018) $128 = 0x555557581b40 <dbug_item_print_buf> "select `*` from (select t.c AS c from test.t) v1 group by c" (gdb) p ((st_select_lex *) 0x7fff90014018)->group_list $129 = {<Sql_alloc> = {<No data fields>}, elements = 1, first = 0x7fff90017eb0, next = 0x7fff90017eb0} Here we see that two different selects: select `*` from (select t.c AS c from test.t) v1 group by c select `*` from test.t tt group by c share the same group_list. We have this when starting to execute mysql_derived_prepare() for the derived table v1 called indirectly from Multiupdate_prelocking_strategy::handle_end()

            Ok, this is a parser problem. Here's a fix:

             diff --git a/sql/sql_lex.h b/sql/sql_lex.h
            index bdc8b54..548272f 100644
            --- a/sql/sql_lex.h
            +++ b/sql/sql_lex.h
            @@ -976,6 +976,7 @@ class st_select_lex: public st_select_lex_node
               */
               SQL_I_List<ORDER>       group_list;
               Group_list_ptrs        *group_list_ptrs;
            +  SQL_I_List<ORDER>       save_group_list;
             
               List<Item>          item_list;  /* list of fields & expressions */
               List<Item>          pre_fix; /* above list before fix_fields */
            @@ -1040,6 +1041,7 @@ class st_select_lex: public st_select_lex_node
               const char *type;               /* type of select for EXPLAIN          */
             
               SQL_I_List<ORDER> order_list;   /* ORDER clause */
            +  SQL_I_List<ORDER> save_order_list;
               SQL_I_List<ORDER> gorder_list;
               Item *select_limit, *offset_limit;  /* LIMIT clause parameters */
             
            @@ -3215,8 +3217,6 @@ struct LEX: public Query_tables_list
               }
             
             
            -  SQL_I_List<ORDER> save_group_list;
            -  SQL_I_List<ORDER> save_order_list;
               LEX_CSTRING *win_ref;
               Window_frame *win_frame;
               Window_frame_bound *frame_top_bound;
            diff --git a/sql/sql_list.h b/sql/sql_list.h
            index b112398..40848c2 100644
            --- a/sql/sql_list.h
            +++ b/sql/sql_list.h
            @@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc
               {
                 elements= tmp.elements;
                 first= tmp.first;
            -    next= tmp.next;
            --- a/sql/sql_list.h
            +++ b/sql/sql_list.h
            @@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc
               {
                 elements= tmp.elements;
                 first= tmp.first;
            -    next= tmp.next;
            +    next= elements ? tmp.next : &first;
                 return *this;
            diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
            index 5e4c41f..cfe8c91 100644
            --- a/sql/sql_lex.cc
            +++ b/sql/sql_lex.cc
            @@ -755,8 +755,6 @@ void LEX::start(THD *thd_arg)
               stmt_var_list.empty();
               proc_list.elements=0;
             
            -  save_group_list.empty();
            -  save_order_list.empty();
               win_ref= NULL;
               win_frame= NULL;
               frame_top_bound= NULL;
            diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
            index 3102aa6..f360b24 100644
            --- a/sql/sql_parse.cc
            +++ b/sql/sql_parse.cc
            @@ -8662,8 +8662,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
             void st_select_lex::prepare_add_window_spec(THD *thd)
             {
               LEX *lex= thd->lex;
            -  lex->save_group_list= group_list;
            -  lex->save_order_list= order_list;
            +  save_group_list= group_list;
            +  save_order_list= order_list;
               lex->win_ref= NULL;
               lex->win_frame= NULL;
               lex->frame_top_bound= NULL;
            @@ -8690,8 +8690,8 @@ bool st_select_lex::add_window_def(THD *thd,
                                                                   win_part_list_ptr,
                                                                   win_order_list_ptr,
                                                                   win_frame);
            -  group_list= thd->lex->save_group_list;
            -  order_list= thd->lex->save_order_list;
            +  group_list= save_group_list;
            +  order_list= save_order_list;
               if (parsing_place != SELECT_LIST)
               {
                 fields_in_window_functions+= win_part_list_ptr->elements +
            @@ -8717,8 +8717,8 @@ bool st_select_lex::add_window_spec(THD *thd,
                                                                      win_part_list_ptr,
                                                                      win_order_list_ptr,
                                                                      win_frame);
            -  group_list= thd->lex->save_group_list;
            -  order_list= thd->lex->save_order_list;
            +  group_list= save_group_list;
            +  order_list= save_order_list;
               if (parsing_place != SELECT_LIST)
               {
                 fields_in_window_functions+= win_part_list_ptr->elements +
            

            This fixes the problem.

            igor Igor Babaev (Inactive) added a comment - Ok, this is a parser problem. Here's a fix: diff --git a/sql/sql_lex.h b/sql/sql_lex.h index bdc8b54..548272f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -976,6 +976,7 @@ class st_select_lex: public st_select_lex_node */ SQL_I_List<ORDER> group_list; Group_list_ptrs *group_list_ptrs; + SQL_I_List<ORDER> save_group_list; List<Item> item_list; /* list of fields & expressions */ List<Item> pre_fix; /* above list before fix_fields */ @@ -1040,6 +1041,7 @@ class st_select_lex: public st_select_lex_node const char *type; /* type of select for EXPLAIN */ SQL_I_List<ORDER> order_list; /* ORDER clause */ + SQL_I_List<ORDER> save_order_list; SQL_I_List<ORDER> gorder_list; Item *select_limit, *offset_limit; /* LIMIT clause parameters */ @@ -3215,8 +3217,6 @@ struct LEX: public Query_tables_list } - SQL_I_List<ORDER> save_group_list; - SQL_I_List<ORDER> save_order_list; LEX_CSTRING *win_ref; Window_frame *win_frame; Window_frame_bound *frame_top_bound; diff --git a/sql/sql_list.h b/sql/sql_list.h index b112398..40848c2 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc { elements= tmp.elements; first= tmp.first; - next= tmp.next; --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -53,7 +53,7 @@ class SQL_I_List :public Sql_alloc { elements= tmp.elements; first= tmp.first; - next= tmp.next; + next= elements ? tmp.next : &first; return *this; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5e4c41f..cfe8c91 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -755,8 +755,6 @@ void LEX::start(THD *thd_arg) stmt_var_list.empty(); proc_list.elements=0; - save_group_list.empty(); - save_order_list.empty(); win_ref= NULL; win_frame= NULL; frame_top_bound= NULL; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3102aa6..f360b24 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8662,8 +8662,8 @@ TABLE_LIST *st_select_lex::convert_right_join() void st_select_lex::prepare_add_window_spec(THD *thd) { LEX *lex= thd->lex; - lex->save_group_list= group_list; - lex->save_order_list= order_list; + save_group_list= group_list; + save_order_list= order_list; lex->win_ref= NULL; lex->win_frame= NULL; lex->frame_top_bound= NULL; @@ -8690,8 +8690,8 @@ bool st_select_lex::add_window_def(THD *thd, win_part_list_ptr, win_order_list_ptr, win_frame); - group_list= thd->lex->save_group_list; - order_list= thd->lex->save_order_list; + group_list= save_group_list; + order_list= save_order_list; if (parsing_place != SELECT_LIST) { fields_in_window_functions+= win_part_list_ptr->elements + @@ -8717,8 +8717,8 @@ bool st_select_lex::add_window_spec(THD *thd, win_part_list_ptr, win_order_list_ptr, win_frame); - group_list= thd->lex->save_group_list; - order_list= thd->lex->save_order_list; + group_list= save_group_list; + order_list= save_order_list; if (parsing_place != SELECT_LIST) { fields_in_window_functions+= win_part_list_ptr->elements + This fixes the problem.
            Johnston Rex Johnston added a comment -

            Igor's patch passes all mtr tests, one interesting thing. Previously this

            SELECT
            id IN (SELECT id FROM t1
              WINDOW w AS (ORDER BY 
                    (SELECT  1 FROM t1 WHERE EXISTS 
                            ( SELECT id FROM t1 GROUP BY id  
                                      WINDOW w2 AS (ORDER BY id)
            )))) FROM t1
            

            emitted a warning

            Column 'id' in group statement is ambiguous

            With the patch, it's gone.

            Johnston Rex Johnston added a comment - Igor's patch passes all mtr tests, one interesting thing. Previously this SELECT id IN ( SELECT id FROM t1 WINDOW w AS ( ORDER BY ( SELECT 1 FROM t1 WHERE EXISTS ( SELECT id FROM t1 GROUP BY id WINDOW w2 AS ( ORDER BY id) )))) FROM t1 emitted a warning Column 'id' in group statement is ambiguous With the patch, it's gone.

            People

              sanja Oleksandr Byelkin
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.