=== 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