BUG#14019 : group by converts literal string to column name

   When resolving unqualified name references MySQL was not
   checking what is the item type for the reference. Thus
   e.g a string literal item that has by convention a name
   equal to its string value will also work as a reference to 
   a SELECT list item or a table field.
   Fixed by allowing only Item_ref or Item_field to referenced by
   (unqualified) name.
parent 55dd569b
...@@ -74,11 +74,6 @@ grp group_concat(c order by 1) ...@@ -74,11 +74,6 @@ grp group_concat(c order by 1)
1 a 1 a
2 b,c 2 b,c
3 C,D,d,d,D,E 3 C,D,d,d,D,E
select grp,group_concat(c order by "c") from t1 group by grp;
grp group_concat(c order by "c")
1 a
2 b,c
3 C,D,d,d,D,E
select grp,group_concat(distinct c order by c) from t1 group by grp; select grp,group_concat(distinct c order by c) from t1 group by grp;
grp group_concat(distinct c order by c) grp group_concat(distinct c order by c)
1 a 1 a
......
...@@ -773,3 +773,48 @@ select sql_buffer_result max(f1)+1 from t1; ...@@ -773,3 +773,48 @@ select sql_buffer_result max(f1)+1 from t1;
max(f1)+1 max(f1)+1
3 3
drop table t1; drop table t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
SELECT a FROM t1 GROUP BY 'a';
a
1
SELECT a FROM t1 GROUP BY "a";
a
1
SELECT a FROM t1 GROUP BY `a`;
a
1
2
set sql_mode=ANSI_QUOTES;
SELECT a FROM t1 GROUP BY "a";
a
1
2
SELECT a FROM t1 GROUP BY 'a';
a
1
SELECT a FROM t1 GROUP BY `a`;
a
1
2
set sql_mode='';
SELECT a FROM t1 HAVING 'a' > 1;
a
SELECT a FROM t1 HAVING "a" > 1;
a
SELECT a FROM t1 HAVING `a` > 1;
a
2
SELECT a FROM t1 ORDER BY 'a' DESC;
a
1
2
SELECT a FROM t1 ORDER BY "a" DESC;
a
1
2
SELECT a FROM t1 ORDER BY `a` DESC;
a
2
1
DROP TABLE t1;
...@@ -32,7 +32,6 @@ select grp,group_concat(d order by a desc) from t1 group by grp; ...@@ -32,7 +32,6 @@ select grp,group_concat(d order by a desc) from t1 group by grp;
select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp; select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp;
select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp; select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp;
select grp,group_concat(c order by 1) from t1 group by grp; select grp,group_concat(c order by 1) from t1 group by grp;
select grp,group_concat(c order by "c") from t1 group by grp;
select grp,group_concat(distinct c order by c) from t1 group by grp; select grp,group_concat(distinct c order by c) from t1 group by grp;
select grp,group_concat(distinct c order by c desc) from t1 group by grp; select grp,group_concat(distinct c order by c desc) from t1 group by grp;
explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp; explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp;
......
...@@ -610,4 +610,27 @@ select sql_buffer_result max(f1) is null from t1; ...@@ -610,4 +610,27 @@ select sql_buffer_result max(f1) is null from t1;
select sql_buffer_result max(f1)+1 from t1; select sql_buffer_result max(f1)+1 from t1;
drop table t1; drop table t1;
#
# BUG#14019-4.1-opt
#
CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1),(2);
SELECT a FROM t1 GROUP BY 'a';
SELECT a FROM t1 GROUP BY "a";
SELECT a FROM t1 GROUP BY `a`;
set sql_mode=ANSI_QUOTES;
SELECT a FROM t1 GROUP BY "a";
SELECT a FROM t1 GROUP BY 'a';
SELECT a FROM t1 GROUP BY `a`;
set sql_mode='';
SELECT a FROM t1 HAVING 'a' > 1;
SELECT a FROM t1 HAVING "a" > 1;
SELECT a FROM t1 HAVING `a` > 1;
SELECT a FROM t1 ORDER BY 'a' DESC;
SELECT a FROM t1 ORDER BY "a" DESC;
SELECT a FROM t1 ORDER BY `a` DESC;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -2284,12 +2284,19 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, ...@@ -2284,12 +2284,19 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
const char *field_name=0; const char *field_name=0;
const char *table_name=0; const char *table_name=0;
bool found_unaliased_non_uniq= 0; bool found_unaliased_non_uniq= 0;
/*
true if the item that we search for is a valid name reference
(and not an item that happens to have a name).
*/
bool is_ref_by_name= 0;
uint unaliased_counter; uint unaliased_counter;
LINT_INIT(unaliased_counter); LINT_INIT(unaliased_counter);
*unaliased= FALSE; *unaliased= FALSE;
if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM) is_ref_by_name= (find->type() == Item::FIELD_ITEM ||
find->type() == Item::REF_ITEM);
if (is_ref_by_name)
{ {
field_name= ((Item_ident*) find)->field_name; field_name= ((Item_ident*) find)->field_name;
table_name= ((Item_ident*) find)->table_name; table_name= ((Item_ident*) find)->table_name;
...@@ -2401,7 +2408,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, ...@@ -2401,7 +2408,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
} }
} }
else if (!table_name && (item->eq(find,0) || else if (!table_name && (item->eq(find,0) ||
find->name && item->name && is_ref_by_name && find->name && item->name &&
!my_strcasecmp(system_charset_info, !my_strcasecmp(system_charset_info,
item->name,find->name))) item->name,find->name)))
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment