diff options
-rw-r--r-- | sql/sql_derived.cc | 64 | ||||
-rw-r--r-- | tests/client_test.c | 48 |
2 files changed, 83 insertions, 29 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 81269a8cbcf..2e2ad6786fc 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -148,36 +148,42 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, } derived_result->set_table(table); - - if (is_union) - { - // execute union without clean up - if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK))) - res= unit->exec(); - } - else + /* + if it is preparation PS only then we do not need real data and we + can skip execution (and parameters is not defined, too) + */ + if (!thd->current_statement) { - unit->offset_limit_cnt= first_select->offset_limit; - unit->select_limit_cnt= first_select->select_limit+ - first_select->offset_limit; - if (unit->select_limit_cnt < first_select->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; - if (unit->select_limit_cnt == HA_POS_ERROR) - first_select->options&= ~OPTION_FOUND_ROWS; - - lex->current_select= first_select; - res= mysql_select(thd, &first_select->ref_pointer_array, - (TABLE_LIST*) first_select->table_list.first, - first_select->with_wild, - first_select->item_list, first_select->where, - (first_select->order_list.elements+ - first_select->group_list.elements), - (ORDER *) first_select->order_list.first, - (ORDER *) first_select->group_list.first, - first_select->having, (ORDER*) NULL, - (first_select->options | thd->options | - SELECT_NO_UNLOCK), - derived_result, unit, first_select); + if (is_union) + { + // execute union without clean up + if (!(res= unit->prepare(thd, derived_result, SELECT_NO_UNLOCK))) + res= unit->exec(); + } + else + { + unit->offset_limit_cnt= first_select->offset_limit; + unit->select_limit_cnt= first_select->select_limit+ + first_select->offset_limit; + if (unit->select_limit_cnt < first_select->select_limit) + unit->select_limit_cnt= HA_POS_ERROR; + if (unit->select_limit_cnt == HA_POS_ERROR) + first_select->options&= ~OPTION_FOUND_ROWS; + + lex->current_select= first_select; + res= mysql_select(thd, &first_select->ref_pointer_array, + (TABLE_LIST*) first_select->table_list.first, + first_select->with_wild, + first_select->item_list, first_select->where, + (first_select->order_list.elements+ + first_select->group_list.elements), + (ORDER *) first_select->order_list.first, + (ORDER *) first_select->group_list.first, + first_select->having, (ORDER*) NULL, + (first_select->options | thd->options | + SELECT_NO_UNLOCK), + derived_result, unit, first_select); + } } if (!res) diff --git a/tests/client_test.c b/tests/client_test.c index 9c440460f9b..8de0767e5e3 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -8905,6 +8905,53 @@ static void test_bind_nagative() myquery(rc); } +static void test_derived() +{ + MYSQL_STMT *stmt; + int rc, i; + MYSQL_BIND bind[1]; + long my_val = 0L; + long my_length = 0L; + long my_null = 0L; + const char *query= + "select count(1) from (select f.id from t1 f where f.id=?) as x"; + + myheader("test_derived"); + + rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql,"create table t1 (id int(8), primary key (id)) \ +TYPE=InnoDB DEFAULT CHARSET=utf8"); + myquery(rc); + + rc= mysql_query(mysql, "insert into t1 values (1)"); + myquery(rc); + + stmt= mysql_prepare(mysql, query, strlen(query)); + mystmt_init(stmt); + + bind[0].buffer_type = FIELD_TYPE_LONG; + bind[0].buffer = (char *)&my_val; + bind[0].length = &my_length; + bind[0].is_null = (char*)&my_null; + my_val= 1; + rc= mysql_bind_param(stmt, bind); + mystmt(stmt,rc); + + for (i= 0; i < 3; i++) + { + rc= mysql_execute(stmt); + mystmt(stmt, rc); + assert(1 == my_process_stmt_result(stmt)); + } + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -9172,6 +9219,7 @@ int main(int argc, char **argv) test_multi(); /* test of multi delete & update */ test_insert_select(); /* test INSERT ... SELECT */ test_bind_nagative(); /* bind negative to unsigned BUG#3223 */ + test_derived(); /* derived table with parameter BUG#3020 */ end_time= time((time_t *)0); total_time+= difftime(end_time, start_time); |