Почему текстовое значение не равно значению символа? - PullRequest
1 голос
/ 06 октября 2019

Я просматриваю книгу о PostgreSQL и нахожу следующий пример:

SELECT
        'a '::VARCHAR(2) = 'a '::TEXT AS "Text and varchar",
        'a '::CHAR(2) = 'a '::TEXT AS "Char and text",
        'a '::CHAR(2) = 'a '::VARCHAR(2) AS "Char and varchar";

, который дает:

enter image description here

что странно, и в книге сказано:

Предыдущий пример показывает, что 'a' :: CHAR (2) равно 'a' :: VARCHAR (2), но оба имеют разную длину,что не логично. Кроме того, это показывает, что 'a' :: CHAR (2) не равно 'a' :: text. Наконец, 'a' :: VARCHAR (2) равно 'a' :: text. Предыдущий пример вызывает путаницу, потому что, если переменная a равна b, а b равна c, a должно быть равно c в соответствии с математикой.

Но нет никакого объяснения, почему? Есть ли что-то в том, как хранятся данные, или, возможно, это какое-то устаревшее поведение типа CHAR?

1 Ответ

2 голосов
/ 06 октября 2019

Похоже, что поведение, которое вы видите, объясняется тем, что Postgres делает некий кастинг за сценой. Рассмотрим следующую слегка измененную версию вашего запроса:

SELECT
    'a '::VARCHAR(2) = 'a '::TEXT AS "Text and varchar",
    'a '::CHAR(2) = CAST('a '::TEXT AS CHAR(2)) AS "Char and text",
    'a '::CHAR(2) = 'a '::VARCHAR(2) AS "Char and varchar";

Возвращает True для всех трех сравнений. Очевидно, Postgres использует обе стороны второго сравнения к text, и a[ ] ([ ] обозначает пробел) - это не то же самое, что происходит от CHAR(2) и text.

Напомним, что для сравнения A = B в базе данных SQL оба типа A и B должны быть одинаковыми. Если нет, даже если кажется, что сравнение на равенство работает само по себе, под капотом, скорее всего, происходит неявное приведение.

...