Лексическая структура

4.1. Лексическая структура

Входной поток SQL состоит из последовательности команд. А команда в свою очередь из последовательности токенов и завершается точкой с запятой (";"). Конец входного потока также завершает команду. Какие токены являются правильными а какие нет, зависит от синтаксиса отдельной команды.

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

Например, следующие строки в потоке ввода SQL являются (синтаксически) правильными:

SELECT * FROM MY_TABLE;
UPDATE MY_TABLE SET A = 5;
INSERT INTO MY_TABLE VALUES (3, 'hi there');

Эта последовательность из трёх команд, по одной в каждой строке (что необязательно; в одной строке может быть несколько команд, но при этом, и команда может быть разбита на несколько строк).

Кроме того, в потоке ввода SQL могут встречаться комментарии. Они не имеют токенов, они просто являются эквивалентом пробелов.

Синтаксис SQL не является очень строгим относительно токенов, идентифицирующих команды, а также операндов и параметров. Первые несколько токенов обычно являются именем команды, как в примере, данном выше, и обычно будет говориться о командах "SELECT", "UPDATE" и "INSERT". Но, например, команда UPDATE всегда требует токен SET, который должен к тому же находится в определённой позиции, а определённый вариант команды INSERT также требует, чтобы токен VALUES находился в надлежащем месте. Точные правила синтаксиса для каждой команды описываются в Part VI.

4.1.1. Идентификаторы и ключевые слова

Такие токены как SELECT, UPDATE или VALUES в показанном выше примере, являются примерами ключевых слов, т.е. таких слов, которые имеют фиксированное значение в языке SQL. Токены MY_TABLE и A являются примерами идентификаторов Они идентифицируют имена таблиц или других объектов базы данных, в зависимости от команды, в которой они используются. Таким образом, они иногда просто называются "именами" Ключевые слова и идентификаторы имеют одну и ту же лексическую структуру и это означает, что нельзя заранее знать является ли токен идентификатором или ключевым словом в неизвестном языке. Полный список ключевых слов можно найти в Appendix C.

Идентификаторы SQL и ключевые слова должны начинаться с букв (a-z, а также с букв с диакритическими отметками и нелатинских букв) или символа подчёркивания (_). Остальные символы в идентификаторе или ключевом слове могут быть буквами, подчёркиваниями, цифрами (0-9) или знаками доллара ($). Заметим, что знак доллара в идентификаторах, не разрешается по стандарту SQL, так что его использование может сделать приложения менее переносимыми. Стандарт SQL не будет определять никаких ключевых слов, содержащих цифры или начинающихся или заканчивающихся подчёркиванием, так что идентификаторы в таком виде являются наиболее безопасными с точки зрения их конфликтов с будущими расширениями этого стандарта.

Длина идентфикатора должна быть не более NAMEDATALEN-1 байт; в командах могуть использоваться и более длинные имена, но они будут урезаны. По умолчанию значение NAMEDATALEN составляет 64, так что максимальная длина идентификатора может быть 63 байта. Если это ограничение вызывает проблемы, вы можете изменить константу NAMEDATALEN в файле src/include/pg_config_manual.h.

Ключевые слова и неэкранированные идентификаторы являются независимыми от регистра букв. Таким образом

UPDATE MY_TABLE SET A = 5;

эквивалентно

uPDaTE my_TabLE SeT a = 5;

Часто используемое соглашение состоит в том, что ключевые слова пишут в верхнем регистре, а имена в нижнем, т.е.

UPDATE my_table SET a = 5;

