diff options
-rw-r--r-- | mysql-test/r/ps.result | 18 | ||||
-rw-r--r-- | mysql-test/t/ps.test | 15 | ||||
-rw-r--r-- | sql/sql_class.cc | 9 | ||||
-rw-r--r-- | sql/sql_derived.cc | 48 | ||||
-rw-r--r-- | sql/table.cc | 3 | ||||
-rw-r--r-- | sql/table.h | 6 |
6 files changed, 96 insertions, 3 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 3fed0a5b0d1..209d3d85108 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -4316,4 +4316,22 @@ set join_cache_level=@join_cache_level_save; deallocate prepare stmt; drop view v1,v2,v3; drop table t1,t2,t3; +# +# MDEV-10657: incorrect result returned with binary protocol +# (prepared statements) +# +create table t1 (code varchar(10) primary key); +INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3'); +SELECT X.* +FROM +(SELECT CODE, RN +FROM +(SELECT A.CODE, @cnt := @cnt + 1 AS RN +FROM t1 A, (SELECT @cnt := 0) C) T +) X; +CODE RN +LINE1 1 +LINE2 2 +LINE3 3 +drop table t1; # End of 5.5 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 4431f722ae0..ea67e1074f9 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3843,4 +3843,19 @@ deallocate prepare stmt; drop view v1,v2,v3; drop table t1,t2,t3; +--echo # +--echo # MDEV-10657: incorrect result returned with binary protocol +--echo # (prepared statements) +--echo # + +create table t1 (code varchar(10) primary key); +INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3'); +SELECT X.* +FROM + (SELECT CODE, RN + FROM + (SELECT A.CODE, @cnt := @cnt + 1 AS RN + FROM t1 A, (SELECT @cnt := 0) C) T + ) X; +drop table t1; --echo # End of 5.5 tests diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 00d860e7887..b007729494e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2192,6 +2192,8 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, MEM_ROOT *runtime_memroot) { Item_change_record *change; + DBUG_ENTER("THD::nocheck_register_item_tree_change"); + DBUG_PRINT("enter", ("Register %p <- %p", old_value, (*place))); /* Now we use one node per change, which adds some memory overhead, but still is rather fast as we use alloc_root for allocations. @@ -2204,12 +2206,13 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, OOM, thd->fatal_error() is called by the error handler of the memroot. Just return. */ - return; + DBUG_VOID_RETURN; } change= new (change_mem) Item_change_record; change->place= place; change->old_value= old_value; change_list.append(change); + DBUG_VOID_RETURN; } /** @@ -2250,7 +2253,11 @@ void THD::rollback_item_tree_changes() DBUG_ENTER("rollback_item_tree_changes"); while ((change= it++)) + { + DBUG_PRINT("info", ("revert %p -> %p", + change->old_value, (*change->place))); *change->place= change->old_value; + } /* We can forget about changes memory: it's allocated in runtime memroot */ change_list.empty(); DBUG_VOID_RETURN; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 6cd4547aaf9..2a6d82c161a 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -361,6 +361,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX *parent_lex= derived->select_lex; Query_arena *arena, backup; DBUG_ENTER("mysql_derived_merge"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (derived->merged) DBUG_RETURN(FALSE); @@ -508,6 +511,9 @@ unconditional_materialization: bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_merge_for_insert"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (derived->merged_for_insert) DBUG_RETURN(FALSE); if (derived->init_derived(thd, FALSE)) @@ -554,6 +560,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived) { SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_init"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); // Skip already prepared views/DT if (!unit || unit->prepared) @@ -624,7 +633,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_prepare"); bool res= FALSE; - DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit)); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); // Skip already prepared views/DT if (!unit || unit->prepared || @@ -781,6 +792,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) bool res= FALSE; DBUG_ENTER("mysql_derived_optimize"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (unit->optimized) DBUG_RETURN(FALSE); @@ -846,6 +860,9 @@ err: bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_create"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); TABLE *table= derived->table; SELECT_LEX_UNIT *unit= derived->get_unit(); @@ -895,9 +912,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) { - DBUG_ENTER("mysql_derived_fill"); + Field_iterator_table field_iterator; SELECT_LEX_UNIT *unit= derived->get_unit(); bool res= FALSE; + DBUG_ENTER("mysql_derived_fill"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); if (unit->executed && !unit->uncacheable && !unit->describe) DBUG_RETURN(FALSE); @@ -937,7 +958,27 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) if (derived_result->flush()) res= TRUE; unit->executed= TRUE; + + if (derived->field_translation) + { + /* reset translation table to materialized table */ + field_iterator.set_table(derived->table); + for (uint i= 0; + !field_iterator.end_of_fields(); + field_iterator.next(), i= i + 1) + { + Item *item; + + if (!(item= field_iterator.create_item(thd))) + { + res= TRUE; + break; + } + thd->change_item_tree(&derived->field_translation[i].item, item); + } + } } + if (res || !lex->describe) unit->cleanup(); lex->current_select= save_current_select; @@ -966,6 +1007,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived) bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) { DBUG_ENTER("mysql_derived_reinit"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (derived->alias ? derived->alias : "<NULL>"), + derived->get_unit())); st_select_lex_unit *unit= derived->get_unit(); if (derived->table) diff --git a/sql/table.cc b/sql/table.cc index fbcd91f5326..9cade76cb78 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4108,6 +4108,9 @@ bool TABLE_LIST::create_field_translation(THD *thd) Query_arena *arena, backup; bool res= FALSE; DBUG_ENTER("TABLE_LIST::create_field_translation"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); if (thd->stmt_arena->is_conventional() || thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) diff --git a/sql/table.h b/sql/table.h index c981243f28c..98f8c7ad73f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2107,6 +2107,9 @@ struct TABLE_LIST inline void set_merged_derived() { DBUG_ENTER("set_merged_derived"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); derived_type= ((derived_type & DTYPE_MASK) | DTYPE_TABLE | DTYPE_MERGE); set_check_merged(); @@ -2119,6 +2122,9 @@ struct TABLE_LIST void set_materialized_derived() { DBUG_ENTER("set_materialized_derived"); + DBUG_PRINT("enter", ("Alias: '%s' Unit: %p", + (alias ? alias : "<NULL>"), + get_unit())); derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) | DTYPE_TABLE | DTYPE_MATERIALIZE); set_check_materialized(); |