From 91d2150dd69ce62f7aef3cc2855ddb975cde82da Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Sep 2005 12:37:16 -0700 Subject: [PATCH 1/3] sql_select.cc: Fixed bug #12885. Forced inheritence of the maybe_null flag for the expressions containing GROUP BY attributes in selects with ROLLUP. olap.test, olap.result: Added test case for bug #12885. mysql-test/r/olap.result: Added test case for bug #12885. mysql-test/t/olap.test: Added test case for bug #12885. sql/sql_select.cc: Fixed bug #12885. Forced inheritence of the maybe_null flag for the expressions containing GROUP BY attributes in selects with ROLLUP. --- mysql-test/r/olap.result | 13 +++++++++++++ mysql-test/t/olap.test | 13 +++++++++++++ sql/sql_select.cc | 17 ++++++++++++++--- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result index 7178895cf80..65f7c649624 100644 --- a/mysql-test/r/olap.result +++ b/mysql-test/r/olap.result @@ -516,3 +516,16 @@ a b c count 1 NULL NULL 2 NULL NULL NULL 2 DROP TABLE t1; +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +SELECT * FROM (SELECT a, a + 1, COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t; +a a + 1 COUNT(*) +1 2 1 +2 3 1 +NULL NULL 2 +SELECT * FROM (SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t; +a LENGTH(a) COUNT(*) +1 1 1 +2 1 1 +NULL NULL 2 +DROP TABLE t1; diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test index c9a16b897c6..76c62d14621 100644 --- a/mysql-test/t/olap.test +++ b/mysql-test/t/olap.test @@ -250,4 +250,17 @@ SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP; DROP TABLE t1; +# +# Bug #11885: derived table specified by a subquery with +# ROLLUP over expressions on not nullable group by attributes +# + +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); + +SELECT * FROM (SELECT a, a + 1, COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t; +SELECT * FROM (SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t; + +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e7af2a1aa75..3de546fd619 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9277,6 +9277,8 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select) The function replaces occurrences of group by fields in expr by ref objects for these fields unless they are under aggregate functions. + The function also corrects value of the the maybe_null attribute + for the items of all subexpressions containing group by fields. IMPLEMENTATION The function recursively traverses the tree of the expr expression, @@ -9287,6 +9289,9 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select) This substitution is needed GROUP BY queries with ROLLUP if SELECT list contains expressions over group by attributes. + TODO: Some functions are not null-preserving. For those functions + updating of the maybe_null attribute is an overkill. + EXAMPLES SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP @@ -9307,6 +9312,7 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list, arg != arg_end; arg++) { Item *item= *arg; + bool arg_changed= FALSE; if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM) { ORDER *group_tmp; @@ -9318,15 +9324,20 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list, if(!(new_item= new Item_ref(group_tmp->item, 0, item->name))) return 1; // fatal_error is set thd->change_item_tree(arg, new_item); - *changed= TRUE; + arg_changed= TRUE; } } } else if (item->type() == Item::FUNC_ITEM) { - if (change_group_ref(thd, (Item_func *) item, group_list, changed)) + if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed)) return 1; } + if (arg_changed) + { + expr->maybe_null= 1; + *changed= TRUE; + } } } return 0; @@ -9389,7 +9400,7 @@ bool JOIN::rollup_init() } if (item->type() == Item::FUNC_ITEM) { - bool changed= 0; + bool changed= FALSE; if (change_group_ref(thd, (Item_func *) item, group_list, &changed)) return 1; /* From 1e5069703abf8e0ae5df69a811cdd38633f5291d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Sep 2005 13:45:49 -0700 Subject: [PATCH 2/3] Manual merge --- mysql-test/t/olap.test | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test index 76c62d14621..98dc3e5056b 100644 --- a/mysql-test/t/olap.test +++ b/mysql-test/t/olap.test @@ -2,6 +2,10 @@ drop table if exists t1,t2; --enable_warnings +set @sav_dpi= @@div_precision_increment; +set div_precision_increment= 5; +show variables like 'div_precision_increment'; + create table t1 (product varchar(32), country_id int not null, year int, profit int); insert into t1 values ( 'Computer', 2,2000, 1200), ( 'TV', 1, 1999, 150), @@ -153,6 +157,13 @@ SELECT DISTINCT SUM(b), COUNT(DISTINCT b), COUNT(*) FROM t1 SELECT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP; SELECT DISTINCT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP; +SELECT b, a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP; +SELECT DISTINCT b,a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP; + +ALTER TABLE t1 ADD COLUMN c INT; +SELECT a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP; +SELECT distinct a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP; + DROP TABLE t1; # @@ -184,6 +195,7 @@ SELECT a, SUM(a) m FROM t1 GROUP BY a WITH ROLLUP; SELECT * FROM ( SELECT a, SUM(a) m FROM t1 GROUP BY a WITH ROLLUP ) t2; DROP TABLE t1; +set div_precision_increment= @sav_dpi; # # Tests for bug #7914: ROLLUP over expressions on temporary table @@ -264,3 +276,22 @@ SELECT * FROM (SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP) t; DROP TABLE t1; # End of 4.1 tests + +# +# Tests for bug #11639: ROLLUP over view executed through filesort +# + +CREATE TABLE t1(id int, type char(1)); +INSERT INTO t1 VALUES + (1,"A"),(2,"C"),(3,"A"),(4,"A"),(5,"B"), + (6,"B"),(7,"A"),(8,"C"),(9,"A"),(10,"C"); +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT type FROM t1 GROUP BY type WITH ROLLUP; +SELECT type FROM v1 GROUP BY type WITH ROLLUP; +EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP; + +DROP VIEW v1; +DROP TABLE t1; + + From 2eaee052bc8456d315b58ce776f6f7c3b24a893f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Sep 2005 15:45:31 -0700 Subject: [PATCH 3/3] olap.result, olap.test: Added a test case with VIEW for bug #12885. mysql-test/t/olap.test: Added a test case with VIEW for bug #12885. mysql-test/r/olap.result: Added a test case with VIEW for bug #12885. --- mysql-test/r/olap.result | 16 ++++++++++++++++ mysql-test/t/olap.test | 19 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result index b5b43cba3c7..df0ee09ea8e 100644 --- a/mysql-test/r/olap.result +++ b/mysql-test/r/olap.result @@ -602,3 +602,19 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using filesort DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); +CREATE VIEW v1 AS +SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP; +DESC v1; +Field Type Null Key Default Extra +a bigint(11) YES NULL +LENGTH(a) bigint(10) YES NULL +COUNT(*) bigint(21) NO 0 +SELECT * FROM v1; +a LENGTH(a) COUNT(*) +1 1 1 +2 1 1 +NULL NULL 2 +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test index 98dc3e5056b..3a6a5e46f37 100644 --- a/mysql-test/t/olap.test +++ b/mysql-test/t/olap.test @@ -263,8 +263,8 @@ SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP; DROP TABLE t1; # -# Bug #11885: derived table specified by a subquery with -# ROLLUP over expressions on not nullable group by attributes +# Bug #12885(1): derived table specified by a subquery with +# ROLLUP over expressions on not nullable group by attributes # CREATE TABLE t1 (a int(11) NOT NULL); @@ -294,4 +294,19 @@ EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP; DROP VIEW v1; DROP TABLE t1; +# +# Bug #12885(2): view specified by a subquery with +# ROLLUP over expressions on not nullable group by attributes +# +CREATE TABLE t1 (a int(11) NOT NULL); +INSERT INTO t1 VALUES (1),(2); + +CREATE VIEW v1 AS + SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP; + +DESC v1; +SELECT * FROM v1; + +DROP VIEW v1; +DROP TABLE t1;