Вы жертва неявного преобразования типов
MySQL рассматривает значения из столбца битового поля как integer
и выполняет неявное приведение типа к CHAR(1)
для сравнения.
Вот что на самом деле делает MySQL, шаг за шагом:
SELECT `foo` = CHAR(1) -- Need to cast incompatible data types
SELECT 0 = CHAR(1) -- Bitfield is treated as integer
SELECT 0 = CAST(CHAR(1) AS INT) -- char 0x01 gets cast to integer
SELECT 0 = 0 -- result: 1 (boolean TRUE for MySQL)
Но неявный тип зависит от данных . Это приводит к неожиданным результатам быстро, потому что это довольно трудно обнаружить. Например:
SELECT `foo` = CHAR(49) -- Need to cast incompatible data types
SELECT 0 = CHAR(49) -- Bitfield is treated as integer
SELECT 0 = CAST(CHAR(49) AS INT) -- char 0x31 gets cast to integer
SELECT 0 = CAST("1" AS INT) -- but: char 0x31 equals "1"
SELECT 0 = 1 -- result: 0 (boolean FALSE for MySQL)
Почему это происходит? Числовой тип - это единственный тип, который можно сравнивать как с битовым полем, так и с (двоичной) строкой с помощью оператора равенства. Таким образом, столбец битового поля получает приведение к integer
:
В числовом контексте MySQL рассматривает битовый литерал как целое число.
Также персонажу необходимо привести к integer
, следуя этим правилам . Удивительно, но для того, чтобы привести двоичный символ в целое число, MySQL, по-видимому, сначала преобразовал его в обычный символ, например:
SELECT CAST(CAST(CHAR(49) AS CHAR) AS INT) -- result 1
MySQL должен дважды выполнять неявные типы типов, потому что:
SELECT CHAR(49) -- result 0x31
Здесь функция CHAR возвращает двоичный символ без какой-либо кодировки, однако приведение к integer
может произойти, только если символ можно интерпретировать с использованием кодировки. Вероятно, результат, полученный с CHAR(49)
, искажен настройкой кодирования моего соединения с MySQL.