Подтвердить что ты не робот

Почему "2" > "10"?

Почему "2" с начальным пространством больше, чем "10"?

select ' 2' > '10';
 ?column? 
----------
 t
(1 row)

Я попробовал его с латинскими и английскими коллаборациями utf8:

                                    List of databases
   Name    |   Owner    | Encoding  |    Collation     |      Ctype       |   Access privileges   
-----------+------------+-----------+------------------+------------------+-----------------------
 cpn       | cpn        | UTF8      | en_US.UTF-8      | en_US.UTF-8      | 
 teste     | cpn        | LATIN1    | en_US.ISO-8859-1 | en_US.ISO-8859-1 | 

Я знаю, что он имеет отношение к типу, потому что когда он выполняется, он работает как ожидалось:

teste=> select ' 2'::char > '10';
 ?column? 
----------
 f
(1 row)

Что именно происходит здесь?

EDIT:

Все вышеизложенное было выполнено с 8.4.8 в Fedora 13. Но я только что протестировал с 9.04 в Centos 6 с тем же результатом:

select ' 2' > '10';
 ?column? 
----------
 t
(1 row)

Список баз данных

   Name    |   Owner    | Encoding  |  Collation  |    Ctype    |   Access privileges   
-----------+------------+-----------+-------------+-------------+-----------------------
 cpn       | postgres   | UTF8      | en_US.UTF-8 | en_US.UTF-8 | 

Новое редактирование:

Это еще больше запутать:

select ' ' > '1';
 ?column? 
----------
 f
(1 row)
4b9b3361

Ответ 1

Я думаю, что PostgreSQL автоматически пытается выяснить тип за кулисами, а в Linux он пытается избавиться от '', некоторые из сравнений также основаны на языковой версии.

  • Таким образом, ' 2' > '10' становится '2'>'10', а сравнение - '2'>'1'; они не равны, поэтому не нужно продолжать с остальной частью строки, а ascii('2') больше, чем ascii('1'), поэтому он вычисляет true.

  • Если бы это была операция равенства (например, '22' = '22 '), это привело бы к false, поскольку Postgres выполняет байтовое сравнение по байтам. Это важно, потому что при выполнении сравнений двигатель использует два разных алгоритма.

  • Если вы укажете тип с помощью typecasting, он не будет переопределять правила пространства (' '=>'').


Также кредит распространяется на: RhodiumToad и Peerce в #postgresql

Ответ 2

Я думаю, что это связано с настройками локали.

Согласно Документы PostgreSQL: поддержка локалей:

Настройки локали влияют на следующие функции SQL:

  • Порядок сортировки в запросах с использованием ORDER BY по текстовым данным
  • Возможность использования индексов с предложениями LIKE
  • Верхняя, нижняя и начальная функции
  • Семейство функций to_char