mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-7810 Wrong result on execution of a query as a PS (both 1st and further executions)
Alternative fix that doesn't cause view.test crash in --ps: Remember when Item_ref was fixed right in the constructor and did not have a full Item_ref::fix_fields() call. Later in PS/SP, after Item_ref::cleanup, we use this knowledge to avoid doing full fix_fields() for items that were never supposed to be fix_field'ed. Simplify the test case.
This commit is contained in:
@@ -2150,20 +2150,11 @@ drop database mysqltest4;
|
||||
# (both 1st and further executions)
|
||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0),(8);
|
||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
||||
a
|
||||
0
|
||||
8
|
||||
SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a));
|
||||
MIN(t3.a)
|
||||
0
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) );
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
|
||||
a
|
||||
0
|
||||
PREPARE stmt FROM "
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||
";
|
||||
execute stmt;
|
||||
a
|
||||
|
@@ -2190,20 +2190,11 @@ drop database mysqltest4;
|
||||
# (both 1st and further executions)
|
||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0),(8);
|
||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
||||
a
|
||||
0
|
||||
8
|
||||
SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a));
|
||||
MIN(t3.a)
|
||||
0
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) );
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
|
||||
a
|
||||
0
|
||||
PREPARE stmt FROM "
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||
";
|
||||
execute stmt;
|
||||
a
|
||||
|
@@ -1848,13 +1848,9 @@ drop database mysqltest4;
|
||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0),(8);
|
||||
|
||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
||||
SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a));
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) );
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
|
||||
PREPARE stmt FROM "
|
||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
||||
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||
";
|
||||
execute stmt;
|
||||
execute stmt;
|
||||
|
10
sql/item.cc
10
sql/item.cc
@@ -6754,7 +6754,7 @@ Item_ref::Item_ref(Name_resolution_context *context_arg,
|
||||
/*
|
||||
This constructor used to create some internals references over fixed items
|
||||
*/
|
||||
if (ref && *ref && (*ref)->fixed)
|
||||
if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
|
||||
set_properties();
|
||||
}
|
||||
|
||||
@@ -6798,7 +6798,7 @@ Item_ref::Item_ref(TABLE_LIST *view_arg, Item **item,
|
||||
/*
|
||||
This constructor is used to create some internal references over fixed items
|
||||
*/
|
||||
if (ref && *ref && (*ref)->fixed)
|
||||
if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
|
||||
set_properties();
|
||||
}
|
||||
|
||||
@@ -6873,7 +6873,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
SELECT_LEX *current_sel= thd->lex->current_select;
|
||||
|
||||
if (!ref || ref == not_found_item)
|
||||
if (set_properties_only)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else if (!ref || ref == not_found_item)
|
||||
{
|
||||
DBUG_ASSERT(reference_trough_name != 0);
|
||||
if (!(ref= resolve_ref_in_select_and_group(thd, this,
|
||||
|
@@ -2946,6 +2946,7 @@ class Item_ref :public Item_ident
|
||||
{
|
||||
protected:
|
||||
void set_properties();
|
||||
bool set_properties_only; // the item doesn't need full fix_fields
|
||||
public:
|
||||
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
|
||||
Field *result_field; /* Save result here */
|
||||
@@ -2955,7 +2956,7 @@ public:
|
||||
const char *db_arg, const char *table_name_arg,
|
||||
const char *field_name_arg)
|
||||
:Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
|
||||
result_field(0), ref(0), reference_trough_name(1) {}
|
||||
set_properties_only(0), result_field(0), ref(0), reference_trough_name(1) {}
|
||||
/*
|
||||
This constructor is used in two scenarios:
|
||||
A) *item = NULL
|
||||
@@ -2978,7 +2979,7 @@ public:
|
||||
|
||||
/* Constructor need to process subselect with temporary tables (see Item) */
|
||||
Item_ref(THD *thd, Item_ref *item)
|
||||
:Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
|
||||
:Item_ident(thd, item), set_properties_only(0), result_field(item->result_field), ref(item->ref) {}
|
||||
enum Type type() const { return REF_ITEM; }
|
||||
enum Type real_type() const { return ref ? (*ref)->type() :
|
||||
REF_ITEM; }
|
||||
|
@@ -2007,37 +2007,6 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
|
||||
*where_item= NULL;
|
||||
*having_item= NULL;
|
||||
|
||||
/*
|
||||
For PS we have to do fix_fields(expr) here to ensure that it's
|
||||
evaluated in the outer context. If not, then fix_having() will do
|
||||
a fix_fields(expr) in the inner context and mark expr as
|
||||
'depended', which will cause update_ref_and_keys() to find wrong
|
||||
keys.
|
||||
When not running PS, fix_fields(expr) as already been done earlier and
|
||||
the following test does nothing.
|
||||
*/
|
||||
if (expr && !expr->fixed)
|
||||
{
|
||||
bool tmp;
|
||||
SELECT_LEX *save_current_select= thd->lex->current_select;
|
||||
Item_subselect *save_item;
|
||||
|
||||
thd->lex->current_select= thd->lex->current_select->outer_select();
|
||||
/*
|
||||
For st_select_lex::mark_as_dependent, who needs to mark
|
||||
this sub query as correlated.
|
||||
*/
|
||||
save_item= thd->lex->current_select->master_unit()->item;
|
||||
thd->lex->current_select->master_unit()->item= this;
|
||||
|
||||
tmp= expr->fix_fields(thd, 0);
|
||||
|
||||
thd->lex->current_select->master_unit()->item= save_item;
|
||||
thd->lex->current_select= save_current_select;
|
||||
if (tmp)
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
if (join_having || select_lex->with_sum_func ||
|
||||
select_lex->group_list.elements)
|
||||
{
|
||||
|
@@ -6936,6 +6936,8 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||
return found;
|
||||
}
|
||||
}
|
||||
else
|
||||
item->can_be_depended= TRUE;
|
||||
|
||||
if (db && lower_case_table_names)
|
||||
{
|
||||
|
Reference in New Issue
Block a user