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

Optimizer trace and context escape a double quote twice in the first range of a long range list

    XMLWordPrintable

Details

    Description

      Likely cause: commit 9443c4035b8ddb518b8b6b9b6fbba10deb41c043 (MDEV-39720), in Json_writer::add_str(). It is not a regression: CS 13.1.1 has the commit, and the versions from before it do not escape the values at all.

      CREATE TABLE t1 (c VARCHAR(10), KEY (c));
      INSERT INTO t1 VALUES ('a"1'),('b"2'),('x'),('y');
      SET optimizer_trace='enabled=on';
      SELECT c FROM t1 WHERE c IN ('a"1', 'b"2');
      SELECT INSTR(trace, CONCAT(CHAR(92), CHAR(92))) INTO @n FROM information_schema.OPTIMIZER_TRACE;
      --let $n= query_get_value(SELECT @n AS n, n, 1)
      if ($n != 0)
      {
        --die The optimizer trace escapes the double quote in the first range twice, in a list of ranges longer than one line
      }
      SET optimizer_trace=DEFAULT;
      DROP TABLE t1;

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      mysqltest: At line 9: The optimizer trace escapes the double quote in the first range twice, in a list of ranges longer than one line

      The ranges in the trace:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

                              "ranges": [
                                "(a\\\"1) <= (c) <= (a\\\"1)",
                                "(b\"2) <= (c) <= (b\"2)"
                              ],

      The first range has two backslashes too many. The second range is right.

      MySQL prints both ranges in the same form:

      MySQL

      +--------+---------------------+---------------------+
      | MySQL  | First range         | Second range        |
      +--------+---------------------+---------------------+
      | 5.5.62 | no optimizer trace  | no optimizer trace  |
      | 5.6.51 | "a\"1 <= c <= a\"1" | "b\"2 <= c <= b\"2" |
      | 5.7.44 | "a\"1 <= c <= a\"1" | "b\"2 <= c <= b\"2" |
      | 8.0.36 | "c = 'a\\\"1'"      | "c = 'b\\\"2'"      |
      | 9.1.0  | "c = 'a\\\"1'"      | "c = 'b\\\"2'"      |
      +--------+---------------------+---------------------+

      The recorded optimizer context holds the same wrong first range, so a replay of the context does not find the ranges:

      CREATE TABLE t1 (c VARCHAR(20), KEY (c));
      INSERT INTO t1 VALUES ('aaaaaaaa"1'),('bbbbbbbb"2'),('cccccccc"3'),('x'),('y');
      SET optimizer_record_context=ON;
      SELECT c FROM t1 WHERE c IN ('aaaaaaaa"1', 'bbbbbbbb"2', 'cccccccc"3');
      SET optimizer_record_context=OFF;
      SELECT context INTO DUMPFILE '../../tmp/ctx.sql' FROM information_schema.OPTIMIZER_CONTEXT;
      --source $MYSQLTEST_VARDIR/tmp/ctx.sql
      --remove_file $MYSQLTEST_VARDIR/tmp/ctx.sql
      SET optimizer_replay_context='opt_context';
      SELECT c FROM t1 WHERE c IN ('aaaaaaaa"1', 'bbbbbbbb"2', 'cccccccc"3');
      --let $w= query_get_value(SHOW WARNINGS, Code, 1)
      SET optimizer_replay_context='';
      if ($w == 4270)
      {
        --die The replay of the recorded optimizer context gives warning 4270, as the first range in the context is escaped twice
      }
      DROP TABLE t1;

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      mysqltest: At line 15: The replay of the recorded optimizer context gives warning 4270, as the first range in the context is escaped twice

      The replay gives this warning:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 07/11/2026

      Warning	4270	Failed to match the stats from replay context with the optimizer stats: the given list of ranges i.e. [(aaaaaaaa"1) <= (c) <= (aaaaaaaa"1), (bbbbbbbb"2) <= (c) <= (bbbbbbbb"2), (cccccccc"3) <= (c) <= (cccccccc"3), ] doesn't exist in the list of ranges for table_name test.t1 and index_name c

      Optimized builds give the same results.

      From the code it seems that Json_writer::add_str() escapes the value, and Single_line_formatting_helper keeps the escaped value while it tries to fit the array on one line. When the array does not fit, Single_line_formatting_helper::disable_and_flush() in sql/my_json_writer.cc writes the kept value with add_str(), which escapes it again. On main, MDEV-36986 changed this call to add_escaped_quoted_str(), which does not escape the value again.

      Attachments

        Issue Links

          Activity

            People

              bsrikanth Srikanth Bondalapati
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - 0d
                  0d
                  Remaining:
                  Time Spent - 1h Remaining Estimate - 1.5d
                  1.5d
                  Logged:
                  Time Spent - 1h Remaining Estimate - 1.5d
                  1h

                  Git Integration

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