| Bug #20547 | SQL_LEN_DATA_AT_EXEC not working | ||
|---|---|---|---|
| Submitted: | 19 Jun 2006 21:59 | Modified: | 14 Sep 2006 10:13 |
| Reporter: | Anders Karlsson | ||
| Status: | Closed | ||
| Category: | Connector/ODBC | Severity: | S3 (Non-critical) |
| Version: | 3.51.12 | OS: | Linux (Linux) |
| Assigned to: | Bogdan Degtyariov | Target Version: | |
[21 Jun 2006 14:41]
Tonci Grgin
Verified with test case attached. Output: Connecting to myodbc1 ABCDEF SQLSetPos Out of memory (Needed 0 bytes) Error: [MySQL][ODBC 3.51 Driver][mysqld-5.0.23-debug]General driver defined error
[21 Jun 2006 14:47]
Tonci Grgin
Test case
Attachment: TestUpdateStream.cpp (text/x-c++), 5.61 KiB.
[17 Jul 2006 15:57]
Bogdan Degtyariov
Thank you for your bug report. This issue has been committed to our source repository of
that product and will be incorporated into the next release.
If necessary, you can access the source repository and build the latest available
version, including the bug fix. More information about accessing the source trees is
available at
http://www.mysql.com/doc/en/Installing_source_tree.html
[14 Sep 2006 10:13]
MC Brown
A note has been added to the 3.51.13 changelog.

Description: Using MyODBC and doing a SQLBindCol and binding the length to the return value from SQL_LEN_DATA_AT_EXEC fails with a memory allocation error. This is due to the fact that the SQL_LEN_DATA_AT_EXEC places a value in the length variable that is passed to SQLBindCol that is really a flag. This flag is a negative value (-100) so as not to collide with real length values. The problem with MyODBC is that it just picks up the lenth value (the last parameter to SQLBindCol) and uses that, without looking for this flag. What happens then is the this value (-100) is used as an unsigned (4294967196) when allocating space for the string, and this fails obviously. To see what happens for yourself, look at the driver code in cursor.c in the function copy_rowdata. Put a breakpoint there are see what the "length" value ends up at. This is passed to extend_buffer, which subsequently fails. Looking at cursor.c in the function build_set_clause, one can also see that there is a "TODO: : handle ..SQL_DATA_AT_EXEC here..." comment. How to repeat: ... some C code here ... SQLINTEGER nLen; SQLRETURN nRet; nLen = SQL_LEN_DATA_AT_EXEC(0); SQLBindCol(hstmt, 1, SQL_C_CHAR, (SQLPOINTER)0, 0, &nLen); if(SQLSetPos(hstmt,1, SQL_UPDATE, SQL_LOCK_NO_CHANGE) != SQL_SUCCESS) { ... Handle error here. }