Skip to content

Commit 462808f

Browse files
Oleksandr Byelkinsanja-byelkin
authored andcommitted
MDEV-10657: incorrect result returned with binary protocol (prepared statements)
If translation table present when we materialize the derived table then change it to point to the materialized table. Added debug info to see really what happens with what derived.
1 parent 924db8b commit 462808f

File tree

6 files changed

+96
-3
lines changed

6 files changed

+96
-3
lines changed

mysql-test/r/ps.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4316,4 +4316,22 @@ set join_cache_level=@join_cache_level_save;
43164316
deallocate prepare stmt;
43174317
drop view v1,v2,v3;
43184318
drop table t1,t2,t3;
4319+
#
4320+
# MDEV-10657: incorrect result returned with binary protocol
4321+
# (prepared statements)
4322+
#
4323+
create table t1 (code varchar(10) primary key);
4324+
INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3');
4325+
SELECT X.*
4326+
FROM
4327+
(SELECT CODE, RN
4328+
FROM
4329+
(SELECT A.CODE, @cnt := @cnt + 1 AS RN
4330+
FROM t1 A, (SELECT @cnt := 0) C) T
4331+
) X;
4332+
CODE RN
4333+
LINE1 1
4334+
LINE2 2
4335+
LINE3 3
4336+
drop table t1;
43194337
# End of 5.5 tests

mysql-test/t/ps.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,4 +3843,19 @@ deallocate prepare stmt;
38433843
drop view v1,v2,v3;
38443844
drop table t1,t2,t3;
38453845

3846+
--echo #
3847+
--echo # MDEV-10657: incorrect result returned with binary protocol
3848+
--echo # (prepared statements)
3849+
--echo #
3850+
3851+
create table t1 (code varchar(10) primary key);
3852+
INSERT INTO t1(code) VALUES ('LINE1'), ('LINE2'), ('LINE3');
3853+
SELECT X.*
3854+
FROM
3855+
(SELECT CODE, RN
3856+
FROM
3857+
(SELECT A.CODE, @cnt := @cnt + 1 AS RN
3858+
FROM t1 A, (SELECT @cnt := 0) C) T
3859+
) X;
3860+
drop table t1;
38463861
--echo # End of 5.5 tests

sql/sql_class.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2192,6 +2192,8 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value,
21922192
MEM_ROOT *runtime_memroot)
21932193
{
21942194
Item_change_record *change;
2195+
DBUG_ENTER("THD::nocheck_register_item_tree_change");
2196+
DBUG_PRINT("enter", ("Register %p <- %p", old_value, (*place)));
21952197
/*
21962198
Now we use one node per change, which adds some memory overhead,
21972199
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,
22042206
OOM, thd->fatal_error() is called by the error handler of the
22052207
memroot. Just return.
22062208
*/
2207-
return;
2209+
DBUG_VOID_RETURN;
22082210
}
22092211
change= new (change_mem) Item_change_record;
22102212
change->place= place;
22112213
change->old_value= old_value;
22122214
change_list.append(change);
2215+
DBUG_VOID_RETURN;
22132216
}
22142217

22152218
/**
@@ -2250,7 +2253,11 @@ void THD::rollback_item_tree_changes()
22502253
DBUG_ENTER("rollback_item_tree_changes");
22512254

22522255
while ((change= it++))
2256+
{
2257+
DBUG_PRINT("info", ("revert %p -> %p",
2258+
change->old_value, (*change->place)));
22532259
*change->place= change->old_value;
2260+
}
22542261
/* We can forget about changes memory: it's allocated in runtime memroot */
22552262
change_list.empty();
22562263
DBUG_VOID_RETURN;

sql/sql_derived.cc

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
361361
SELECT_LEX *parent_lex= derived->select_lex;
362362
Query_arena *arena, backup;
363363
DBUG_ENTER("mysql_derived_merge");
364+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
365+
(derived->alias ? derived->alias : "<NULL>"),
366+
derived->get_unit()));
364367

365368
if (derived->merged)
366369
DBUG_RETURN(FALSE);
@@ -508,6 +511,9 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
508511
bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
509512
{
510513
DBUG_ENTER("mysql_derived_merge_for_insert");
514+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
515+
(derived->alias ? derived->alias : "<NULL>"),
516+
derived->get_unit()));
511517
if (derived->merged_for_insert)
512518
DBUG_RETURN(FALSE);
513519
if (derived->init_derived(thd, FALSE))
@@ -554,6 +560,9 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived)
554560
{
555561
SELECT_LEX_UNIT *unit= derived->get_unit();
556562
DBUG_ENTER("mysql_derived_init");
563+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
564+
(derived->alias ? derived->alias : "<NULL>"),
565+
derived->get_unit()));
557566

