Skip to content

Commit cd8de08

Browse files
author
Tor Didriksen
committed
merge 5.0 => 5.1 : Bug#12329653
--BZR-- revision-id: [email protected] property-branch-nick: 5.1-security testament3-sha1: b2bba6fb66d99d9d24c568d1a1ab87598e6b0f40
2 parents f6aca9d + f86c580 commit cd8de08

File tree

12 files changed

+128
-57
lines changed

12 files changed

+128
-57
lines changed

mysql-test/r/explain.result

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,12 @@ SELECT @@session.sql_mode INTO @old_sql_mode;
176176
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
177177
EXPLAIN EXTENDED SELECT 1 FROM t1
178178
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
179-
ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
180-
SHOW WARNINGS;
181-
Level Code Message
182-
Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
183-
Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
179+
id select_type table type possible_keys key key_len ref rows filtered Extra
180+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
181+
2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
182+
2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
183+
Warnings:
184+
Note 1003 select 1 AS `1` from `test`.`t1` where 0
184185
SET SESSION sql_mode=@old_sql_mode;
185186
DROP TABLE t1;
186187
End of 5.0 tests.

mysql-test/r/subselect.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4435,6 +4435,32 @@ pk int_key
44354435
3 3
44364436
7 3
44374437
DROP TABLE t1,t2;
4438+
#
4439+
# Bug#12329653
4440+
# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
4441+
#
4442+
CREATE TABLE t1(a1 int);
4443+
INSERT INTO t1 VALUES (1),(2);
4444+
SELECT @@session.sql_mode INTO @old_sql_mode;
4445+
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
4446+
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
4447+
1
4448+
1
4449+
1
4450+
PREPARE stmt FROM
4451+
'SELECT 1 UNION ALL
4452+
SELECT 1 FROM t1
4453+
ORDER BY
4454+
(SELECT 1 FROM t1 AS t1_0
4455+
WHERE 1 < SOME (SELECT a1 FROM t1)
4456+
)' ;
4457+
EXECUTE stmt ;
4458+
ERROR 21000: Subquery returns more than 1 row
4459+
EXECUTE stmt ;
4460+
ERROR 21000: Subquery returns more than 1 row
4461+
SET SESSION sql_mode=@old_sql_mode;
4462+
DEALLOCATE PREPARE stmt;
4463+
DROP TABLE t1;
44384464
End of 5.0 tests.
44394465
CREATE TABLE t1 (a INT, b INT);
44404466
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);

mysql-test/t/explain.test

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Test of different EXPLAIN's
2+
# Test of different EXPLAINs
33

44
--disable_warnings
55
drop table if exists t1;
@@ -157,11 +157,12 @@ CREATE TABLE t1 (f1 INT);
157157
SELECT @@session.sql_mode INTO @old_sql_mode;
158158
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
159159

160-
# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
161-
--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
160+
# EXPLAIN EXTENDED (with subselect). used to crash.
161+
# This is actually a valid query for this sql_mode,
162+
# but it was transformed in such a way that it failed, see
163+
# Bug#12329653 - EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
162164
EXPLAIN EXTENDED SELECT 1 FROM t1
163165
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
164-
SHOW WARNINGS;
165166

166167
SET SESSION sql_mode=@old_sql_mode;
167168

mysql-test/t/subselect.test

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,6 +3393,39 @@ ORDER BY outr.pk;
33933393

33943394
DROP TABLE t1,t2;
33953395

3396+
--echo #
3397+
--echo # Bug#12329653
3398+
--echo # EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
3399+
--echo #
3400+
3401+
CREATE TABLE t1(a1 int);
3402+
INSERT INTO t1 VALUES (1),(2);
3403+
3404+
SELECT @@session.sql_mode INTO @old_sql_mode;
3405+
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
3406+
3407+
## First a simpler query, illustrating the transformation
3408+
## '1 < some (...)' => '1 < max(...)'
3409+
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
3410+
3411+
## The query which made the server crash.
3412+
PREPARE stmt FROM
3413+
'SELECT 1 UNION ALL
3414+
SELECT 1 FROM t1
3415+
ORDER BY
3416+
(SELECT 1 FROM t1 AS t1_0
3417+
WHERE 1 < SOME (SELECT a1 FROM t1)
3418+
)' ;
3419+
3420+
--error ER_SUBQUERY_NO_1_ROW
3421+
EXECUTE stmt ;
3422+
--error ER_SUBQUERY_NO_1_ROW
3423+
EXECUTE stmt ;
3424+
3425+
SET SESSION sql_mode=@old_sql_mode;
3426+
3427+
DEALLOCATE PREPARE stmt;
3428+
DROP TABLE t1;
33963429

33973430
--echo End of 5.0 tests.
33983431

