LIKE + обратный слеш + нижнее подчёркивание = нестандартное поведение

3,684 views
Skip to first unread message

Кактус

unread,
Jan 20, 2017, 7:33:38 AM1/20/17
to ClickHouse

SELECT * FROM foo WHERE abc LIKE '%#\_%'


Ожидалось, что в выборку попаду все строки в поле abc которых есть значения вида blabla#_blabla#blabla
MySQL так и сделал, но не ClickHouse




Из документации не совсем понятно: такое поведение LIKE - это нормально? Другие БД не требуют экранирования обратного слеша, который экранирует нижнее подчёркивание

Roman Kislenok

unread,
Jan 25, 2017, 1:58:09 AM1/25/17
to ClickHouse
На самом деле в документации к `like` сказано:
Use the backslash (\) for escaping metasymbols. See the note on escaping in the description of the 'match' function.
А вот уже в документации к `match` написано:
Note that the backslash symbol (\) is used for escaping in the regular expression. The same symbol is used for escaping in string literals. So in order to escape the symbol in a regular expression, you must write two backslashes (\\) in a string literal.

Поэтому нужно указывать пару '\\'

пятница, 20 января 2017 г., 22:33:38 UTC+10 пользователь Кактус написал:

man...@gmail.com

unread,
Jan 26, 2017, 3:42:28 PM1/26/17
to ClickHouse
Спасибо.

По поводу MySQL.

Насколько я помню, раньше там было такое же поведение, но в последних версиях сделали исправление специально для того, чтобы в случае LIKE было достаточно указывать только один бэкслеш для экранирования _ и %.

Это исправление весьма необычное и частное.
Суть в том, что при записи последовательности типа \_ в строковых литералах, они рассматриваются, как два символа - \_. То есть, при разборе такой последовательности, бэкслеш сохраняется.
Тогда как последовательности вида \y (неизвестная эксейп последовательность) рассматриваются как один символ y.
То есть, для символов _ и % сделано исключение в парсере строковых литералов.

Но такое исключение не сделано для регекспов. Из-за этого возникает неконсистентность: в LIKE достаточно указывать один бэкслеш для экранирования, а в RLIKE - два.
Смотрите примеры: https://gist.github.com/alexey-milovidov/756bab8a6c49994ac9556469201c5644

Поэтому я пока сомневаюсь - нужно ли нам делать такую же необычную логику, как в MySQL.
Reply all
Reply to author
Forward
0 new messages