=== modified file driver/error.c --- driver/error.c 2010-01-30 23:08:01 +0000 +++ driver/error.c 2010-12-21 18:48:16 +0000 @@ -351,6 +351,8 @@ { unsigned int err= mysql_errno(&stmt->dbc->mysql); switch (err) { + case 0: /* no error */ + return SQL_SUCCESS; case CR_SERVER_GONE_ERROR: case CR_SERVER_LOST: return set_stmt_error(stmt, "08S01", mysql_error(&stmt->dbc->mysql), err); === modified file driver/results.c --- driver/results.c 2010-06-14 21:38:23 +0000 +++ driver/results.c 2010-12-21 18:48:16 +0000 @@ -664,8 +664,8 @@ field->table ? field->table : ""); case SQL_DESC_CASE_SENSITIVE: - *(SQLINTEGER *)NumericAttributePtr= ((field->charsetnr == 63 || field->flags & BINARY_FLAG) && - (test(field->org_table_length > 0) || + *(SQLINTEGER *)NumericAttributePtr= ((field->charsetnr == 63 || field->flags & BINARY_FLAG) && + (test(field->org_table_length > 0) || ((stmt->dbc->flag & FLAG_NO_BINARY_RESULT) == 0)) ? SQL_TRUE : SQL_FALSE); break; @@ -1379,6 +1379,9 @@ return SQL_NO_DATA_FOUND; } + if (handle_connection_error(stmt)) + return SQL_ERROR; + if ( !(stmt->dbc->flag & FLAG_NO_LOCALE) ) setlocale(LC_NUMERIC, "C"); res= SQL_SUCCESS; @@ -1396,7 +1399,11 @@ if ( i == 0 ) save_position= mysql_row_tell(stmt->result); if ( !(values= mysql_fetch_row(stmt->result)) ) + { + if (handle_connection_error(stmt)) + res= SQL_ERROR; break; + } if ( stmt->fix_fields ) values= (*stmt->fix_fields)(stmt,values); else @@ -1486,7 +1493,7 @@ for ( ; i < stmt->stmt_options.rows_in_set ; i++ ) stmt->stmt_options.rowStatusPtr[i]= SQL_ROW_NOROW; - if ( !stmt->result_array && !if_forward_cache(stmt) ) + if (SQL_SUCCEEDED(res) && !stmt->result_array && !if_forward_cache(stmt)) { /* read data from first row */ stmt->end_of_set= mysql_row_seek(stmt->result,save_position); === modified file test/my_use_result.c --- test/my_use_result.c 2010-01-30 23:08:01 +0000 +++ test/my_use_result.c 2010-12-21 18:48:16 +0000 @@ -112,9 +112,94 @@ } +/** + Bug #39878: "Don't Cache Results" crashes when using catalog functions +*/ +DECLARE_TEST(t_bug39878) +{ + int i; + SQLINTEGER row_count= 0; + SQLRETURN rc; + + ok_stmt(hstmt, SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE, + (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, 0)); + + printMessage("Creating table t_bug39878"); + + ok_sql(hstmt, "DROP TABLE IF EXISTS t_bug39878"); + ok_sql(hstmt, "CREATE TABLE t_bug39878 (a INT)"); + + // Fill table with data + printMessage("Filling table with data..."); + + ok_sql(hstmt, "INSERT INTO t_bug39878 VALUES (0), (1)"); + + ok_stmt(hstmt, SQLPrepare(hstmt, (SQLCHAR *) + "INSERT INTO t_bug39878 SELECT a+? FROM t_bug39878", SQL_NTS)); + + ok_stmt(hstmt, SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, + SQL_INTEGER, 0, 0, &row_count, 0, NULL)); + + for (i=1, row_count= 2; i < 14; ++i, row_count *= 2) + ok_stmt(hstmt, SQLExecute(hstmt)); + + printMessage("inseted %d rows.", row_count); + + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_RESET_PARAMS)); + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); + + printMessage("Setting net_write_timeout to 1"); + ok_sql(hstmt, "SET net_write_timeout=1"); + + // Table scan + + ok_sql(hstmt, "SELECT * FROM t_bug39878"); + printMessage("Started table scan, sleeping 2sec ..."); + sleep(2); + + printMessage("Fetching rows..."); + + while (SQL_SUCCEEDED(rc= SQLFetch(hstmt))) + { + row_count--; + } + + print_diag(rc, SQL_HANDLE_STMT, hstmt, "SQLFetch()", __FILE__, __LINE__); + printMessage("Scan interrupted, %d rows left in the table.", row_count); + + { + char *rc_name; + switch(rc) + { + case SQL_SUCCESS: rc_name= "SQL_SUCCESS"; break; + case SQL_SUCCESS_WITH_INFO: rc_name= "SQL_SUCCESS_WITH_INFO"; break; + case SQL_NO_DATA: rc_name= "SQL_NO_DATA"; break; + case SQL_STILL_EXECUTING: rc_name= "SQL_STILL_EXECUTING"; break; + case SQL_ERROR: rc_name= "SQL_ERROR"; break; + case SQL_INVALID_HANDLE: rc_name= "SQL_INVALID_HANDLE"; break; + default: rc_name= "<unknown>"; break; + } + printMessage("Last SQLFetch() returned: %s", rc_name); + } + + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_UNBIND)); + ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); + + is(row_count == 0 || rc == SQL_ERROR); + + // We re-connect to drop the table (as connection might be broken) + free_basic_handles(&henv, &hdbc, &hstmt); + alloc_basic_handles(&henv, &hdbc, &hstmt); + ok_sql(hstmt, "DROP TABLE IF EXISTS t_bug39878"); + + return OK; +} + + BEGIN_TESTS ADD_TEST(t_use_result) ADD_TEST(t_bug4657) + ADD_TEST(t_bug39878) END_TESTS