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

Nested ROW comparison executes a ROW-valued stored function twice

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 11.8, 12.3, 13.1, 12.3.3
    • 11.8, 12.3, 13.1
    • None
    • None
    • MariaDB 12.3.3 binary distribution on x86_64 Debian GNU/Linux

    Description

      MariaDB 12.3.3 on x86_64 Debian GNU/Linux executes a ROW-valued stored function twice when its result is nested inside a row comparison. Direct ROW comparison and a nested scalar-function control execute their functions once.

      Reproducer

      Save the following as case.sql and run mariadb --batch --raw < case.sql.

      CREATE DATABASE row_eval;
      USE row_eval;
       
      DELIMITER //
      CREATE FUNCTION scalar_fn() RETURNS INT NOT DETERMINISTIC
      BEGIN
        SET @calls=COALESCE(@calls,0)+1;
        RETURN 1;
      END//
      CREATE FUNCTION row_fn() RETURNS ROW(a INT,b INT) NOT DETERMINISTIC
      BEGIN
        SET @calls=COALESCE(@calls,0)+1;
        RETURN ROW(1,2);
      END//
      DELIMITER ;
       
      SET @calls=0;
      SELECT ROW(ROW(scalar_fn(),2),3)=ROW(ROW(1,2),3) AS nested_scalar;
      SELECT @calls AS scalar_calls;
       
      SET @calls=0;
      SELECT row_fn()=ROW(1,2) AS direct_row;
      SELECT @calls AS direct_calls;
       
      SET @calls=0;
      SELECT ROW(row_fn(),3)=ROW(ROW(1,2),3) AS nested_row;
      SELECT @calls AS nested_calls;
       
      SET @calls=0;
      SELECT ROW(row_fn(),3)<=>ROW(ROW(1,2),3) AS nullsafe_row;
      SELECT @calls AS nullsafe_calls;
       
      PREPARE stmt FROM 'SELECT ROW(row_fn(),3)=ROW(ROW(1,2),3) AS prepared_row';
      SET @calls=0;
      EXECUTE stmt;
      SELECT @calls AS prepared_calls;
      DEALLOCATE PREPARE stmt;
       
      DROP DATABASE row_eval;
      SET @calls=NULL;

      Observed result

      Every comparison returns 1. The scalar and direct-ROW controls record one function call, while nested equality, nested null-safe equality, and the prepared nested equality each record two calls.

      nested_scalar
      1
      scalar_calls
      1
      direct_row
      1
      direct_calls
      1
      nested_row
      1
      nested_calls
      2
      nullsafe_row
      1
      nullsafe_calls
      2
      prepared_row
      1
      prepared_calls
      2

      Expected result

      Each expression contains one stored-function invocation, so each following call counter should be 1. Evaluating the same composite child during both preparation and comparison must not invoke a nondeterministic function twice.

      This occurs when a ROW-valued stored function is nested inside a row equality or null-safe equality comparison, including through a prepared statement.

      Attachments

        Issue Links

          Activity

            People

              bar Alexander Barkov
              imchifan 刘启帆
              Votes:
              0 Vote for this issue
              Watchers:
              2 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.