Bug #80614 C API doc / mysql_stmt_bind_result

Submitted: 4 Mar 2016 10:08 Modified: 9 Mar 2016 11:51
Reporter: Artur Södler Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S3 (Non-critical)
Version:5.7.11 OS:Windows (XP)
Assigned to: CPU Architecture:Any

[4 Mar 2016 10:08] Artur Södler
Description:
Please document that mysql_stmt_bind_result() is copying bind[] data (but not bind[].buffer[]). Respectively that it is NOT copying bind[] data, if so, and in which versions.

This helps to understand two important points:
1. Changes to the bind[] data after the call to mysql_stmt_bind_result() have no effect.
2. The struct st_mysql_bind members length_value, is_null_value and error_value cannot be returned, unless you set the length, is_null and error members or call mysql_stmt_fetch_column().

Please note that the source code says explicitly that length_value is not used if length is not NULL — implying it *was* used if length is NULL.

Thank you.

How to repeat:
Show the behaviour by deleting line 26 of the following code snippet:

switch (mysql_stmt_fetch (m_pStmt)) {
default: MyFail();
case 1: MyThrowMysql ("mysql_stmt_fetch");
case MYSQL_NO_DATA: m_bEof = true; return false;
case MYSQL_DATA_TRUNCATED:
   {
      MYSQL_BIND *pb = m_pBindOut;
      for (size_t i=0; i<nNumFieldsOut; ++i) {
         if (pb->error_value) {
            unsigned long nLen = pb->length_value;
            unsigned long nOffset = pb->buffer_length; // save the already received part
            char *p = new char [nLen];
            memcpy (p, pb->buffer, nOffset); // save the already received part
            delete [] (char *) pb->buffer;
            pb->buffer = p + nOffset;
            pb->buffer_length = nLen - nOffset;
            if (mysql_stmt_fetch_column (m_pStmt, pb, i, nOffset))
               MyThrowMysql ("mysql_stmt_fetch_column");
            pb->buffer = p;
            pb->buffer_length = nLen;
         }
         ++pb;
      }
   }
   // skip this bind_result call to reproduce:
   if (mysql_stmt_bind_result (m_pStmt, m_pBindOut))
      MyThrowMysql ("mysql_stmt_bind_result");
case 0: break;
}

Suggested fix:
Suggestion 1:

Original doc text: "mysql_stmt_bind_result() is used to associate (that is, bind) output columns in the result set to data buffers and length buffers."

Add: "Internally, mysql_stmt_bind_result() keeps a copy of the bind[] array. You may delete the bind array passed to mysql_stmt_bind_result() immediately after the call."

And/or add: "To update any bind information in the middle of a sequence of fetches, you must call mysql_stmt_bind_result() again."

Suggestion 2:

mysql.h: "length, is_null and error MUST NOT be NULL for use in mysql_stmt_bind_result()."
[9 Mar 2016 11:51] Chiranjeevi Battula
Hello Artur Södler,

Thank you for the bug report.
Verified based on internal discussion with dev's.

Thanks,
Chiranjeevi

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.051 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.