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

          georg Georg Richter created issue -
          georg Georg Richter made changes -
          Field Original Value New Value
          Issue Type Task [ 3 ] Bug [ 1 ]
          georg Georg Richter made changes -
          Affects Version/s 10.6.0 [ 24431 ]
          georg Georg Richter made changes -
          Affects Version/s 10.5.5 [ 24423 ]
          georg Georg Richter made changes -
          Labels django
          elenst Elena Stepanova made changes -
          Component/s Data Manipulation - Insert [ 10101 ]
          Fix Version/s 10.5 [ 23123 ]
          Assignee Rucha Deodhar [ rucha174 ]

          georg, don't SELECT also sends metadata and then an error in case of error, what is wrong here?

          sanja Oleksandr Byelkin added a comment - georg , don't SELECT also sends metadata and then an error in case of error, what is wrong here?
          sanja Oleksandr Byelkin made changes -
          Assignee Rucha Deodhar [ rucha174 ] Oleksandr Byelkin [ sanja ]
          georg Georg Richter added a comment -

          sanja No, for e.g. COM_QUERY cllient expects error packet (0xFF) or metadata. Biut not 0xFF after sending metadata. See https://mariadb.com/kb/en/com_query/

          georg Georg Richter added a comment - sanja No, for e.g. COM_QUERY cllient expects error packet (0xFF) or metadata. Biut not 0xFF after sending metadata. See https://mariadb.com/kb/en/com_query/

          georg SELECT can send not only metadata but also data (part of a result set) and then send an error packet.

          sanja Oleksandr Byelkin added a comment - georg SELECT can send not only metadata but also data (part of a result set) and then send an error packet.

          and INSERT ... RETURNING returns data as SELECT does.

          sanja Oleksandr Byelkin added a comment - and INSERT ... RETURNING returns data as SELECT does.
          georg Georg Richter added a comment -

          sanja Can you give me an example where SELECT returns metadata followed by an error?
          In the example above the statement failed, so I expect an error (and that is how mysql_real_query was designed), but not any metadata.

          georg Georg Richter added a comment - sanja Can you give me an example where SELECT returns metadata followed by an error? In the example above the statement failed, so I expect an error (and that is how mysql_real_query was designed), but not any metadata.
          sanja Oleksandr Byelkin made changes -
          Assignee Oleksandr Byelkin [ sanja ] Rucha Deodhar [ rucha174 ]
          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
          rucha174 Rucha Deodhar made changes -
          Fix Version/s 10.5.10 [ 25204 ]
          Fix Version/s 10.5 [ 23123 ]
          Resolution Not a Bug [ 6 ]
          Status Open [ 1 ] Closed [ 6 ]
          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 Georg Richter made changes -
          Resolution Not a Bug [ 6 ]
          Status Closed [ 6 ] Stalled [ 10000 ]

          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.
          sanja Oleksandr Byelkin made changes -
          Resolution Not a Bug [ 6 ]
          Status Stalled [ 10000 ] Closed [ 6 ]

          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.
          serg Sergei Golubchik made changes -
          Workflow MariaDB v3 [ 113686 ] MariaDB v4 [ 158384 ]

          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.