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

Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_long::val_str on EXPLAIN EXTENDED

Details

    Description

      CREATE TABLE t1 (f1 INT, f2 INT, KEY(f2)) ENGINE=MyISAM;
      INSERT INTO t1 VALUES (6,9);
       
      CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
      INSERT INTO t2 VALUES (2),(0);
       
      EXPLAIN EXTENDED 
      SELECT f1 FROM ( SELECT * FROM t1 ) AS sq
      WHERE f1 IN ( 
        SELECT f3 FROM t2 WHERE f2 IN ( 
          SELECT f3 FROM t2 HAVING f3 >= 8 
        ) 
      );

      Stack trace from 5.5 commit 86f46a3da4a6d82cb510dc4c270d46cfd6a8965b

      5.5/sql/field.cc:3669: virtual String* Field_long::val_str(String*, String*): Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed.
      150325  0:00:42 [ERROR] mysqld got signal 6 ;
       
      #6  0x00007f8f648e2311 in *__GI___assert_fail (assertion=0xe01f70 "!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))", file=<optimized out>, line=3669, function=0xe053a0 "virtual String* Field_long::val_str(String*, String*)") at assert.c:81
      #7  0x00000000007c5bd2 in Field_long::val_str (this=0x7f8f5f458b48, val_buffer=0x7f8f5ffb4340, val_ptr=0x7f8f5f587e20) at 5.5/sql/field.cc:3669
      #8  0x00000000007fc650 in Item_field::val_str (this=0x7f8f5f587e08, str=0x7f8f5ffb4340) at 5.5/sql/item.cc:2566
      #9  0x00000000007f72af in Item::print_value (this=0x7f8f5f587e08, str=0x7f8f5ffb48a0) at 5.5/sql/item.cc:634
      #10 0x000000000080754a in Item_field::print (this=0x7f8f5f587e08, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/item.cc:6697
      #11 0x0000000000808a5f in Item_ref::print (this=0x7f8f5f58aa18, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/item.cc:7204
      #12 0x000000000084351c in Item_func::print_op (this=0x7f8f5f542ab8, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/item_func.cc:491
      #13 0x000000000082ae63 in Item_bool_func2::print (this=0x7f8f5f542ab8, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/item_cmpfunc.h:385
      #14 0x0000000000826070 in Item_cond::print (this=0x7f8f5f5437a8, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/item_cmpfunc.cc:4633
      #15 0x000000000069e315 in st_select_lex::print (this=0x7f8f60553a60, thd=0x7f8f60550060, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/sql_select.cc:23366
      #16 0x00000000006298f8 in st_select_lex_unit::print (this=0x7f8f60553380, str=0x7f8f5ffb48a0, query_type=QT_TO_SYSTEM_CHARSET) at 5.5/sql/sql_lex.cc:2361
      #17 0x000000000063c0d8 in execute_sqlcom_select (thd=0x7f8f60550060, all_tables=0x7f8f5f5696b0) at 5.5/sql/sql_parse.cc:4674
      #18 0x00000000006353de in mysql_execute_command (thd=0x7f8f60550060) at 5.5/sql/sql_parse.cc:2234
      #19 0x000000000063ece2 in mysql_parse (thd=0x7f8f60550060, rawbuf=0x7f8f5f687078 "EXPLAIN EXTENDED \nSELECT f1 FROM ( SELECT * FROM t1 ) AS sq\nWHERE f1 IN ( \nSELECT f3 FROM t2 WHERE f2 IN ( \nSELECT f3 FROM t2 HAVING f3 >= 8 \n) \n)", length=146, parser_state=0x7f8f5ffb5620) at 5.5/sql/sql_parse.cc:5909
      #20 0x0000000000632925 in dispatch_command (command=COM_QUERY, thd=0x7f8f60550060, packet=0x7f8f60609061 "", packet_length=146) at 5.5/sql/sql_parse.cc:1079
      #21 0x0000000000631ab1 in do_command (thd=0x7f8f60550060) at 5.5/sql/sql_parse.cc:793
      #22 0x0000000000734122 in do_handle_one_connection (thd_arg=0x7f8f60550060) at 5.5/sql/sql_connect.cc:1266
      #23 0x0000000000733be1 in handle_one_connection (arg=0x7f8f60550060) at 5.5/sql/sql_connect.cc:1181
      #24 0x0000000000b6c629 in pfs_spawn_thread (arg=0x7f8f60571fc0) at 5.5/storage/perfschema/pfs.cc:1015
      #25 0x00007f8f666ddb50 in start_thread (arg=<optimized out>) at pthread_create.c:304
      #26 0x00007f8f6499370d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

      Attachments

        Issue Links

          Activity

            sanja Oleksandr Byelkin added a comment - - edited

            join->conds in first call of used tables update and on second one are different. Second contain no field we are looking for, so it is not updated.

            2 calls of SELECT_LEX::update_used_tables() :

            (gdb) p join
            $2 = (JOIN *) 0x7fffed777088
            (gdb) p this
            $3 = (st_select_lex * const) 0x7fffef4b6168
            (gdb) p this->select_number
            $4 = 1
            (gdb) p dbug_print_item(join->conds)
            $5 = 0x555556d4d4e0 <dbug_item_print_buf> "t1.f1 in (subquery#3)"
            (gdb)

            (gdb) p join
            $6 = (JOIN *) 0x7fffed777088
            (gdb) p this
            $7 = (st_select_lex * const) 0x7fffef4b6168
            (gdb) p this->select_number
            $8 = 1
            (gdb) p dbug_print_item(join->conds)
            $9 = 0x555556d4d4e0 <dbug_item_print_buf> "(1 and 1 and (t1.f1 = t2.f3))"

            sanja Oleksandr Byelkin added a comment - - edited join->conds in first call of used tables update and on second one are different. Second contain no field we are looking for, so it is not updated. 2 calls of SELECT_LEX::update_used_tables() : (gdb) p join $2 = (JOIN *) 0x7fffed777088 (gdb) p this $3 = (st_select_lex * const) 0x7fffef4b6168 (gdb) p this->select_number $4 = 1 (gdb) p dbug_print_item(join->conds) $5 = 0x555556d4d4e0 <dbug_item_print_buf> "t1.f1 in (subquery#3)" (gdb) (gdb) p join $6 = (JOIN *) 0x7fffed777088 (gdb) p this $7 = (st_select_lex * const) 0x7fffef4b6168 (gdb) p this->select_number $8 = 1 (gdb) p dbug_print_item(join->conds) $9 = 0x555556d4d4e0 <dbug_item_print_buf> "(1 and 1 and (t1.f1 = t2.f3))"

            condition transformation above made by
            convert_join_subqueries_to_semijoins -> convert_subq_to_sj
            and first it looks like this:
            (t1.f1 in (subquery#3) and (1 and (t1.f1 = t2.f3)))

            t1.f2 returned by:
            setup_jtbm_semi_joins -> setup_jtbm_semi_joins
            and it converted to
            ((1 and 1 and (t1.f1 = t2.f3)) and ((t1.f2 = `<subquery4>`.f3)))

            but used tables was not updated after this

            sanja Oleksandr Byelkin added a comment - condition transformation above made by convert_join_subqueries_to_semijoins -> convert_subq_to_sj and first it looks like this: (t1.f1 in (subquery#3) and (1 and (t1.f1 = t2.f3))) t1.f2 returned by: setup_jtbm_semi_joins -> setup_jtbm_semi_joins and it converted to ((1 and 1 and (t1.f1 = t2.f3)) and ((t1.f2 = `<subquery4>`.f3))) but used tables was not updated after this

            revision-id: 30a3b97bb321706a0e271268ee30ed62964311a7 (mariadb-10.1.10-24-g30a3b97)
            parent(s): ff8d4009a7743b99c1c13831172b08041a4b272e
            committer: Oleksandr Byelkin
            timestamp: 2016-01-25 21:52:37 +0100
            message:

            MDEV-7827: Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_long::val_str on EXPLAIN EXTENDED

            It looks like printing expression can touch fields which never be calculated normally, so it have no sens to print it by value

            Assert added: a view field should be never print by values (normally view is not optimized and constant tables is not read so we are safe)

            —

            sanja Oleksandr Byelkin added a comment - revision-id: 30a3b97bb321706a0e271268ee30ed62964311a7 (mariadb-10.1.10-24-g30a3b97) parent(s): ff8d4009a7743b99c1c13831172b08041a4b272e committer: Oleksandr Byelkin timestamp: 2016-01-25 21:52:37 +0100 message: MDEV-7827 : Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed in Field_long::val_str on EXPLAIN EXTENDED It looks like printing expression can touch fields which never be calculated normally, so it have no sens to print it by value Assert added: a view field should be never print by values (normally view is not optimized and constant tables is not read so we are safe) —

            An alternative fix:

            diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
            index 898e3ae..c7be909 100644
            --- a/sql/sql_lex.cc
            +++ b/sql/sql_lex.cc
            @@ -3916,6 +3916,19 @@ void SELECT_LEX::update_used_tables()
                   tl->on_expr->update_used_tables();
                   tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
                 }
            +    /* 
            +      - There is no need to check sj_on_expr, because merged semi-joins inject
            +        sj_on_expr into the parent's WHERE clase.
            +      - For non-merged semi-joins (aka JTBMs), we need to check their
            +        left_expr. There is no need to check the rest of the subselect, we know
            +        it is uncorrelated and so cannot refer to any tables in this select.
            +    */
            +    if (tl->jtbm_subselect)
            +    {
            +      Item *left_expr= tl->jtbm_subselect->left_expr;
            +      left_expr->walk(&Item::update_table_bitmaps_processor, FALSE, NULL);
            +    }
            +    
                 embedding= tl->embedding;
                 while (embedding)
                 {

            It makes the crash go away.
            I am not sure about what is exactly the reason I have to call Item::update_table_bitmaps_processor. I first tried update_used_tables() and that didn't work : as soon as Item_ref saw that it refers to upper subselect, it stopped doing anything.

            sanja, we need to discuss this.

            psergei Sergei Petrunia added a comment - An alternative fix: diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 898e3ae..c7be909 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3916,6 +3916,19 @@ void SELECT_LEX::update_used_tables() tl->on_expr->update_used_tables(); tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL); } + /* + - There is no need to check sj_on_expr, because merged semi-joins inject + sj_on_expr into the parent's WHERE clase. + - For non-merged semi-joins (aka JTBMs), we need to check their + left_expr. There is no need to check the rest of the subselect, we know + it is uncorrelated and so cannot refer to any tables in this select. + */ + if (tl->jtbm_subselect) + { + Item *left_expr= tl->jtbm_subselect->left_expr; + left_expr->walk(&Item::update_table_bitmaps_processor, FALSE, NULL); + } + embedding= tl->embedding; while (embedding) { It makes the crash go away. I am not sure about what is exactly the reason I have to call Item::update_table_bitmaps_processor. I first tried update_used_tables() and that didn't work : as soon as Item_ref saw that it refers to upper subselect, it stopped doing anything. sanja , we need to discuss this.

            We've agreed that the last version of the fix is correct and should be pushed.

            psergei Sergei Petrunia added a comment - We've agreed that the last version of the fix is correct and should be pushed.

            People

              sanja Oleksandr Byelkin
              elenst Elena Stepanova
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.