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

Bulk DELETE ... RETURNING * sends rows that do not match the result set metadata when the table changes between parameter sets

    XMLWordPrintable

Details

    Description

      A per-row bulk operation (COM_STMT_BULK_EXECUTE that executes the statement once per parameter set, e.g. DELETE, or INSERT with a subquery depending on a parameter after MDEV-23864) sends the RETURNING metadata in the first execution only. If the statement is reprepared in a later execution because the table changed, the shape of RETURNING * changes, but the rows are still sent under the old metadata. The client gets wrong values without any error.

      How to repeat

      CREATE TABLE t1 (id INT PRIMARY KEY, val INT);
      INSERT INTO t1 VALUES (1,10),(2,20),(3,30);
      -- bulk, parameter sets (1,10), (2,20), (3,30):
      DELETE FROM t1 WHERE id = ? AND val = ? RETURNING *;
      -- connection 2, between parameter sets 1 and 2:
      ALTER TABLE t1 ADD COLUMN c INT DEFAULT 7 FIRST;

      The client runs the bulk statement on connection 1 with SET debug_sync='before_execute_sql_command SIGNAL s1 WAIT_FOR go EXECUTE 2', and a second connection runs the DDL while the second parameter set waits (debug build). Without debug_sync the same happens when the DDL is concurrent and lands between two parameter sets.

      With the MDEV-23864 patch (10.11, debug), which fixes the assertion below, the client gets 2 columns and the rows

      1 10
      7 2
      7 3

      instead of (1,10), (2,20), (3,30); the rows 2 and 3 are deleted. SERVER_STATUS_METADATA_CHANGED is not set.

      Without the patch (11.4.13 debug, source revision 4813c2f0a8a79e4e4c000cc8c9447096fafe7033) the server fails the assertion

      sql_error.cc:468: void Diagnostics_area::set_error_status(...): Assertion `! is_set() || m_can_overwrite_status' failed.

      in Reprepare_observer::report_error() <- check_and_update_table_version() <- open_tables(), because the diagnostics area has the status of the previous parameter set.

      Probably the reprepare after the metadata was sent should fail the statement (e.g. with ER_NEED_REPREPARE or ER_PS_REBIND) if the RETURNING list changed, rather than sending mismatched rows.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              sanja Oleksandr Byelkin
              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.