mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
A fix and test case for Bug#6050 "EXECUTE stmt reports ambiguous field
names with ident. tables fr. diff. schemata": revise all uses of Item_field and make them prepared-statements friendly when necessary. mysql-test/r/ps.result: Test results fixed: the test case for Bug#6050 mysql-test/r/ps_1general.result: Test results fixed: in prepared statements we expand '*' to a list of fully qualified fields (db.table.column). mysql-test/t/ps.test: A test for Bug#6050 "EXECUTE stmt reports ambiguous fieldnames with ident. tables fr. diff. schemata" sql/item.cc: Revise all Item_field constructors: we need to make sure that no Item_field object points to unaccessible memory in prepared statements. sql/item.h: Revise all Item_field constructors: we need to make sure that no Item_field object points to unaccessible memory in prepared statements. sql/sql_base.cc: Item_field use changed to be prepared statements friendly. sql/sql_class.h: New check of Item_arena state. sql/sql_union.cc: Fixing the problem with name resolving in UNION and prepared statements: In case of SELECT a, b, c FROM t1 UNION SELECT a, b, c FROM t2 the list of selected items is represented as a List<Item_field>, where each Item_field points to a field of temporary table. But the temporary table is created anew on each execution of the prepared statement. So on each subsequent execution we should reset Item_field items to point to fields from freshly-created temporary table. sql/table.h: Comment TABLE member.
This commit is contained in:
@@ -266,14 +266,14 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
|
||||
if (first_select->next_select())
|
||||
{
|
||||
|
||||
// it is not single select
|
||||
/* This is not a single select */
|
||||
|
||||
/*
|
||||
Check that it was possible to aggregate
|
||||
all collations together for UNION.
|
||||
*/
|
||||
List_iterator_fast<Item> tp(types);
|
||||
Item_arena *arena= thd->current_arena;
|
||||
Item *type;
|
||||
while ((type= tp++))
|
||||
{
|
||||
@@ -305,7 +305,11 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
thd_arg->lex->current_select= lex_select_save;
|
||||
if (!item_list.elements)
|
||||
{
|
||||
Item_arena *arena= thd->current_arena, backup;
|
||||
/*
|
||||
We're in statement prepare or in execution
|
||||
of a conventional statement.
|
||||
*/
|
||||
Item_arena backup;
|
||||
if (arena->is_stmt_prepare())
|
||||
thd->set_n_backup_item_arena(arena, &backup);
|
||||
Field **field;
|
||||
@@ -345,6 +349,20 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
fake_select_lex->table_list.empty();
|
||||
}
|
||||
}
|
||||
else if (arena->is_stmt_execute())
|
||||
{
|
||||
/*
|
||||
We're in execution of a prepared statement: reset field items
|
||||
to point at fields from the created temporary table.
|
||||
*/
|
||||
List_iterator_fast<Item> it(item_list);
|
||||
for (Field **field= table->field; *field; field++)
|
||||
{
|
||||
Item_field *item_field= (Item_field*) it++;
|
||||
DBUG_ASSERT(item_field);
|
||||
item_field->set_field(*field);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
first_select->braces= 0; // remove our changes
|
||||
|
Reference in New Issue
Block a user