merge 5.0 => 5.1 : Bug#12329653
This commit is contained in:
commit
9baf84e99a
@ -176,11 +176,12 @@ SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1
|
||||
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
|
||||
ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
|
||||
2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where 0
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
|
@ -4435,6 +4435,32 @@ pk int_key
|
||||
3 3
|
||||
7 3
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug#12329653
|
||||
# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
#
|
||||
CREATE TABLE t1(a1 int);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
|
||||
1
|
||||
1
|
||||
1
|
||||
PREPARE stmt FROM
|
||||
'SELECT 1 UNION ALL
|
||||
SELECT 1 FROM t1
|
||||
ORDER BY
|
||||
(SELECT 1 FROM t1 AS t1_0
|
||||
WHERE 1 < SOME (SELECT a1 FROM t1)
|
||||
)' ;
|
||||
EXECUTE stmt ;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
EXECUTE stmt ;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests.
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Test of different EXPLAIN's
|
||||
# Test of different EXPLAINs
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
@ -157,11 +157,12 @@ CREATE TABLE t1 (f1 INT);
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
|
||||
# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
|
||||
--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
|
||||
# EXPLAIN EXTENDED (with subselect). used to crash.
|
||||
# This is actually a valid query for this sql_mode,
|
||||
# but it was transformed in such a way that it failed, see
|
||||
# Bug#12329653 - EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1
|
||||
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
|
||||
SHOW WARNINGS;
|
||||
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
|
||||
|
@ -3393,6 +3393,39 @@ ORDER BY outr.pk;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#12329653
|
||||
--echo # EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1(a1 int);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
||||
SELECT @@session.sql_mode INTO @old_sql_mode;
|
||||
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
|
||||
|
||||
## First a simpler query, illustrating the transformation
|
||||
## '1 < some (...)' => '1 < max(...)'
|
||||
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
|
||||
|
||||
## The query which made the server crash.
|
||||
PREPARE stmt FROM
|
||||
'SELECT 1 UNION ALL
|
||||
SELECT 1 FROM t1
|
||||
ORDER BY
|
||||
(SELECT 1 FROM t1 AS t1_0
|
||||
WHERE 1 < SOME (SELECT a1 FROM t1)
|
||||
)' ;
|
||||
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
EXECUTE stmt ;
|
||||
--error ER_SUBQUERY_NO_1_ROW
|
||||
EXECUTE stmt ;
|
||||
|
||||
SET SESSION sql_mode=@old_sql_mode;
|
||||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
|
@ -4464,14 +4464,14 @@ mark_non_agg_field:
|
||||
SELECT_LEX *select_lex= cached_table ?
|
||||
cached_table->select_lex : context->select_lex;
|
||||
if (!thd->lex->in_sum_func)
|
||||
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
select_lex->set_non_agg_field_used(true);
|
||||
else
|
||||
{
|
||||
if (outer_fixed)
|
||||
thd->lex->in_sum_func->outer_fields.push_back(this);
|
||||
else if (thd->lex->in_sum_func->nest_level !=
|
||||
thd->lex->current_select->nest_level)
|
||||
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
select_lex->set_non_agg_field_used(true);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -1016,6 +1016,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
it.replace(item);
|
||||
}
|
||||
|
||||
DBUG_EXECUTE("where",
|
||||
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
{
|
||||
DBUG_ASSERT(select_lex->non_agg_field_used());
|
||||
select_lex->set_non_agg_field_used(false);
|
||||
}
|
||||
|
||||
save_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
|
||||
/*
|
||||
|
@ -247,10 +247,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
in_sum_func->outer_fields.push_back(field);
|
||||
}
|
||||
else
|
||||
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
|
||||
sel->set_non_agg_field_used(true);
|
||||
}
|
||||
if (sel->nest_level > aggr_level &&
|
||||
(sel->full_group_by_flag & SUM_FUNC_USED) &&
|
||||
(sel->agg_func_used()) &&
|
||||
!sel->group_list.elements)
|
||||
{
|
||||
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
||||
@ -259,7 +259,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
|
||||
aggr_sel->set_agg_func_used(true);
|
||||
update_used_tables();
|
||||
thd->lex->in_sum_func= in_sum_func;
|
||||
return FALSE;
|
||||
|
@ -1469,13 +1469,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||
bool allow_null_cond, int *error);
|
||||
extern Item **not_found_item;
|
||||
|
||||
/*
|
||||
A set of constants used for checking non aggregated fields and sum
|
||||
functions mixture in the ONLY_FULL_GROUP_BY_MODE.
|
||||
*/
|
||||
#define NON_AGG_FIELD_USED 1
|
||||
#define SUM_FUNC_USED 2
|
||||
|
||||
/*
|
||||
This enumeration type is used only by the function find_item_in_list
|
||||
to return the info on how an item has been resolved against a list
|
||||
|
@ -1621,6 +1621,8 @@ void st_select_lex::init_query()
|
||||
nest_level= 0;
|
||||
link_next= 0;
|
||||
lock_option= TL_READ_DEFAULT;
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
}
|
||||
|
||||
void st_select_lex::init_select()
|
||||
@ -1651,7 +1653,8 @@ void st_select_lex::init_select()
|
||||
non_agg_fields.empty();
|
||||
cond_value= having_value= Item::COND_UNDEF;
|
||||
inner_refs_list.empty();
|
||||
full_group_by_flag= 0;
|
||||
m_non_agg_field_used= false;
|
||||
m_agg_func_used= false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -713,16 +713,7 @@ public:
|
||||
joins on the right.
|
||||
*/
|
||||
List<String> *prev_join_using;
|
||||
/*
|
||||
Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate
|
||||
functions and non aggregated fields when GROUP BY list is absent.
|
||||
Bits:
|
||||
0 - non aggregated fields are used in this select,
|
||||
defined as NON_AGG_FIELD_USED.
|
||||
1 - aggregate functions are used in this select,
|
||||
defined as SUM_FUNC_USED.
|
||||
*/
|
||||
uint8 full_group_by_flag;
|
||||
|
||||
void init_query();
|
||||
void init_select();
|
||||
st_select_lex_unit* master_unit();
|
||||
@ -830,7 +821,22 @@ public:
|
||||
|
||||
void clear_index_hints(void) { index_hints= NULL; }
|
||||
|
||||
private:
|
||||
/*
|
||||
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
|
||||
- Non-aggregated fields are used in this select.
|
||||
- Aggregate functions are used in this select.
|
||||
In MODE_ONLY_FULL_GROUP_BY only one of these may be true.
|
||||
*/
|
||||
bool non_agg_field_used() const { return m_non_agg_field_used; }
|
||||
bool agg_func_used() const { return m_agg_func_used; }
|
||||
|
||||
void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; }
|
||||
void set_agg_func_used(bool val) { m_agg_func_used= val; }
|
||||
|
||||
private:
|
||||
bool m_non_agg_field_used;
|
||||
bool m_agg_func_used;
|
||||
|
||||
/* current index hint kind. used in filling up index_hints */
|
||||
enum index_hint_type current_index_hint_type;
|
||||
index_clause_map current_index_hint_clause;
|
||||
|
@ -930,9 +930,6 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||
const char *save_where;
|
||||
char* db_name;
|
||||
char db_name_string[FN_REFLEN];
|
||||
bool save_use_only_table_context;
|
||||
uint8 saved_full_group_by_flag;
|
||||
nesting_map saved_allow_sum_func;
|
||||
DBUG_ENTER("fix_fields_part_func");
|
||||
|
||||
if (part_info->fixed)
|
||||
@ -999,23 +996,26 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||
of interesting side effects, both desirable and undesirable.
|
||||
*/
|
||||
|
||||
save_use_only_table_context= thd->lex->use_only_table_context;
|
||||
thd->lex->use_only_table_context= TRUE;
|
||||
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
|
||||
saved_full_group_by_flag= thd->lex->current_select->full_group_by_flag;
|
||||
saved_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func= 0;
|
||||
{
|
||||
const bool save_use_only_table_context= thd->lex->use_only_table_context;
|
||||
thd->lex->use_only_table_context= TRUE;
|
||||
thd->lex->current_select->cur_pos_in_select_list= UNDEF_POS;
|
||||
const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
|
||||
const bool save_agg_func= thd->lex->current_select->agg_func_used();
|
||||
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
|
||||
thd->lex->allow_sum_func= 0;
|
||||
|
||||
error= func_expr->fix_fields(thd, (Item**)&func_expr);
|
||||
error= func_expr->fix_fields(thd, (Item**)&func_expr);
|
||||
|
||||
/*
|
||||
Restore full_group_by_flag and allow_sum_func,
|
||||
fix_fields should not affect mysql_select later, see Bug#46923.
|
||||
*/
|
||||
thd->lex->current_select->full_group_by_flag= saved_full_group_by_flag;
|
||||
thd->lex->allow_sum_func= saved_allow_sum_func;
|
||||
|
||||
thd->lex->use_only_table_context= save_use_only_table_context;
|
||||
/*
|
||||
Restore agg_field/agg_func and allow_sum_func,
|
||||
fix_fields should not affect mysql_select later, see Bug#46923.
|
||||
*/
|
||||
thd->lex->current_select->set_non_agg_field_used(save_agg_field);
|
||||
thd->lex->current_select->set_agg_func_used(save_agg_func);
|
||||
thd->lex->allow_sum_func= saved_allow_sum_func;
|
||||
thd->lex->use_only_table_context= save_use_only_table_context;
|
||||
}
|
||||
|
||||
context->table_list= save_table_list;
|
||||
context->first_name_resolution_table= save_first_table;
|
||||
|
@ -426,19 +426,18 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
|
||||
int res;
|
||||
nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
|
||||
/*
|
||||
Need to save the value, so we can turn off only the new NON_AGG_FIELD
|
||||
Need to save the value, so we can turn off only any new non_agg_field_used
|
||||
additions coming from the WHERE
|
||||
*/
|
||||
uint8 saved_flag= thd->lex->current_select->full_group_by_flag;
|
||||
const bool saved_non_agg_field_used=
|
||||
thd->lex->current_select->non_agg_field_used();
|
||||
DBUG_ENTER("setup_without_group");
|
||||
|
||||
thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
|
||||
res= setup_conds(thd, tables, leaves, conds);
|
||||
|
||||
/* it's not wrong to have non-aggregated columns in a WHERE */
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
|
||||
thd->lex->current_select->full_group_by_flag= saved_flag |
|
||||
(thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED);
|
||||
thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used);
|
||||
|
||||
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
|
||||
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
||||
@ -644,7 +643,8 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
aggregate functions with implicit grouping (there is no GROUP BY).
|
||||
*/
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
|
||||
select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
|
||||
select_lex->non_agg_field_used() &&
|
||||
select_lex->agg_func_used())
|
||||
{
|
||||
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
|
||||
ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
|
||||
|
Loading…
x
Reference in New Issue
Block a user