Loading mysql-test/r/ps.result +57 −0 Original line number Diff line number Diff line Loading @@ -563,3 +563,60 @@ execute stmt; execute stmt; deallocate prepare stmt; drop table t1; create table t1 ( id int(11) unsigned not null primary key auto_increment, partner_id varchar(35) not null, t1_status_id int(10) unsigned ); insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"), ("3", "partner3", "10"), ("4", "partner4", "10"); create table t2 ( id int(11) unsigned not null default '0', t1_line_id int(11) unsigned not null default '0', article_id varchar(20), sequence int(11) not null default '0', primary key (id,t1_line_id) ); insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"), ("2", "2", "sup", "2"), ("2", "3", "sup", "3"), ("2", "4", "imp", "4"), ("3", "1", "sup", "0"), ("4", "1", "sup", "0"); create table t3 ( id int(11) not null default '0', preceeding_id int(11) not null default '0', primary key (id,preceeding_id) ); create table t4 ( user_id varchar(50) not null, article_id varchar(20) not null, primary key (user_id,article_id) ); insert into t4 values("nicke", "imp"); prepare stmt from 'select distinct t1.partner_id from t1 left join t3 on t1.id = t3.id left join t1 pp on pp.id = t3.preceeding_id where exists ( select * from t2 as pl_inner where pl_inner.id = t1.id and pl_inner.sequence <= ( select min(sequence) from t2 pl_seqnr where pl_seqnr.id = t1.id ) and exists ( select * from t4 where t4.article_id = pl_inner.article_id and t4.user_id = ? ) ) and t1.id = ? group by t1.id having count(pp.id) = 0'; set @user_id = 'nicke'; set @id = '2'; execute stmt using @user_id, @id; partner_id execute stmt using @user_id, @id; partner_id mysql-test/t/ps.test +68 −0 Original line number Diff line number Diff line Loading @@ -581,3 +581,71 @@ execute stmt; execute stmt; deallocate prepare stmt; drop table t1; # # Bug#11458 "Prepared statement with subselects return random data": # drop PARAM_TABLE_BIT from the list of tables used by a subquery # create table t1 ( id int(11) unsigned not null primary key auto_increment, partner_id varchar(35) not null, t1_status_id int(10) unsigned ); insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"), ("3", "partner3", "10"), ("4", "partner4", "10"); create table t2 ( id int(11) unsigned not null default '0', t1_line_id int(11) unsigned not null default '0', article_id varchar(20), sequence int(11) not null default '0', primary key (id,t1_line_id) ); insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"), ("2", "2", "sup", "2"), ("2", "3", "sup", "3"), ("2", "4", "imp", "4"), ("3", "1", "sup", "0"), ("4", "1", "sup", "0"); create table t3 ( id int(11) not null default '0', preceeding_id int(11) not null default '0', primary key (id,preceeding_id) ); create table t4 ( user_id varchar(50) not null, article_id varchar(20) not null, primary key (user_id,article_id) ); insert into t4 values("nicke", "imp"); prepare stmt from 'select distinct t1.partner_id from t1 left join t3 on t1.id = t3.id left join t1 pp on pp.id = t3.preceeding_id where exists ( select * from t2 as pl_inner where pl_inner.id = t1.id and pl_inner.sequence <= ( select min(sequence) from t2 pl_seqnr where pl_seqnr.id = t1.id ) and exists ( select * from t4 where t4.article_id = pl_inner.article_id and t4.user_id = ? ) ) and t1.id = ? group by t1.id having count(pp.id) = 0'; set @user_id = 'nicke'; set @id = '2'; execute stmt using @user_id, @id; execute stmt using @user_id, @id; sql/item.cc +1 −28 Original line number Diff line number Diff line Loading @@ -889,6 +889,7 @@ void Item_param::set_null() max_length= 0; decimals= 0; state= NULL_VALUE; item_type= Item::NULL_ITEM; DBUG_VOID_RETURN; } Loading Loading @@ -1339,34 +1340,6 @@ bool Item_param::convert_str_value(THD *thd) return rc; } bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select; /* Parameters in a subselect should mark the subselect as not constant during prepare */ if (state == NO_VALUE) { /* SELECT_LEX_UNIT::item set only for subqueries, so test of it presence can be barrier to stop before derived table SELECT or very outer SELECT */ for(; cursel->master_unit()->item; cursel= cursel->outer_select()) { Item_subselect *subselect_item= cursel->master_unit()->item; subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; subselect_item->const_item_cache= 0; } } fixed= 1; return 0; } bool Item_param::basic_const_item() const { Loading sql/item.h +0 −1 Original line number Diff line number Diff line Loading @@ -564,7 +564,6 @@ class Item_param :public Item bool get_time(TIME *tm); bool get_date(TIME *tm, uint fuzzydate); int save_in_field(Field *field, bool no_conversions); bool fix_fields(THD *, struct st_table_list *, Item **); void set_null(); void set_int(longlong i, uint32 max_length_arg); Loading sql/item_subselect.h +0 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,6 @@ class Item_subselect :public Item_result_field friend class Item_in_optimizer; friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **); }; /* single value subselect */ Loading Loading
mysql-test/r/ps.result +57 −0 Original line number Diff line number Diff line Loading @@ -563,3 +563,60 @@ execute stmt; execute stmt; deallocate prepare stmt; drop table t1; create table t1 ( id int(11) unsigned not null primary key auto_increment, partner_id varchar(35) not null, t1_status_id int(10) unsigned ); insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"), ("3", "partner3", "10"), ("4", "partner4", "10"); create table t2 ( id int(11) unsigned not null default '0', t1_line_id int(11) unsigned not null default '0', article_id varchar(20), sequence int(11) not null default '0', primary key (id,t1_line_id) ); insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"), ("2", "2", "sup", "2"), ("2", "3", "sup", "3"), ("2", "4", "imp", "4"), ("3", "1", "sup", "0"), ("4", "1", "sup", "0"); create table t3 ( id int(11) not null default '0', preceeding_id int(11) not null default '0', primary key (id,preceeding_id) ); create table t4 ( user_id varchar(50) not null, article_id varchar(20) not null, primary key (user_id,article_id) ); insert into t4 values("nicke", "imp"); prepare stmt from 'select distinct t1.partner_id from t1 left join t3 on t1.id = t3.id left join t1 pp on pp.id = t3.preceeding_id where exists ( select * from t2 as pl_inner where pl_inner.id = t1.id and pl_inner.sequence <= ( select min(sequence) from t2 pl_seqnr where pl_seqnr.id = t1.id ) and exists ( select * from t4 where t4.article_id = pl_inner.article_id and t4.user_id = ? ) ) and t1.id = ? group by t1.id having count(pp.id) = 0'; set @user_id = 'nicke'; set @id = '2'; execute stmt using @user_id, @id; partner_id execute stmt using @user_id, @id; partner_id
mysql-test/t/ps.test +68 −0 Original line number Diff line number Diff line Loading @@ -581,3 +581,71 @@ execute stmt; execute stmt; deallocate prepare stmt; drop table t1; # # Bug#11458 "Prepared statement with subselects return random data": # drop PARAM_TABLE_BIT from the list of tables used by a subquery # create table t1 ( id int(11) unsigned not null primary key auto_increment, partner_id varchar(35) not null, t1_status_id int(10) unsigned ); insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"), ("3", "partner3", "10"), ("4", "partner4", "10"); create table t2 ( id int(11) unsigned not null default '0', t1_line_id int(11) unsigned not null default '0', article_id varchar(20), sequence int(11) not null default '0', primary key (id,t1_line_id) ); insert into t2 values ("1", "1", "sup", "0"), ("2", "1", "sup", "1"), ("2", "2", "sup", "2"), ("2", "3", "sup", "3"), ("2", "4", "imp", "4"), ("3", "1", "sup", "0"), ("4", "1", "sup", "0"); create table t3 ( id int(11) not null default '0', preceeding_id int(11) not null default '0', primary key (id,preceeding_id) ); create table t4 ( user_id varchar(50) not null, article_id varchar(20) not null, primary key (user_id,article_id) ); insert into t4 values("nicke", "imp"); prepare stmt from 'select distinct t1.partner_id from t1 left join t3 on t1.id = t3.id left join t1 pp on pp.id = t3.preceeding_id where exists ( select * from t2 as pl_inner where pl_inner.id = t1.id and pl_inner.sequence <= ( select min(sequence) from t2 pl_seqnr where pl_seqnr.id = t1.id ) and exists ( select * from t4 where t4.article_id = pl_inner.article_id and t4.user_id = ? ) ) and t1.id = ? group by t1.id having count(pp.id) = 0'; set @user_id = 'nicke'; set @id = '2'; execute stmt using @user_id, @id; execute stmt using @user_id, @id;
sql/item.cc +1 −28 Original line number Diff line number Diff line Loading @@ -889,6 +889,7 @@ void Item_param::set_null() max_length= 0; decimals= 0; state= NULL_VALUE; item_type= Item::NULL_ITEM; DBUG_VOID_RETURN; } Loading Loading @@ -1339,34 +1340,6 @@ bool Item_param::convert_str_value(THD *thd) return rc; } bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select; /* Parameters in a subselect should mark the subselect as not constant during prepare */ if (state == NO_VALUE) { /* SELECT_LEX_UNIT::item set only for subqueries, so test of it presence can be barrier to stop before derived table SELECT or very outer SELECT */ for(; cursel->master_unit()->item; cursel= cursel->outer_select()) { Item_subselect *subselect_item= cursel->master_unit()->item; subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; subselect_item->const_item_cache= 0; } } fixed= 1; return 0; } bool Item_param::basic_const_item() const { Loading
sql/item.h +0 −1 Original line number Diff line number Diff line Loading @@ -564,7 +564,6 @@ class Item_param :public Item bool get_time(TIME *tm); bool get_date(TIME *tm, uint fuzzydate); int save_in_field(Field *field, bool no_conversions); bool fix_fields(THD *, struct st_table_list *, Item **); void set_null(); void set_int(longlong i, uint32 max_length_arg); Loading
sql/item_subselect.h +0 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,6 @@ class Item_subselect :public Item_result_field friend class Item_in_optimizer; friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **); friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **); }; /* single value subselect */ Loading