Bug #74449 Incorrect datetime casting with charcter_set_connection=sjis

Submitted: 20 Oct 2014 9:39 Modified: 20 Oct 2014 10:44
Reporter: Tsubasa Tanaka (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Charsets Severity:S3 (Non-critical)
Version:5.5.40, 5.6.21, 5.7.5, 5.6.22 OS:Linux (CentOS 6.3)
Assigned to: CPU Architecture:Any
Tags: cast, datetime, INDEX

[20 Oct 2014 9:39] Tsubasa Tanaka
Description:
When character_set_connection= sjis, MySQL can't use index on datetime type column correctly.
The query which can use range scan under character_set_connection=utf8, but the query executes whole index scan under character_set_connection=sjis.

This maybe relate these.

#68531: incorrect interpret single digits in time values http://bugs.mysql.com/bug.php?id=68531 

#68557: sjis changes in 5.5 break date parsing 
http://bugs.mysql.com/bug.php?id=68557 

How to repeat:
mysql> CREATE TABLE t1 (dt datetime not null, key(dt));
Query OK, 0 rows affected (0.09 sec)

mysql> INSERT INTO t1 VALUES ('2010-01-01'), ('2011-01-01'), ('2012-01-01'), ('2013-01-01'), ('2014-01-01');
Query OK, 5 rows affected (0.04 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SHOW SESSION VARIABLES LIKE 'character%';
+--------------------------+-----------------------------------+
| Variable_name            | Value                             |
+--------------------------+-----------------------------------+
| character_set_client     | utf8                              |
| character_set_connection | utf8                              |
| character_set_database   | utf8                              |
| character_set_filesystem | binary                            |
| character_set_results    | utf8                              |
| character_set_server     | utf8                              |
| character_set_system     | utf8                              |
| character_sets_dir       | /usr/mysql/5.6.21/share/charsets/ |
+--------------------------+-----------------------------------+
8 rows in set (0.15 sec)

mysql> explain SELECT * FROM t1 WHERE dt < '2012-12-31';
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | range | dt            | dt   | 5       | NULL |    3 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.24 sec)

mysql> SET SESSION character_set_connection= sjis;
Query OK, 0 rows affected (0.04 sec)

mysql> explain SELECT * FROM t1 WHERE dt < '2012-12-31';
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | NULL          | dt   | 5       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
[20 Oct 2014 10:21] MySQL Verification Team
Hello tsubasa,

Thank you for the report and test case.

Thanks,
Umesh
[20 Oct 2014 10:22] MySQL Verification Team
// 5.6.22

mysql> CREATE TABLE t1 (dt datetime not null, key(dt));
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t1 VALUES ('2010-01-01'), ('2011-01-01'), ('2012-01-01'), ('2013-01-01'), ('2014-01-01');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SHOW SESSION VARIABLES LIKE 'character%';
+--------------------------+-------------------------------------------------------------+
| Variable_name            | Value                                                       |
+--------------------------+-------------------------------------------------------------+
| character_set_client     | utf8                                                        |
| character_set_connection | utf8                                                        |
| character_set_database   | latin1                                                      |
| character_set_filesystem | binary                                                      |
| character_set_results    | utf8                                                        |
| character_set_server     | latin1                                                      |
| character_set_system     | utf8                                                        |
| character_sets_dir       | /data/ushastry/server/mysql-advanced-5.6.22/share/charsets/ |
+--------------------------+-------------------------------------------------------------+
8 rows in set (0.00 sec)

mysql> explain SELECT * FROM t1 WHERE dt < '2012-12-31';
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | range | dt            | dt   | 5       | NULL |    3 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

mysql> SET SESSION character_set_connection= sjis;
Query OK, 0 rows affected (0.00 sec)

mysql> explain SELECT * FROM t1 WHERE dt < '2012-12-31';
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | NULL          | dt   | 5       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
[20 Oct 2014 10:39] Tsubasa Tanaka
Hello Umesh,
Thank you for verifying.

This bug brings our environment serious performance issue :(

Just information for people facing same problem,
workaround is using CAST function to avoid implicit cast.

mysql56> SELECT @@character_set_connection;
+----------------------------+
| @@character_set_connection |
+----------------------------+
| sjis                       |
+----------------------------+
1 row in set (0.00 sec)

mysql56> explain SELECT * FROM t1 WHERE dt < '2012-12-31';
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | NULL          | dt   | 5       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.00 sec)

mysql56> explain SELECT * FROM t1 WHERE dt < CAST('2012-12-31' AS datetime);
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | range | dt            | dt   | 5       | NULL |    3 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
1 row in set (0.01 sec)
[20 Oct 2014 10:44] Tsubasa Tanaka
And I found this maybe duplicate of that one.

#62307: Condition "TIME = '19:20'" does not use index in sjis
http://bugs.mysql.com/bug.php?id=62307

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.053 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.