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)
|
# (both 1st and further executions)
|
||||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||||
INSERT INTO t1 VALUES (0),(8);
|
INSERT INTO t1 VALUES (0),(8);
|
||||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (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) ) );
|
|
||||||
a
|
a
|
||||||
0
|
0
|
||||||
PREPARE stmt FROM "
|
PREPARE stmt FROM "
|
||||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
|
||||||
";
|
";
|
||||||
execute stmt;
|
execute stmt;
|
||||||
a
|
a
|
||||||
|
@@ -2190,20 +2190,11 @@ drop database mysqltest4;
|
|||||||
# (both 1st and further executions)
|
# (both 1st and further executions)
|
||||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||||
INSERT INTO t1 VALUES (0),(8);
|
INSERT INTO t1 VALUES (0),(8);
|
||||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (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) ) );
|
|
||||||
a
|
a
|
||||||
0
|
0
|
||||||
PREPARE stmt FROM "
|
PREPARE stmt FROM "
|
||||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
|
||||||
";
|
";
|
||||||
execute stmt;
|
execute stmt;
|
||||||
a
|
a
|
||||||
|
@@ -1848,13 +1848,9 @@ drop database mysqltest4;
|
|||||||
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
|
||||||
INSERT INTO t1 VALUES (0),(8);
|
INSERT INTO t1 VALUES (0),(8);
|
||||||
|
|
||||||
SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2;
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (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) ) );
|
|
||||||
PREPARE stmt FROM "
|
PREPARE stmt FROM "
|
||||||
SELECT a FROM ( SELECT DISTINCT t9.* FROM t1 AS t9, t1 AS t2 ) AS sq
|
SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
|
||||||
WHERE a IN ( SELECT MIN(t3.a) FROM ( t1 AS t3 INNER JOIN t1 AS t4 ON (t3.a = t4.a) ) )
|
|
||||||
";
|
";
|
||||||
execute stmt;
|
execute stmt;
|
||||||
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
|
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();
|
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
|
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();
|
set_properties();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6873,7 +6873,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
DBUG_ASSERT(fixed == 0);
|
DBUG_ASSERT(fixed == 0);
|
||||||
SELECT_LEX *current_sel= thd->lex->current_select;
|
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);
|
DBUG_ASSERT(reference_trough_name != 0);
|
||||||
if (!(ref= resolve_ref_in_select_and_group(thd, this,
|
if (!(ref= resolve_ref_in_select_and_group(thd, this,
|
||||||
|
@@ -2946,6 +2946,7 @@ class Item_ref :public Item_ident
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void set_properties();
|
void set_properties();
|
||||||
|
bool set_properties_only; // the item doesn't need full fix_fields
|
||||||
public:
|
public:
|
||||||
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
|
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
|
||||||
Field *result_field; /* Save result here */
|
Field *result_field; /* Save result here */
|
||||||
@@ -2955,7 +2956,7 @@ public:
|
|||||||
const char *db_arg, const char *table_name_arg,
|
const char *db_arg, const char *table_name_arg,
|
||||||
const char *field_name_arg)
|
const char *field_name_arg)
|
||||||
:Item_ident(context_arg, db_arg, table_name_arg, 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:
|
This constructor is used in two scenarios:
|
||||||
A) *item = NULL
|
A) *item = NULL
|
||||||
@@ -2978,7 +2979,7 @@ public:
|
|||||||
|
|
||||||
/* Constructor need to process subselect with temporary tables (see Item) */
|
/* Constructor need to process subselect with temporary tables (see Item) */
|
||||||
Item_ref(THD *thd, Item_ref *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 type() const { return REF_ITEM; }
|
||||||
enum Type real_type() const { return ref ? (*ref)->type() :
|
enum Type real_type() const { return ref ? (*ref)->type() :
|
||||||
REF_ITEM; }
|
REF_ITEM; }
|
||||||
|
@@ -2007,37 +2007,6 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
|
|||||||
*where_item= NULL;
|
*where_item= NULL;
|
||||||
*having_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 ||
|
if (join_having || select_lex->with_sum_func ||
|
||||||
select_lex->group_list.elements)
|
select_lex->group_list.elements)
|
||||||
{
|
{
|
||||||
|
@@ -6936,6 +6936,8 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
item->can_be_depended= TRUE;
|
||||||
|
|
||||||
if (db && lower_case_table_names)
|
if (db && lower_case_table_names)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user