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

INSERT ... RETURNING sends metadata on error

Details

    Description

      When INSERT ... RETURNING fails, it sends metadata and afterwards error packet:

        rc= mysql_query(mysql, "CREATE TEMPORARY TABLE t1 (a int not null auto_increment primary key, b json)");
        check_mysql_rc(rc, mysql);
       
        rc= mysql_query(mysql, "INSERT INTO t1 (a,b) VALUES (NULL, '[incorrect json]') RETURNING a");
        check_mysql_rc(rc, mysql);  /* <- this should fail */
       
        result= mysql_store_result(mysql);
        mysql_free_result(result);
       
        diag("Error: %s", mysql_error(mysql));
      

      Output:

      Error: CONSTRAINT `t1.b` failed for `test`.`t1`
      

      Attachments

        Activity

          rucha174 Rucha Deodhar added a comment - - edited

          georg
          Example a sub query that returns more than one row.
          For example:

          create table t1 (a int);
          insert into t1 values (1),(2),(3);
          select a from t1 where a=(select a from t1 where a>1);
          

          We first send metadata. Then when we start sending data. And when the sub query shouldn't send more than one row, we get error.
          INSERT...RETURNING sends data just like SELECT does

          rucha174 Rucha Deodhar added a comment - - edited georg Example a sub query that returns more than one row. For example: create table t1 (a int ); insert into t1 values ( 1 ),( 2 ),( 3 ); select a from t1 where a=(select a from t1 where a> 1 ); We first send metadata. Then when we start sending data. And when the sub query shouldn't send more than one row, we get error. INSERT...RETURNING sends data just like SELECT does
          georg Georg Richter added a comment -

          Both the Maria and the MySQL documentation describe the return value of the mysql_real_query function:
          "Zero for success. Nonzero if an error occurred. "

          The current implementation breaks the API but is also not consistent:

          create table t1 (a int primary key);
          create table t2 (a int);
          insert into t1 values (1),(2),(3);
          insert into t2 values select a from t1;
          

          /* this will return an error */
          rc= mysql_real_query(mysql, SL("SELECT a FROM t1 WERE a= (SELECT a FROM t1))");
          /* this wil lnot return an error */
          rc= mysql_real_query(mysql, SL("SELECT a FROM t2 WHERE a=(SELECT a FROM t2))");
          

          Also the documentation for mysql_field_count states, that this function should be used to determine if a previously exceuted statement produced a result set. In Connectors we use this to allocate buffers before processing the resultset. It doesn't make sense to allocate buffers for processing result set if an error instead of a result set will follow.

          The current implementation is not only inconsistent, it also breaks a lot of applications.

          PQExec (postgresql client library) for example returns an error immediately with and without index.

          georg Georg Richter added a comment - Both the Maria and the MySQL documentation describe the return value of the mysql_real_query function: "Zero for success. Nonzero if an error occurred. " The current implementation breaks the API but is also not consistent: create table t1 (a int primary key); create table t2 (a int); insert into t1 values (1),(2),(3); insert into t2 values select a from t1; /* this will return an error */ rc= mysql_real_query(mysql, SL("SELECT a FROM t1 WERE a= (SELECT a FROM t1))"); /* this wil lnot return an error */ rc= mysql_real_query(mysql, SL("SELECT a FROM t2 WHERE a=(SELECT a FROM t2))"); Also the documentation for mysql_field_count states, that this function should be used to determine if a previously exceuted statement produced a result set. In Connectors we use this to allocate buffers before processing the resultset. It doesn't make sense to allocate buffers for processing result set if an error instead of a result set will follow. The current implementation is not only inconsistent, it also breaks a lot of applications. PQExec (postgresql client library) for example returns an error immediately with and without index.
          georg Georg Richter added a comment -

          I will reopen this ticket - if it is not a server bug, it should be changed to documentation issue, since it needs to be documented when and under which circumstances mysql_send_query, mysql_real_query and mysql_stmt_execute will not return an error and how to handle errors with unbuffered result sets and server side cursors. Also the client/server protocol documentation needs to be updated.

          georg Georg Richter added a comment - I will reopen this ticket - if it is not a server bug, it should be changed to documentation issue, since it needs to be documented when and under which circumstances mysql_send_query, mysql_real_query and mysql_stmt_execute will not return an error and how to handle errors with unbuffered result sets and server side cursors. Also the client/server protocol documentation needs to be updated.

          georg Yes exactly what I meant, sending error after metadata is not a server bug, it always can do so.

          sanja Oleksandr Byelkin added a comment - georg Yes exactly what I meant, sending error after metadata is not a server bug, it always can do so.

          georg you better create clear MDEV for documentation with reference to this bug, otherwise docuentation team will have hard time to understand what is needed from them.

          sanja Oleksandr Byelkin added a comment - georg you better create clear MDEV for documentation with reference to this bug, otherwise docuentation team will have hard time to understand what is needed from them.

          People

            rucha174 Rucha Deodhar
            georg Georg Richter
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

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