[MDEV-18300] ASAN error in Field_blob::get_key_image upon UPDATE with subquery Created: 2019-01-18  Updated: 2019-04-11  Resolved: 2019-04-11

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 10.1, 10.2, 10.3, 10.4
Fix Version/s: 10.2.24, 10.1.39, 10.3.15, 10.4.5

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Varun Gupta (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-18412 ASAN complains in 10.0 after merge fr... Closed

 Description   

--source include/have_innodb.inc
 
CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB;
CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB;
 
UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' );
 
# Cleanup
DROP TABLE t1, t2;

10.4 4edb29380c ASAN

==18916==ERROR: AddressSanitizer: unknown-crash on address 0x6210000c1d8e at pc 0x5619488525af bp 0x7fc1284bc990 sp 0x7fc1284bc988
WRITE of size 3069 at 0x6210000c1d8e thread T27
    #0 0x5619488525ae in Field_blob::get_key_image(unsigned char*, unsigned int, Field::imagetype) /data/src/10.4/sql/field.cc:8450
    #1 0x561948c1e6e6 in Field::make_key_image(st_mem_root*, KEY_PART const*) /data/src/10.4/sql/opt_range.cc:8192
    #2 0x561948c1fed7 in Field::stored_field_make_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, scalar_comparison_op, Item*) /data/src/10.4/sql/opt_range.cc:8392
    #3 0x561948c1f4e8 in Field_str::get_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, Item_bool_func const*, scalar_comparison_op, Item*) /data/src/10.4/sql/opt_range.cc:8306
    #4 0x561948c1e144 in Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM*, Field*, KEY_PART*, Item_func::Functype, Item*) /data/src/10.4/sql/opt_range.cc:8161
    #5 0x561948c1c7e2 in Item_bool_func::get_mm_parts(RANGE_OPT_PARAM*, Field*, Item_func::Functype, Item*) /data/src/10.4/sql/opt_range.cc:7995
    #6 0x561948c1c03e in Item_equal::get_mm_tree(RANGE_OPT_PARAM*, Item**) /data/src/10.4/sql/opt_range.cc:7950
    #7 0x561948bfee47 in calculate_cond_selectivity_for_table(THD*, TABLE*, Item**) /data/src/10.4/sql/opt_range.cc:3188
    #8 0x5619482225e7 in make_join_statistics /data/src/10.4/sql/sql_select.cc:5055
    #9 0x561948204e4e in JOIN::optimize_inner() /data/src/10.4/sql/sql_select.cc:1932
    #10 0x561948200385 in JOIN::optimize() /data/src/10.4/sql/sql_select.cc:1451
    #11 0x561948105ac1 in st_select_lex::optimize_unflattened_subqueries(bool) /data/src/10.4/sql/sql_lex.cc:4140
    #12 0x5619483d0e75 in mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*) /data/src/10.4/sql/sql_update.cc:433
    #13 0x561948169b73 in mysql_execute_command(THD*) /data/src/10.4/sql/sql_parse.cc:4585
    #14 0x5619481802b2 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.4/sql/sql_parse.cc:8116
    #15 0x56194815a77f in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.4/sql/sql_parse.cc:1852
    #16 0x561948157807 in do_command(THD*) /data/src/10.4/sql/sql_parse.cc:1397
    #17 0x5619484cdd06 in do_handle_one_connection(CONNECT*) /data/src/10.4/sql/sql_connect.cc:1402
    #18 0x5619484cd712 in handle_one_connection /data/src/10.4/sql/sql_connect.cc:1308
    #19 0x561949034383 in pfs_spawn_thread /data/src/10.4/storage/perfschema/pfs.cc:1862
    #20 0x7fc133e60493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
    #21 0x7fc13224693e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe893e)
 
0x6210000c1d8e is located 142 bytes inside of 4172-byte region [0x6210000c1d00,0x6210000c2d4c)
allocated by thread T27 here:
    #0 0x7fc1340ca73f in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5473f)
    #1 0x5619499df1d6 in sf_malloc /data/src/10.4/mysys/safemalloc.c:118
    #2 0x5619499afb53 in my_malloc /data/src/10.4/mysys/my_malloc.c:101
    #3 0x56194998f65f in alloc_root /data/src/10.4/mysys/my_alloc.c:250
    #4 0x561948c1e554 in Field::make_key_image(st_mem_root*, KEY_PART const*) /data/src/10.4/sql/opt_range.cc:8188
    #5 0x561948c1fed7 in Field::stored_field_make_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, scalar_comparison_op, Item*) /data/src/10.4/sql/opt_range.cc:8392
    #6 0x561948c1f4e8 in Field_str::get_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, Item_bool_func const*, scalar_comparison_op, Item*) /data/src/10.4/sql/opt_range.cc:8306
    #7 0x561948c1e144 in Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM*, Field*, KEY_PART*, Item_func::Functype, Item*) /data/src/10.4/sql/opt_range.cc:8161
    #8 0x561948c1c7e2 in Item_bool_func::get_mm_parts(RANGE_OPT_PARAM*, Field*, Item_func::Functype, Item*) /data/src/10.4/sql/opt_range.cc:7995
    #9 0x561948c1c03e in Item_equal::get_mm_tree(RANGE_OPT_PARAM*, Item**) /data/src/10.4/sql/opt_range.cc:7950
    #10 0x561948bfee47 in calculate_cond_selectivity_for_table(THD*, TABLE*, Item**) /data/src/10.4/sql/opt_range.cc:3188
    #11 0x5619482225e7 in make_join_statistics /data/src/10.4/sql/sql_select.cc:5055
    #12 0x561948204e4e in JOIN::optimize_inner() /data/src/10.4/sql/sql_select.cc:1932
    #13 0x561948200385 in JOIN::optimize() /data/src/10.4/sql/sql_select.cc:1451
    #14 0x561948105ac1 in st_select_lex::optimize_unflattened_subqueries(bool) /data/src/10.4/sql/sql_lex.cc:4140
    #15 0x5619483d0e75 in mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*) /data/src/10.4/sql/sql_update.cc:433
    #16 0x561948169b73 in mysql_execute_command(THD*) /data/src/10.4/sql/sql_parse.cc:4585
    #17 0x5619481802b2 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.4/sql/sql_parse.cc:8116
    #18 0x56194815a77f in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.4/sql/sql_parse.cc:1852
    #19 0x561948157807 in do_command(THD*) /data/src/10.4/sql/sql_parse.cc:1397
    #20 0x5619484cdd06 in do_handle_one_connection(CONNECT*) /data/src/10.4/sql/sql_connect.cc:1402
    #21 0x5619484cd712 in handle_one_connection /data/src/10.4/sql/sql_connect.cc:1308
    #22 0x561949034383 in pfs_spawn_thread /data/src/10.4/storage/perfschema/pfs.cc:1862
    #23 0x7fc133e60493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
 
Thread T27 created by T0 here:
    #0 0x7fc134099bba in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x23bba)
    #1 0x56194903494b in spawn_thread_v1 /data/src/10.4/storage/perfschema/pfs.cc:1912
    #2 0x561947eb1d86 in inline_mysql_thread_create /data/src/10.4/include/mysql/psi/mysql_thread.h:1268
    #3 0x561947ec7fa4 in create_thread_to_handle_connection(CONNECT*) /data/src/10.4/sql/mysqld.cc:6438
    #4 0x561947ec86a9 in create_new_thread(CONNECT*) /data/src/10.4/sql/mysqld.cc:6508
    #5 0x561947ec8a39 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /data/src/10.4/sql/mysqld.cc:6625
    #6 0x561947ec9685 in handle_connections_sockets() /data/src/10.4/sql/mysqld.cc:6790
    #7 0x561947ec7461 in mysqld_main(int, char**) /data/src/10.4/sql/mysqld.cc:6060
    #8 0x561947eafc0f in main /data/src/10.4/sql/main.cc:25
    #9 0x7fc13217e2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
 
SUMMARY: AddressSanitizer: unknown-crash /data/src/10.4/sql/field.cc:8450 Field_blob::get_key_image(unsigned char*, unsigned int, Field::imagetype)
Shadow bytes around the buggy address:
  0x0c4280010360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280010370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280010380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c4280010390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c42800103a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c42800103b0: 00[00]00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c42800103c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c42800103d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c42800103e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c42800103f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c4280010400: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==18916==ABORTING

Not reproducible on 10.3, not sure whether it's because the problem is 10.4-specific, or it's triggered by new defaults.



 Comments   
Comment by Alice Sherepa [ 2019-01-18 ]

Reproducible on MariaDB 10.1-10.4

--source include/have_innodb.inc
 set use_stat_tables=preferably;
 set optimizer_use_condition_selectivity=4;
 
CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB;
CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB;
 
ANALYZE TABLE t1,t2;
UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' );
 
# Cleanup
DROP TABLE t1, t2;

10.1 1d72db45a880d07f

 
AddressSanitizer: use-after-poison on address 0x62100009cec1 at pc 0x7f448d264bec bp 0x7f447739f710 sp 0x7f447739eeb8
WRITE of size 764 at 0x62100009cec1 thread T23
    #0 0x7f448d264beb in __asan_memset (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8cbeb)
    #1 0x56544da6597e in memset /usr/include/x86_64-linux-gnu/bits/string3.h:90
    #2 0x56544da6597e in Field_blob::get_key_image(unsigned char*, unsigned int, Field::imagetype) /10.1/sql/field.cc:8197
    #3 0x56544dd6a770 in Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM*, Field*, KEY_PART*, Item_func::Functype, Item*) /10.1/sql/opt_range.cc:7946
    #4 0x56544dd7b37b in Item_bool_func::get_mm_parts(RANGE_OPT_PARAM*, Field*, Item_func::Functype, Item*) /10.1/sql/opt_range.cc:7664
    #5 0x56544dd83154 in Item_equal::get_mm_tree(RANGE_OPT_PARAM*, Item**) /10.1/sql/opt_range.cc:7619
    #6 0x56544dd715d6 in calculate_cond_selectivity_for_table(THD*, TABLE*, Item**) /10.1/sql/opt_range.cc:3080
    #7 0x56544d6fe42d in make_join_statistics /10.1/sql/sql_select.cc:4173
    #8 0x56544d6fe42d in JOIN::optimize_inner() /10.1/sql/sql_select.cc:1403
    #9 0x56544d705794 in JOIN::optimize() /10.1/sql/sql_select.cc:1058
    #10 0x56544d5e592e in st_select_lex::optimize_unflattened_subqueries(bool) /10.1/sql/sql_lex.cc:3795
    #11 0x56544d7e5ceb in mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*) /10.1/sql/sql_update.cc:375
    #12 0x56544d60a1b4 in mysql_execute_command(THD*) /10.1/sql/sql_parse.cc:3790
    #13 0x56544d6191e2 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /10.1/sql/sql_parse.cc:7468
    #14 0x56544d61f753 in dispatch_command(enum_server_command, THD*, char*, unsigned int) /10.1/sql/sql_parse.cc:1496
    #15 0x56544d625d56 in do_command(THD*) /10.1/sql/sql_parse.cc:1124
    #16 0x56544d89ca11 in do_handle_one_connection(THD*) /10.1/sql/sql_connect.cc:1330
    #17 0x56544d89cefd in handle_one_connection /10.1/sql/sql_connect.cc:1242
    #18 0x56544e6c6791 in pfs_spawn_thread /10.1/storage/perfschema/pfs.cc:1861
    #19 0x7f448c5526b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #20 0x7f448bbfd41c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)

Comment by Alice Sherepa [ 2019-01-29 ]

I am getting something similar with blob compressed. Can not reproduce currently, getting the same as MDEV-18408

10.4 c2318291be74582387

/10.4/sql/mysqld(0x186fb7b Field_blob_compressed::get_key_image(unsigned char*, unsigned int, Field::imagetype) + 63)[0x55c871997b7b]
/10.4/sql/mysqld(Field::make_key_image(st_mem_root*, KEY_PART const*)+0x2b7)[0x55c871d347d1]
/10.4/sql/mysqld(Field::stored_field_make_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, scalar_comparison_op, Item*)+0x150)[0x55c871d35fde]
/10.4/sql/mysqld(Field_str::get_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, Item_bool_func const*, scalar_comparison_op, Item*)+0x260)[0x55c871d355ea]
sql/opt_range.cc:8194(Field::make_key_image(st_mem_root*, KEY_PART const*))[0x55c871d3423f]
sql/opt_range.cc:8393(Field::stored_field_make_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, scalar_comparison_op, Item*))[0x55c871d32922]
sql/opt_range.cc:8307(Field_str::get_mm_leaf(RANGE_OPT_PARAM*, KEY_PART*, Item_bool_func const*, scalar_comparison_op, Item*))[0x55c871d2c828]
sql/opt_range.cc:8162(Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM*, Field*, KEY_PART*, Item_func::Functype, Item*))[0x55c871aa20ac]
sql/opt_range.cc:7996(Item_bool_func::get_mm_parts(RANGE_OPT_PARAM*, Field*, Item_func::Functype, Item*))[0x55c871d2fc8e]
sql/opt_range.cc:7141(Item_bool_func::get_ne_mm_tree(RANGE_OPT_PARAM*, Field*, Item*, Item*))[0x55c871154943]
sql/item_cmpfunc.h:832(Item_func_ne::get_func_mm_tree(RANGE_OPT_PARAM*, Field*, Item*))[0x55c8711555c7]
sql/opt_range.cc:7675(Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM*, Item_field*, Item*))[0x55c871d3069f]
/10.4/sql/mysqld(Item_cond_and::get_mm_tree(RANGE_OPT_PARAM*, Item**)+0x1b3)[0x55c871d301c1]
/10.4/sql/mysqld(Item_cond::get_mm_tree(RANGE_OPT_PARAM*, Item**)+0x19f)[0x55c871d304b1]
/10.4/sql/mysqld(Item_cond_and::get_mm_tree(RANGE_OPT_PARAM*, Item**)+0x1b3)[0x55c871d301c1]
/10.4/sql/mysqld(Item_cond::get_mm_tree(RANGE_OPT_PARAM*, Item**)+0x19f)[0x55c871d304b1]
sql/item_cmpfunc.h:206(Item_bool_func::get_full_func_mm_tree_for_args(RANGE_OPT_PARAM*, Item*, Item*))[0x55c871d1612c]
sql/item_cmpfunc.h:493(Item_bool_func2_with_rev::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c871340344]
sql/opt_range.cc:7770(Item_cond::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c871323310]
sql/opt_range.cc:7729(Item_cond_and::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c87131e932]
sql/opt_range.cc:7753(Item_cond::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c871339a82]
sql/opt_range.cc:7729(Item_cond_and::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c871313f12]
sql/opt_range.cc:7753(Item_cond::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x55c87128809e]
sql/opt_range.cc:3189(calculate_cond_selectivity_for_table(THD*, TABLE*, Item**))[0x55c8712a1a42]
sql/sql_select.cc:5056(make_join_statistics(JOIN*, List<TABLE_LIST>&, st_dynamic_array*))[0x55c87127a6d7]
sql/sql_select.cc:1932(JOIN::optimize_inner())[0x55c8712778b7]
sql/sql_select.cc:1451(JOIN::optimize())[0x55c8715d4f0b]
sql/sql_select.cc:4279(mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*))[0x55c8715d48d5]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f7740c3a6ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f773fecb41d]

