Index: driver/results.c =================================================================== --- driver/results.c (revision 962) +++ driver/results.c (working copy) @@ -1221,7 +1221,7 @@ bool upd_status ) { ulong rows_to_fetch; - long cur_row, max_row; + long cur_row, max_row= 0; uint i; SQLRETURN res,tmp_res; STMT FAR *stmt= (STMT FAR*) hstmt; @@ -1244,7 +1244,9 @@ if ((stmt->dbc->flag & FLAG_NO_CACHE)) { - if (stmt->result_array) + if (stmt->stmt_options.rows_in_set) + max_row= stmt->stmt_options.rows_in_set + stmt->current_row; + else if (stmt->result_array) values= stmt->result_array + (cur_row * stmt->result->field_count); else values= mysql_fetch_row(stmt->result); @@ -1258,7 +1260,7 @@ if ( !pcrow ) pcrow= &dummy_pcrow; - max_row= (long) mysql_num_rows(stmt->result); + max_row= max_row ? max_row : (long) mysql_num_rows(stmt->result); stmt->last_getdata_col= (uint) ~0; stmt->current_values= 0; /* For SQLGetData */ @@ -1266,8 +1268,7 @@ { case SQL_FETCH_NEXT: - cur_row= (stmt->current_row < 0 ? 0 : - stmt->current_row+stmt->rows_found_in_set); + /* cur_row is already set to the proper position from STMT */ break; case SQL_FETCH_PRIOR: cur_row= (stmt->current_row <= 0 ? -1 : @@ -1365,7 +1366,14 @@ save_position= mysql_row_tell(stmt->result); if ( !(values= mysql_fetch_row(stmt->result)) ) break; + } + else if (stmt->stmt_options.rows_in_set) + { + values= mysql_fetch_row(stmt->result); + if(!values) + goto nodata; } + if ( stmt->fix_fields ) values= (*stmt->fix_fields)(stmt,values); else @@ -1436,8 +1444,11 @@ lengths++; } } + stmt->current_row++; cur_row++; } + +nodata: stmt->rows_found_in_set= i; *pcrow= i; Index: test/my_cursor.c =================================================================== --- test/my_cursor.c (revision 962) +++ test/my_cursor.c (working copy) @@ -2596,6 +2596,263 @@ } +/** + Bug #32420: Don't cache results and SQLExtendedFetch ignore SQL_ROWSET_SIZE + option +*/ +DECLARE_TEST(t_bug32420) +{ + HDBC hdbc1; + HSTMT hstmt1; + + SQLINTEGER nData[4]; + SQLCHAR szData[4][16]; + SQLUSMALLINT rgfRowStatus[4]; + SQLCHAR conn[256], conn_out[256]; + SQLSMALLINT conn_out_len; + SQLUINTEGER row_count; + + /* Don't cache result option in the connection string */ + sprintf(conn, "DRIVER={MySQL ODBC 3.51 Driver};USER=%s;PASSWORD=%s;" + "DATABASE=%s;SERVER=%s;OPTION=1048576", + myuid, mypwd, mydb, myserver); + + if (mysock != NULL) + { + strcat((char *)conn, ";SOCKET="); + strcat((char *)conn, (char *)mysock); + } + + ok_env(henv, SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1)); + + ok_con(hdbc1, SQLDriverConnect(hdbc1, NULL, conn, sizeof(conn), conn_out, + sizeof(conn_out), &conn_out_len, + SQL_DRIVER_NOPROMPT)); + ok_con(hdbc1, SQLAllocStmt(hdbc1, &hstmt1)); + + ok_sql(hstmt1, "drop table if exists bug32420"); + ok_sql(hstmt1, "CREATE TABLE bug32420 ("\ + "tt_int INT PRIMARY KEY auto_increment,"\ + "tt_varchar VARCHAR(128) NOT NULL)"); + ok_sql(hstmt1, "INSERT INTO bug32420 VALUES "\ + "(100, 'string 1'),"\ + "(200, 'string 2'),"\ + "(300, 'string 3'),"\ + "(400, 'string 4'),"\ + "(500, 'string 5'),"\ + "(600, 'string 6'),"\ + "(700, 'string 7'),"\ + "(800, 'string 8'),"\ + "(900, 'string 9'),"\ + "(910, 'string A'),"\ + "(920, 'string B')"); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + + ok_stmt(hstmt1, SQLSetStmtOption(hstmt1, SQL_ROWSET_SIZE, 4)); + + ok_sql(hstmt1, "select * from bug32420"); + ok_stmt(hstmt1, SQLBindCol(hstmt1, 1, SQL_C_LONG, nData, 0, NULL)); + ok_stmt(hstmt1, SQLBindCol(hstmt1, 2, SQL_C_CHAR, szData, sizeof(szData[0]), + NULL)); + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 100); + is_str(szData[0], "string 1", 8); + is_num(nData[1], 200); + is_str(szData[1], "string 2", 8); + is_num(nData[2], 300); + is_str(szData[2], "string 3", 8); + is_num(nData[3], 400); + is_str(szData[3], "string 4", 8); + + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 500); + is_str(szData[0], "string 5", 8); + is_num(nData[1], 600); + is_str(szData[1], "string 6", 8); + is_num(nData[2], 700); + is_str(szData[2], "string 7", 8); + is_num(nData[3], 800); + is_str(szData[3], "string 8", 8); + + /* + Now checking the last records when the result is shorter than + ROWSET_SIZE + */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 3); + is_num(nData[0], 900); + is_str(szData[0], "string 9", 8); + is_num(nData[1], 910); + is_str(szData[1], "string A", 8); + is_num(nData[2], 920); + is_str(szData[2], "string B", 8); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + ok_sql(hstmt1, "drop table if exists bug32420"); + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_DROP)); + ok_con(hdbc1, SQLDisconnect(hdbc1)); + ok_con(hdbc1, SQLFreeHandle(SQL_HANDLE_DBC, hdbc1)); + + /* + Result cache is enabled. Need to check that cached results are not + broken + */ + sprintf(conn,"DRIVER={MySQL ODBC 3.51 Driver};USER=%s;PASSWORD=%s;" + "DATABASE=%s;SERVER=%s", + myuid, mypwd, mydb, myserver); + + if (mysock != NULL) + { + strcat((char *)conn, ";SOCKET="); + strcat((char *)conn, (char *)mysock); + } + + ok_env(henv, SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1)); + + ok_con(hdbc1, SQLDriverConnect(hdbc1, NULL, conn, sizeof(conn), conn_out, + sizeof(conn_out), &conn_out_len, + SQL_DRIVER_NOPROMPT)); + ok_con(hdbc1, SQLAllocStmt(hdbc1, &hstmt1)); + ok_stmt(hstmt1, SQLSetStmtAttr(hstmt1, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, 0)); + ok_sql(hstmt1, "drop table if exists bug32420"); + ok_sql(hstmt1, "CREATE TABLE bug32420 ("\ + "tt_int INT PRIMARY KEY auto_increment,"\ + "tt_varchar VARCHAR(128) NOT NULL)"); + ok_sql(hstmt1, "INSERT INTO bug32420 VALUES "\ + "(100, 'string 1'),"\ + "(200, 'string 2'),"\ + "(300, 'string 3'),"\ + "(400, 'string 4'),"\ + "(500, 'string 5'),"\ + "(600, 'string 6'),"\ + "(700, 'string 7'),"\ + "(800, 'string 8'),"\ + "(900, 'string 9'),"\ + "(910, 'string A'),"\ + "(920, 'string B')"); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + + ok_stmt(hstmt1, SQLSetStmtOption(hstmt1, SQL_ROWSET_SIZE, 4)); + + ok_sql(hstmt1, "select * from bug32420"); + ok_stmt(hstmt1, SQLBindCol(hstmt1, 1, SQL_C_LONG, nData, 0, NULL)); + ok_stmt(hstmt1, SQLBindCol(hstmt1, 2, SQL_C_CHAR, szData, sizeof(szData[0]), + NULL)); + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 100); + is_str(szData[0], "string 1", 8); + is_num(nData[1], 200); + is_str(szData[1], "string 2", 8); + is_num(nData[2], 300); + is_str(szData[2], "string 3", 8); + is_num(nData[3], 400); + is_str(szData[3], "string 4", 8); + + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 500); + is_str(szData[0], "string 5", 8); + is_num(nData[1], 600); + is_str(szData[1], "string 6", 8); + is_num(nData[2], 700); + is_str(szData[2], "string 7", 8); + is_num(nData[3], 800); + is_str(szData[3], "string 8", 8); + + /* + Now checking the last records when the result is shorter than + ROWSET_SIZE + */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_NEXT, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 3); + is_num(nData[0], 900); + is_str(szData[0], "string 9", 8); + is_num(nData[1], 910); + is_str(szData[1], "string A", 8); + is_num(nData[2], 920); + is_str(szData[2], "string B", 8); + + /* Dynamic cursor allows fetching first records */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_FIRST, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 100); + is_str(szData[0], "string 1", 8); + is_num(nData[1], 200); + is_str(szData[1], "string 2", 8); + is_num(nData[2], 300); + is_str(szData[2], "string 3", 8); + is_num(nData[3], 400); + is_str(szData[3], "string 4", 8); + + /* Fetching last records */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_LAST, 0, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 800); + is_str(szData[0], "string 8", 8); + is_num(nData[1], 900); + is_str(szData[1], "string 9", 8); + is_num(nData[2], 910); + is_str(szData[2], "string A", 8); + is_num(nData[3], 920); + is_str(szData[3], "string B", 8); + + /* Fetching with absolute offset */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_ABSOLUTE, 3, &row_count, + rgfRowStatus)); + + is_num(row_count, 4); + is_num(nData[0], 300); + is_str(szData[0], "string 3", 8); + is_num(nData[1], 400); + is_str(szData[1], "string 4", 8); + is_num(nData[2], 500); + is_str(szData[2], "string 5", 8); + is_num(nData[3], 600); + is_str(szData[3], "string 6", 8); + + /* Fetching with relative offset */ + ok_stmt(hstmt1, SQLExtendedFetch(hstmt1, SQL_FETCH_RELATIVE, 2, &row_count, + rgfRowStatus)); + + is_num(row_count, 3); + is_num(nData[0], 900); + is_str(szData[0], "string 9", 8); + is_num(nData[1], 910); + is_str(szData[1], "string A", 8); + is_num(nData[2], 920); + is_str(szData[2], "string B", 8); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + ok_sql(hstmt1, "drop table if exists bug32420"); + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_DROP)); + ok_con(hdbc1, SQLDisconnect(hdbc1)); + ok_con(hdbc1, SQLFreeHandle(SQL_HANDLE_DBC, hdbc1)); + + return OK; +} + + BEGIN_TESTS ADD_TEST(my_positioned_cursor) ADD_TEST(my_setpos_cursor) @@ -2636,6 +2893,7 @@ ADD_TEST(bug10563) ADD_TEST(bug6741) ADD_TEST(t_chunk) + ADD_TEST(t_bug32420) END_TESTS