=== modified file 'ChangeLog' --- ChangeLog 2010-10-01 21:29:56 +0000 +++ ChangeLog 2010-10-09 09:47:45 +0000 @@ -14,6 +14,8 @@ * MSI installer does not set InstallLocation value in registry. (Bug #56978) * SQLProcedureColumns doesn't work with certain data/parameters combinations. (Bug #57182) + * SQLRowCount return wrong result row count for SQLTables and some other + catalog functions. (Bug #57182) ---- === modified file 'driver/catalog.c' --- driver/catalog.c 2010-10-01 21:29:56 +0000 +++ driver/catalog.c 2010-10-08 16:37:19 +0000 @@ -105,7 +105,7 @@ } stmt->fake_result= 1; - set_rows_count(stmt, rowcnt); + set_row_count(stmt, rowcnt); mysql_link_fields(stmt, fields, fldcnt); @@ -582,7 +582,7 @@ assert(pos - buff < sizeof(buff)); - if( !SQL_SUCCEEDED(rc= MySQLPrepare(hstmt, (SQLCHAR *)buff, SQL_NTS, FALSE))) + if( !SQL_SUCCEEDED(rc= MySQLPrepare(hstmt, (SQLCHAR *)buff, (SQLINTEGER)(pos - buff), FALSE))) return rc; return my_SQLExecute(stmt); === modified file 'driver/catalog_no_i_s.c' --- driver/catalog_no_i_s.c 2010-10-01 21:29:56 +0000 +++ driver/catalog_no_i_s.c 2010-10-09 10:09:57 +0000 @@ -489,7 +489,7 @@ mysql_free_result(table_res); } - stmt->result->row_count= rows; + set_row_count(stmt, rows); mysql_link_fields(stmt, SQLCOLUMNS_fields, SQLCOLUMNS_FIELDS); return SQL_SUCCESS; @@ -668,8 +668,10 @@ data+= SQLTABLES_PRIV_FIELDS; } } - stmt->result->row_count= row_count; + + set_row_count(stmt, row_count); mysql_link_fields(stmt,SQLTABLES_priv_fields,SQLTABLES_PRIV_FIELDS); + return SQL_SUCCESS; } @@ -815,7 +817,7 @@ data+= SQLCOLUMNS_PRIV_FIELDS; } } - stmt->result->row_count= row_count; + set_row_count(stmt, row_count); mysql_link_fields(stmt,SQLCOLUMNS_priv_fields,SQLCOLUMNS_PRIV_FIELDS); return SQL_SUCCESS; } @@ -844,7 +846,7 @@ { MYSQL *mysql= &stmt->dbc->mysql; /** @todo determine real size for buffer */ - char buff[255], *to; + char buff[36 + 4*NAME_LEN + 1], *to; to= strmov(buff, "SHOW TABLE STATUS "); if (catalog && *catalog) @@ -876,8 +878,12 @@ MYLOG_QUERY(stmt, buff); - if (mysql_query(mysql,buff)) + assert(to - buff < sizeof(buff)); + + if (mysql_real_query(mysql,buff,(unsigned long)(to - buff))) + { return NULL; + } return mysql_store_result(mysql); } @@ -1096,7 +1102,7 @@ return handle_connection_error(stmt); } - stmt->result->row_count= row_count; + set_row_count(stmt, row_count); mysql_link_fields(stmt,SQLFORE_KEYS_fields,SQLFORE_KEYS_FIELDS); return SQL_SUCCESS; @@ -1198,8 +1204,8 @@ data+= SQLPRIM_KEYS_FIELDS; } } - stmt->result->row_count= row_count; + set_row_count(stmt, row_count); mysql_link_fields(stmt,SQLPRIM_KEYS_fields,SQLPRIM_KEYS_FIELDS); return SQL_SUCCESS; @@ -1647,7 +1653,7 @@ } } - set_rows_count(stmt, return_params_num); + set_row_count(stmt, return_params_num); mysql_link_fields(stmt, SQLPROCEDURECOLUMNS_fields, SQLPROCEDURECOLUMNS_FIELDS); @@ -1969,11 +1975,15 @@ prev= &pos->next; } else + { --stmt->result->row_count; } + } (*prev)= 0; mysql_data_seek(stmt->result,0); /* Restore pointer */ } + + set_row_count(stmt, stmt->result->row_count); mysql_link_fields(stmt,SQLSTAT_fields,SQLSTAT_FIELDS); return SQL_SUCCESS; @@ -2193,7 +2203,7 @@ data+= SQLTABLES_FIELDS; } - stmt->result->row_count= row_count; + set_row_count(stmt, row_count); } mysql_link_fields(stmt, SQLTABLES_fields, SQLTABLES_FIELDS); === modified file 'driver/myutil.h' --- driver/myutil.h 2010-10-01 21:29:56 +0000 +++ driver/myutil.h 2010-10-06 15:01:39 +0000 @@ -313,7 +313,7 @@ int proc_get_param_sql_type_index(SQLCHAR *ptype, int len); SQLTypeMap *proc_get_param_map_by_index(int index); char *proc_param_next_token(char *str, char *str_end); -void set_rows_count(STMT * stmt, my_ulonglong rows); +void set_row_count(STMT * stmt, my_ulonglong rows); #ifdef __WIN__ #define cmp_database(A,B) myodbc_strcasecmp((const char *)(A),(const char *)(B)) === modified file 'driver/utility.c' --- driver/utility.c 2010-10-01 21:29:56 +0000 +++ driver/utility.c 2010-10-06 15:01:39 +0000 @@ -3418,7 +3418,7 @@ number of affected rows for constructed resulsets. Setting mysql.affected_rows is required for SQLRowCount to return correct data for such resultsets. */ -void set_rows_count(STMT *stmt, my_ulonglong rows) +void set_row_count(STMT *stmt, my_ulonglong rows) { if (stmt != NULL && stmt->result != NULL) { === modified file 'test/my_catalog.c' --- test/my_catalog.c 2010-10-01 21:29:56 +0000 +++ test/my_catalog.c 2010-10-09 09:36:02 +0000 @@ -26,6 +26,7 @@ DECLARE_TEST(my_columns_null) { + SQLLEN rowCount= 0; /* initialize data */ ok_sql(hstmt,"drop table if exists my_column_null"); @@ -37,6 +38,10 @@ (SQLCHAR *)"my_column_null", SQL_NTS, NULL, SQL_NTS)); + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); + + is_num(rowCount, 2); + is_num(2, my_print_non_format_result(hstmt)); ok_stmt(hstmt, SQLFreeStmt(hstmt, SQL_CLOSE)); @@ -73,16 +78,22 @@ SQLCHAR database[100]; SQLRETURN rc; SQLINTEGER nrows; - SQLLEN lenOrNull; + SQLLEN lenOrNull, rowCount= 0; + ok_sql(hstmt, "DROP DATABASE IF EXISTS my_all_db_test1"); ok_sql(hstmt, "DROP DATABASE IF EXISTS my_all_db_test2"); ok_sql(hstmt, "DROP DATABASE IF EXISTS my_all_db_test3"); ok_sql(hstmt, "DROP DATABASE IF EXISTS my_all_db_test4"); - ok_stmt(hstmt, SQLTables(hstmt,(SQLCHAR *)"%",1,"",0,"",0,NULL,0)); + ok_stmt(hstmt, SQLTables(hstmt,(SQLCHAR *)SQL_ALL_CATALOGS,1,"",0,"",0,NULL,0)); + + /* Added calls to SQLRowCount just to have tests of it with SQLTAbles. */ + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); nrows = my_print_non_format_result(hstmt); + + is_num(rowCount, nrows) rc = SQLFreeStmt(hstmt, SQL_CLOSE); mystmt(hstmt,rc); @@ -97,7 +108,9 @@ rc = SQLTables(hstmt,(SQLCHAR *)"test",4,NULL,0,NULL,0,NULL,0); mystmt(hstmt,rc); - my_print_non_format_result(hstmt); + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); + is_num(rowCount, my_print_non_format_result(hstmt)); + rc = SQLFreeStmt(hstmt, SQL_CLOSE); mystmt(hstmt,rc); @@ -172,6 +185,9 @@ "", 0, "", 0, "", 0); mystmt(hstmt,rc); + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); + is_num(rowCount, 0); + is_num(my_print_non_format_result(hstmt), 0); rc = SQLFreeStmt(hstmt, SQL_CLOSE); mystmt(hstmt,rc); @@ -691,6 +707,7 @@ { SQLRETURN r; SQLINTEGER rows; + SQLLEN rowCount; ok_stmt(hstmt, SQLTables(hstmt,NULL,0,NULL,0,NULL,0,NULL,0)); @@ -710,9 +727,11 @@ r = SQLTables(hstmt, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR *)"TABLE", SQL_NTS); + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); + mystmt(hstmt,r); - myresult(hstmt); + is_num(myresult(hstmt), rowCount); r = SQLFreeStmt(hstmt, SQL_CLOSE); mystmt(hstmt,r); @@ -1526,7 +1545,7 @@ ok_stmt(hstmt, SQLDescribeCol(hstmt, 5, szColName, sizeof(szColName), &iName, &iType, &uiDef, &iScale, &iNullable)); - is_str(szColName, "REMARKS", 7); + is_str(szColName, "REMARKS", 8); is_num(iName, 7); if (iType != SQL_VARCHAR && iType != SQL_WVARCHAR) return FAIL; @@ -1629,9 +1648,9 @@ ok_sql(hstmt, "drop table if exists t_bug51422_r"); ok_sql(hstmt, "create table t_bug51422_r (id int unsigned not null primary key, ukey int unsigned not null," - "name varchar(10) not null, UNIQUE KEY uk(ukey))"); + "name varchar(10) not null, UNIQUE KEY uk(ukey)) ENGINE=InnoDB"); ok_sql(hstmt, "create table t_bug51422 (id int unsigned not null primary key, refid int unsigned not null," - "foreign key t_bug51422fk (id) references t_bug51422_r (ukey))"); + "foreign key t_bug51422fk (id) references t_bug51422_r (ukey)) ENGINE=InnoDB"); ok_stmt(hstmt, SQLForeignKeys(hstmt, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, (SQLCHAR *)"t_bug51422", SQL_NTS)); @@ -1659,7 +1678,7 @@ SQLLEN catalog_len, schema_len, table_len, column_len; SQLCHAR keyname[BUF_LEN]; SQLSMALLINT key_seq, i; - SQLLEN keyname_len, key_seq_len; + SQLLEN keyname_len, key_seq_len, rowCount; ok_sql(hstmt, "drop table if exists t_bug36441_0123456789"); ok_sql(hstmt, "create table t_bug36441_0123456789(" @@ -1671,6 +1690,10 @@ ok_stmt(hstmt, SQLPrimaryKeys(hstmt, NULL, SQL_NTS, NULL, SQL_NTS, "t_bug36441_0123456789", SQL_NTS)); + /* Test of SQLRowCount with SQLPrimaryKeys */ + ok_stmt(hstmt, SQLRowCount(hstmt, &rowCount)); + is_num(rowCount, 2); + ok_stmt(hstmt, SQLBindCol(hstmt, 1, SQL_C_CHAR , catalog, sizeof(catalog), &catalog_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 2, SQL_C_CHAR , schema , sizeof(schema) , &schema_len)); ok_stmt(hstmt, SQLBindCol(hstmt, 3, SQL_C_CHAR , table , sizeof(table) , &table_len)); @@ -2167,8 +2190,116 @@ } -BEGIN_TESTS +/* SQLRowCount() doesn't work with SQLTables and other functions + Testing of that with SQLTables, SQLColumn is incorporated in other testcases +*/ +DECLARE_TEST(t_bug55870) +{ + SQLLEN rowCount; + SQLCHAR noI_SconnStr[256], query[256]; + HDBC hdbc1; + HSTMT hstmt1; + + ok_sql(hstmt, "drop table if exists bug55870r"); + ok_sql(hstmt, "drop table if exists bug55870_2"); + ok_sql(hstmt, "drop table if exists bug55870"); + ok_sql(hstmt, "create table bug55870(a int not null primary key, " + "b varchar(20) not null, c varchar(100) not null, INDEX(b)) ENGINE=InnoDB"); + + /* There should be no problems with I_S version of SQLTablePrivileges. Thus need connection + not using I_S. SQlStatistics doesn't have I_S version, but it ma change at certain point. + Thus let's test it on NO_I_S connection too */ + ok_env(henv, SQLAllocConnect(henv, &hdbc1)); + + sprintf((char *)noI_SconnStr, "DSN=%s;UID=%s;PWD=%s; NO_I_S=1", mydsn, myuid, mypwd); + + if (mysock != NULL) + { + strcat((char *)noI_SconnStr, ";SOCKET="); + strcat((char *)noI_SconnStr, (char *)mysock); + } + + if (myport) + { + char pbuff[20]; + sprintf(pbuff, ";PORT=%d", myport); + strcat((char *)noI_SconnStr, pbuff); + } + + sprintf(query, "grant Insert, Select on bug55870 to %s", myuid); + ok_stmt(hstmt, SQLExecDirect(hstmt, query, SQL_NTS)); + sprintf(query, "grant Insert (c), Select (c), Update (c) on bug55870 to %s", myuid); + ok_stmt(hstmt, SQLExecDirect(hstmt, query, SQL_NTS)); + + ok_con(hdbc1, SQLDriverConnect(hdbc1, NULL, noI_SconnStr, sizeof(noI_SconnStr), NULL, + 0, NULL, SQL_DRIVER_NOPROMPT)); + ok_con(hdbc1, SQLAllocStmt(hdbc1, &hstmt1)); + + ok_stmt(hstmt1, SQLStatistics(hstmt1, NULL, 0, NULL, 0, + "bug55870", SQL_NTS, + SQL_INDEX_UNIQUE, SQL_QUICK)); + ok_stmt(hstmt1, SQLRowCount(hstmt1, &rowCount)); + is_num(rowCount, 1); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + + ok_stmt(hstmt1, SQLTablePrivileges(hstmt1, "test", SQL_NTS, 0, 0, "bug55870", + SQL_NTS)); + + ok_stmt(hstmt1, SQLRowCount(hstmt1, &rowCount)); + is_num(rowCount, my_print_non_format_result(hstmt1)); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + + ok_stmt(hstmt1, SQLColumnPrivileges(hstmt1, "test", SQL_NTS, 0, 0, "bug55870", + SQL_NTS, "c", SQL_NTS)); + + ok_stmt(hstmt1, SQLRowCount(hstmt1, &rowCount)); + is_num(rowCount, my_print_non_format_result(hstmt1)); + + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); + + ok_sql(hstmt, "create table bug55870_2 (id int not null primary key, value " + "varchar(255) not null) ENGINE=InnoDB"); + ok_sql(hstmt, "create table bug55870r (id int unsigned not null primary key," + "refid int not null, refid2 int not null," + "somevalue varchar(20) not null, foreign key b55870fk1 (refid) " + "references bug55870 (a), foreign key b55870fk2 (refid2) " + "references bug55870_2 (id)) ENGINE=InnoDB"); + + /* actually... looks like no-i_s version of SQLForeignKeys is broken on latest + server versions. comment in "show table status..." contains nothing */ + ok_stmt(hstmt1, SQLForeignKeys(hstmt1, NULL, 0, NULL, 0, NULL, 0, NULL, 0, + NULL, 0, (SQLCHAR *)"bug55870r", SQL_NTS)); + + ok_stmt(hstmt1, SQLRowCount(hstmt1, &rowCount)); + is_num(rowCount, my_print_non_format_result(hstmt1)); + + /** surprise-surprise - just removing table is not enough to remove related + records from tables_priv and columns_priv + */ + sprintf(query, "revoke select,insert on bug55870 from %s", myuid); + ok_stmt(hstmt, SQLExecDirect(hstmt, query, SQL_NTS)); + + sprintf(query, "revoke select (c),insert (c),update (c) on bug55870 from %s", myuid); + ok_stmt(hstmt, SQLExecDirect(hstmt, query, SQL_NTS)); + + /* + ok_sql(hstmt, "drop table if exists bug55870r"); + ok_sql(hstmt, "drop table if exists bug55870_2"); + ok_sql(hstmt, "drop table if exists bug55870");*/ + + + 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_columns_null) ADD_TEST(my_drop_table) ADD_TEST(my_table_dbs) @@ -2208,6 +2339,7 @@ ADD_TEST(t_bug50195) ADD_TEST(t_sqlprocedurecolumns) ADD_TEST(t_bug57182) + ADD_TEST(t_bug55870) END_TESTS