sql/item.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4464,14 +4464,14 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
44644464
SELECT_LEX *select_lex= cached_table ?
44654465
cached_table->select_lex : context->select_lex;
44664466
if (!thd->lex->in_sum_func)
4467-
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
4467+
select_lex->set_non_agg_field_used(true);
44684468
else
44694469
{
44704470
if (outer_fixed)
44714471
thd->lex->in_sum_func->outer_fields.push_back(this);
44724472
else if (thd->lex->in_sum_func->nest_level !=
44734473
thd->lex->current_select->nest_level)
4474-
select_lex->full_group_by_flag|= NON_AGG_FIELD_USED;
4474+
select_lex->set_non_agg_field_used(true);
44754475
}
44764476
}
44774477
return FALSE;

sql/item_subselect.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
10161016
it.replace(item);
10171017
}
10181018

1019+
DBUG_EXECUTE("where",
1020+
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
1021+
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
1022+
{
1023+
DBUG_ASSERT(select_lex->non_agg_field_used());
1024+
select_lex->set_non_agg_field_used(false);
1025+
}
1026+
10191027
save_allow_sum_func= thd->lex->allow_sum_func;
10201028
thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
10211029
/*

sql/item_sum.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
247247
in_sum_func->outer_fields.push_back(field);
248248
}
249249
else
250-
sel->full_group_by_flag|= NON_AGG_FIELD_USED;
250+
sel->set_non_agg_field_used(true);
251251
}
252252
if (sel->nest_level > aggr_level &&
253-
(sel->full_group_by_flag & SUM_FUNC_USED) &&
253+
(sel->agg_func_used()) &&
254254
!sel->group_list.elements)
255255
{
256256
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
@@ -259,7 +259,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
259259
}
260260
}
261261
}
262-
aggr_sel->full_group_by_flag|= SUM_FUNC_USED;
262+
aggr_sel->set_agg_func_used(true);
263263
update_used_tables();
264264
thd->lex->in_sum_func= in_sum_func;
265265
return FALSE;

sql/mysql_priv.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,13 +1469,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
14691469
bool allow_null_cond, int *error);
14701470
extern Item **not_found_item;
14711471

1472-
/*
1473-
A set of constants used for checking non aggregated fields and sum
1474-
functions mixture in the ONLY_FULL_GROUP_BY_MODE.
1475-
*/
1476-
#define NON_AGG_FIELD_USED 1
1477-
#define SUM_FUNC_USED 2
1478-
14791472
/*
14801473
This enumeration type is used only by the function find_item_in_list
14811474
to return the info on how an item has been resolved against a list

sql/sql_lex.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,8 @@ void st_select_lex::init_query()
16211621
nest_level= 0;
16221622
link_next= 0;
16231623
lock_option= TL_READ_DEFAULT;
1624+
m_non_agg_field_used= false;
1625+
m_agg_func_used= false;
16241626
}
16251627

16261628
void st_select_lex::init_select()
@@ -1651,7 +1653,8 @@ void st_select_lex::init_select()
16511653
non_agg_fields.empty();
16521654
cond_value= having_value= Item::COND_UNDEF;
16531655
inner_refs_list.empty();
1654-
full_group_by_flag= 0;
1656+
m_non_agg_field_used= false;
1657+
m_agg_func_used= false;
16551658
}
16561659

16571660
/*

sql/sql_lex.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -713,16 +713,7 @@ class st_select_lex: public st_select_lex_node
713713
joins on the right.
714714
*/
715715
List<String> *prev_join_using;
716-
/*
717-
Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate
718-
functions and non aggregated fields when GROUP BY list is absent.
719-
Bits:
720-
0 - non aggregated fields are used in this select,
721-
defined as NON_AGG_FIELD_USED.
722-
1 - aggregate functions are used in this select,
723-
defined as SUM_FUNC_USED.
724-
*/
725-
uint8 full_group_by_flag;
716+
726717
void init_query();
727718
void init_select();
728719
st_select_lex_unit* master_unit();
@@ -830,7 +821,22 @@ class st_select_lex: public st_select_lex_node
830821

831822
void clear_index_hints(void) { index_hints= NULL; }
832823

833-
private:
824+
/*
825+
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
826+
- Non-aggregated fields are used in this select.
827+
- Aggregate functions are used in this select.
828+
In MODE_ONLY_FULL_GROUP_BY only one of these may be true.
829+
*/
830+
bool non_agg_field_used() const { return m_non_agg_field_used; }
831+
bool agg_func_used() const { return m_agg_func_used; }
832+
833+
void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; }
834+
void set_agg_func_used(bool val) { m_agg_func_used= val; }
835+
836+
private:
837+
bool m_non_agg_field_used;
838+
bool m_agg_func_used;
839+
834840
/* current index hint kind. used in filling up index_hints */
835841
enum index_hint_type current_index_hint_type;
836842
index_clause_map current_index_hint_clause;

0 commit comments

Comments
 (0)