Существует второй вид идентификатора: разделённый индентификатор или заключённый в кавычки идентификтор. Он имеет форму заклюёченной в двойные кавычки (") произвольной последовательности символов. Разделённый идентификатор всегда является идентификатором и никогда не может быть ключевым словом. Так "select" может быть использован в качестве названия колонки или таблицы с именем "select", в то время как не заключённое в кавычки слово select является ключевым словом. В результате его использование там, где необходимо ввести имя таблицы или колонки, будет вызывать ошибку. Данный выше пример может быть переписан с использованием заключенных в кавычки идентификаторов:

UPDATE "my_table" SET "a" = 5;

Заключённые в кавычки идентификаторы могут содержать любые символы, кроме символа с кодом ноль. (Чтобы включить символ двойной кавычки нужно использовать две двойные кавычки). Это позволяет конструировать такие имена таблиц или колонок, которые в других случаях были бы невозможны, например содержащие пробелы или амперсанды. Но ограничение на длину идентификатора остаётся в силе.

Одним из вариантов, заключённого в кавычки идентификатора, позволяет включать экранированные символы Unicode, которые идентифицируются по их кодам. Такой вариант идентификатора начинается с U& (U в верхем или нижнем регистре, за которым следует аперсанд) сразу же после открывающей двойной кавычки, без каких-либо пробелов между ними, например U&"foo". (Обратите внимание, что это создаёт двусмысленность с оператором &. Использование пробелов вокруг данного оператора, даёт возможность избежать данную проблему). Внутри кавычек, символы Unicode могут быть заданы в экранированной форме, с помощью обратной косой черты, за которой следует 4-х разрядный шестнадцетиричный код или, в качестве альтернативы, за обратной косой чертой следует знак плюс и семиразрядный шестнадцатеричный код. Например, идентификатор "data" может быть записан как:

U&"d\0061t\+000061"

Далее представлен менее простой пример, записывающий русское слово "слон" кирилицей:

U&"\0441\043B\043E\043D"

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

U&"d!0061t!+000061" UESCAPE '!'

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

Чтобы включить символ экранирования непосредственно в идентификатор, напишите его дважды.

Синтаксис экранирования Unicode работает только, когда кодировкой сервера является UTF8. Когда используются другие кодировки сервера, могут быть заданы только коды в диапазоне ASCII (до \007F включительно). Для задания суррогатных пар UTF-16 могут быть использованы как 4-х так и 6-ти разрядные формы, для символов с кодами больше, чем U+FFFF, хотя доступность 6-ти разрядной формы технически делает это ненужным. (Суррогатные пары не сохраняются напрямую, но комбинируются в единый код, который затем кодируется в UTF-8.)

Заключение идентификатора в кавычки также делает его зависимым от регистра букв. Например, идентификаторы FOO, foo и "foo" считаются PostgreSQL одинаковыми, а "Foo" и "FOO" отличаются от предыдущих трёх и друг от друга. (Преобразование незаключённых в кавычки имен в нижний регистр в PostgreSQL является несовместимым со стандартном SQL, который говорит, что незаключённые в кавычки имена должны конвертироваться в верхний регистр. Так, в соответствии со стандартном, имя foo должно быть эквивалентно "FOO", а не "foo". Если вы хотите писать переносимые приложения, вы должны позаботится о том, чтобы либо всегда использовать кавычки, либо никогда не использовать их.

4.1.2. Константы

В PostgreSQL существует три вида неявно-задаваемых констант: строки, битовые строки и числа. Константы могут также быть заданы с явным указанием типа, что может позволить более аккуратно представить значение константы и более эффективно ей управлять. Эти альтернативы описываются в следующих разделах.

4.1.2.1. Строковые константы

Строковая константа в SQL - это произвольная последовательность символов, заключённых в одинарные кавычки ('), например, 'This is a string'. Чтобы включить символ одинарной кавычки внутрь строковой константы, нужно написать его дважды, например, 'Dianne''s horse'. Обратите внимание, что это не тоже самое: что символ двойной кавычки (").

Две строковые константы, которые разделены только пустым пространством с как минимум одним переводом строки сливаются и будут считаться одной строковой константой. Например:

SELECT 'foo'
'bar';

эквивалентно:

SELECT 'foobar';

но:

SELECT 'foo'      'bar';

является неправильным синтаксисом. (Такое странное поведение задаётся в SQL; PostgreSQL следует стандарту).

4.1.2.2. Строковые константы с экранированными последовательностями в стиле языка Си

PostgreSQL также понимает "экранированные" строковые константы: которые являются расширением стандарта SQL. Экранированные строки задаются с помощью буквы E (в верхнем или нижнем регистре), за которой следует открывающая одиночная кавычка, например E'foo'. (Если экранированная строковая константа занимает несколько строк, пишите E только перед первой открывающей кавычкой.) Внутри экранированной строки, символ обратная косая черта (\), начинает экранированную обратной косой чертой последовательность как в языке Си, в которой комбинация обратной косой черты и следующего за ней символа или символов, представляет специальное байтовое значение, как показано в Table 4-1.

Table 4-1. Последовательности, экранированные обратной косой чертой

Экранированная последовательностьИнтерпретация
\bзабой символа
\fподача формы
\nновая строка
\rвозврат каретки
\tтабуляция
\o, \oo, \ooo (o = 0 - 7) байт в восьмеричной системе
\xh, \xhh (h = 0 - 9, A - F) байт в шестнадцатеричной системе
\uxxxx, \Uxxxxxxxx (x = 0 - 9, A - F) 16 или 32-битный шестнадцатеричное значение символа Unicode

Любой другой символ, следующий за обратной косой чертой представляет сам себя. Таким образом, чтобы включить символ обратной косой черты, нужно написать его дважды (\\). Также, в экранированную строку может быть включена одиночная кавычка, с помощью написания \', в дополнение к обычному способу ''.

Вы сами должны следить, чтобы байтовые последовательности который вы создаёте, особенно когда используются восьмеричные или шестнадцатеричные последовательности, были правильными символами в кодировке, которая установлена на сервере. Когда кодировкой на сервере является UTF-8, то вместо этого должны использоваться последовательности Unicode или альтернативный ситаксис экранирования Unicode, описанный в Section 4.1.2.3. (Это альтернатива ручного ввода UTF-8 по байтам, который очень обременителен.)

Ситаксис Unicode последовательности работает полностью только, когда кодировкой сервера является UTF8. Когда используются другие серверные кодировки, могут быть заданы только коды в диапазоне ASCII (до \u007F включительно). Для задания суррогатных пар UTF-16 могут быть использованы как 4-х так и 8-ми разрядные формы, для символов с кодами больше, чем U+FFFF, хотя доступность 8-ми разрядной формы технически делает это ненужным. (Суррогатные пары используются, когда кодировкой сервера является UTF8, они сперва комбинируются в единый код, который затем кодируется в UTF-8.)

Caution

Если конфигурационный параметр standard_conforming_strings установлен в off, то PostgreSQL распознаёт экранирование обратной косой чертой как в обычных строковых константах, так и в экранированных. Однако,в PostgreSQL 9.1 по умолчанию установлено on, что означает, что экранирование обратной косой чертой распознаётся только в строковых константах. Такое поведение больше соответствует стандартам, но может привести к неправильной работе приложений, который следуют историческому поведению, где экранирование обратной косой чертой распознаётся всегда. В качестве обходного пути, вы можете установить этот параметр в off, но лучше мигрировать в сторону отказа от использования экранирования с обратной косой чертой. Если вам необходимо использовать экранирование с обратной косой чертой, чтобы представить специальный символ, пишите строковую константу с E.

В дополнение к standard_conforming_strings, поведением, связанным с обработкой обратной косой черты в строковых константах, управляют также конфигурационные параметры escape_string_warning и backslash_quote.

Символ с нулевым кодом не может быть в строковой константе.

4.1.2.3. Строковые константы с экранированным Unicode

PostgreSQL также поддерживает другой тип синтаксиса экранирования для строк, который позволяет задавать произвольные символы Unicode с помощью их кодов. Строковая константа с экранированным Unicode начинается с U& (U в верхнем или нижнем регистре, за которой следует амперсанд) сразу после открывающей кавычки, без каких-либо пробелов между ними, например U&'foo'. (Обратите внимание, что это создаёт двусмысленность с оператором &. Использование пробелов вокруг данного оператора, даёт возможность избежать данную проблему). Внутри кавычек, символы Unicode могут быть заданы в экранированной форме, с помощью обратной косой черты, за которой следует 4-х разрядный шестнадцетиричный код или, в качестве альтернативы, за обратной косой чертой следует знак плюс и семиразрядный шестнадцатеричный код. Например, строка 'data' может быть записана как:

U&'d\0061t\+000061'

Далее представлен менее простой пример, записывающий русское слово "слон" кирилицей:

U&'\0441\043B\043E\043D'

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

U&'d!0061t!+000061' UESCAPE '!'

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

Синтаксис экранирования Unicode работает только, когда кодировкой сервера является UTF8. Когда используются другие кодировки сервера, могут быть заданы только коды в диапазоне ASCII (до \007F включительно). Для задания суррогатных пар UTF-16 могут быть использованы как 4-х так и 6-ти разрядные формы, для символов с кодами больше, чем U+FFFF, хотя доступность 6-ти разрядной формы технически делает это ненужным. (Суррогатные пары не сохраняются напрямую, но комбинируются в единый код, который затем кодируется в UTF-8.)

Также синтаксис экранирования Unicode для строковых констант работает только, когда включен конфигурационный параметр standard_conforming_strings. Это потому, что в противном случае данный синтаксис может привести к путанице клиенские программы, которые производят разбор операторов SQL до точки, в которой можно выполнить SQL иньекции и другие небезопасные вещи. Если параметр установлен в off, данный синтаксис будет отвергаться с появлением сообщения об ошибке.

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

4.1.2.4. Константы, экранированные знаками доллара

Несмотря на то, что стандартный синтаксис для задания строковых констант обычно удобен, он может быть труден для понимания, если строка содержит множество одинарных кавычек или символов обратной косой черты, так как каждый из этих символов должен быть сдвоен. Чтобы в таких ситуациях сделать запросы более читабельными, PostgreSQL предоставляет другой способ написания строковых констант — "между знаками доллара". Строковые константы в знаках доллара состоят из знака доллара ($), необязательного "тэга" из нуля или более символов, другого знака доллара, произвольной последовательности символов, которые представляют собой содержательную часть строки, знака доллара, такого же тэга, который был вначале и завешающего знака доллара. Например, далее показывается два разных способа задания строки "Dianne's horse" с помощью заключения в знаки долларов:

$$Dianne's horse$$
$SomeTag$Dianne's horse$SomeTag$

Обратите внимание, что внутри заключённой в знаки доллара строки, одинарные кавычки могут быть использованы без экранирования. Строковая константа в этом случае всегда записывается литерально. Символы обратной косой черты здесь не являются специальными также как и знаки доллара, если только они не входят в последовательность, совпадающую с открывающим тэгом.

Можно задать вложенные строковых константы, заключенные в знаки доллара, если выбирать разные тэги для каждого уровня вложенности. Это наиболее подходит в использовании определений функций. Например:

$function$
BEGIN
    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
END;
$function$

Здесь, последовательность $q$[\t\r\n\v\\]$q$ представляет заключённую в доллары литеральную строку [\t\r\n\v\\], которая будет распознана, когда PostgreSQL запустит тело функции. Но поскольку данная последовательность не совпадает с внешним долларовым разделителем $function$, то она просто является вложенной константой по отношению к внешней строковой константе.

Тэг строки, заключённой в доллары следует тем же правилам, что и не заключённый в доллары идентификатор, за исключением того, что он не может содержать знака доллара. Тэги являются зависимыми от регистра, так что $tag$Содержимое строки$tag$ — это правильно, а $TAG$Содержимое строки$tag$ — неправильно.

Заключённые в доллары строки, за которыми следует ключевое слово или идентифкатор должны отделяться от него пробелами; в противном сдучае долларовый разделитель будет считаться частью предшествующего ему идентифкатора.

Заключённые в доллары строки не являются частью стандарта SQL, но часто они являются более удобным способом записи сложных строковых литералов, чем соответствующий стандарту синтаксис с одинарными кавычками. Этот способ особенно полезен для представления одних строковых констант внутри других констант, что часто необходимо в определениях функций. При использовании синтаксиса с одинарной кавычкой, каждый символ обратной косой черты в приведённом выше примере должен был бы быть записан как четыре символа обратная косая черта, которые бы подавили два символа обратная косая черта при разборе первоначальной строковой константы, а затем один символ обратной косой черты при пере-разборе внутренней строки во время выполнения функции.

4.1.2.5. Битово-строковые константы

Битово-строковые константы выглядят как обычные строковые константы с символом B (в нижнем или верхнем регистре) который идёт сразу перед открываюшей кавычкой (без пробелов), например, B'1001'. В битово-строковой константе допускаются только символы 0 и 1.

Кроме-того, битово-строковые константы могут быть заданы в шестнадцатеричной нотации, используя лидирующий символ X (в верхнем или нижнем регистре), например, X'1FF'. Такая нотация эквивалентна битово-строковой константе с четырмя двоичными разрядами для каждого шестнадцатеричного разряда.

Обе формы битово-строковые констант могут занимать несколько строк таким же образом как и обычные строковые константы. Экранирование символом доллара не может быть использовано в битово-строковых константах.

4.1.2.6. Числовые константы

Числовые константы принимаются в трёх общих формах:

цифры
цифры.[цифры][e[+-]цифры]
[цифры].цифры[e[+-]цифры]
цифрыe[+-]цифры

где цифры - это одна или более десятичных цифр (от 0 до 9). По крайней мере одна цифра должна следовать до или после десятичной точки, если она используется. По крайней мере одна цифра должна следовать за символом экспоненты (e), если этот символ есть. В константе не должно быть пробелов или других символов. Заметим, что все знаки плюс или минус вначале константы не являются фактической частью константы; эти знаки являются оператором, который применяется к константе.

Вот несколько примеров правильных числовых констант:

42
3.5
4.
.001
5e2
1.925e-3

Числовая константа, которая не имеет ни десятичной точки ни символа экспоненты, считается имеющей тип integer (целое), если её значение умещается в тип integer (32 бита); в противном случае считается, что константа имеет тип bigint (большое целое), если её значение умещается в тип bigint (64 бита); в противном случае считается, что константа имеет тип numeric. Константы, которые содержат десятичную точку и/или символ экпоненты всегда считаются имеющими тип numeric.

Первоначальное назначение типа данных числовой константы просто запускает алгоритмы определения типа. В большинстве случаев константа будет автоматически приведена к наиболее соответствующему ей типу, в зависимости от контекста. Когда это необходимо, вы можете заставить числовое значение принудительно интерпретироваться как специальный тип данных, через его указание. Например, вы можете принудительно заставить числовое значение интерпретироваться как тип real (float4), написав

REAL '1.23'  -- string style
1.23::REAL   -- PostgreSQL (historical) style

Фактически существует несколько специальных случаев нотаций приведения типов, которые обсуждаются далее.

4.1.2.7. Константы и другие типы

Константу произвольного типа можно ввести с помощью одной из следующих нотаций:

type 'string'
'string'::type
CAST ( 'string' AS type )

Тест строковой константы передаётся на вход подпрограммы конвертации для типа type. Результатом является константа, указанного типа. Явное указание типа может быть опущено, если нет неоднозначности в понимании того типа, которому должна соответствовать константа (например, когда она напрямую назначается для колонки таблицы), в этом случае она будет автоматически преобразована к нужному типу.

Строковая константа может быть написана или через обычную SQL нотацию или через экранирование знаком доллара.

Также возможно задать преобразование типа с помощью синтаксиса в стиле функции:

имя типа ( 'string' )

но таким способом могут быть использованы не все имена типов; подробности см. в Section 4.2.9 for details.

::, CAST() и синтаксис в стиле функции могут также быть использованы для задания преобразования типов произвольных выражений в момент их вычисления, как описывается в Section 4.2.9. Чтобы избежать синтаксической путаницы, ситаксис тип 'строка' может быть использован только для задания типа простой литеральной константы. Другое ограничение на синтаксис тип 'строка' состоит в том, что такая конструкция не работает для типов массивов; используйте :: или CAST() чтобы задать тип массив констант.

Синтаксис CAST() соответствует стандарту SQL. Синтаксис тип 'строка' является производным стандарта: SQL определяет данный синтаксис только для некоторых типов данных, но PostgreSQL разрешает его для всех типов. Синтаксис с :: является историческим для PostgreSQL, потому как является синтаксисом вызова функций.

4.1.3. Операторы

Имя оператора - это последовательность из NAMEDATALEN-1 символов (по умолчанию 63) из следующего списка:

+ - * / < > = ~ ! @ # % ^ & | ` ?

Для имён операторов существует несколько ограничений, однако:

  • -- и /* не могут быть в имени оператора, так как они будут восприняты как начало комментария.

  • Имя оператора, состоящее из нескольких символов не может заканчиваться на + или -, если только это имя также не содержит один из следующих символов:

    ~ ! @ # % ^ & | ` ?

    Например, @- является разрешённым именем оператора, а *- - нет. Это ограничение позволяет PostgreSQL производить разбор SQL запросов не требуя обязательного наличия пробелов между токенами.

При работе с именами операторов, которые не соответствуют стандарту SQL, вам обычно будет нужно разделять оперторы пробелами, чтобы избежать неоднозначности. Например, если вы задали в левой части оператор @, вы не можете писать X*@Y; вы должны писать X* @Y, чтобы иметь уверенность, что PostgreSQL прочтёт это выражение как два имени оператора, а не одно.

4.1.4. Специальные символы

Некоторые символы, которые не являются ни цифрами ни буквами, имеют специальное значение, которое зависит от оператора. Подробности использования этих символов можно найти в описании соответствующих синтаксических элементов. Данная секция только говорит о наличии таких символов и суммирует их предназначение.

  • Знак доллара ($) следующий за цифрами используется для представления позиционного параметра в теле описания функции или подготовляемого оператора. В других контекстах знак доллара может быть частью идентификатора или экранированной знаком доллара строковой константы.

  • Круглые скобки (()) имеют свой собственный смысл в групповых выражениях и при задании приоритета выполнения операций. В других случаях круглые скобки требуются как часть фиксированного синтаксиса определённых команд SQL.

  • Квадратные скобки ([]) используются для выбора элементов массива. Подробности о массивах см. в Section 8.14.

  • Запятые (,) используются в некоторых ситаксических конструкциях для разделения элментов списка.

  • Точка с запятой (;) завершает команду SQL. Она не может быть использована внутри команды за исключением использования внутри строковой константы или заключённого в кавычки идентификатора.

  • Двоеточие (:) используется для выбора "слайсов" из массива. (См. Section 8.14.) В определённых диалектах SQL (таких как Embedded SQL), двоеточие используется как префикс имён переменных.

  • Звёздочка (*) используется в некоторых случаях для указания всех колонок в строке таблицы или составных значений. Она также имеет специальное значение, когда используется как аргумент какой-либо агрегатной функции, показывая что агрегат не требует какого-либо явного параметра.

  • Точка (.) используется в числовых константах и для разделения имён схемы, таблицы и поля.

4.1.5. Комментарии

Комментарий - это последовательность символов, которая начинается с двойного символа дефиса и продолжается до конца строки, например:

-- This is a standard SQL comment

Кроме того, можно использовать блок комментария в стиле языка C:

/* multiline comment
 * with nesting: /* вложенный блок комментариев */
 */

где комментарий начинается с /* и продолжается пока не встретится */. Показанный выше вложенный блок комментариев соответствует стандарту SQL, но не стандарту языка C, таким образом один комментарий может содержать большие блоки кода, которые также могут содержать блоки комментариев.

Комментарии удаляются из входного потока перед анализом синтаксиса и просто заменяются на пробелы.

4.1.6. Приоритеты операторов

Table 4-2 показывает приоритет и ассоциативность операторов в PostgreSQL. Приортитет и ассоциативность операторов жёстко встроенны в анализатор. Это может создать поведение, которое не является интуитивно-понятным; например логические операторы < и > имеют приоритет, который отличается от приоритета операторов <= и >=. Также, когда вы будете использовать комбинации бинарных и унарных операторов, вам иногда придётся добавлять круглые скобки. Например:

SELECT 5 ! - 6;

будет понято как:

SELECT 5 ! (- 6);

потому что анализатор не знает — пока не станет слишком позно — что ! задаётся как постфиксный оператор, а не как инфиксный. Чтобы получить в данном случае желаемое поведение, вы должны написать так:

SELECT (5 !) - 6;

Такова плата за расширяемость.

Table 4-2. Приоритет операторов (в порядке снижения)

Оператор/ЭлементАссоциативностьОписание
.слеваразделитель имени таблицы/колонки
::слеваприведение типа в стиле PostgreSQL
[ ]слевавыбор элемента массива
+ -справаунарный плюс, унарный минус
^слевазнак степени
* / %слеваумножение, деление, целочисленное деление
+ -слевасложение, вычитание
IS IS TRUE, IS FALSE, IS NULL и т.д.
ISNULL проверка на null
NOTNULL проверка на не null
(все другие)слевавсе другие стандартные и заданные пользователем операторы
IN список членов
BETWEEN вместимостьдиапазон вместимости
OVERLAPS перекрытие временного интервала
LIKE ILIKE SIMILAR совпадение строкового шаблона
< > меньше чем, больше чем
=справаприсваивание, назначение
NOTсправалогическое отрицание
ANDслевалогическое умножение
ORслевалогическое сложение

Заметим, что данные правила приоритетов операторов также применимы к оператором, определённым пользователем, которые имеют такие же имена как и встроенные операторы, описанные выше. Например, если вы определили оператор "+" для какого-либо своего типа данных, он будет иметь такой же приоритет как и встроенный оператор "+", не зависимо от того, что его создали вы.

Когда в синтаксисе OPERATOR используется имя оператора вместе с именем схемы, как в этом примере:

SELECT 3 OPERATOR(pg_catalog.+) 4;

OPERATOR сконструированный оператор имеет по умолчанию приоритет указанный в Table 4-2 для оператора "все другие". Это истина не зависит от того какой оператор будет внутри OPERATOR().

Back to top

(С) Виктор Вислобоков, 2008-2023