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()."