Loading mysql-test/r/group_by.result +102 −0 Original line number Diff line number Diff line Loading @@ -933,3 +933,105 @@ b sum(1) 18 6 19 6 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b INT); INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3); SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b; MAX(a)-MIN(a) 1 1 1 SELECT CEILING(MIN(a)) FROM t1 GROUP BY b; CEILING(MIN(a)) 1 3 5 SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1 GROUP BY b; CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END Positive Positive Positive SELECT a + 1 FROM t1 GROUP BY a; a + 1 2 3 4 5 6 7 SELECT a + b FROM t1 GROUP BY b; ERROR 42000: 'test.t1.a' isn't in GROUP BY SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer; (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) 1 2 3 4 5 6 SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1); 1 1 1 1 1 1 1 SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1); ERROR 42S22: Unknown column 'test.t1_outer.b' in 'field list' SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) 21 21 21 SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) FROM t1 AS t1_outer; (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) 3 3 3 3 3 3 SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY SELECT 1 FROM t1 as t1_outer WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1); 1 1 1 1 1 1 1 SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0; b 1 2 3 SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12; 1 1 1 SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1); 1 1 SELECT 1 FROM t1 GROUP BY b HAVING a = 2; ERROR 42S22: Unknown column 'a' in 'having clause' SELECT 1 FROM t1 GROUP BY SUM(b); ERROR HY000: Invalid use of group function SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN (SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING SUM(t1_inner.b)+t1_outer.b > 5); ERROR 42000: 'test.t1_outer.b' isn't in GROUP BY DROP TABLE t1; SET SQL_MODE = ''; mysql-test/t/group_by.test +51 −0 Original line number Diff line number Diff line Loading @@ -701,3 +701,54 @@ EXPLAIN SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b; SELECT b, sum(1) FROM t1 GROUP BY b; SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b; DROP TABLE t1; # # Bug #23417: Too strict checks against GROUP BY in the ONLY_FULL_GROUP_BY mode # CREATE TABLE t1 (a INT PRIMARY KEY, b INT); INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3); SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b; SELECT CEILING(MIN(a)) FROM t1 GROUP BY b; SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1 GROUP BY b; SELECT a + 1 FROM t1 GROUP BY a; --error ER_WRONG_FIELD_WITH_GROUP SELECT a + b FROM t1 GROUP BY b; SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer; SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1); --error ER_WRONG_FIELD_WITH_GROUP SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; --error ER_BAD_FIELD_ERROR SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1); SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) FROM t1 AS t1_outer; --error ER_WRONG_FIELD_WITH_GROUP SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; SELECT 1 FROM t1 as t1_outer WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1); SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0; SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12; SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1); --error ER_BAD_FIELD_ERROR SELECT 1 FROM t1 GROUP BY b HAVING a = 2; --error ER_INVALID_GROUP_FUNC_USE SELECT 1 FROM t1 GROUP BY SUM(b); --error ER_WRONG_FIELD_WITH_GROUP SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN (SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING SUM(t1_inner.b)+t1_outer.b > 5); DROP TABLE t1; SET SQL_MODE = ''; sql/item.cc +21 −2 Original line number Diff line number Diff line Loading @@ -3469,6 +3469,16 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) { if (*from_field) { if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && select->cur_pos_in_select_list != UNDEF_POS) { /* As this is an outer field it should be added to the list of non aggregated fields of the outer select. */ marker= select->cur_pos_in_select_list; select->non_agg_fields.push_back(this); } if (*from_field != view_ref_found) { prev_subselect_item->used_tables_cache|= (*from_field)->table->map; Loading Loading @@ -3671,10 +3681,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) bool Item_field::fix_fields(THD *thd, Item **reference) { DBUG_ASSERT(fixed == 0); if (!field) // If field is not checked { Field *from_field= (Field *)not_found_field; bool outer_fixed= false; if (!field) // If field is not checked { /* In case of view, find_field_in_tables() write pointer to view field expression to 'reference', i.e. it substitute that expression instead Loading Loading @@ -3766,6 +3777,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto error; else if (!ret) return FALSE; outer_fixed= 1; } set_field(from_field); Loading Loading @@ -3809,6 +3821,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference) } #endif fixed= 1; if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !outer_fixed && !thd->lex->in_sum_func && thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS) { thd->lex->current_select->non_agg_fields.push_back(this); marker= thd->lex->current_select->cur_pos_in_select_list; } return FALSE; error: Loading sql/item.h +2 −1 Original line number Diff line number Diff line Loading @@ -452,7 +452,8 @@ class Item { Item *next; uint32 max_length; uint name_length; /* Length of name */ uint8 marker, decimals; int8 marker; uint8 decimals; my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ my_bool unsigned_flag; Loading sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -410,7 +410,8 @@ MY_LOCALE *my_locale_by_name(const char *name); #define UNCACHEABLE_EXPLAIN 8 /* Don't evaluate subqueries in prepare even if they're not correlated */ #define UNCACHEABLE_PREPARE 16 /* Used to chack GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) #ifdef EXTRA_DEBUG /* Sync points allow us to force the server to reach a certain line of code Loading Loading
mysql-test/r/group_by.result +102 −0 Original line number Diff line number Diff line Loading @@ -933,3 +933,105 @@ b sum(1) 18 6 19 6 DROP TABLE t1; CREATE TABLE t1 (a INT PRIMARY KEY, b INT); INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3); SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b; MAX(a)-MIN(a) 1 1 1 SELECT CEILING(MIN(a)) FROM t1 GROUP BY b; CEILING(MIN(a)) 1 3 5 SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1 GROUP BY b; CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END Positive Positive Positive SELECT a + 1 FROM t1 GROUP BY a; a + 1 2 3 4 5 6 7 SELECT a + b FROM t1 GROUP BY b; ERROR 42000: 'test.t1.a' isn't in GROUP BY SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer; (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) 1 2 3 4 5 6 SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1); 1 1 1 1 1 1 1 SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1); ERROR 42S22: Unknown column 'test.t1_outer.b' in 'field list' SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) 21 21 21 SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) FROM t1 AS t1_outer; (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) 3 3 3 3 3 3 SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY SELECT 1 FROM t1 as t1_outer WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1); 1 1 1 1 1 1 1 SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0; b 1 2 3 SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12; 1 1 1 SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1); 1 1 SELECT 1 FROM t1 GROUP BY b HAVING a = 2; ERROR 42S22: Unknown column 'a' in 'having clause' SELECT 1 FROM t1 GROUP BY SUM(b); ERROR HY000: Invalid use of group function SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN (SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING SUM(t1_inner.b)+t1_outer.b > 5); ERROR 42000: 'test.t1_outer.b' isn't in GROUP BY DROP TABLE t1; SET SQL_MODE = '';
mysql-test/t/group_by.test +51 −0 Original line number Diff line number Diff line Loading @@ -701,3 +701,54 @@ EXPLAIN SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b; SELECT b, sum(1) FROM t1 GROUP BY b; SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b; DROP TABLE t1; # # Bug #23417: Too strict checks against GROUP BY in the ONLY_FULL_GROUP_BY mode # CREATE TABLE t1 (a INT PRIMARY KEY, b INT); INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3); SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b; SELECT CEILING(MIN(a)) FROM t1 GROUP BY b; SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1 GROUP BY b; SELECT a + 1 FROM t1 GROUP BY a; --error ER_WRONG_FIELD_WITH_GROUP SELECT a + b FROM t1 GROUP BY b; SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer; SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1); --error ER_WRONG_FIELD_WITH_GROUP SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; --error ER_BAD_FIELD_ERROR SELECT 1 FROM t1 as t1_outer GROUP BY a HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1); SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1) FROM t1 AS t1_outer; --error ER_WRONG_FIELD_WITH_GROUP SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1) FROM t1 AS t1_outer GROUP BY t1_outer.b; SELECT 1 FROM t1 as t1_outer WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1); SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0; SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12; SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1); --error ER_BAD_FIELD_ERROR SELECT 1 FROM t1 GROUP BY b HAVING a = 2; --error ER_INVALID_GROUP_FUNC_USE SELECT 1 FROM t1 GROUP BY SUM(b); --error ER_WRONG_FIELD_WITH_GROUP SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN (SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING SUM(t1_inner.b)+t1_outer.b > 5); DROP TABLE t1; SET SQL_MODE = '';
sql/item.cc +21 −2 Original line number Diff line number Diff line Loading @@ -3469,6 +3469,16 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) { if (*from_field) { if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && select->cur_pos_in_select_list != UNDEF_POS) { /* As this is an outer field it should be added to the list of non aggregated fields of the outer select. */ marker= select->cur_pos_in_select_list; select->non_agg_fields.push_back(this); } if (*from_field != view_ref_found) { prev_subselect_item->used_tables_cache|= (*from_field)->table->map; Loading Loading @@ -3671,10 +3681,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) bool Item_field::fix_fields(THD *thd, Item **reference) { DBUG_ASSERT(fixed == 0); if (!field) // If field is not checked { Field *from_field= (Field *)not_found_field; bool outer_fixed= false; if (!field) // If field is not checked { /* In case of view, find_field_in_tables() write pointer to view field expression to 'reference', i.e. it substitute that expression instead Loading Loading @@ -3766,6 +3777,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) goto error; else if (!ret) return FALSE; outer_fixed= 1; } set_field(from_field); Loading Loading @@ -3809,6 +3821,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference) } #endif fixed= 1; if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !outer_fixed && !thd->lex->in_sum_func && thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS) { thd->lex->current_select->non_agg_fields.push_back(this); marker= thd->lex->current_select->cur_pos_in_select_list; } return FALSE; error: Loading
sql/item.h +2 −1 Original line number Diff line number Diff line Loading @@ -452,7 +452,8 @@ class Item { Item *next; uint32 max_length; uint name_length; /* Length of name */ uint8 marker, decimals; int8 marker; uint8 decimals; my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ my_bool unsigned_flag; Loading
sql/mysql_priv.h +2 −1 Original line number Diff line number Diff line Loading @@ -410,7 +410,8 @@ MY_LOCALE *my_locale_by_name(const char *name); #define UNCACHEABLE_EXPLAIN 8 /* Don't evaluate subqueries in prepare even if they're not correlated */ #define UNCACHEABLE_PREPARE 16 /* Used to chack GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */ #define UNDEF_POS (-1) #ifdef EXTRA_DEBUG /* Sync points allow us to force the server to reach a certain line of code Loading