Bug #39644 Binding SQL_C_BIT to an integer column is not working
Submitted: 25 Sep 2008 10:24 Modified: 23 Oct 16:40
Reporter: Bogdan Degtyariov
Status: Closed
Category:Connector/ODBC Severity:S2 (Serious)
Version:5.1.5 OS:Any
Assigned to: Bogdan Degtyariov Target Version:
Tags: SQL_C_BIT

[25 Sep 2008 10: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 10:31] Bogdan Degtyariov
patch and test case

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

[20 Oct 2008 19: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 20:22] Jess Balint
Bug#36470 was marked as a duplicate of this.
[12 Aug 23:54] Gerald Schade
Does anybody work on fixing this bug, which is still present?
[10 Sep 11:51] Lawrin 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 13:35] Tonci Grgin
Bug#47760 was marked as duplicate of this report.
[19 Oct 20:45] Lawrin 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 22:17] Lawrin Novitsky
Patch has been pushed as revision #843. it will be in 5.1.6 release
[23 Oct 16: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.