558567
// Skip already prepared views/DT
559568
if (!unit || unit->prepared)
@@ -624,7 +633,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
624633
SELECT_LEX_UNIT *unit= derived->get_unit();
625634
DBUG_ENTER("mysql_derived_prepare");
626635
bool res= FALSE;
627-
DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit));
636+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
637+
(derived->alias ? derived->alias : "<NULL>"),
638+
derived->get_unit()));
628639

629640
// Skip already prepared views/DT
630641
if (!unit || unit->prepared ||
@@ -781,6 +792,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
781792

782793
bool res= FALSE;
783794
DBUG_ENTER("mysql_derived_optimize");
795+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
796+
(derived->alias ? derived->alias : "<NULL>"),
797+
derived->get_unit()));
784798

785799
if (unit->optimized)
786800
DBUG_RETURN(FALSE);
@@ -846,6 +860,9 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
846860
bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
847861
{
848862
DBUG_ENTER("mysql_derived_create");
863+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
864+
(derived->alias ? derived->alias : "<NULL>"),
865+
derived->get_unit()));
849866
TABLE *table= derived->table;
850867
SELECT_LEX_UNIT *unit= derived->get_unit();
851868

@@ -895,9 +912,13 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived)
895912

896913
bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
897914
{
898-
DBUG_ENTER("mysql_derived_fill");
915+
Field_iterator_table field_iterator;
899916
SELECT_LEX_UNIT *unit= derived->get_unit();
900917
bool res= FALSE;
918+
DBUG_ENTER("mysql_derived_fill");
919+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
920+
(derived->alias ? derived->alias : "<NULL>"),
921+
derived->get_unit()));
901922

902923
if (unit->executed && !unit->uncacheable && !unit->describe)
903924
DBUG_RETURN(FALSE);
@@ -937,7 +958,27 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
937958
if (derived_result->flush())
938959
res= TRUE;
939960
unit->executed= TRUE;
961+
962+
if (derived->field_translation)
963+
{
964+
/* reset translation table to materialized table */
965+
field_iterator.set_table(derived->table);
966+
for (uint i= 0;
967+
!field_iterator.end_of_fields();
968+
field_iterator.next(), i= i + 1)
969+
{
970+
Item *item;
971+
972+
if (!(item= field_iterator.create_item(thd)))
973+
{
974+
res= TRUE;
975+
break;
976+
}
977+
thd->change_item_tree(&derived->field_translation[i].item, item);
978+
}
979+
}
940980
}
981+
941982
if (res || !lex->describe)
942983
unit->cleanup();
943984
lex->current_select= save_current_select;
@@ -966,6 +1007,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
9661007
bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
9671008
{
9681009
DBUG_ENTER("mysql_derived_reinit");
1010+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
1011+
(derived->alias ? derived->alias : "<NULL>"),
1012+
derived->get_unit()));
9691013
st_select_lex_unit *unit= derived->get_unit();
9701014

9711015
if (derived->table)

sql/table.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4108,6 +4108,9 @@ bool TABLE_LIST::create_field_translation(THD *thd)
41084108
Query_arena *arena, backup;
41094109
bool res= FALSE;
41104110
DBUG_ENTER("TABLE_LIST::create_field_translation");
4111+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
4112+
(alias ? alias : "<NULL>"),
4113+
get_unit()));
41114114

41124115
if (thd->stmt_arena->is_conventional() ||
41134116
thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())

sql/table.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,9 @@ struct TABLE_LIST
21072107
inline void set_merged_derived()
21082108
{
21092109
DBUG_ENTER("set_merged_derived");
2110+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
2111+
(alias ? alias : "<NULL>"),
2112+
get_unit()));
21102113
derived_type= ((derived_type & DTYPE_MASK) |
21112114
DTYPE_TABLE | DTYPE_MERGE);
21122115
set_check_merged();
@@ -2119,6 +2122,9 @@ struct TABLE_LIST
21192122
void set_materialized_derived()
21202123
{
21212124
DBUG_ENTER("set_materialized_derived");
2125+
DBUG_PRINT("enter", ("Alias: '%s' Unit: %p",
2126+
(alias ? alias : "<NULL>"),
2127+
get_unit()));
21222128
derived_type= ((derived_type & (derived ? DTYPE_MASK : DTYPE_VIEW)) |
21232129
DTYPE_TABLE | DTYPE_MATERIALIZE);
21242130
set_check_materialized();

0 commit comments

Comments
 (0)