From 115616381dd2238d4889271357d7cae228ae09fa Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Mon, 16 Oct 2006 13:10:25 +0300 Subject: [PATCH] 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. --- mysql-test/r/func_gconcat.result | 5 ---- mysql-test/r/group_by.result | 45 ++++++++++++++++++++++++++++++++ mysql-test/t/func_gconcat.test | 1 - mysql-test/t/group_by.test | 23 ++++++++++++++++ sql/sql_base.cc | 11 ++++++-- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index db0125b7d4f..d4a46bfd79f 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -74,11 +74,6 @@ grp group_concat(c order by 1) 1 a 2 b,c 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; grp group_concat(distinct c order by c) 1 a diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 4ad28091164..61b73dc7005 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -773,3 +773,48 @@ select sql_buffer_result max(f1)+1 from t1; max(f1)+1 3 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; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 8f50690dd8b..d51d88d50ef 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -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 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 "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; explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index f14fab2d30e..064d46aa0c0 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -610,4 +610,27 @@ select sql_buffer_result max(f1) is null from t1; select sql_buffer_result max(f1)+1 from 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 diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0a9529d6067..40adf5e1f15 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2284,12 +2284,19 @@ find_item_in_list(Item *find, List &items, uint *counter, const char *field_name=0; const char *table_name=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; LINT_INIT(unaliased_counter); *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; table_name= ((Item_ident*) find)->table_name; @@ -2401,7 +2408,7 @@ find_item_in_list(Item *find, List &items, uint *counter, } } 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, item->name,find->name))) {