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

REGEXP_REPLACE time grows with the square of the string length

    XMLWordPrintable

Details

    Description

      # REGEXP_REPLACE on 300000 characters, each one a match
      SET @t= UNIX_TIMESTAMP(NOW(6));
      SELECT LENGTH(REGEXP_REPLACE(REPEAT('a', 300000), 'a', 'b')) INTO @l;
      --let $s= query_get_value(SELECT ROUND(UNIX_TIMESTAMP(NOW(6)) - @t) AS s, s, 1)
      if ($s > 10)
      {
        --die REGEXP_REPLACE on 300000 characters ran for $s seconds
      }

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 05/10/2026

      mysqltest: At line 7: REGEXP_REPLACE on 300000 characters ran for 43 seconds

      CS 13.1.0 da18481158c81ca94689702073c3e04aad85a6a3 (Debug, Clang 22.1.8-20260622) Build 18/08/2026

      mysqltest: At line 7: REGEXP_REPLACE on 300000 characters ran for 111 seconds

      The time grows with the square of the string length. SELECT LENGTH(REGEXP_REPLACE(s, 'a', 'b')) in the client, where s is REPEAT('a', n) in the given character set:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 05/10/2026

      n        utf8mb4    latin1     binary
      50000    1.08 s     0.87 s     0.05 s
      100000   4.93 s     5.10 s     0.05 s
      200000   21.52 s    20.02 s    0.06 s
      600000   160.51 s

      Three gdb samples of the query thread all show the UTF-8 check of PCRE2, each time over a large part of the subject:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Optimized, Clang 22.1.8-20260622) Build 05/10/2026

      #0  _pcre2_valid_utf_8 (string=0x6e5f201304c3 'a' <repeats 200 times>..., length=375545, erroroffset=0x6e5f200165d0) at extra/pcre2/src/pcre2/src/pcre2_valid_utf.c:133
      #1  0x00005c2f22ba72c3 in pcre2_match_8 (code=<optimized out>, subject=0x6e5f20104c20 'a' <repeats 200 times>..., length=600000, start_offset=<optimized out>, options=<optimized out>, match_data=0x6e5f20016570, mcontext=0x0) at extra/pcre2/src/pcre2/src/pcre2_match.c:7337
      #2  0x00005c2f22a4251d in Regexp_processor_pcre::pcre_exec_with_warn (this=0x6e5f20018770, code=0x6e5f201304c3, data=0x6e5f20016570, subject=0x5baf9 <error: Cannot access memory at address 0x5baf9>, length=<optimized out>, startoffset=<optimized out>, options=0) at sql/item_cmpfunc.cc:6390
      #3  Regexp_processor_pcre::exec (this=this@entry=0x6e5f20018770, str=0x5baf9 <error: Cannot access memory at address 0x5baf9>, str@entry=0x6e5f20104c20 'a' <repeats 200 times>..., length=length@entry=600000, offset=offset@entry=178339) at sql/item_cmpfunc.cc:6407
      #4  0x00005c2f22aa05f1 in Item_func_regexp_replace::val_str_internal (this=0x6e5f200186b0, str=0x6e5f200189e0, null_to_empty=<optimized out>) at sql/item_strfunc.cc:1628

      From the code it seems that Item_func_regexp_replace::val_str_internal() calls Regexp_processor_pcre::exec() once for each match (sql/item_strfunc.cc:1628), and that exec() calls pcre2_match() with options 0 (sql/item_cmpfunc.cc:6390 and sql/item_cmpfunc.cc:6407). So each call checks the rest of the subject for valid UTF-8 again. A binary subject has no UTF-8 check, which matches the binary column above. The PCRE2 documentation suggests PCRE2_NO_UTF_CHECK for the second and subsequent calls to pcre2_match() on the same subject.

      Attachments

        Issue Links

          Activity

            People

              bar Alexander Barkov
              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 - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0d
                  0d
                  Logged:
                  Time Spent - 2.25h
                  2.25h

                  Git Integration

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