MySQL → Как я фиксил баг в MySql
Эту историю можно было бы закинуть и в говнокод, но здесь не все очевидно и есть поучительные вещи.
Сотрудник сегодня скинул интересные запросы:
Empty set (1.61 sec)
1 row in set (0.11 sec)
1 row in set (0.03 sec)
Таблица t2 была создана до него, t1 создавал он сам.
В общем, он бил себя в грудь и орал, что нашел баг в мускуле. Я не верю ни в такие баги, ни в мистику (меня этому научили уже давно). Если вы видите такой «баг», то для начала найдите все баги у себя.
Не поверил я ему. Полез в эти базы, появился просто спортивный интерес:) Запускаю запросы, действительно отработали так, как он мне их сбросил. Я умышленно изменил таблицы и не показал результаты работы запросов, так вот, меня насторожило, что первый запрос выдал в результате поле login 'IGOR', а второй запрос — поле username 'igor'.
А он в качестве аргумента, что баг найден сделал так:
+-----------------------+
| if('IGOR'='igor',1,0) |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
+------------------------+
| if('IGOR'!='igor',1,0) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.00 sec)
Сука, думаю, вот тебе и баг у мускула. Полез дальше в структуру таблиц, а там я вижу.
t1.login — сравнение стоит utf8_bin
t2.username — сравнение стоит utf8_general_ci
utf8_bin — хранит буковки 'G' и 'g' по-разному.
Поменял utf8_bin на utf8_general_ci и пофиксил баг у mysql:)
Сотрудник сегодня скинул интересные запросы:
mysql> select * from db1.users t1 inner join db2.users t2 on t1.login=t2.username;
Empty set (1.61 sec)
mysql> select * from db1.users t1 where t1.login='igor';
1 row in set (0.11 sec)
mysql> select * from db2.users t2 where t2.username='igor';
1 row in set (0.03 sec)
Таблица t2 была создана до него, t1 создавал он сам.
В общем, он бил себя в грудь и орал, что нашел баг в мускуле. Я не верю ни в такие баги, ни в мистику (меня этому научили уже давно). Если вы видите такой «баг», то для начала найдите все баги у себя.
Не поверил я ему. Полез в эти базы, появился просто спортивный интерес:) Запускаю запросы, действительно отработали так, как он мне их сбросил. Я умышленно изменил таблицы и не показал результаты работы запросов, так вот, меня насторожило, что первый запрос выдал в результате поле login 'IGOR', а второй запрос — поле username 'igor'.
А он в качестве аргумента, что баг найден сделал так:
mysql> select if('IGOR'='igor',1,0);
+-----------------------+
| if('IGOR'='igor',1,0) |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select if('IGOR'!='igor',1,0);
+------------------------+
| if('IGOR'!='igor',1,0) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.00 sec)
Сука, думаю, вот тебе и баг у мускула. Полез дальше в структуру таблиц, а там я вижу.
t1.login — сравнение стоит utf8_bin
t2.username — сравнение стоит utf8_general_ci
utf8_bin — хранит буковки 'G' и 'g' по-разному.
Поменял utf8_bin на utf8_general_ci и пофиксил баг у mysql:)



