mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
fixed union with prepared statement bug found by Konstantin
This commit is contained in:
@@ -1004,6 +1004,7 @@ void st_select_lex_unit::init_query()
|
|||||||
table= 0;
|
table= 0;
|
||||||
fake_select_lex= 0;
|
fake_select_lex= 0;
|
||||||
cleaned= 0;
|
cleaned= 0;
|
||||||
|
item_list.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_query()
|
void st_select_lex::init_query()
|
||||||
|
@@ -226,14 +226,24 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
|
|
||||||
thd_arg->lex->current_select= lex_select_save;
|
thd_arg->lex->current_select= lex_select_save;
|
||||||
{
|
{
|
||||||
|
Statement *stmt= thd->current_statement;
|
||||||
|
Statement backup;
|
||||||
|
if (stmt)
|
||||||
|
thd->set_n_backup_item_arena(stmt, &backup);
|
||||||
Field **field;
|
Field **field;
|
||||||
for (field= table->field; *field; field++)
|
for (field= table->field; *field; field++)
|
||||||
{
|
{
|
||||||
Item_field *item= new Item_field(*field);
|
Item_field *item= new Item_field(*field);
|
||||||
if (!item || item_list.push_back(item))
|
if (!item || item_list.push_back(item))
|
||||||
|
{
|
||||||
|
if (stmt)
|
||||||
|
thd->restore_backup_item_arena(stmt, &backup);
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stmt)
|
||||||
|
thd->restore_backup_item_arena(stmt, &backup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
first_select->braces= 0; // remove our changes
|
first_select->braces= 0; // remove our changes
|
||||||
@@ -427,7 +437,7 @@ int st_select_lex_unit::cleanup()
|
|||||||
{
|
{
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
cleaned= 0;
|
cleaned= 1;
|
||||||
|
|
||||||
if (union_result)
|
if (union_result)
|
||||||
{
|
{
|
||||||
@@ -461,9 +471,11 @@ void st_select_lex_unit::reinit_exec_mechanism()
|
|||||||
{
|
{
|
||||||
prepared= optimized= executed= 0;
|
prepared= optimized= executed= 0;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
if (first_select()->next_select())
|
||||||
|
{
|
||||||
List_iterator_fast<Item> it(item_list);
|
List_iterator_fast<Item> it(item_list);
|
||||||
Item_field *field;
|
Item *field;
|
||||||
while ((field= (Item_field *)it++))
|
while ((field= it++))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
we can't cleanup here, because it broke link to temporary table field,
|
we can't cleanup here, because it broke link to temporary table field,
|
||||||
@@ -472,5 +484,6 @@ void st_select_lex_unit::reinit_exec_mechanism()
|
|||||||
*/
|
*/
|
||||||
field->fixed= 0;
|
field->fixed= 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -160,7 +160,10 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
|
|||||||
MYSQL_STMT *STDCALL
|
MYSQL_STMT *STDCALL
|
||||||
mysql_simple_prepare(MYSQL *mysql, const char *query)
|
mysql_simple_prepare(MYSQL *mysql, const char *query)
|
||||||
{
|
{
|
||||||
return mysql_prepare(mysql, query, strlen(query));
|
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
|
||||||
|
if (mysql_stmt_prepare(stmt, query, strlen(query)))
|
||||||
|
return 0;
|
||||||
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -8377,6 +8380,58 @@ static void test_subqueries_ref()
|
|||||||
myquery(rc);
|
myquery(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_union()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
myheader("test_union");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"CREATE TABLE t1 "
|
||||||
|
"(id INTEGER NOT NULL PRIMARY KEY, "
|
||||||
|
" name VARCHAR(20) NOT NULL)");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"INSERT INTO t1 (id, name) VALUES "
|
||||||
|
"(2, 'Ja'), (3, 'Ede'), "
|
||||||
|
"(4, 'Haag'), (5, 'Kabul'), "
|
||||||
|
"(6, 'Almere'), (7, 'Utrecht'), "
|
||||||
|
"(8, 'Qandahar'), (9, 'Amsterdam'), "
|
||||||
|
"(10, 'Amersfoort'), (11, 'Constantine')");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"CREATE TABLE t2 "
|
||||||
|
"(id INTEGER NOT NULL PRIMARY KEY, "
|
||||||
|
" name VARCHAR(20) NOT NULL)");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"INSERT INTO t2 (id, name) VALUES "
|
||||||
|
"(4, 'Guam'), (5, 'Aruba'), "
|
||||||
|
"(6, 'Angola'), (7, 'Albania'), "
|
||||||
|
"(8, 'Anguilla'), (9, 'Argentina'), "
|
||||||
|
"(10, 'Azerbaijan'), (11, 'Afghanistan'), "
|
||||||
|
"(12, 'Burkina Faso'), (13, 'Faroe Islands')");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_simple_prepare(mysql,
|
||||||
|
"SELECT t1.name FROM t1 UNION "
|
||||||
|
"SELECT t2.name FROM t2");
|
||||||
|
mystmt_init(stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
mystmt(stmt,rc);
|
||||||
|
assert(20 == my_process_stmt_result(stmt));
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@@ -8634,8 +8689,7 @@ int main(int argc, char **argv)
|
|||||||
test_distinct(); /* distinct aggregate functions */
|
test_distinct(); /* distinct aggregate functions */
|
||||||
test_subqueries_ref(); /* outer reference in subqueries converted
|
test_subqueries_ref(); /* outer reference in subqueries converted
|
||||||
Item_field -> Item_ref */
|
Item_field -> Item_ref */
|
||||||
|
test_union(); /* test union with prepared statements */
|
||||||
|
|
||||||
|
|
||||||
end_time= time((time_t *)0);
|
end_time= time((time_t *)0);
|
||||||
total_time+= difftime(end_time, start_time);
|
total_time+= difftime(end_time, start_time);
|
||||||
|
Reference in New Issue
Block a user