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

Optimizer trace: multi-component range is not printed correctly

Details

    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.

      Attachments

        Activity

          psergei Sergei Petrunia added a comment - - edited

          (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.

          psergei Sergei Petrunia added a comment - - edited (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.

          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.

          psergei Sergei Petrunia added a comment - 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.

          bb-10.4-mdev22401

          psergei Sergei Petrunia added a comment - bb-10.4-mdev22401

          People

            psergei Sergei Petrunia
            psergei Sergei Petrunia
            Votes:
            0 Vote for this issue
            Watchers:
            1 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.