Bug #61991 SQLGetData return shorter than expected string when multiple rows are fetched
Submitted: 26 Jul 2011 21:14 Modified: 15 Sep 2011 18:49
Reporter: Yan Dai Email Updates:
Status: Verified Impact on me:
Category:Connector / ODBC Severity:S2 (Serious)
Version:5.1.8 OS:Windows (Windows 7 Enterprise)
Assigned to: Bogdan Degtyariov CPU Architecture:Any

[26 Jul 2011 21:14] Yan Dai
I am running MySQL connector installed from version 
5.1.8 on a 64 bit machine.

The table names from select table query are truncated on some test scenarios.

Please see "How to repeat" section.

With SQLGetData calls, the returned table name are "object_equip" and "Transactions". It appeared last record's length is used for return data when doing multiple row fetch.

How to repeat:
First create two tables:


Then call following functions. To show the code cleanly, I omitted the return error checking.

SQLExecDirect(handle, SqlString("SELECT table_name from information_schema.TABLES where table_schema=(select database())"), SQL_NTS);

SQLULEN nRowsFetched = 0;
SetStatementAttrPtr(SQL_ATTR_ROWS_FETCHED_PTR, &nRowsFetched);
SetStatementAttr(SQL_ATTR_ROW_ARRAY_SIZE, 100);

SQLFetchScroll(handle, SQL_FETCH_NEXT, 0);

SQLCHAR pBuffer[65536];
SQLGetData(handle, 1, SQL_C_CHAR, pBuffer, 65536, &len);

The len returned will be 12 instead of real length of "object_equipment".

Suggested fix:
In results.c sql_get_data() function, the length should not use the length in last row, it should use the corresponding column current_values. 

The following code 

    /* catalog functions with "fake" results won't have lengths */
    length= irrec->row.datalen;
    if (!length && stmt->current_values[ColumnNumber])
      length= strlen(stmt->current_values[ColumnNumber]);

changed to:

    /* catalog functions with "fake" results won't have lengths */
    length= irrec->row.datalen;
    if (stmt->current_values[ColumnNumber])
      length= strlen(stmt->current_values[ColumnNumber]);

These changes would fix the issue.
[5 Aug 2011 11:35] Bogdan Degtyariov

Thank you for the very detailed bug description.
I was able to repeat the problem locally.
Setting the bug status to verified and checking the solution kindly offered by you.
[5 Aug 2011 12:20] Bogdan Degtyariov
We cannot just use your patch as it is because it would break handling empty result sets.

It seems that the irrec->row.datalen is set to the last result length, which is 12 in this particular case because the length of the table name `Transactions` is 12.
[5 Aug 2011 16:43] Yan Dai
I found another issue in SQLGetData that using strlen for column value length did not work for blob or unicode data. I would suggest to add current_lengths corresponding to current_values in STMT struct and set current_lengths via mysql_fetch_lengths() call when mysql_fetch_row is called.

I made a patch to solve the original issue and incorrect blob length issue. Please see the attachment.
[5 Aug 2011 16:44] Yan Dai
bug fix for length setup in SQLGetData

Attachment: bug61991.patch (application/octet-stream, text), 3.04 KiB.

[15 Sep 2011 18:49] Yan Dai
Hi Bogdan,
   Thanks for reviewing the previous patch. Did you get a chance to review the patch I submitted on Aug, 5th?