Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/mysql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ static COMMANDS commands[] = {
{ "ADDTIME", 0, 0, 0, ""},
{ "AES_ENCRYPT", 0, 0, 0, ""},
{ "AES_DECRYPT", 0, 0, 0, ""},
{ "ANY_VALUE", 0, 0, 0, ""},
{ "AREA", 0, 0, 0, ""},
{ "ASIN", 0, 0, 0, ""},
{ "ASBINARY", 0, 0, 0, ""},
Expand Down
96 changes: 96 additions & 0 deletions mysql-test/main/any_value.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
CREATE TABLE t0 (a INT, b INT);
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (c INT, d INT);
CREATE TABLE t3 (x INT, y INT, z INT);
CREATE TABLE t4 (x INT, y INT, INDEX idx (y, x));
CREATE TABLE t5 (x INT, y CHAR(1), z INT);
INSERT INTO t1 VALUES (1,10),(2,10),(NULL,20),(3,20),(NULL,30),(4,40);
INSERT INTO t2 VALUES (1,100),(2,200),(3,300);
INSERT INTO t3 VALUES (1,10,10),(2,10,10),(3,20,20),(4,20,20),(5,30,30);
INSERT INTO t4 VALUES (1,10),(2,10),(3,20),(4,20),(5,30);
INSERT INTO t5 VALUES (1,'a',1),(1,'a',2),(1,'b',3),(1,'b',4),(2,'a',5),(2,'a',6),(2,'b',7);
SET SQL_MODE=ONLY_FULL_GROUP_BY;
SELECT ANY_VALUE(b) FROM t0;
ANY_VALUE(b)
NULL
SELECT ANY_VALUE(b) FROM t1;
ANY_VALUE(b)
10
SELECT COUNT(*), ANY_VALUE(b) FROM t1;
COUNT(*) ANY_VALUE(b)
6 10
SELECT c FROM t2 WHERE ANY_VALUE(d) = 200;
ERROR HY000: Invalid use of group function
SELECT ANY_VALUE(b) FROM t0 GROUP BY b;
ANY_VALUE(b)
SELECT ANY_VALUE(a), b FROM t1 GROUP BY b;
ANY_VALUE(a) b
1 10
NULL 20
NULL 30
4 40
SELECT ANY_VALUE(b) FROM t1 GROUP BY b;
ANY_VALUE(b)
10
20
30
40
SELECT b, ANY_VALUE(a + 100) FROM t1 GROUP BY b;
b ANY_VALUE(a + 100)
10 101
20 NULL
30 NULL
40 104
SELECT b, ANY_VALUE(a * 2 + b) FROM t1 GROUP BY b;
b ANY_VALUE(a * 2 + b)
10 12
20 NULL
30 NULL
40 48
SELECT y, ANY_VALUE(x + z) FROM t3 GROUP BY y;
y ANY_VALUE(x + z)
10 11
20 23
30 35
SELECT y, ANY_VALUE(x) FROM t4 GROUP BY y;
y ANY_VALUE(x)
10 1
20 3
30 5
EXPLAIN SELECT y, ANY_VALUE(x) FROM t4 GROUP BY y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 index NULL idx 10 NULL 5 Using index
SELECT b, (SELECT SUM(t2.d) + SUM(t1.a) FROM t2) AS sub FROM t1 GROUP BY b;
b sub
10 603
20 603
30 NULL
40 604
SELECT b, (SELECT SUM(t2.d) + ANY_VALUE(t1.a) FROM t2) AS sub FROM t1 GROUP BY b;
b sub
10 601
20 NULL
30 NULL
40 604
SELECT y, ANY_VALUE(z) FROM t3 GROUP BY y HAVING ANY_VALUE(z) = 20;
y ANY_VALUE(z)
20 20
SELECT x, y, ANY_VALUE(z) FROM t5 GROUP BY x, y WITH ROLLUP;
x y ANY_VALUE(z)
1 a 1
1 b 3
1 NULL 1
2 a 5
2 b 7
2 NULL 5
NULL NULL 1
DROP TABLE t0,t1,t2,t3,t4,t5;
CREATE TABLE t (a CHAR CHARACTER SET latin2);
INSERT INTO t VALUES ('a'),('b');
SELECT charset(ANY_VALUE(a)), collation(ANY_VALUE(a)) FROM t;
charset(ANY_VALUE(a)) collation(ANY_VALUE(a))
latin2 latin2_general_ci
SELECT coercibility(ANY_VALUE(a)), coercibility(ANY_VALUE('x')) FROM t;
coercibility(ANY_VALUE(a)) coercibility(ANY_VALUE('x'))
2 6
DROP TABLE t;
73 changes: 73 additions & 0 deletions mysql-test/main/any_value.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
CREATE TABLE t0 (a INT, b INT);
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t2 (c INT, d INT);
CREATE TABLE t3 (x INT, y INT, z INT);
CREATE TABLE t4 (x INT, y INT, INDEX idx (y, x));
CREATE TABLE t5 (x INT, y CHAR(1), z INT);
INSERT INTO t1 VALUES (1,10),(2,10),(NULL,20),(3,20),(NULL,30),(4,40);
INSERT INTO t2 VALUES (1,100),(2,200),(3,300);
INSERT INTO t3 VALUES (1,10,10),(2,10,10),(3,20,20),(4,20,20),(5,30,30);
INSERT INTO t4 VALUES (1,10),(2,10),(3,20),(4,20),(5,30);
INSERT INTO t5 VALUES (1,'a',1),(1,'a',2),(1,'b',3),(1,'b',4),(2,'a',5),(2,'a',6),(2,'b',7);

SET SQL_MODE=ONLY_FULL_GROUP_BY;

#
# Without GROUP BY
#

SELECT ANY_VALUE(b) FROM t0;
SELECT ANY_VALUE(b) FROM t1;

# Mixing real aggregate function
SELECT COUNT(*), ANY_VALUE(b) FROM t1;

# In WHERE
--error ER_INVALID_GROUP_FUNC_USE
SELECT c FROM t2 WHERE ANY_VALUE(d) = 200;

#
# With GROUP BY
#

SELECT ANY_VALUE(b) FROM t0 GROUP BY b;

# Regular use in SELECT-list
SELECT ANY_VALUE(a), b FROM t1 GROUP BY b;
SELECT ANY_VALUE(b) FROM t1 GROUP BY b;

# Expression inside ANY_VALUE
SELECT b, ANY_VALUE(a + 100) FROM t1 GROUP BY b;
SELECT b, ANY_VALUE(a * 2 + b) FROM t1 GROUP BY b;
SELECT y, ANY_VALUE(x + z) FROM t3 GROUP BY y;

# Table with index on GROUP BY column
SELECT y, ANY_VALUE(x) FROM t4 GROUP BY y;
EXPLAIN SELECT y, ANY_VALUE(x) FROM t4 GROUP BY y;

# Correlated subquery
SELECT b, (SELECT SUM(t2.d) + SUM(t1.a) FROM t2) AS sub FROM t1 GROUP BY b;

SELECT b, (SELECT SUM(t2.d) + ANY_VALUE(t1.a) FROM t2) AS sub FROM t1 GROUP BY b;

# In HAVING
SELECT y, ANY_VALUE(z) FROM t3 GROUP BY y HAVING ANY_VALUE(z) = 20;

# Rollup
SELECT x, y, ANY_VALUE(z) FROM t5 GROUP BY x, y WITH ROLLUP;

DROP TABLE t0,t1,t2,t3,t4,t5;

#
# Charset/Collation/Coercibility Tests
#

CREATE TABLE t (a CHAR CHARACTER SET latin2);
INSERT INTO t VALUES ('a'),('b');

# Charset/Collation preserved

SELECT charset(ANY_VALUE(a)), collation(ANY_VALUE(a)) FROM t;
SELECT coercibility(ANY_VALUE(a)), coercibility(ANY_VALUE('x')) FROM t;

DROP TABLE t;
50 changes: 49 additions & 1 deletion mysql-test/main/group_by.result
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,10 @@ m
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 SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1)
3
7
11
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
Expand Down Expand Up @@ -3154,3 +3157,48 @@ we BPYFY BPYFY
we c c
DROP TABLE t1, t2;
# End of 11.8 tests
#
# MDEV-39932: Assert correct ONLY_FULL_GROUP_BY behavior with outer refs in correlated subqueries
#
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE = 'ONLY_FULL_GROUP_BY';
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);
SELECT (SELECT SUM(t1_inner.a) + t1_outer.a FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
SELECT (SELECT SUM(t1_outer.b) + t1_outer.a FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
SELECT (SELECT SUM(t1_inner.a + t1_outer.a) FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
SELECT (SELECT SUM(t1_outer.a) + t1_outer.b FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
c1
4
9
14
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner WHERE t1_inner.a = t1_outer.a LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
SELECT (SELECT t1_inner.a FROM t1 AS t1_inner WHERE t1_outer.a > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
SELECT (SELECT t1_inner.a FROM t1 AS t1_inner WHERE SUM(t1_outer.a) > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
c1
NULL
1
1
SELECT (SELECT t1_inner.a FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING t1_inner.a + SUM(t1_outer.a) > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;
c1
3
1
1
DROP TABLE t1;
SET sql_mode=@save_sql_mode;
#
# End of 10.11 tests
#
46 changes: 45 additions & 1 deletion mysql-test/main/group_by.test
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,6 @@ SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1)
AS m
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;

Expand Down Expand Up @@ -2231,3 +2230,48 @@ DROP TABLE t1, t2;
--echo # End of 11.8 tests



--echo #
--echo # MDEV-39932: Assert correct ONLY_FULL_GROUP_BY behavior with outer refs in correlated subqueries
--echo #
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE = 'ONLY_FULL_GROUP_BY';

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);

--error ER_WRONG_FIELD_WITH_GROUP
SELECT (SELECT SUM(t1_inner.a) + t1_outer.a FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

--error ER_WRONG_FIELD_WITH_GROUP
SELECT (SELECT SUM(t1_outer.b) + t1_outer.a FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

--error ER_WRONG_FIELD_WITH_GROUP
SELECT (SELECT SUM(t1_inner.a + t1_outer.a) FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

SELECT (SELECT SUM(t1_outer.a) + t1_outer.b FROM t1 AS t1_inner LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

--error ER_WRONG_FIELD_WITH_GROUP
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner WHERE t1_inner.a = t1_outer.a LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

--error ER_WRONG_FIELD_WITH_GROUP
SELECT (SELECT t1_inner.a FROM t1 AS t1_inner WHERE t1_outer.a > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

SELECT (SELECT t1_inner.a FROM t1 AS t1_inner WHERE SUM(t1_outer.a) > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

SELECT (SELECT t1_inner.a FROM t1 AS t1_inner GROUP BY t1_inner.a HAVING t1_inner.a + SUM(t1_outer.a) > 5 LIMIT 1) AS c1
FROM t1 AS t1_outer GROUP BY t1_outer.b;

DROP TABLE t1;
SET sql_mode=@save_sql_mode;

--echo #
--echo # End of 10.11 tests
--echo #
1 change: 1 addition & 0 deletions sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6155,6 +6155,7 @@ 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 &&
!thd->lex->in_sum_func &&
select->cur_pos_in_select_list != UNDEF_POS)
{
/*
Expand Down
57 changes: 51 additions & 6 deletions sql/item_sum.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,20 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
in_sum_func->outer_fields.push_back(field, thd->mem_root);
}
else
{
sel->set_non_agg_field_used(true);
sel->join->non_agg_fields.push_back(field, thd->mem_root);
}
}
if (sel->nest_level > aggr_level &&
(sel->agg_func_used()) &&
!sel->group_list.elements)
else if (sel->nest_level > aggr_level)
{
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
ER_THD(thd, ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
return TRUE;
if ((sel->agg_func_used()) && !sel->group_list.elements)
{
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
ER_THD(thd, ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
return TRUE;
}
sel->join->non_agg_fields.push_back(field, thd->mem_root);
}
}
}
Expand Down Expand Up @@ -2610,6 +2615,46 @@ bool Item_sum_max::add()
}


bool Item_sum_any_value::add()
{
DBUG_ENTER("Item_sum_any_value::add");

if (!has_value)
{
value->store(args[0]);
value->cache_value();
null_value= args[0]->null_value;
has_value= 1;
}
DBUG_RETURN(0);
}


void Item_sum_any_value::clear()
{
DBUG_ENTER("Item_sum_any_value::clear");
if (!const_item())
{
value->clear();
null_value= 1;
has_value= 0;
}
DBUG_VOID_RETURN;
}


void Item_sum_any_value::update_field() {}


Item *Item_sum_any_value::copy_or_same(THD* thd)
{
DBUG_ENTER("Item_sum_any_value::copy_or_same");
Item_sum_any_value *item= new (thd->mem_root) Item_sum_any_value(thd, this);
item->setup_hybrid(thd, args[0], value);
DBUG_RETURN(item);
}


/* bit_or and bit_and */

longlong Item_sum_bit::val_int()
Expand Down
Loading