diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7639f32353c..2e5b60d5f3f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -572,34 +572,42 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, if (open_and_lock_tables(thd, tables)) DBUG_RETURN(1); - - fix_tables_pointers(thd->lex.all_selects_list); - if (!result && !(result= new select_send())) + if (lex->describe) { - delete select_lex->having; - delete select_lex->where; - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + if (!(result= new select_send())) + { + send_error(thd, ER_OUT_OF_RESOURCES); + DBUG_RETURN(1); + } + if (send_prep_stmt(stmt, 0) || send_item_params(stmt)) + DBUG_RETURN(1); + } + else + { + fix_tables_pointers(thd->lex.all_selects_list); + if (!result && !(result= new select_send())) + { + delete select_lex->having; + delete select_lex->where; + send_error(thd, ER_OUT_OF_RESOURCES); + DBUG_RETURN(1); + } + + JOIN *join= new JOIN(thd, fields, select_options, result); + thd->used_tables= 0; // Updated by setup_fields + + if (join->prepare(&select_lex->ref_pointer_array, tables, + wild_num, conds, og_num, order, group, having, proc, + select_lex, unit, 0, 0)) + DBUG_RETURN(1); + + if (send_prep_stmt(stmt, fields.elements) || + thd->protocol_simple.send_fields(&fields, 0) || + send_item_params(stmt)) + DBUG_RETURN(1); + join->cleanup(thd); } - - JOIN *join= new JOIN(thd, fields, select_options, result); - thd->used_tables= 0; // Updated by setup_fields - - if (join->prepare(&select_lex->ref_pointer_array, tables, - wild_num, conds, og_num, order, group, having, proc, - select_lex, unit, 0, 0)) - DBUG_RETURN(1); - - /* - Currently return only column list info only, and we are not - sending any info on where clause. - */ - if (send_prep_stmt(stmt, fields.elements) || - thd->protocol_simple.send_fields(&fields, 0) || - send_item_params(stmt)) - DBUG_RETURN(1); - join->cleanup(thd); DBUG_RETURN(0); } diff --git a/tests/client_test.c b/tests/client_test.c index 4d8be29c525..bd2ec4930ef 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -5926,7 +5926,7 @@ static void test_field_misc() /* To test SET OPTION feature with prepare stmts - bug #85 + bug #85 (reported by mark@mysql.com) */ static void test_set_option() { @@ -5991,7 +5991,7 @@ static void test_set_option() /* To test a misc GRANT option - bug #89 + bug #89 (reported by mark@mysql.com) */ static void test_prepare_grant() { @@ -6084,8 +6084,8 @@ static void test_prepare_grant() /* To test a crash when invalid/corrupted .frm is used in the - SHOW TABLE STATUS (in debug mode) - bug #93 + SHOW TABLE STATUS + bug #93 (reported by serg@mysql.com). */ static void test_frm_bug() { @@ -6167,6 +6167,215 @@ static void test_frm_bug() mysql_query(mysql,"drop table if exists test_frm_bug"); } +/* + To test DECIMAL conversion +*/ +static void test_decimal_bug() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[1]; + double data; + int rc; + my_bool is_null; + + myheader("test_decimal_bug"); + + mysql_autocommit(mysql, TRUE); + + rc= mysql_query(mysql,"drop table if exists test_decimal_bug"); + myquery(rc); + + rc = mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10,2))"); + myquery(rc); + + rc = mysql_query(mysql, "insert into test_decimal_bug value(8),(10.22),(5.61)"); + myquery(rc); + + stmt = mysql_prepare(mysql,"select c1 from test_decimal_bug where c1= ?",50); + mystmt_init(stmt); + + bind[0].buffer_type= MYSQL_TYPE_DOUBLE; + bind[0].buffer= (char *)&data; + bind[0].buffer_length= 0; + bind[0].is_null= &is_null; + bind[0].length= 0; + + is_null= 0; + rc = mysql_bind_param(stmt, bind); + mystmt(stmt,rc); + + data= 8.0; + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + data=0; + rc = mysql_bind_result(stmt, bind); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + fprintf(stdout, "\n data: %g", data); + myassert(data == 8.0); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + + data= 5.61; + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + data=0; + rc = mysql_bind_result(stmt, bind); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + fprintf(stdout, "\n data: %g", data); + myassert(data == 5.61); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + + is_null= 1; + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + + data= 10.22; is_null= 0; + rc = mysql_execute(stmt); + mystmt(stmt,rc); + + data=0; + rc = mysql_bind_result(stmt, bind); + mystmt(stmt,rc); + + rc = mysql_fetch(stmt); + mystmt(stmt,rc); + + fprintf(stdout, "\n data: %g", data); + myassert(data == 10.22); + + rc = mysql_fetch(stmt); + myassert(rc == MYSQL_NO_DATA); + + mysql_stmt_close(stmt); +} + + +/* + To test EXPLAIN bug + bug #115 (reported by mark@mysql.com & georg@php.net). +*/ + +static void test_explain_bug() +{ + MYSQL_STMT *stmt; + MYSQL_RES *result; + int rc; + + myheader("test_explain_bug"); + + mysql_autocommit(mysql,TRUE); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS test_explain"); + myquery(rc); + + rc = mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))"); + myquery(rc); + + stmt = mysql_prepare(mysql, "explain test_explain", 30); + mystmt_init(stmt); + + rc = mysql_execute(stmt); + mystmt(stmt, rc); + + myassert( 2 == my_process_stmt_result(stmt)); + + result = mysql_prepare_result(stmt); + mytest(result); + + fprintf(stdout, "\n total fields in the result: %d", + mysql_num_fields(result)); + myassert(7 == mysql_num_fields(result)); + + verify_prepare_field(result,0,"Field","",MYSQL_TYPE_STRING, + "","","",NAME_LEN); + + verify_prepare_field(result,1,"Type","",MYSQL_TYPE_STRING, + "","","",40); + + verify_prepare_field(result,2,"Collation","",MYSQL_TYPE_STRING, + "","","",40); + + verify_prepare_field(result,3,"Null","",MYSQL_TYPE_STRING, + "","","",1); + + verify_prepare_field(result,4,"Key","",MYSQL_TYPE_STRING, + "","","",3); + + verify_prepare_field(result,5,"Default","",MYSQL_TYPE_STRING, + "","","",NAME_LEN); + + verify_prepare_field(result,6,"Extra","",MYSQL_TYPE_STRING, + "","","",20); + + mysql_free_result(result); + mysql_stmt_close(stmt); + + stmt = mysql_prepare(mysql, "explain select id, name FROM test_explain", 50); + mystmt_init(stmt); + + rc = mysql_execute(stmt); + mystmt(stmt, rc); + + myassert( 1 == my_process_stmt_result(stmt)); + + result = mysql_prepare_result(stmt); + mytest(result); + + fprintf(stdout, "\n total fields in the result: %d", + mysql_num_fields(result)); + myassert(10 == mysql_num_fields(result)); + + verify_prepare_field(result,0,"id","",MYSQL_TYPE_LONGLONG, + "","","",3); + + verify_prepare_field(result,1,"select_type","",MYSQL_TYPE_STRING, + "","","",19); + + verify_prepare_field(result,2,"table","",MYSQL_TYPE_STRING, + "","","",NAME_LEN); + + verify_prepare_field(result,3,"type","",MYSQL_TYPE_STRING, + "","","",10); + + verify_prepare_field(result,4,"possible_keys","",MYSQL_TYPE_STRING, + "","","",NAME_LEN*32); + + verify_prepare_field(result,5,"key","",MYSQL_TYPE_STRING, + "","","",NAME_LEN); + + verify_prepare_field(result,6,"key_len","",MYSQL_TYPE_LONGLONG, + "","","",3); + + verify_prepare_field(result,7,"ref","",MYSQL_TYPE_STRING, + "","","",NAME_LEN*16); + + verify_prepare_field(result,8,"rows","",MYSQL_TYPE_LONGLONG, + "","","",10); + + verify_prepare_field(result,9,"Extra","",MYSQL_TYPE_STRING, + "","","",255); + + mysql_free_result(result); + mysql_stmt_close(stmt); +} + + /* Read and parse arguments and MySQL options from my.cnf @@ -6385,10 +6594,12 @@ int main(int argc, char **argv) test_ushort_bug(); /* test a simple conv bug from php */ test_sshort_bug(); /* test a simple conv bug from php */ test_stiny_bug(); /* test a simple conv bug from php */ - test_field_misc(); /* check the field info for misc case, bug: #74 */ + test_field_misc(); /* check the field info for misc case, bug: #74 */ test_set_option(); /* test the SET OPTION feature, bug #85 */ test_prepare_grant(); /* to test the GRANT command, bug #89 */ test_frm_bug(); /* test the crash when .frm is invalid, bug #93 */ + test_explain_bug(); /* test for the EXPLAIN, bug #115 */ + test_decimal_bug(); /* test for the decimal bug */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time);