=== modified file 'driver/cursor.c' --- driver/cursor.c 2008-12-09 00:44:36 +0000 +++ driver/cursor.c 2008-12-09 00:47:34 +0000 @@ -496,6 +496,7 @@ length= strlen(*row_data); aprec->octet_length_ptr= &length; + aprec->indicator_ptr= &length; if (!SQL_SUCCEEDED(insert_param(stmt, (char **) &to, stmt->apd, aprec, iprec, 0))) @@ -819,6 +820,7 @@ length= -(length - SQL_LEN_DATA_AT_EXEC_OFFSET); aprec->octet_length_ptr= &length; + aprec->indicator_ptr= &length; if ( copy_rowdata(stmt,aprec,iprec,&net,&to) != SQL_SUCCESS ) return(SQL_ERROR); @@ -1190,6 +1192,7 @@ } aprec->octet_length_ptr= &length; + aprec->indicator_ptr= &length; if (copy_rowdata(stmt, aprec, iprec, &net, &to) != SQL_SUCCESS) return SQL_ERROR; === modified file 'driver/execute.c' --- driver/execute.c 2008-09-03 16:07:44 +0000 +++ driver/execute.c 2008-12-09 00:12:02 +0000 @@ -247,6 +247,7 @@ DBC *dbc= stmt->dbc; NET *net= &dbc->mysql.net; SQLLEN *octet_length_ptr= NULL; + SQLINTEGER *indicator_ptr= NULL; char *to= *toptr; if (aprec->octet_length_ptr) @@ -257,6 +258,10 @@ sizeof(SQLLEN), row); length= *octet_length_ptr; } + indicator_ptr= ptr_offset_adjust(aprec->indicator_ptr, + apd->bind_offset_ptr, + apd->bind_type, + sizeof(SQLLEN), row); if (aprec->data_ptr) { @@ -266,7 +271,12 @@ apd->bind_type, default_size, row); } - if (!octet_length_ptr || *octet_length_ptr == SQL_NTS) + if (indicator_ptr && *indicator_ptr == SQL_NULL_DATA) + { + *toptr= add_to_buffer(net,*toptr,"NULL",4); + return SQL_SUCCESS; + } + else if (!octet_length_ptr || *octet_length_ptr == SQL_NTS) { if (data) { @@ -284,11 +294,6 @@ length= 0; /* TODO? This is actually an error */ } } - else if ( *octet_length_ptr == SQL_NULL_DATA ) - { - *toptr= add_to_buffer(net,*toptr,"NULL",4); - return SQL_SUCCESS; - } /* We may see SQL_COLUMN_IGNORE from bulk INSERT operations, where we may have been told to ignore a column in one particular row. So we === modified file 'test/my_basics.c' --- test/my_basics.c 2008-09-11 03:02:39 +0000 +++ test/my_basics.c 2008-12-09 00:11:21 +0000 @@ -938,6 +938,35 @@ } +/* + Bug #41256 - NULL parameters don't work correctly with ADO. + The null indicator pointer can be set separately through the + descriptor field. This wasn't being checked separately. +*/ +DECLARE_TEST(t_bug41256) +{ + SQLHANDLE apd; + SQLINTEGER val= 40; + SQLLEN vallen= 19283; + SQLINTEGER ind= SQL_NULL_DATA; + SQLINTEGER reslen= 40; + ok_stmt(hstmt, SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_DESC, + &apd, SQL_IS_POINTER, NULL)); + ok_stmt(hstmt, SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_INTEGER, + SQL_C_LONG, 0, 0, &val, 0, &vallen)); + ok_desc(apd, SQLSetDescField(apd, 1, SQL_DESC_INDICATOR_PTR, + &ind, SQL_IS_POINTER)); + ok_sql(hstmt, "select ?"); + val= 80; + ok_stmt(hstmt, SQLFetch(hstmt)); + ok_stmt(hstmt, SQLGetData(hstmt, 1, SQL_C_LONG, &val, 0, &reslen)); + is_num(SQL_NULL_DATA, reslen); + is_num(80, val); + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); + return OK; +} + + BEGIN_TESTS ADD_TEST(my_basics) ADD_TEST(t_max_select) @@ -962,6 +991,7 @@ ADD_TEST(t_bug32727) ADD_TEST(t_bug28820) ADD_TEST(t_bug31959) + ADD_TEST(t_bug41256) END_TESTS