Bug #29871 MyODBC problem with MS Query ('Memory allocation error')
Submitted: 18 Jul 2007 15:41 Modified: 26 Feb 2008 12:21
Reporter: Bogdan Degtyariov Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:3.51.16, 3.51.17 OS:Any
Assigned to: Bogdan Degtyariov CPU Architecture:Any
Tags: Excel, MyODBC, query
Triage: D2 (Serious)

[18 Jul 2007 15:41] Bogdan Degtyariov
Description:
The problem appears in MS Query when trying to import the data into Excel.

How to repeat:
Open MS excel > Data > new database query >pick up the DSN just configed and pick up some tables > View data or edit query in Microsoft Query > Allow editing > Modify some data field and try to return data to Excel.

Suggested fix:
When MS Query uses parameters in queries MyODBC incorrectly calculates the size of the buffer as:

if ( length > param->ValueMax )
    length = param->ValueMax;

for ValueMax == -1 the length cannot be considered as valid.

To fix the problem it is necessary to add a new condition:
if ( length > param->ValueMax && param->ValueMax > 0)
    length = param->ValueMax;
[15 Aug 2007 10:06] Bogdan Degtyariov
Trying to narrow the problem to a C test case
[15 Aug 2007 12:47] Bogdan Degtyariov
I found out that MSQuery binds the query parameters in an unusual way. It mostly affects integer columns. The value type is SQL_C_CHAR whereas the parameter type is SQL_INTEGER. This causes misinterpretation of the parameter when inserting it into the resulting SQL query.
[15 Aug 2007 15:36] Bogdan Degtyariov
parameter length -1 appeared due to use of a deprecated function SQLSetParam instead of SQLBindParam. I wonder why it is mapped so, that SQLBindParam is being called with SQL_SETPARAM_VALUE_MAX (-1L) whereas the direct call of SQLBindParam with this option fails:
[ HY090] [Microsoft][ODBC Driver Manager] Invalid string or buffer length
[15 Aug 2007 16:33] Bogdan Degtyariov
Patch and test case

Attachment: patch29871.diff (application/octet-stream, text), 1.85 KiB.

[30 Aug 2007 15:55] Jim Winstead
change

  if ( length > param->ValueMax && param->ValueMax > 0 )

to

  if (length != SQL_SETPARAM_VALUE_MAX && length > param->ValueMax)

and fix the formatting of the comment preceding this line.

okay to push.
[13 Sep 2007 11:02] Bogdan Degtyariov
The following condition does not work for MS Query:

if (length != SQL_SETPARAM_VALUE_MAX && length > param->ValueMax)

it has to be changed to:

if (param->ValueMax != SQL_SETPARAM_VALUE_MAX && length > param->ValueMax)
[13 Sep 2007 11:36] MC Brown
A note has been added to the 3.51.20 changelog: 

SQLSetParam() caused memory allocation errors due to driver manager's mapping of deprecated functions (buffer length -1).
[21 Sep 2007 17:51] Bogdan Degtyariov
New patch incuding SQLSetParam function (mapped to SQLBindParameter)

Attachment: patch29871v2.diff (application/octet-stream, text), 2.71 KiB.

[22 Sep 2007 8:08] Jim Winstead
the comment should be written in doxygen-style, and some of the code formatting fixed, but the code looks fine.
[4 Oct 2007 21:01] Jim Winstead
The fix for this bug was committed to the source repository, and will be in 3.51.21.
[12 Oct 2007 13:12] MC Brown
A note has been added to the 3.51.21 changelog:
 
SQLSetParam() caused memory allocation errors due to driver manager's mapping of deprecated functions (buffer length -1).
[2 Feb 2008 3:08] Jess Balint
The test for this bug is failing. The function is not exported (I checked 3.51.23 release DLL).

SQLSetPos() needs to be exported. Also, the test-case should verify that the correct data was inserted.
[2 Feb 2008 3:08] Jess Balint
Sorry, SQLSetParam() needs to be exported.
[7 Feb 2008 16:52] Bogdan Degtyariov
New version of the patch

Attachment: patch29871v6.diff (application/octet-stream, text), 2.27 KiB.

[26 Feb 2008 12:21] MC Brown
The existing changelog entry has also been tagged against the 3.51.24 release.