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

Value does not change - User-Defined Variable

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.5, 10.6, 10.11, 11.0, 11.1, 11.2, 11.3, 10.11.7, 11.3.2
    • None
    • Variables

    Description

      User-defined variable assignment is sometimes ignored and sometimes not:

      This is somewhat weird:

      > select @n:=0
          -> ,case when @n=0 then concat_ws('~',@n:=+1,'test-1') end
          -> ,@n
          -> ,case when @n=0 then concat_ws('~',@n:=@n+1,'test-2') end
          -> ,@n
          -> ;
      +-------+--------------------------------------------------------+------+----------------------------------------------------------+------+
      | @n:=0 | case when @n=0 then concat_ws('~',@n:=+1,'test-1') end | @n   | case when @n=0 then concat_ws('~',@n:=@n+1,'test-2') end | @n   |
      +-------+--------------------------------------------------------+------+----------------------------------------------------------+------+
      |     0 | 1~test-1                                               |    0 | 1~test-2                                                 |    1 |
      +-------+--------------------------------------------------------+------+----------------------------------------------------------+------+
      1 row in set (0.00 sec)
      

      And workaround is weirder:

      > select @n:=0
          -> ,case when @n=0 then concat_ws('~',@n:=@n^@n+1,'test-1') end
          -> ,@n
          -> ,case when @n=0 then concat_ws('~',@n:=@n+1,'test-2') end
          -> ,@n
          -> ;
      +-------+-------------------------------------------------------------+------+----------------------------------------------------------+------+
      | @n:=0 | case when @n=0 then concat_ws('~',@n:=@n^@n+1,'test-1') end | @n   | case when @n=0 then concat_ws('~',@n:=@n+1,'test-2') end | @n   |
      +-------+-------------------------------------------------------------+------+----------------------------------------------------------+------+
      |     0 | 1~test-1                                                    |    1 | NULL                                                     |    1 |
      +-------+-------------------------------------------------------------+------+----------------------------------------------------------+------+
      1 row in set (0.00 sec)
      

      Documentation says:
      "It is unsafe to read a user-defined variable and set its value in the same statement (unless the command is SET), because the order of these actions is undefined."

      Keeping that in mind, at least this case is still very wrong:

      > select @n:=0;
      +-------+
      | @n:=0 |
      +-------+
      |     0 |
      +-------+
      1 row in set (0.00 sec)
       
      MariaDB [(none)]> select @n
          -> ,case when @n=0 then concat_ws('~',@n:=+1,'test-1') end
          -> ,@n
          -> ;
      +------+--------------------------------------------------------+------+
      | @n   | case when @n=0 then concat_ws('~',@n:=+1,'test-1') end | @n   |
      +------+--------------------------------------------------------+------+
      |    1 | NULL                                                   |    1 |
      +------+--------------------------------------------------------+------+
      1 row in set (0.00 sec)
       
      MariaDB [(none)]> select @n;
      +------+
      | @n   |
      +------+
      |    1 |
      +------+
      1 row in set (0.00 sec)
       
      MariaDB [(none)]> select version();
      +---------------------------------------+
      | version()                             |
      +---------------------------------------+
      | 11.3.2-MariaDB-1:11.3.2+maria~ubu2204 |
      +---------------------------------------+
      1 row in set (0.00 sec)
      

      Order of columns is not an issue within case-when. How does "order of actions" imply that the case-when condition apparently evaluates twice?
      Also, when optimizing queries, should we no longer expect "then" part to evaluate only if "when" is true? Same is often true for "or" and "and" in expressions elsewhere.

      Constant expression assignment `@n:=+1` should not work differently than variable expression assignment `@n:=@n+1` in same context, engine optimization went a step too far here.

      Expected:

      > select @n:=0;
      +-------+
      | @n:=0 |
      +-------+
      |     0 |
      +-------+
      1 row in set (0.00 sec)
       
      MariaDB [(none)]> select @n
          -> ,case when @n=0 then concat_ws('~',@n:=+1,'test-1') end
          -> ,@n
          -> ;
      +------+--------------------------------------------------------+------+
      | @n   | case when @n=0 then concat_ws('~',@n:=+1,'test-1') end | @n   |
      +------+--------------------------------------------------------+------+
      |    0 | 1~test-1                                               |    1 |
      +------+--------------------------------------------------------+------+
      1 row in set (0.00 sec)
       
      MariaDB [(none)]> select @n;
      +------+
      | @n   |
      +------+
      |    1 |
      +------+
      1 row in set (0.00 sec)
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            janezr-bens Janez Resnik
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

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