Comment by Alice Sherepa [ 2019-03-05 ]

The same test case, but with BLOB COMPRESSED instead of BLOB:

10.3 8f4de38f65ba89c62

/10.3/sql/field.h:3866: virtual uint Field_blob_compressed::get_key_image(uchar*, uint, Field::imagetype): Assertion `0' failed.
 
sql/opt_range.cc:8178(Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM*, Field*, KEY_PART*, Item_func::Functype, Item*))[0x5591ed030f2a]
sql/opt_range.cc:7885(Item_bool_func::get_mm_parts(RANGE_OPT_PARAM*, Field*, Item_func::Functype, Item*))[0x5591ed02eb86]
sql/opt_range.cc:7840(Item_equal::get_mm_tree(RANGE_OPT_PARAM*, Item**))[0x5591ed02e3f5]
sql/opt_range.cc:3078(calculate_cond_selectivity_for_table(THD*, TABLE*, Item**))[0x5591ed0123a0]
sql/sql_select.cc:5002(make_join_statistics(JOIN*, List<TABLE_LIST>&, st_dynamic_array*))[0x5591ec69fa44]
sql/sql_select.cc:1888(JOIN::optimize_inner())[0x5591ec68316c]
sql/sql_select.cc:1451(JOIN::optimize())[0x5591ec67eed4]
sql/sql_lex.cc:4042(st_select_lex::optimize_unflattened_subqueries(bool))[0x5591ec59589c]
sql/sql_update.cc:433(mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*))[0x5591ec83ca3e]
sql/sql_parse.cc:4584(mysql_execute_command(THD*))[0x5591ec5ed51d]
sql/sql_parse.cc:8095(mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool))[0x5591ec60391b]
sql/sql_parse.cc:1856(dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool))[0x5591ec5de3e0]
sql/sql_parse.cc:1396(do_command(THD*))[0x5591ec5db502]
sql/sql_connect.cc:1403(do_handle_one_connection(CONNECT*))[0x5591ec92fd52]
sql/sql_connect.cc:1310(handle_one_connection)[0x5591ec92f72f]
perfschema/pfs.cc:1864(pfs_spawn_thread)[0x5591edc5bd6f]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7efc0a7206ba]
x86_64/clone.S:111(clone)[0x7efc09bb541d]
 
Query (0x62b000000288): UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' )

Comment by Varun Gupta (Inactive) [ 2019-03-14 ]

Patch
http://lists.askmonty.org/pipermail/commits/2019-March/013553.html

Comment by Varun Gupta (Inactive) [ 2019-03-25 ]

Some investigations to make the approach clearer:

We have this function:

  void set_all_nulls()
  {
    column_stat_nulls= no_values_provided_bitmap();
  }

where column_stat_nulls is set to 11111111000 (currently), the bits that are not set are db_name, table_name and column_name.

Each bit is reset with this , that tells we will store the value for the column considered in the statistical table

  void set_not_null(uint stat_field_no)
  {
    column_stat_nulls&= ~(1 << stat_field_no);
  }

This function checks if we set any value for the fields in the stat table for the particular column

  bool no_stat_values_provided()
  {
    if (column_stat_nulls == no_values_provided_bitmap())
      return true;
    return false;
  }

So if we don't read statistics for a table, then column_stat_nulls is set to 0.

Comment by Sergei Petrunia [ 2019-03-27 ]

Notes from the investigation/ phone discussion:

read_statistics_for_tables_if_needed():

  • For most statements, the statistics is read by
    read_statistics_for_tables_if_needed() call in open_and_lock_tables().
  • For some reason, single-table UPDATE statement is special: it calls
    open_tables and then lock_tables(). It does NOT call open_and_lock_tables().
  • This is why the patch adds a read_statistics_for_tables_if_needed() call
    into sql_update.cc (but not sql_delete.cc or elsewhere)

Odd return value of is_eits_usable():

The workflow goes as follows:

1. The statistics is allocated. Column_statistics::column_stat_nulls is set to
0. (which means "All values are present" (YES!))

2. Reading the statistics starts with a call to
Column_statistics::set_all_nulls(), which assigns `column_stat_nulls=
no_values_provided_bitmap()`. This sets all bits to 1 (which means "no
value"), except the three bits which denote table name, db name, and column
name.

The dangerous part is between step #1 and step #2. There, the statistics object
does NOT have any information, but is_eits_usable() returns true!

Agreed to add an assert to catch such cases.

Comment by Sergei Petrunia [ 2019-03-27 ]

Waiting for an adjusted patch with the mentioned assert for final checks.

Comment by Varun Gupta (Inactive) [ 2019-03-28 ]

Patch
http://lists.askmonty.org/pipermail/commits/2019-March/013592.html

Comment by Sergei Petrunia [ 2019-03-30 ]

Ok to push.

Generated at Thu Feb 08 08:43:02 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.