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

Range selectivity computation for blob columns is wrong

    XMLWordPrintable

Details

    Description

      Split from MDEV-31182

      Consider the following case

      --source include/have_sequence.inc
      SET histogram_type = DOUBLE_PREC_HB;
      CREATE TABLE t (a INT);
      INSERT INTO t select seq from seq_10_to_99;
      ANALYZE TABLE t PERSISTENT FOR ALL;
      select db_name, table_name, min_value, max_value, hex(histogram) from mysql.column_stats where table_name='t';
      ALTER TABLE t MODIFY a BLOB, ALGORITHM=COPY;
      select db_name, table_name, min_value, max_value, hex(histogram) from mysql.column_stats where table_name='t';
       
      SELECT a FROM t WHERE a LIKE '3%';
       
      DROP TABLE t;
      

      The COPY algorithm causes the stats not to be dropped, so now we have stats for a blob column. In the "SELECT ... LIKE '3%'" statement, it computes the selectivity in Histogram_binary::range_selectivity, using field->pos_in_interval to compute the positions of the min and max ranges in the column range. Both positions should be the same value, between 0.2 and 0.3. The method resolves to Field_str::pos_in_interval and then pos_in_interval_for_string, which is nonsensical for blob fields. More specifically, the data structure of the blob values midp_val, min_val, max_val are 2 bytes of length data followed by 8 bytes of address data of the payload, for example:

      (rr) p min_val[0]
      $131 = 2 '\002'
      (rr) p *(char**)(min_val+2)
      $60 = 0x52100012b050 "10", '\276' <repeats 14 times>, "99", '\276' <repeats 14 times>, "\230\241\201\365kU"
      (rr) p min_len
      $62 = 10
      

      And pos_in_interval_for_string treats the first 8 bytes of the three values as big endian ulonglong for comparison. This only makes sense if the values stores the payload directly. For blobs, this amounts to comparing the concatenation of the length bytes and the first 6 bytes of the payload address.

      Note that data is not collected if the table is defined with a blob column to begin with, and the documentation also says that stats are not collected for blob columns, in which case the fix should be dropping the stats at "ALTER TABLE t MODIFY a BLOB, ALGORITHM=COPY;" rather than implementing Field_blob::pos_in_interval, see MDEV-40400, which I mark as blocking this issue

      Attachments

        Issue Links

          Activity

            People

              ycp Yuchen Pei
              ycp Yuchen Pei
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - 1.55d
                  1.55d
                  Remaining:
                  Remaining Estimate - 1.55d
                  1.55d
                  Logged:
                  Time Spent - Not Specified
                  Not Specified

                  Git Integration

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