Bug #39644 Binding SQL_C_BIT to an integer column is not working
Submitted: 25 Sep 2008 8:24 Modified: 23 Oct 2009 14:40
Reporter: Bogdan Degtyariov Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:5.1.5 OS:Any
Assigned to: Bogdan Degtyariov CPU Architecture:Any
Tags: SQL_C_BIT

[25 Sep 2008 8:24] Bogdan Degtyariov
Description:
Binding SQL_C_BIT to an integer column is not working when using myodbc 5.1.5, but it's working fine when using myodbc 3.51.26.

Looks like in version 5.1.5 the sql_get_data() function works correctly only for BOOLEAN columns that correspond to SQL_C_BIT buffers.

How to repeat:
DECLARE_TEST(t_bit_bug)
{
  char col1 = 0x3f;
  char col2 = 0xff;
  char col3 = 0x0;
  char col4 = 0x1;

  ok_sql(hstmt, "drop table if exists t_bit_bug");
  ok_sql(hstmt, "create table t_bit_bug(col1 INT, col2 INT,"\
	            "col3 BIT, col4 BIT)");

  ok_sql(hstmt, "insert into t_bit_bug VALUES (5, 0, 1, 0)");

  /* Do SELECT */
  ok_sql(hstmt, "SELECT * from t_bit_bug");

  /* Now bind buffers */
  ok_stmt(hstmt, SQLBindCol(hstmt, 1, SQL_C_BIT, &col1, sizeof(char), 0));
  ok_stmt(hstmt, SQLBindCol(hstmt, 2, SQL_C_BIT, &col2, sizeof(char), 0));
  ok_stmt(hstmt, SQLBindCol(hstmt, 3, SQL_C_BIT, &col3, sizeof(char), 0));
  ok_stmt(hstmt, SQLBindCol(hstmt, 4, SQL_C_BIT, &col4, sizeof(char), 0));

  /* Fetch and check results */
  ok_stmt(hstmt, SQLFetch(hstmt));

  is( col1 == 1 );
  is( col2 == 0 );
  is( col3 == 1 );
  is( col4 == 0 );

  /* Clean-up */
  ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE));
  ok_sql(hstmt, "drop table t_bit_bug");

  return OK;
}

Suggested fix:
=== modified file 'driver/results.c'
--- driver/results.c	2008-08-22 22:12:25 +0000
+++ driver/results.c	2008-09-25 07:31:31 +0000
@@ -193,7 +193,7 @@
     case SQL_C_BIT:
       if (rgbValue)
       {
-        if (value[0] == 1 || !atoi(value))
+        if (value[0] && value[0] != '0')
           *((char *)rgbValue)= 1;
         else
           *((char *)rgbValue)= 0;
[25 Sep 2008 8:31] Bogdan Degtyariov
patch and test case

Attachment: patch39644.diff (application/octet-stream, text), 1.80 KiB.

[20 Oct 2008 17:32] Jess Balint
I don't think value[0] != '0' is the right thing to do here. I'm not sure when it was changed from 3.51 but it looks like we just shouldn't negate the result of the atoi() call. I think it should be something like this:

        if (value[0] == 1 || atoi(value))
[20 Oct 2008 18:22] Jess Balint
Bug#36470 was marked as a duplicate of this.
[12 Aug 2009 21:54] Gerald Schade
Does anybody work on fixing this bug, which is still present?
[10 Sep 2009 9:51] Lawrenty Novitsky
My opinion that logic should be like this:
atoi() != 0 || (any non-zero byte).

Because first character can be '0' and string will still render to non-zero number. and first byte can be easily 0 for numeric type, while whole number will be not 0.

so patch seems to be correct only if we want to consider 1st byte only. and that doesn't look correct for me.
[1 Oct 2009 11:35] Tonci Grgin
Bug#47760 was marked as duplicate of this report.
[19 Oct 2009 18:45] Lawrenty Novitsky
Since current code is absolutely wrong, and this one will work in 99%(if not more) cases, i prefer to approve it and push it so it will get to this coming release.
[19 Oct 2009 20:17] Lawrenty Novitsky
Patch has been pushed as revision #843. it will be in 5.1.6 release
[23 Oct 2009 14:40] Tony Bedford
An entry has been added to the 5.1.6 changelog:

Binding SQL_C_BIT to an INTEGER column did not work.

The sql_get_data() function only worked correctly for BOOLEAN columns that corresponded to SQL_C_BIT buffers.