Commit f90f3414 authored by Alexander Barkov's avatar Alexander Barkov

Bug#52849 [Com]: datetime index not work

Problem: after introduction of "WL#2649 Number-to-string conversions"

This query:
  SET NAMES cp850; -- Or any other non-latin1 ASCII-based character set
  SELECT * FROM t1
  WHERE datetime_column='2010-01-01 00:00:00'
started to add extra character set conversion: 
  SELECT * FROM t1
  WHERE CONVERT(datetime_column USING cp850)='2010-01-01 00:00:00';

so index on DATETIME column was not used anymore.
Fix:
  avoid convertion of NUMERIC/DATETIME items
  (i.e. those with derivation DERIVATION_NUMERIC).
parent 9eae31ab
...@@ -638,3 +638,22 @@ CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)) ...@@ -638,3 +638,22 @@ CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7))
Warnings: Warnings:
Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567' Warning 1292 Truncated incorrect datetime value: '2008-07-29T10:42:51.1234567'
End of 5.1 tests End of 5.1 tests
#
# Start of 5.5 tests
#
#
# Bug#52849 datetime index not work
#
CREATE TABLE t1 (Id INT, AtTime DATETIME, KEY AtTime (AtTime));
SET NAMES CP850;
INSERT INTO t1 VALUES (1,'2010-04-12 22:30:12'), (2,'2010-04-12 22:30:12'), (3,'2010-04-12 22:30:12');
EXPLAIN EXTENDED SELECT * FROM t1 FORCE INDEX(attime) WHERE AtTime = '2010-02-22 18:40:07';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref AtTime AtTime 9 const 1 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`Id` AS `Id`,`test`.`t1`.`AtTime` AS `AtTime` from `test`.`t1` FORCE INDEX (`attime`) where (`test`.`t1`.`AtTime` = '2010-02-22 18:40:07')
DROP TABLE t1;
SET NAMES latin1;
#
# End of 5.5 tests
#
...@@ -446,3 +446,21 @@ SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS ...@@ -446,3 +446,21 @@ SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS
SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)); SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7));
--echo End of 5.1 tests --echo End of 5.1 tests
--echo #
--echo # Start of 5.5 tests
--echo #
--echo #
--echo # Bug#52849 datetime index not work
--echo #
CREATE TABLE t1 (Id INT, AtTime DATETIME, KEY AtTime (AtTime));
SET NAMES CP850;
INSERT INTO t1 VALUES (1,'2010-04-12 22:30:12'), (2,'2010-04-12 22:30:12'), (3,'2010-04-12 22:30:12');
EXPLAIN EXTENDED SELECT * FROM t1 FORCE INDEX(attime) WHERE AtTime = '2010-02-22 18:40:07';
DROP TABLE t1;
SET NAMES latin1;
--echo #
--echo # End of 5.5 tests
--echo #
...@@ -1796,6 +1796,24 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, ...@@ -1796,6 +1796,24 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname,
&dummy_offset)) &dummy_offset))
continue; continue;
/*
No needs to add converter if an "arg" is NUMERIC or DATETIME
value (which is pure ASCII) and at the same time target DTCollation
is ASCII-compatible. For example, no needs to rewrite:
SELECT * FROM t1 WHERE datetime_field = '2010-01-01';
to
SELECT * FROM t1 WHERE CONVERT(datetime_field USING cs) = '2010-01-01';
TODO: avoid conversion of any values with
repertoire ASCII and 7bit-ASCII-compatible,
not only numeric/datetime origin.
*/
if ((*arg)->collation.derivation == DERIVATION_NUMERIC &&
(*arg)->collation.repertoire == MY_REPERTOIRE_ASCII &&
!((*arg)->collation.collation->state & MY_CS_NONASCII) &&
!(coll.collation->state & MY_CS_NONASCII))
continue;
if (!(conv= (*arg)->safe_charset_converter(coll.collation)) && if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII)) ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
conv= new Item_func_conv_charset(*arg, coll.collation, 1); conv= new Item_func_conv_charset(*arg, coll.collation, 1);
......
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