From 2ba3544f0e053d95e82b9a899fd9b86cbb19b9ce Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 19 Mar 2005 23:12:50 -0800 Subject: [PATCH] func_group.test, func_group.result: Added a test case for bug #9210. sql_select.cc: Fixed bug #9210. The function calc_group_buffer did not cover the case when the GROUP BY expression was decimal. Slightly optimized the other code. sql/sql_select.cc: Fixed bug #9210. The function calc_group_buffer did not cover the case when the GROUP by expression was decimal. Slightly optimized the other code. mysql-test/t/func_group.test: Added a test case for bug #9210. --- mysql-test/r/func_group.result | 59 ++++++++++++++++++++++++++++++++++ mysql-test/t/func_group.test | 23 +++++++++++++ sql/sql_select.cc | 48 ++++++++++++++++----------- 3 files changed, 111 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 81663cd9d66..3e06018226d 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -888,3 +888,62 @@ SELECT COUNT(DISTINCT a) FROM t1; COUNT(DISTINCT a) 2 DROP TABLE t1; +CREATE TABLE t1 (a int, b int, c int); +INSERT INTO t1 (a, b, c) VALUES +(1,1,1), (1,1,2), (1,1,3), +(1,2,1), (1,2,2), (1,2,3), +(1,3,1), (1,3,2), (1,3,3), +(2,1,1), (2,1,2), (2,1,3), +(2,2,1), (2,2,2), (2,2,3), +(2,3,1), (2,3,2), (2,3,3), +(3,1,1), (3,1,2), (3,1,3), +(3,2,1), (3,2,2), (3,2,3), +(3,3,1), (3,3,2), (3,3,3); +SELECT b/c as v, a FROM t1 ORDER BY v; +v a +0.33333 3 +0.33333 1 +0.33333 2 +0.50000 1 +0.50000 2 +0.50000 3 +0.66667 2 +0.66667 1 +0.66667 3 +1.00000 3 +1.00000 2 +1.00000 3 +1.00000 1 +1.00000 2 +1.00000 3 +1.00000 2 +1.00000 1 +1.00000 1 +1.50000 3 +1.50000 2 +1.50000 1 +2.00000 1 +2.00000 3 +2.00000 2 +3.00000 3 +3.00000 2 +3.00000 1 +SELECT b/c as v, SUM(a) FROM t1 GROUP BY v; +v SUM(a) +0.33333 6 +0.50000 6 +0.66667 6 +1.00000 18 +1.50000 6 +2.00000 6 +3.00000 6 +SELECT SUM(a) FROM t1 GROUP BY b/c; +SUM(a) +6 +6 +6 +18 +6 +6 +6 +DROP TABLE t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 0f03eae7e12..9b6f91067d4 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -601,3 +601,26 @@ INSERT INTO t1 (a) VALUES ("A"), ("a"), ("a "), ("a "), ("B"), ("b"), ("b "), ("b "); SELECT COUNT(DISTINCT a) FROM t1; DROP TABLE t1; + +# +# Test for buf #9210: GROUP BY with expression if a decimal type +# + +CREATE TABLE t1 (a int, b int, c int); +INSERT INTO t1 (a, b, c) VALUES + (1,1,1), (1,1,2), (1,1,3), + (1,2,1), (1,2,2), (1,2,3), + (1,3,1), (1,3,2), (1,3,3), + (2,1,1), (2,1,2), (2,1,3), + (2,2,1), (2,2,2), (2,2,3), + (2,3,1), (2,3,2), (2,3,3), + (3,1,1), (3,1,2), (3,1,3), + (3,2,1), (3,2,2), (3,2,3), + (3,3,1), (3,3,2), (3,3,3); + +SELECT b/c as v, a FROM t1 ORDER BY v; +SELECT b/c as v, SUM(a) FROM t1 GROUP BY v; +SELECT SUM(a) FROM t1 GROUP BY b/c; + +DROP TABLE t1; + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 811ba863a76..1e05400e88e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11891,7 +11891,8 @@ calc_group_buffer(JOIN *join,ORDER *group) join->group= 1; for (; group ; group=group->next) { - Field *field=(*group->item)->get_tmp_table_field(); + Item *group_item= *group->item; + Field *field= group_item->get_tmp_table_field(); if (field) { if (field->type() == FIELD_TYPE_BLOB) @@ -11901,27 +11902,36 @@ calc_group_buffer(JOIN *join,ORDER *group) else key_length+= field->pack_length(); } - else if ((*group->item)->result_type() == REAL_RESULT) - key_length+=sizeof(double); - else if ((*group->item)->result_type() == INT_RESULT) - key_length+=sizeof(longlong); - else if ((*group->item)->result_type() == STRING_RESULT) - { - /* - Group strings are taken as varstrings and require an length field. - A field is not yet created by create_tmp_field() - and the sizes should match up. - */ - key_length+= (*group->item)->max_length + HA_KEY_BLOB_LENGTH; - } else - { - /* This case should never be choosen */ - DBUG_ASSERT(0); - join->thd->fatal_error(); + { + switch (group_item->result_type()) { + case REAL_RESULT: + key_length+= sizeof(double); + break; + case INT_RESULT: + key_length+= sizeof(longlong); + break; + case DECIMAL_RESULT: + key_length+= my_decimal_get_binary_size(group_item->max_length - + (group_item->decimals ? 1 : 0), + group_item->decimals); + break; + case STRING_RESULT: + /* + Group strings are taken as varstrings and require an length field. + A field is not yet created by create_tmp_field() + and the sizes should match up. + */ + key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH; + break; + default: + /* This case should never be choosen */ + DBUG_ASSERT(0); + join->thd->fatal_error(); + } } parts++; - if ((*group->item)->maybe_null) + if (group_item->maybe_null) null_parts++; } join->tmp_table_param.group_length=key_length+null_parts;