July 22, 2010

В ожидании 9.1 - standard_conforming_strings = on

Перевод Waiting for 9.1 – standard_conforming_strings = on с select * from depesz;

В основном я пишу о новых возможностях, но это изменение довольно таки важное.

20 июля Robert Haas сделал следующие изменения:

Значение standard_conforming_strings по умолчанию теперь on.

Это изменение должно быть доведено до сведения разработчиков драйверов и в
замечаниях к релизу должно быть указанным как не совместимое с предыдущими
релизами.


Что это и почему так важно?
Допустим вы хотите выбрать какое-то значение содержащее символ ' (апостроф). Т.к. строки тоже определяются этим символом нам нужно замаскировать его.

Долгое время можно было делать так:

$ SELECT 'guns \'n roses';
?COLUMN?
---------------
guns 'n roses
(1 row)


Это выглядит нормально для любого программиста, работающего на другом языке, но у нас есть небольшая проблема - SQL стандарт это не приемлет.

Некоторое время назад, не помню когда точно, да и это не так важно, PostgreSQL представил маскированые строковые константы, которые выглядят так:

$ SELECT E'guns \'n roses';
?COLUMN?
---------------
guns 'n roses
(1 row)


И когда вы используете обычные строки с маскированием обратной косой чертой, он выдаёт предупреждение:

$ SELECT 'guns \'n roses';
WARNING: nonstandard USE of \' in a string literal
LINE 1: select 'guns \'n roses';
^
HINT: USE '' TO WRITE quotes IN strings, OR USE the escape string syntax (E'...').
?COLUMN?
---------------
guns 'n roses
(1 row)


Т.е. всё работает так же как и раньше, только добавилось это предупреждение. Конечно же оно (предупреждение) может быть отключено (escape_string_warning GUC), и вы можете запретить маскирование установив standard_conforming_strings в on.

Теперь, в 9.1, standard_conforming_strings будет по умолчанию on. А это значит, что с нашим тестом случится следующее:

$ SELECT 'guns \'n roses';
>>


PostgreSQL теперь трактует \ как обычный символ, и т.к. кол-во апострофов нечётное значит что одна из строк ещё не завержена и запрос ещё не готов.

Простой пример:

$ SELECT 'first line\nsecond line';
?COLUMN?
-------------
first line +
second line
(1 row)

$ SET standard_conforming_strings = ON;
SET

$ SELECT 'first line\nsecond line';
?COLUMN?
-------------------------
first line\nsecond line
(1 row)


Итак, как теперь писать запросы с апострофами и символами новой строки? Короткий ответ - делать это правильно. Пример:

$ SELECT 'guns ''n roses';
?COLUMN?
---------------
guns 'n roses
(1 row)

$ select E'first line\nsecond line';
?column?
-------------
first line +
second line
(1 row)


Если вы пишите запросы сами, это не большая проблема, но если используете что-то что строит их за вас (ORM или что-то формирующее параметры) - это должно быть исправлено (если не было исправлено ранее).

Конечно же можно изменить standard_conforming_strings обратно в off, но это не будет нормальным решением.

1 comment:

Anonymous said...

Thank you

Post a Comment