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

UNCACHEABLE_RAND inconsistently set on unions

    XMLWordPrintable

Details

    • Bug
    • Status: In Review (View Workflow)
    • Major
    • Resolution: Unresolved
    • 12.2
    • 12.2
    • Parser
    • None
    • Can result in unexpected behaviour
    • Q4/2025 Server Development

    Description

      The following query doesn't mark its union's cacheable flag as UNCACHEABLE_RAND:

      create table t1 (a int);
      create table t2 select * from t1 where 1 in (select 1 union select 2 union select RAND());
      

      However there's no problem with the following query:

      select * from t1 where 1 in (select 1 union select RAND());
      

      As described by psergei in this PR comment thread, the problem begins from:

      (gdb) wher 10
        #0  st_select_lex_unit::register_select_chain (this=0x7fff1c017e28, first_sel=0x7fff1c0178c0) at /home/psergey/dev-git2/10.11-look/sql/sql_lex.cc:10117
        #1  0x0000555555f652d2 in LEX::create_unit (this=0x7fff1c005168, first_sel=0x7fff1c0178c0) at /home/psergey/dev-git2/10.11-look/sql/sql_lex.cc:6275
        #2  0x0000555555f74c17 in LEX::parsed_select_expr_start (this=0x7fff1c005168, s1=0x7fff1c0178c0, s2=0x7fff1c018658, unit_type=UNION_TYPE, distinct=true) at /home/psergey/dev-git2/10.11-look/sql/sql_lex.cc:10388
        #3  0x0000555555f74f81 in LEX::add_primary_to_query_expression_body (this=0x7fff1c005168, unit=0x7fff1c017e28, sel=0x7fff1c018658, unit_type=UNION_TYPE, distinct=true,            oracle=false) at /home/psergey/dev-git2/10.11-look/sql/sql_lex.cc:10458
        #4  0x0000555555f75017 in LEX::add_primary_to_query_expression_body (this=0x7fff1c005168, unit=0x7fff1c017e28, sel=0x7fff1c018658, unit_type=UNION_TYPE, distinct=true) at /home/  psergey/dev-git2/10.11-look/sql/sql_lex.cc:10473
        #5  0x00005555562c2136 in MYSQLparse (thd=0x7fff1c000d78) at /home/psergey/dev-git2/10.11-look/sql/sql_yacc.yy:8774
      

      in LEX::add_primary_to_query_expression_body() there are two codepaths:

          if (!sel1->next_select())
            unit= parsed_select_expr_start(sel1, sel2, unit_type, distinct);
          else      
            unit= parsed_select_expr_cont(unit, sel2, unit_type, distinct, oracle);
      

      if-branch is taken for the first two UNION members. else-branch is for the rest.
      Then, parsed_select_expr_cont() calls create_unit() (which doesn't really create it for the second member), which calls

        unit->register_select_chain(first_sel);
      

      which propagates the uncacheable flag from UNION members to the SELECT_LEX_UNIT object. LEX::parsed_select_expr_cont() just doesn't do this.

      Attachments

        Issue Links

          Activity

            People

              psergei Sergei Petrunia
              Gosselin Dave Gosselin
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated: