4.1. Лексическая структура#
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
. Точные правила синтаксиса для каждой команды описаны в
Часть VI.
4.1.1. Идентификаторы и ключевые слова #
Компоненты типа SELECT
, UPDATE
или
VALUES
в приведенном выше примере являются примерами
ключевых слов, то есть слов, которые имеют фиксированное
значение в языке SQL. Компоненты MY_TABLE
и A
являются примерами
идентификаторов. Они идентифицируют имена
таблиц, столбцов или других объектов базы данных, в зависимости от
команды, в которой они используются. Поэтому их иногда просто
называют “именами”. Ключевые слова и идентификаторы имеют
одну и ту же лексическую структуру, что означает, что нельзя определить,
является ли компонент идентификатором или ключевым словом, не зная языка.
Полный список ключевых слов можно найти в Предметный указатель 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;
Имена, заключенные в кавычки, могут содержать любой символ, за исключением символа с кодом ноль. (Чтобы включить в идентификатор двойные кавычки, напишите две двойные кавычки). Это позволяет использовать имена таблиц или столбцов, которые в противном случае были бы невозможны, например, имена содержащие пробелы или амперсанды. Ограничение на длину при этом все еще действует.
Заключение идентификатора в кавычки также делает его чувствительным к регистру, в то время как имена без кавычек всегда приводятся к нижнему регистру. Например, идентификаторы FOO
, foo
и "foo"
считаются одинаковыми в Tantor SE-1C, но "Foo"
и "FOO"
отличаются от этих трех и друг от друга. (Приведение имен без кавычек к нижнему регистру в Tantor SE-1C несовместимо со стандартом SQL, который требует, чтобы имена без кавычек были приведены к верхнему регистру. Таким образом, foo
должно быть эквивалентно "FOO"
, а не "foo"
согласно стандарту. Если нужно писать переносимые приложения, рекомендуется всегда заключать в кавычки определенное имя или никогда не заключать его в кавычки).
Другой вариант идентификаторов в кавычках позволяет использовать экранированные символы Unicode по их кодам. Этот вариант начинается с U&
(большая или маленькая буква U, за которой следует амперсанд) непосредственно перед открывающей двойной кавычкой, без пробелов между ними, например U&"foo"
. (Обратите внимание, что это создает неоднозначность с оператором &
. Используйте пробелы вокруг оператора, чтобы избежать этого). Внутри кавычек символы Unicode можно указать в экранированной форме, используя обратную косую черту, за которой следует код из четырехзначного шестнадцатеричного числа кода или же, обратную косую черту, за которой следует плюс, а далее код из шестизначного шестнадцатеричного числа. Например, идентификатор "data"
можно записать как
U&"d\0061t\+000061"
В следующем более сложном примере записано русское слово “слон” кириллицей:
U&"\0441\043B\043E\043D"
Если нужен другой символ экранирования, а не обратная косая черта, его можно указать с помощью UESCAPE
предложение после строки, например:
U&"d!0061t!+000061" UESCAPE '!'
Экранирующий символ может быть любым одиночным символом, кроме шестнадцатеричной цифры, знака плюс, апострофа, двойной кавычки или символа пробела. Обратите внимание, что экранирующий символ записывается в апострофах, а не в двойных кавычках, после UESCAPE
.
Чтобы включить символ экранирования в идентификатор буквально, напишите его дважды.
Четырехзначная, или шестизначная форма экранирования может быть использована для указания суррогатных пар UTF-16 для создания символов с кодовыми точками, превышающими U+FFFF, хотя наличие шестизначной формы технически делает это ненужным. (Суррогатные пары не хранятся напрямую, а объединяются в одну кодовую точку).
Если кодировка сервера не UTF-8, кодовая точка Unicode, идентифицируемая одной из этих последовательностей экранирования, преобразуется в фактическую кодировку сервера; ошибка сообщается, если это невозможно.
4.1.2. Константы #
Есть три вида неявно типизированных констант в Tantor SE-1C: строки, битовые строки и числа. Константы также могут быть записаны с явным указанием типа, что может обеспечить их более точное представление и более эффективную обработку системой. Эти альтернативы обсуждаются в следующих подразделах.
4.1.2.1. Строковые константы #
Строковая константа в SQL - это произвольная последовательность символов, ограниченная апострофами ('
), например 'This is a string'
. Чтобы включить символ апострофа в строковую константу, напишите рядом два апострофа, например 'Dianne''s horse'
. Обратите внимание, что это не то же самое, что символ двойной кавычки ("
).
Два строковых константы, разделенные только пробелами и минимум одним символом перехода строки, объединяются и эффективно обрабатываются, как если бы строка была записана как одна константа. Например:
SELECT 'foo' 'bar';
равнозначно:
SELECT 'foobar';
но:
SELECT 'foo' 'bar';
не является допустимым синтаксисом. (Это слегка странное поведение зафиксировано в стандарте SQL; Tantor SE-1C следует стандарту).
4.1.2.2. Строковые константы с символами в стиле C #
Tantor SE-1C также принимает “экранирующие” строковые константы, которые являются расширением стандарта SQL.
Экранирующая строковая константа задается путем написания буквы E
(в верхнем или нижнем регистре) непосредственно перед открывающим апострофом, например, E'foo'
. (При продолжении экранирующей строковой константы на нескольких строках, напишите E
только перед первым открывающим апострофом).
Внутри экранирующей строки обратная косая черта (\
) начинает последовательность обратной косой черты в стиле C, в которой сочетание обратной косой черты и следующего символа(-ов) дает специальное байтовое значение, как показано в Таблица 4.1.
Таблица 4.1. Экранирующие последовательности с обратной косой чертой
Экранирующая последовательность с обратной косой чертой | Интерпретация |
---|---|
\b | возврат на один символ |
\f | перевод формы |
\n | newline |
\r | возврат каретки |
\t | табуляция |
\ , \ , \ (o = 0–7) | восьмеричное значение байта |
\x , \x (h = 0–9, A–F) | шестнадцатеричное значение байта |
\u , \U (x = 0–9, A–F) | 16- или 32-битный шестнадцатеричный код символа Unicode |
Любой другой символ, следующий за обратной косой чертой, воспринимается буквально. Таким образом, чтобы включить в строку символ обратной косой черты, напишите две обратные косые черты (\\
). Также апостроф можно включить в экранирующую строку, написав \'
, в дополнение к стандартному ''
.
Необходимо следить, чтобы при создании последовательности байтов, особенно при использовании восьмеричных или шестнадцатеричных экранирующих последовательностей, использовались допустимые символы в серверной кодировке. Можно использовать экранирующие последовательности Unicode или альтернативного синтаксиса экранирующих последовательностей Unicode, описанных в разделе Раздел 4.1.2.3; в этом случае сервер будет проверять возможность преобразования символов.
Предостережение
Если параметр конфигурации standard_conforming_strings установлен в значение off
, то Tantor SE-1C распознает обратные косые черты и в обычных и экранирующих строковых константах. Однако, начиная с версии PostgreSQL 9.1, значение по умолчанию устанавливается в on
, т.е. обратные косые черты распознаются только в строковых константах. Такое поведение соответствует стандартам, но может нарушить работу приложений по старому сценарию, когда обратные косые черты всегда распознавались. В качестве обходного решения, можно установить этот параметр в значение off
, но лучше не использовать обратные косые черты в качестве экранирующих символов. Если необходимо использовать обратную косую черту для представления специального символа, используйте строковую константу с префиксом E
.
В дополнение к параметру standard_conforming_strings
, параметры конфигурации escape_string_warning и backslash_quote определяют обработку обратных косых черт в строковых константах.
Символ с кодом ноль не может использоваться в строковой константе.
4.1.2.3. Строковые константы с символами в стиле Unicode #
Tantor SE-1C также поддерживает другой тип синтаксиса экранирования для строк, который позволяет указывать произвольные символы Unicode по кодам. Константа строки с экранированием Unicode начинается с U&
(буква U в верхнем или нижнем регистре, за которой следует амперсанд) непосредственно перед открывающей кавычкой, без пробелов между ними, например U&'foo'
. (Обратите внимание, что это создает неоднозначность с оператором &
. Используйте пробелы до и после оператора, чтобы избежать этой проблемы). Внутри кавычек символы Unicode можно указать в экранированной форме, написав обратную косую черту, за которой следует код их четырех шестнадцатеричных цифр или же обратную косую черту за которым следует знак плюс, за которым идет код из шести шестнадцатеричных цифр номер. Например, строка 'data'
может быть записана как
U&'d\0061t\+000061'
В следующем более сложном примере записано русское слово “слон” кириллицей:
U&'\0441\043B\043E\043D'
Если нужен другой символ экранирования, а не обратная косая черта, его можно указать с помощью UESCAPE
предложение после строки, например:
U&'d!0061t!+000061' UESCAPE '!'
Экранирующий символ может быть любым одиночным символом, кроме шестнадцатеричной цифры, знака плюс, апострофа, двойной кавычки или символа пробела.
Чтобы включить символ экранирования в строку буквально, напишите его дважды.
Можно использовать как четырехзначную, так и шестизначную форму экранирования для указания суррогатных пар UTF-16 для создания символов с кодовыми точками, превышающими U+FFFF, хотя наличие шестизначной формы технически делает это ненужным. (Пары суррогатов не хранятся напрямую, а объединяются в одну кодовую точку).
Если кодировка сервера не UTF-8, кодовая точка Unicode, идентифицируемая одной из этих последовательностей экранирования, преобразуется в фактическую кодировку сервера; ошибка сообщается, если это невозможно.
Также, экранирующий синтаксис Unicode для строковых констант работает только когда параметр конфигурации standard_conforming_strings включен. Это происходит потому, что в противном случае этот синтаксис может запутать клиентские программы, которые анализируют SQL-запросы, что может привести к уязвимости для SQL-инъекций и аналогичным проблемам безопасности. Если параметр установлен в значение off, этот синтаксис будет отклонен с сообщением об ошибке.
4.1.2.4. Строковые константы, заключенные в знаки доллара #
Хотя стандартный синтаксис для указания строковых констант обычно
удобен, его может быть трудно понять, когда желаемая строка
содержит много одинарных кавычек, так как каждая из них должна
быть удвоена. Чтобы сделать запросы более читаемыми в таких ситуациях,
Tantor SE-1C предоставляет другой способ - “заключение в долларовые кавычки”, для записи строковых констант.
Долларовая строковая константа
состоит из знака доллара ($
), необязательного
“тега” из нуля или более символов, еще одного знака
доллара, произвольной последовательности символов, составляющих
содержимое строки, знака доллара, того же тега, с которого начинается цитирование, и знака доллара. Например, вот два
разных способа указать строку “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\\]
, которая будет распознана при выполнении тела функции в Tantor SE-1C. Но поскольку эта последовательность не соответствует внешнему тегу в знаках доллара $function$
, с точки зрения внешней строки, это просто символы в пределах константы.
Если в строке со знаками доллара есть тег, но подчиняется тем же правилам, что и идентификатор без кавычек, за исключением того, что тег не может содержать знак доллара. Теги чувствительны к регистру, поэтому $tag$String content$tag$
является правильным, а $TAG$String content$tag$
- нет.
Строка, заключенная в знаки доллара и следующая за ключевым словом или идентификатором, должна быть отделена от него пробелом; в противном случае знаки доллара будут восприняты как часть предыдущего идентификатора.
Долларовая кавычка не является частью стандарта SQL, но часто является более удобным способом записи сложных строковых литералов, чем стандартный синтаксис с апострофом. Она особенно полезна при представлении строковых констант внутри других констант, что часто требуется в определениях процедурных функций. При использовании синтаксиса с апострофом, каждая обратная косая черта в приведенном выше примере должна быть записана как четыре обратных черты, которые были бы сокращены до двух при разборе исходной строковой константы, а затем до одного при повторном разборе внутренней строковой константы во время выполнения функции.
4.1.2.5. Битовые строковые константы #
Битовые строковые константы выглядят как обычные строковые константы с символом B
(в верхнем или нижнем регистре) непосредственно перед открывающей кавычкой (без промежуточных пробелов), например, B'1001'
. Единственные допустимые символы внутри битовых строковых констант - это 0
и 1
.
Альтернативно, битовые строковые константы могут быть записаны в шестнадцатеричном виде с использованием начального символа X
(в верхнем или нижнем регистре), например, X'1FF'
. Эта запись эквивалентна битовой строковой константе с четырьмя двоичными цифрами вместо одной шестнадцатеричной цифры.
Оба вида битовых констант можно переносить на следующие строки так же, как обычные строковые константы. Заключение в долларовые кавычки не используется в битовых константах.
4.1.2.6. Числовые константы #
Числовые константы задаются в следующих общих формах:
digits
digits
.[digits
][e[+-]digits
] [digits
].digits
[e[+-]digits
]digits
e[+-]digits
где digits
— это одна или несколько десятичных цифр (от 0 до 9). По крайней мере одна цифра должна быть перед или после десятичной точки, если она используется. По крайней мере одна цифра должна следовать за маркером экспоненты (e
), если он присутствует. В константе не может быть пробелов или других символов, кроме подчеркиваний, которые могут использоваться для визуальной группировки, как описано ниже. Обратите внимание, что любой ведущий плюс или минус на самом деле не считается частью константы; это оператор, применяемый к константе.
Вот несколько примеров допустимых числовых констант:
42
3.5
4.
.001
5e2
1.925e-3
Дополнительно, недесятичные целочисленные константы принимаются в следующих формах:
0xhexdigits
0ooctdigits
0bbindigits
где hexdigits
— это одна или несколько шестнадцатеричных цифр
(0-9, A-F), octdigits
— это одна или несколько восьмеричных
цифр (0-7), и bindigits
— это одна или несколько двоичных
цифр (0 или 1). Шестнадцатеричные цифры и префиксы системы счисления могут быть в
верхнем или нижнем регистре. Обратите внимание, что только целые числа могут иметь не-десятичные формы,
а не числа с дробными частями.
Это несколько примеров допустимых недесятичных целых чисел:
0b100101
0B10011001
0o273
0O755
0x42f
0XFFFF
Для визуальной группировки можно вставлять символы подчеркивания между цифрами. Это не влияет на значение константы. Например:
1_500_000_000
0b10001000_00000000
0o_1_755
0xFFFF_FFFF
1.618_034
Подчеркивания не допускаются в начале или в конце числовой константы или группы цифр (то есть непосредственно перед или после десятичной точки или маркера экспоненты), и более одного подчеркивания подряд не допускается.
Числовая константа, не содержащая ни десятичной точки, ни экспоненты, изначально считается типом 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
' AStype
)
Текст строковой константы передается в процедуру преобразования ввода для типа, называемого type
. Результатом является константа указанного типа. Явное приведение типа можно опустить, если нет неоднозначности относительно типа, который должна иметь константа (например, когда она непосредственно присваивается столбцу таблицы), в этом случае она приводится автоматически.
Строковая константа может быть записана с использованием обычного синтаксиса SQL или с использованием долларовых кавычек.
Также можно записать приведение типа как функцию:
typename
( 'string
' )
но не все имена типов могут быть использованы таким образом; см. Раздел 4.2.9 для получения подробной информации.
Конструкции ::
, CAST()
и синтаксис вызова функций также можно использовать для указания преобразования типов произвольных выражений во время выполнения, как описано в разделе Раздел 4.2.9. Чтобы избежать синтаксической неоднозначности, синтаксис
используется только для указания типа простой текстовой константы. Еще одно ограничение синтаксиса type
'string
'
заключается в том, что он не работает для массивов; используйте type
'string
'::
или CAST()
для указания типа таких констант.
Синтаксис CAST()
соответствует SQL. Синтаксис
является обобщением стандарта: SQL поддерживает этот синтаксис только для нескольких типов данных, но Tantor SE-1C позволяет его использовать для всех типов. Синтаксис с использованием type
'string
'::
исторически используется в Tantor SE-1C, также как и синтаксис вызова функции.
4.1.3. Операторы #
Имя оператора - это последовательность из максимум NAMEDATALEN
-1
(по умолчанию 63) символов из следующего списка:
+ - * / < > = ~ ! @ # % ^ & | ` ?
Но есть несколько ограничений на имена операторов:
--
и/*
не могут использоваться в имени оператора, так как они будут восприняты как начало комментария.Многосимвольное имя оператора не может заканчиваться на
+
или-
, если имя также не содержит хотя бы один из этих символов:~ ! @ # % ^ & | ` ?
Например,
@-
является допустимым именем оператора, но*-
нет. Это ограничение позволяет Tantor SE-1C разбирать запросы, совместимые с SQL, без необходимости использования пробелов между компонентами.
При работе с операторами, не соответствующими стандарту SQL, обычно необходимо разделять соседние операторы пробелами, чтобы избежать неоднозначности. Например, если вы определили префиксный оператор с именем @
, вы не можете написать X*@Y
; необходимо написать X* @Y
, чтобы гарантировать, что Tantor SE-1C прочитает это как два имени операторов, а не одно.
4.1.4. Специальные символы #
Некоторые символы, которые не являются буквенно-цифровыми, имеют специальное значение, но не являются операторами. Подробности об их использовании можно найти в описании соответствующего синтаксического элемента. В этом разделе лишь кратко описано назначение этих символов.
В теле определения функции или подготовленного оператора символ доллара (
$
), за которым следуют цифры, используется для представления позиционного параметра. В других контекстах символ доллара может быть частью идентификатора или строковой константы, заключенной в двойные долларовые кавычки.Круглые скобки (
()
) выполняют стандартную функцию для группировки выражений и обеспечения приоритета. В некоторых случаях скобки нужны в составе фиксированного синтаксиса определенных SQL-команд.Квадратные скобки (
[]
) используются для выбора элементов массива. См. Раздел 8.15 для получения дополнительной информации о массивах.В некоторых синтаксических конструкциях запятые (
,
) используются для разделения элементов списка.Точка с запятой (
;
) завершает SQL-команду. Она не может использоваться внутри команды, за исключением строковой константы или идентификатора в кавычках.Двоеточие (
:
) используется для выбора “срезов” из массивов. (См. Раздел 8.15). В некоторых диалектах SQL (например, в Embedded SQL) двоеточие используется как префикс в именах переменных.Звездочка (
*
) используется в некоторых контекстах для обозначения всех полей строки таблицы или составного значения. Она также имеет особое значение, когда используется в качестве аргумента агрегатной функции, а именно, агрегатных функций, которые не требуют явных параметров.Точка (
.
) используется в числовых константах и для разделения имен схемы, таблицы и столбца.
4.1.5. Комментарии #
Комментарий - это последовательность символов, начинающаяся с двойного дефиса и продолжающаяся до конца строки, например:
-- This is a standard SQL comment
Также можно использовать комментарии в стиле C:
/* multiline comment * with nesting: /* nested block comment */ */
где комментарий начинается с /*
и продолжается до
соответствующего вхождения */
. Эти блочные комментарии можно вкладывать друг в друга, как указано в стандарте SQL, (но не в стандарте C), так что можно комментировать более крупные блоки кода, которые могут уже содержать блочные комментарии.
Комментарий удаляется из входного потока перед дальнейшим синтаксическим анализом и фактически заменяется пробелом.
4.1.6. Приоритет операторов #
Таблица 4.2 показывает приоритет и ассоциативность операторов в Tantor SE-1C. Большинство операторов имеют одинаковый приоритет и левую ассоциативность. Приоритет и ассоциативность операторов жестко заданы в парсере. Добавьте скобки, если нужно, чтобы выражение с несколькими операторами было разобрано иначе, чем предполагают правила приоритизации.
Таблица 4.2. Приоритет операторов (от наивысшего к наименьшему)
Оператор/Элемент | Ассоциативность | Описание |
---|---|---|
. | слева-направо | разделитель имени таблицы/столбца |
:: | left | Tantor SE-1C-стиль приведения типов |
[ ] | слева-направо | выбор элемента массива |
+ - | справа-налево | унарный плюс, унарный минус |
СОРТИРОВКА | левый | выбор сортировки |
AT | left | AT TIME ZONE |
^ | слева-направо | возведение в степень |
* / % | слева-направо | умножение, деление, остаток от деления |
+ - | слева-направо | сложение, вычитание |
(любой другой оператор) | слева | все остальные встроенные и пользовательские операторы |
BETWEEN IN LIKE ILIKE SIMILAR | содержание диапазона, принадлежность к множеству, сопоставление строк | |
< > = <= >= <>
| операторы сравнения | |
IS ISNULL NOTNULL | IS TRUE , IS FALSE , IS
NULL , IS DISTINCT FROM , и т.п. | |
NOT | справа-налево | логическое отрицание |
AND | слева-направо | логическое соединение |
OR | слева-направо | логическое дизъюнкция |
Обратите внимание, что правила приоритизации операторов также применяются к определенным пользователем операторам, с теми же именами, что и встроенные операторы, упомянутые выше. Например, если вы определите оператор “+” для некоторого пользовательского типа данных, он будет иметь тот же приоритет, что и встроенный оператор “+”, независимо от того, что он делает.
Когда в синтаксисе OPERATOR
используется оператор с указанием схемы, например:
SELECT 3 OPERATOR(pg_catalog.+) 4;
конструкция OPERATOR
считается имеющей приоритет по умолчанию,
указанный в Таблица 4.2 для
“любого другого оператора”. Это верно независимо от
того, какой конкретный оператор находится внутри OPERATOR()
.
Примечание
В версиях PostgreSQL до 9.5 использовались немного другие правила приоритизации операторов. В частности, операторы <=
, >=
и <>
ранее обрабатывались по общим правилам; тесты IS
ранее имели более высокий приоритет; и конструкции NOT BETWEEN
и связанные с ними в некоторых случаях действовали несогласованно, принимая приоритет NOT
вместо BETWEEN
. Эти правила были изменены для обеспечения соответствия стандарту SQL и с целью уменьшения путаницы от несогласованного обращения к логически равнозначным конструкциям. В большинстве случаев эти изменения не приведут к изменению поведения или просто вызовут ошибку “нет такого оператора”, которую можно исправить, добавив скобки. Однако есть некоторые частные случаи, в которых запрос может изменить свое поведение, не выдавая ошибку разбора.