[MDEV-22401] Optimizer trace: multi-component range is not printed correctly Created: 2020-04-28  Updated: 2020-05-05  Resolved: 2020-04-29

Status: Closed
Project: MariaDB Server
Component/s: Optimizer
Affects Version/s: 10.4
Fix Version/s: 10.4.13

Type: Bug Priority: Blocker
Reporter: Sergei Petrunia Assignee: Sergei Petrunia
Resolution: Fixed Votes: 0
Labels: optimizer_trace


 Description   

create table t2 (kp1 int, kp2 int, key(kp1, kp2));
insert into t2 values (1,1),(1,5),(5,1),(5,5);
set optimizer_trace=1;
select * from t2 force index(kp1) where (kp1=2 and kp2 >=4);

select * from information_schema.optimizer_trace;

shows

      "range_scan_alternatives": [
        {
          "index": "kp1",
          "ranges": ["(2,3) <= (kp1,kp2)"],
          "rowid_ordered": false,
          "using_mrr": false,
          "index_only": false,
          "rows": 10,  
          "cost": 58.75,
          "chosen": true
        }
      ],

This is clearly incorrect as kp1=2 allows the range to have an upper bound too.



 Comments   
Comment by Sergei Petrunia [ 2020-04-28 ]

(gdb) wher 5
  #0  print_range (out=0x7ffff4118630, key_part=0x7ffc9001fb60, range=0x7ffff41180c0, n_key_parts=2) at /home/psergey/dev-git2/10.5-cl/sql/opt_range.cc:15797
  #1  0x000055555630c85d in trace_ranges (range_trace=0x7ffff4118740, param=0x7ffff41189b0, idx=0, keypart=0x7ffc90089fe0, key_parts=0x7ffc9001fb60) at /home/psergey/dev-git2/10.5-cl/sql/opt_range.cc:15880
  #2  0x00005555562e9b53 in TRP_RANGE::trace_basic_info (this=0x7ffc9008a0e0, param=0x7ffff41189b0, trace_object=0x7ffff4118950) at /home/psergey/dev-git2/10.5-cl/sql/opt_range.cc:2272
  #3  0x00005555562ebf19 in SQL_SELECT::test_quick_select (this=0x7ffc900168f0, thd=0x7ffc90000d78, keys_to_use=..., prev_tables=0, limit=18446744073709551615, force_quick_range=false, ordered_output=false, remove_false_parts_of_where=true, only_single_index_range_scan=false) at /home/psergey/dev-git2/10.5-cl/sql/opt_range.cc:3036
  #4  0x0000555555e5c771 in get_quick_record_count (thd=0x7ffc90000d78, select=0x7ffc900168f0, table=0x7ffc90023648, keys=0x7ffc90015790, limit=18446744073709551615) at /home/psergey/dev-git2/10.5-cl/sql/sql_select.cc:4712

in print_range:

(gdb) p *range
  $29 = {
    start_key = {
      key = 0x7ffc90089e48 "", 
      length = 10, 
      keypart_map = 3, 
      flag = HA_READ_KEY_EXACT
    }, 
    end_key = {
      key = 0x7ffc90089e58 "", 
      length = 5, 
      keypart_map = 1, 
      flag = HA_READ_AFTER_KEY
    }, 
    ptr = 0x1, 
    range_flag = 2
  }

That is, the range itself is correct.

Comment by Sergei Petrunia [ 2020-04-28 ]

The issue is that print_range() checks range->range_flag for flags like NO_MIN_RANGE or NO_MAX_RANGE.
sel_arg_range_seq_next() doesn't set that correctly (it sets it based only on the last key component).

The rest of the code only checks KEY_MULTI_RANGE::range_flag for flags describing both endpoints, like EQ_RANGE, NULL_RANGE, UNIQUE_RANGE.

As for whether the left/right endpoints are inclusive, this is obtained from start_key.flag and end_key.flag, respectively.
"infinite" endpoints have length=0.

Comment by Sergei Petrunia [ 2020-04-28 ]

bb-10.4-mdev22401

Generated at Thu Feb 08 09:14:28 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.