Fri Jul 27 17:09:47 CDT 2007 Jess Balint * second draft of fix for bug#6741 Fri Jul 27 16:20:35 CDT 2007 Jess Balint * fix and test for bug#6741 diff -rN -u old-odbc3/driver/options.c new-odbc3/driver/options.c --- old-odbc3/driver/options.c 2007-07-27 17:10:33.000000000 -0500 +++ new-odbc3/driver/options.c 2007-07-27 17:10:33.000000000 -0500 @@ -134,7 +134,7 @@ break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: - options->bind_offset= (SQLINTEGER *)ValuePtr; + options->bind_offset= (SQLLEN *)ValuePtr; break; case 1226:/* MS SQL Server Extension */ @@ -233,9 +233,7 @@ break; case SQL_ATTR_ROW_BIND_OFFSET_PTR: - *((SQLINTEGER *) ValuePtr)= options->bind_offset ? - *(options->bind_offset): - 0; + *((SQLLEN *) ValuePtr)= options->bind_offset; break; case SQL_ATTR_ROW_OPERATION_PTR: /* need to support this ....*/ diff -rN -u old-odbc3/driver/results.c new-odbc3/driver/results.c --- old-odbc3/driver/results.c 2007-07-27 17:10:33.000000000 -0500 +++ new-odbc3/driver/results.c 2007-07-27 17:10:33.000000000 -0500 @@ -1372,8 +1372,9 @@ { if ( bind->rgbValue || bind->pcbValue ) { - ulong offset,pcb_offset; + SQLLEN offset,pcb_offset; SQLLEN pcbValue; + if ( stmt->stmt_options.bind_type == SQL_BIND_BY_COLUMN ) { offset= bind->cbValueMax*i; @@ -1381,7 +1382,16 @@ } else pcb_offset= offset= stmt->stmt_options.bind_type*i; + + /* apply SQL_ATTR_ROW_BIND_OFFSET_PTR */ + if (stmt->stmt_options.bind_offset) + { + offset += *stmt->stmt_options.bind_offset; + pcb_offset += *stmt->stmt_options.bind_offset; + } + stmt->getdata_offset= (ulong) ~0L; + if ( (tmp_res= sql_get_data( stmt, bind->fCType, bind->field, @@ -1401,7 +1411,7 @@ res= SQL_ERROR; } if (bind->pcbValue) - *(bind->pcbValue + pcb_offset) = pcbValue; + *(bind->pcbValue + (pcb_offset / sizeof(SQLLEN))) = pcbValue; } if ( lengths ) lengths++; diff -rN -u old-odbc3/test/my_cursor.c new-odbc3/test/my_cursor.c --- old-odbc3/test/my_cursor.c 2007-07-27 17:10:33.000000000 -0500 +++ new-odbc3/test/my_cursor.c 2007-07-27 17:10:33.000000000 -0500 @@ -2486,6 +2486,57 @@ } +DECLARE_TEST(bug6741) +{ + const int vals = 5; + int i; + SQLLEN offset; + struct { + SQLINTEGER xval; + SQLLEN ylen; + } results[vals]; + + ok_sql(hstmt, "drop table if exists t_bug6741"); + ok_sql(hstmt, "create table t_bug6741 (x int, y int)"); + + ok_sql(hstmt, "insert into t_bug6741 values (0,0),(1,NULL),(2,2),(3,NULL),(4,4)"); + ok_sql(hstmt, "select x,y from t_bug6741 order by x"); + + ok_stmt(hstmt, SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_OFFSET_PTR, + &offset, SQL_IS_UINTEGER)); + ok_stmt(hstmt, SQLBindCol(hstmt, 1, SQL_C_LONG, &results[0].xval, 0, NULL)); + ok_stmt(hstmt, SQLBindCol(hstmt, 2, SQL_C_LONG, NULL, 0, &results[0].ylen)); + + /* fetch all the data */ + for(i = 0; i < vals; ++i) + { + offset = i * sizeof(results[0]); + ok_stmt(hstmt, SQLFetch(hstmt)); + } + expect_stmt(hstmt, SQLFetch(hstmt), SQL_NO_DATA_FOUND); + + /* verify it */ + for(i = 0; i < vals; ++i) + { + printf("xval[%d] = %d\n", i, results[i].xval); + printf("ylen[%d] = %d\n", i, results[i].ylen); + is_num(results[i].xval, i); + if(i % 2) + { + is_num(results[i].ylen, SQL_NULL_DATA); + } + else + { + is_num(results[i].ylen, sizeof(SQLINTEGER)); + } + } + + ok_sql(hstmt, "drop table if exists t_bug6741"); + + return OK; +} + + BEGIN_TESTS ADD_TEST(my_positioned_cursor) ADD_TEST(my_setpos_cursor) @@ -2524,6 +2575,7 @@ ADD_TEST(tmysql_pcbvalue) ADD_TEST(t_bug28255) ADD_TEST(bug10563) + ADD_TEST(bug6741) END_TESTS