summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2013-11-12 17:37:32 +0400
committerSergey Petrunya <psergey@askmonty.org>2013-11-12 17:37:32 +0400
commit88bf8b9c8fbfb79ac1690fa96467de9bbb9052e7 (patch)
tree7ee35d607cd75492e61ea65f6c6002dd8dfc1cd2
parentd79d0c4045f5b93ded001ca6b963727b3362cd15 (diff)
downloadmariadb-git-88bf8b9c8fbfb79ac1690fa96467de9bbb9052e7.tar.gz
MDEV-5257: MIN/MAX Optimization (Select tables optimized away) does not work for DateTime
- MIN/MAX optimizer does a check whether a "field CMP const" comparison uses a constant that's longer than the field it is compared to. Make this check only for string columns, also compare character lengths, not byte lengths.
-rw-r--r--mysql-test/r/func_group.result44
-rw-r--r--mysql-test/t/func_group.test53
-rw-r--r--sql/opt_sum.cc24
3 files changed, 118 insertions, 3 deletions
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 9049589b6db..8e50c045775 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -2186,3 +2186,47 @@ AVG(DISTINCT outr.col_int_nokey)
7.5000
DROP TABLE t1;
# End of the bug#57932
+#
+# MDEV-5257: MIN/MAX Optimization (Select tables optimized away) does not work for DateTime
+# MDEV-3855: MIN/MAX optimization doesnt work for int_col > INET_ATON
+# (correct the fix for Bug #884175)
+#
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL AUTO_INCREMENT,
+`b` datetime DEFAULT NULL,
+PRIMARY KEY (`a`),
+KEY `idx_b` (`b`)
+);
+INSERT INTO `t1` (b) VALUES ('2013-01-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-02-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-03-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-04-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-05-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-06-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-07-06 23:59:59');
+# The following should produce "Select tables optimized away"
+EXPLAIN SELECT MIN(b) FROM t1 WHERE b <= '2013-11-06 23:59:59';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+set names utf8;
+# Should be the same as above:
+EXPLAIN SELECT MIN(b) FROM t1 WHERE b <= '2013-11-06 23:59:59';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+DROP TABLE t1;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL AUTO_INCREMENT,
+`b` bigint(20) DEFAULT NULL,
+PRIMARY KEY (`a`),
+KEY `idx_b` (`b`)
+);
+insert into t1 (b) values (INET_ATON('192.168.0.1'));
+insert into t1 (b) values (INET_ATON('192.168.0.2'));
+insert into t1 (b) values (INET_ATON('192.168.0.3'));
+insert into t1 (b) values (INET_ATON('192.168.0.4'));
+insert into t1 (b) values (INET_ATON('192.168.200.200'));
+# should show "Select tables optimized away"
+explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+DROP TABLE t1;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 0c2f28ab25d..cf5f00c3ee1 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -1465,3 +1465,56 @@ SELECT AVG(DISTINCT outr.col_int_nokey) FROM t1 AS outr LEFT JOIN t1 AS outr2 ON
outr.col_int_nokey = outr2.col_int_nokey;
DROP TABLE t1;
--echo # End of the bug#57932
+
+
+--echo #
+--echo # MDEV-5257: MIN/MAX Optimization (Select tables optimized away) does not work for DateTime
+--echo # MDEV-3855: MIN/MAX optimization doesnt work for int_col > INET_ATON
+--echo # (correct the fix for Bug #884175)
+--echo #
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` datetime DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ KEY `idx_b` (`b`)
+);
+
+INSERT INTO `t1` (b) VALUES ('2013-01-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-02-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-03-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-04-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-05-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-06-06 23:59:59');
+INSERT INTO `t1` (b) VALUES ('2013-07-06 23:59:59');
+
+--echo # The following should produce "Select tables optimized away"
+EXPLAIN SELECT MIN(b) FROM t1 WHERE b <= '2013-11-06 23:59:59';
+
+-- connect (con1,localhost,root,,)
+-- connection con1
+set names utf8;
+-- echo # Should be the same as above:
+EXPLAIN SELECT MIN(b) FROM t1 WHERE b <= '2013-11-06 23:59:59';
+
+--connection default
+--disconnect con1
+
+DROP TABLE t1;
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` bigint(20) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ KEY `idx_b` (`b`)
+);
+
+insert into t1 (b) values (INET_ATON('192.168.0.1'));
+insert into t1 (b) values (INET_ATON('192.168.0.2'));
+insert into t1 (b) values (INET_ATON('192.168.0.3'));
+insert into t1 (b) values (INET_ATON('192.168.0.4'));
+insert into t1 (b) values (INET_ATON('192.168.200.200'));
+--echo # should show "Select tables optimized away"
+explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32');
+DROP TABLE t1;
+
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 069fe6452e8..aa8b17a2c85 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -479,6 +479,24 @@ int opt_sum_query(THD *thd,
}
+/*
+ Check if both item1 and item2 are strings, and item1 has fewer characters
+ than item2.
+*/
+
+static bool check_item1_shorter_item2(Item *item1, Item *item2)
+{
+ if (item1->cmp_type() == STRING_RESULT &&
+ item2->cmp_type() == STRING_RESULT)
+ {
+ int len1= item1->max_length / item1->collation.collation->mbmaxlen;
+ int len2= item2->max_length / item2->collation.collation->mbmaxlen;
+ return len1 < len2;
+ }
+ return false; /* When the check is not applicable, it means "not bigger" */
+}
+
+
/**
Test if the predicate compares a field with constants.
@@ -509,7 +527,7 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
if (!(item= it++))
return 0;
args[0]= item->real_item();
- if (args[0]->max_length < args[1]->max_length)
+ if (check_item1_shorter_item2(args[0], args[1]))
return 0;
if (it++)
return 0;
@@ -544,7 +562,7 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
}
else
return 0;
- if (args[0]->max_length < args[1]->max_length)
+ if (check_item1_shorter_item2(args[0], args[1]))
return 0;
break;
case 3:
@@ -559,7 +577,7 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
if (!item->const_item())
return 0;
args[i]= item;
- if (args[0]->max_length < args[i]->max_length)
+ if (check_item1_shorter_item2(args[0], args[1]))
return 0;
}
}