Функции и операторы

QHB предоставляет большое количество функций и операторов для встроенных типов данных. Пользователи также могут определять свои собственные функции и операторы, как описано в части V. Команды qsql \df и \do могут использоваться для вывода списка всех доступных функций и операторов соответственно.

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

Логические операторы

Доступны обычные логические операторы: AND, OR, NOT.

SQL использует трехзначную логическую систему с истиной (TRUE), ложью (FALSE) и неизвестностью (NULL). Соблюдайте следующие таблицы истинности:

aba AND ba OR b
TRUETRUETRUETRUE
TRUEFALSEFALSETRUE
TRUENULLNULLTRUE
FALSEFALSEFALSEFALSE
FALSENULLFALSENULL
NULLNULLNULLNULL
aNOT a
TRUEFALSE
FALSETRUE
NULLNULL

Операторы AND и OR являются коммутативными, то есть вы можете переключать левый и правый операнд, не влияя на результат. Но см. раздел Правила вычисления выражений для получения дополнительной информации о порядке вычисления подвыражений.

Функции сравнения и операторы

Доступны обычные операторы сравнения, как показано в таблице 1.

Таблица 1. Операторы сравнения

операторОписание
<меньше, чем
>больше чем
<=меньше или равно
>=больше или равно
=равный
<> или !=не равный

Операторы сравнения доступны для всех соответствующих типов данных. Все операторы сравнения являются бинарными операторами, которые возвращают значения типа boolean; выражения типа 1 < 2 < 3 недопустимы (потому что нет оператора < для сравнения логического значения с 3).

Есть также некоторые предикаты сравнения, как показано в таблице 2. Они ведут себя подобно операторам, но имеют специальный синтаксис, предписанный стандартом SQL.

Таблица 2. Предикаты сравнения

ВыражениеОписание
a BETWEEN x AND yмежду
a NOT BETWEEN x AND yне между
a BETWEEN SYMMETRIC x AND yмежду, после сортировки значений сравнения
a NOT BETWEEN SYMMETRIC x AND yне между, после сортировки значений сравнения
a IS DISTINCT FROM bне равно, рассматривая null как обычное значение
a IS NOT DISTINCT FROM bравно, рассматривая null как обычное значение
expression IS NULLnull
expression IS NOT NULLне null
expression ISNULLявляется null (нестандартный синтаксис)
expression NOTNULLне равно null (нестандартный синтаксис)
boolean_expression IS TRUEправда
boolean_expression IS NOT TRUEложно или неизвестно
boolean_expression IS FALSEложно
boolean_expression IS NOT FALSEправда или неизвестно
boolean_expression IS UNKNOWNнеизвестно
boolean_expression IS NOT UNKNOWNверно или неверно

Предикат BETWEEN упрощает тестирование диапазона:

a BETWEEN x AND y

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

a >= x AND a <= y

Обратите внимание, что BETWEEN обрабатывает значения конечных точек как включенные в диапазон. NOT BETWEEN делает противоположное сравнение:

a NOT BETWEEN x AND y

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

a < x OR a > y

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

Обычные операторы сравнения выдают null (что означает «неизвестно»), а не истину или ложь, когда любой из входных операндов null. Например, 7 = NULL возвращает null, как и 7 <> NULL. Когда это поведение не подходит, используйте предикаты IS [NOT] DISTINCT FROM:

a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b

Для не-null входных аргументов IS DISTINCT FROM аналогичен оператору <>. Однако, если оба входных аргумента имеют значение null, он возвращает false, а если только один аргумент имеет null значение, он возвращает true. Аналогично, IS NOT DISTINCT FROM идентичен = для не-null аргументов, но возвращает true, если оба аргумента имеют значение null, и false, если только один аргумент имеет значение null. Таким образом, эти предикаты эффективно действуют так, как если бы null был нормальным значением данных, а не «неизвестным».

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

expression IS NULL
expression IS NOT NULL

или эквивалентные, но нестандартные предикаты:

expression ISNULL
expression NOTNULL

Не пишите expression = NULL, потому что NULL "не равно" NULL. (NULL значение представляет неизвестное значение, и неизвестно, равны ли два неизвестных значения).

Заметка
Некоторые приложения могут ожидать, что expression = NULL возвращает true, если expression оценивается как null значение. Настоятельно рекомендуется изменить эти приложения в соответствии со стандартом SQL. Однако, если это невозможно, доступна переменная конфигурации transform_null_equals. Если он включен, QHB преобразует предложения x = NULL в x IS NULL.

Если expression имеет строковое значение, то IS NULL равно true, если само выражение строки равно нулю или когда все поля строки имеют значение null, а IS NOT NULL равно true, если само выражение строки не равно нулю и все поля строки имеют значение ненулевой. Из-за этого поведения IS NULL и IS NOT NULL не всегда возвращают обратные результаты для выражений со значениями строк; в частности, строковое выражение, содержащее как null, так и не-null поля, вернет false для обоих тестов. В некоторых случаях может быть предпочтительнее записать row IS DISTINCT FROM NULL или row IS NOT DISTINCT FROM NULL, которая просто проверит, является ли значение строки в целом нулевым, без каких-либо дополнительных тестов для полей строки.

Булевы значения также могут быть проверены с использованием предикатов

boolean_expression IS TRUE
boolean_expression IS NOT TRUE
boolean_expression IS FALSE
boolean_expression IS NOT FALSE
boolean_expression IS UNKNOWN
boolean_expression IS NOT UNKNOWN

Они всегда будут возвращать истину или ложь, никогда не принимать null значение, даже если операнд null. null вход рассматривается как логическое значение «неизвестно». Обратите внимание, что IS UNKNOWN и IS NOT UNKNOWN фактически совпадают с IS NULL и IS NOT NULL, соответственно, за исключением того, что входное выражение должно иметь логический тип.

Некоторые функции сравнения также доступны, как показано в таблице 3.

Таблица 3. Функции сравнения

ФункцияОписаниеПримерРезультат
num_nonnulls(VARIADIC "any")возвращает количество ненулевых аргументовnum_nonnulls(1, NULL, 2)2
num_nulls(VARIADIC "any")возвращает количество нулевых аргументовnum_nulls(1, NULL, 2)1

Математические функции и операторы

Математические операторы предоставляются для многих типов QHB. Для типов без стандартных математических соглашений (например, типы даты / времени) мы описываем фактическое поведение в последующих разделах.

Таблица 4 показывает доступные математические операторы.

Таблица 4. Математические операторы

ОператорОписаниепримерРезультат
+суммирование2 + 35
-вычитание2 - 3-1
*умножение2 * 36
/деление (целочисленное деление усекает результат)4 / 22
%по модулю (остаток)5 % 41
^возведение в степень (партнеры слева направо)2.0 ^ 3.08
/квадратный корень/ 25.05
/кубический корень/ 27.03
!факториал5 !120
!!факториал (префиксный оператор)!! 5120
@абсолютная величина@ -5.05
&побитовое И91 & 1511
|побитовое ИЛИ32 | 335
#побитовый XOR17 # 520
~побитовое НЕ~1-2
<<битовое смещение влево1 << 416
>>битовое смещение вправо8 >> 22

Битовые операторы работают только с целочисленными типами данных, тогда как остальные доступны для всех числовых типов данных. Побитовые операторы также доступны для битовых типов bit и bit varying, как показано в таблице 8.14.

Таблица 5 показывает доступные математические функции. В таблице dp указывает на double precision. Многие из этих функций представлены в нескольких формах с различными типами аргументов. Если не указано иное, любая форма функции возвращает тот же тип данных, что и ее аргумент. Функции, работающие с данными double precision, в основном реализованы поверх библиотеки C/RUST хост-системы; поэтому точность и поведение в граничных случаях могут варьироваться в зависимости от хост-системы.

Таблица 5. Математические функции

ФункцияТип ответаОписаниеПримерРезультат
abs(x)(так же, как вход)абсолютная величинаabs(-17.4)17.4
cbrt(dp)dpкубический кореньcbrt(27.0)3
ceil(dp or numeric)(так же, как вход)ближайшее целое число больше или равно аргументуceil(-42.8)-42
ceiling(dp or numeric)(так же, как вход)ближайшее целое число больше или равно аргументу (то же, что и ceil)ceiling(-95.3)-95
degrees(dp)dpрадианы в градусыdegrees(0.5)28.6478897565412
div(y numeric, x numeric)numericцелое отношение y / xdiv(9,4)2
exp(dp or numeric)(так же, как вход)экспоненциальныйexp(1.0)2.71828182845905
floor(dp or numeric)(так же, как вход)ближайшее целое число меньше или равно аргументуfloor(-42.8)-43
ln(dp or numeric)(так же, как вход)натуральный логарифмln(2.0)0.693147180559945
log(dp or numeric)(так же, как вход)основание 10 логарифмlog(100.0)2
log10(dp or numeric)(так же, как вход)основание 10 логарифмlog10(100.0)2
log(b numeric, x numeric)numericлогарифм по основанию blog(2.0, 64.0)6.0000000000
mod(y, x)(так же, как типы аргументов)остаток от y / xmod(9,4)1
pi()dpКонстанта πpi()3.14159265358979
power(a dp, b dp)dpвозведенный в степень bpower(9.0, 3.0)729
power(a numeric, b numeric)numericвозведенный в степень bpower(9.0, 3.0)729
radians(dp)dpградусы в радианыradians(45.0)0.785398163397448
round(dp or numeric)(так же, как вход)округлить до ближайшего целогоround(42.4)42
round(v numeric, s int)numericокруглить до десятичных знаковround(42.4382, 2)42.44
scale(numeric)integerмасштаб аргумента (количество десятичных цифр в дробной части)scale(8.41)2
sign(dp or numeric)(так же, как вход)знак аргумента (-1, 0, +1)sign(-8.4)-1
sqrt(dp or numeric)(так же, как вход)квадратный кореньsqrt(2.0)1.4142135623731
trunc(dp or numeric)(так же, как вход)усечь до нуляtrunc(42.8)42
trunc(v numeric, s int)numericусечь до десятичных знаковtrunc(42.4382, 2)42.43
width_bucket(operand dp, b1 dp, b2 dp, count int)intвернуть номер сегмента, которому будет назначен operand в гистограмме, имеющей count сегментов равной ширины, охватывающих диапазон от b1 до b2 ; возвращает 0 или count +1 для входа вне диапазонаwidth_bucket(5.35, 0.024, 10.06, 5)3
width_bucket(operand numeric, b1 numeric, b2 numeric, count int)intвернуть номер сегмента, которому будет назначен operand в гистограмме, имеющей count сегментов равной ширины, охватывающих диапазон от b1 до b2 ; возвращает 0 или count +1 для входа вне диапазонаwidth_bucket(5.35, 0.024, 10.06, 5)3
width_bucket(operand anyelement, thresholds anyarray)intвернуть номер сегмента, которому будет назначен operand, с помощью массива, в котором перечислены нижние границы сегментов; возвращает 0 для входа меньше первой нижней границы; массив thresholds должен быть отсортирован, сначала наименьший, иначе будут получены неожиданные результатыwidth_bucket(now(), array[’yesterday’, ’today’, ’tomorrow’]::timestamptz[])2

В таблице 6 показаны функции для генерации случайных чисел.

Таблица 6. Случайные функции

ФункцияТип ответаОписание
random()dpслучайное значение в диапазоне 0,0 <= x <1,0
setseed(dp)voidустановить начальное значение для последующих вызовов random() (значение от -1,0 до 1,0 включительно)

Функция random() использует простой линейный конгруэнтный алгоритм. Это быстро, но не подходит для криптографических приложений; см. модуль qhbcrypto для более безопасной альтернативы. Если вызывается setseed(), то результаты последующих вызовов random() в текущем сеансе повторяются путем повторной выдачи setseed() с тем же аргументом.

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

Таблица 7. Тригонометрические функции

Функция (радианы)Функция (градусы)Описание
acos(x)acosd(x)обратный косинус
asin(x)asind(x)обратный синус
atan(x)atand(x)обратный тангенс
atan2(y, x)atan2d(y, x)обратный тангенс y / x
cos(x)cosd(x)косинус
cot(x)cotd(x)котангенс
sin(x)sind(x)синус
tan(x)tand(x)тангенс

Заметка
Другой способ работы с углами, измеряемыми в градусах, состоит в использовании функций преобразования единиц измерения radians() и degrees() показанных ранее. Однако использование тригонометрических функций, основанных на градусах, является предпочтительным, поскольку этот способ позволяет избежать ошибки округления в особых случаях, таких как sind(30).

Таблица 8 показывает доступные гиперболические функции. Все эти функции принимают аргументы и возвращают значения типа double precision.

Таблица 8. Гиперболические функции

ФункцияОписаниеПримерРезультат
sinh(x)гиперболический синусsinh(0)0
cosh(x)гиперболический косинусcosh(0)1
tanh(x)тангенс гиперболическийtanh(0)0
asinh(x)обратный гиперболический синусasinh(0)0
acosh(x)обратный гиперболический косинусacosh(1)0
atanh(x)обратный гиперболический тангенсatanh(0)0

Строковые функции и операторы

В этом разделе описываются функции и операторы для проверки и манипулирования строковыми значениями. Строки в этом контексте включают значения типов character, character varying и text. Если не указано иное, все перечисленные ниже функции работают со всеми этими типами, но с осторожностью относитесь к возможным эффектам автоматического заполнения пробелами при использовании типа character. Некоторые функции также существуют изначально для типов битовых строк.

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

Таблица 9. Строковые функции и операторы SQL

ФункцияТип ответаОписаниеПримерРезультат
string | | stringtextКонкатенация строк’Post’ | | ’greSQL’PostgreSQL
string | | non-string или non-string | | stringtextКонкатенация строк с одним нестроковым вводом’Value: ’ | | 42Value: 42
bit_length(string)intКоличество бит в строкеbit_length(’jose’)32
char_length(string) или character_length(string)intКоличество символов в строкеchar_length(’jose’)4
lower(string)textПреобразовать строку в нижний регистрlower(’TOM’)tom
octet_length(string)intКоличество байтов в строкеoctet_length(’jose’)4
overlay(string placing string from int [ for int ])textЗаменить подстрокуoverlay(’Txxxxas’ placing ’hom’ from 2 for 4)Thomas
position(substring in string)intРасположение указанной подстрокиposition(’om’ in ’Thomas’)3
substring(string [ from int ] [ for int ])textИзвлечь подстрокуsubstring(’Thomas’ from 2 for 3)hom
substring(string from pattern)textИзвлечь подстроку, соответствующую регулярному выражению POSIX. См. раздел Сопоставление с образцом для получения дополнительной информации о сопоставлении с образцом.substring('Thomas' from '...$')mas
substring(string from pattern for escape)textИзвлечь подстроку, соответствующую регулярному выражению SQL. См. раздел Сопоставление с образцом для получения дополнительной информации о сопоставлении с образцом.substring('Thomas' from '%#"o_a#"_' for '#')oma
trim([ leading | trailing | both ] [ characters ] from string)textУдалите самую длинную строку, содержащую только символы из characters (по умолчанию пробел) из начала, конца или обоих концов (both по умолчанию) строкиtrim(both ’xyz’ from ’yxTomxx’)Tom
trim([ leading | trailing | both ] [ from ] string [, characters ])textНестандартный синтаксис для trim()trim(both from ’yxTomxx’, ’xyz’)Tom
upper(string)textПреобразовать строку в верхний регистрupper(’tom’)TOM

Доступны дополнительные функции работы со строками, которые перечислены в таблице 10. Некоторые из них используются для реализации стандартных строковых функций SQL, перечисленных в таблице 9.

Таблица 10. Другие строковые функции

ФункцияТип ответаОписаниеПримерРезультат
ascii(string)intКод ASCII первого символа аргумента. Для UTF8 возвращает кодовую точку Unicode символа. Для других многобайтовых кодировок аргумент должен быть символом ASCII.ascii(’x’)120
btrim(string text [, characters text ])textУдалите самую длинную строку, состоящую только из символов в characters (по умолчанию пробел) из начала и конца stringcbtrim(’xyxtrimyyx’, ’xyz’)trim
chr(int)textСимвол с заданным кодом. Для UTF8 аргумент обрабатывается как кодовая точка Unicode. Для других многобайтовых кодировок аргумент должен обозначать символ ASCII. Символ NULL (0) недопустим, поскольку текстовые типы данных не могут хранить такие байты.chr(65)A
concat(str "any" [, str "any" [, ...] ])textОбъединить текстовые представления всех аргументов. NULL аргументы игнорируются.concat(’abcde’, 2, NULL, 22)abcde222
concat_ws(sep text, str "any" [, str "any" [, ...] ])textОбъедините все, кроме первого аргумента, с разделителями. Первый аргумент используется в качестве строки разделителя. NULL аргументы игнорируются.concat_ws(’,’, ’abcde’, 2, NULL, 22)abcde,2,22
convert(string bytea, src_encoding name, dest_encoding name)byteaПреобразовать строку в dest_encoding. Исходная кодировка указывается с помощью src_encoding. string должна быть действительной в этой кодировке. Конверсии могут быть определены с помощью CREATE CONVERSION. Также есть несколько предопределенных конверсий. Смотрите Таблицу 8.11 для доступных преобразований.convert (’text_in_utf8’, ’UTF8’, ’LATIN1’)text_in_utf8 представлен в кодировке Latin-1 (ISO 8859-1)
convert_from(string bytea, src_encoding name)textПреобразовать строку в кодировку базы данных. Исходная кодировка указывается с помощью src_encoding. string должна быть действительной в этой кодировке.convert_from (’text_in_utf8’, ’UTF8’)text_in_utf8 представлен в текущей кодировке базы данных
convert_to(string text, dest_encoding name)byteaПреобразовать строку в dest_encoding.convert_to (’some text’, ’UTF8’)some text представленный в кодировке UTF8
decode(string text, format text)byteaДекодировать двоичные данные из текстового представления в string. Параметры для format такие же, как в encode.decode (’MTIzAAE=’, ’base64’)\x3132330001
encode(data bytea, format text)textКодировать двоичные данные в текстовое представление. Поддерживаемые форматы: base64, hex, escape. escape преобразует нулевые байты и старшие биты в восьмеричные последовательности (\ nnn) и удваивает обратную косую черту.encode (’123\000\001’, ’base64’)MTIzAAE=
format (formatstr text [, formatarg "any" [, ...] ])textОтформатируйте аргументы в соответствии со строкой формата. Эта функция похожа на функцию C sprintf. См. раздел FORMAT.format (’Hello %s, %1$s’, ’World’)Hello World, World
initcap(string)textПреобразуйте первую букву каждого слова в верхний регистр, а остальные в нижний регистр. Слова — это последовательности буквенно-цифровых символов, разделенных не буквенно-цифровыми символами.initcap (’hi THOMAS’)Hi Thomas
left(str text, n int)textВернуть первые n символов в строке. Когда n отрицательно, вернуть все, кроме последних | n | символов.left(’abcde’, 2)ab
length(string)intКоличество символов в stringlength(’jose’)4
length(string bytea, encoding name)intКоличество символов в строке в заданной кодировке. Строка должна быть действительной в этой кодировке.length(’jose’, ’UTF8’)4
lpad(string text, length int [, fill text ])textЗаполнить строку до указанной длины, указанными символами fill (по умолчанию пробел). Если строка уже длиннее length она усекается (справа).lpad(’hi’, 5, ’xy’)xyxhi
ltrim(string text [, characters text ])textУдалить из начала строки, наибольшую подстроку, содержащую символы указанные в characters (по умолчанию пробел)ltrim(’zzzytest’, ’xyz’)test
md5(string)textВычисляет MD5-хеш строки, возвращая результат в шестнадцатеричном видеmd5(’abc’)900150983cd24fb0 d6963f7d28e17f72
parse_ident(qualified_identifier text [, strictmode boolean DEFAULT true ])text[]Разбить qualified_identifier на массив идентификаторов, удаляя кавычки вокруг идентификаторов. По умолчанию дополнительные символы после последнего идентификатора считаются ошибкой, но если второй параметр имеет значение false, такие символы игнорируются. (Такое поведение полезно для анализа имён таких объектов как функции). Учтите, что эта функция не усекает длинные идентификаторы. Если вам нужны усеченные имена, вы можете привести результат к name[].parse_ident (’"SomeSchema".someTable’){SomeSchema,sometable}
pg_client_encoding()nameТекущее имя кодировки клиентаpg_client_encoding()SQL_ASCII
quote_ident(string text)textВернуть указанную строку, заключенную в кавычки, для использования в качестве идентификатора в строке оператора SQL. Кавычки добавляются только в случае необходимости (т.е. если строка содержит неидентифицирующие символы или будет сложена регистром). Встроенные цитаты правильно удвоены. Смотрите также пример - Цитирование значений в динамических запросах.quote_ident(’Foo bar’)"Foo bar"
quote_literal(string text)textВернуть указанную строку, заключенную в кавычки, для использования в качестве строкового литерала в строке оператора SQL. Встроенные одинарные кавычки и обратные слэши корректно удваиваются. Обратите внимание, что quote_literal возвращает null при null входе; если аргумент может быть null, quote_nullable часто более подходит. Смотрите также пример - Цитирование значений в динамических запросах.quote_literal(E’O\’Reilly’)’O”Reilly’
quote_literal(value anyelement)textПриведите указанное значение к тексту и затем процитируйте его как литерал. Встроенные одинарные кавычки и обратные слэши корректно удваиваются.quote_literal(42.5)’42.5’
quote_nullable(string text)textВозврат заданной строки, заключенной в кавычки, для использования в качестве строкового литерала в строке оператора SQL; или, если аргумент null, вернуть NULL. Встроенные одинарные кавычки и обратные слэши корректно удваиваются. Смотрите также пример - Цитирование значений в динамических запросах.quote_nullable(NULL)NULL
quote_nullable(value anyelement)textПриведите данное значение к тексту и затем процитируйте его как литерал; или, если аргумент null, вернуть NULL. Встроенные одинарные кавычки и обратные слэши корректно удваиваются.quote_nullable(42.5)’42.5’
regexp_match(string text, pattern text [, flags text ])text[]Вернуть захваченные подстроки, полученные в результате первого совпадения регулярного выражения POSIX со string. См. раздел Регулярные выражения POSIX для получения дополнительной информации.regexp_match(’foobarbequebaz’, ’(bar)(beque)’){bar,beque}
regexp_matches(string text, pattern text [, flags text ])setof text[]Вернуть захваченные подстроки, полученные в результате сопоставления регулярного выражения POSIX со строкой. См. раздел Регулярные выражения POSIX для получения дополнительной информации.regexp_matches(’foobarbequebaz’, ’ba.’, ’g’){bar} {baz} (2 rows)
regexp_replace(string text, pattern text, replacement text [, flags text ])textЗаменить подстроку(и), соответствующие регулярному выражению POSIX. См. раздел Регулярные выражения POSIX для получения дополнительной информации.regexp_replace(’Thomas’, ’.[mN]a.’, ’M’)ThM
regexp_split_to_array(string text, pattern text [, flags text ])text[]Разделить строку используя регулярное выражение POSIX в качестве разделителя. См. раздел Регулярные выражения POSIX для получения дополнительной информации.regexp_split_to_array(’hello world’, ’\s+’){hello,world}
regexp_split_to_table(string text, pattern text [, flags text ])setof textРазделить строку используя регулярное выражение POSIX в качестве разделителя. См. раздел Регулярные выражения POSIX для получения дополнительной информации.regexp_split_to_table(’hello world’, ’\s+’)hello world (2 rows)
repeat(string text, number int)textПовторите строку указанное число разrepeat(’Pg’, 4)PgPgPgPg
replace(string text, from text, to text)textЗаменить все вхождения в строку подстроки from на подстроку toreplace(’abcdefabcdef’, ’cd’, ’XX’)abXXefabXXef
reverse(str)textВернуть обратную строку.reverse(’abcde’)edcba
right(str text, n int)textВернуть последние n символов в строке. Когда n отрицательно, вернуть все, кроме первых | n | символов.right(’abcde’, 2)de
rpad(string text, length int [, fill text ])textЗаполнить строку до длины, добавив символы fill (пробел по умолчанию). Если строка уже длиннее length она усекается.rpad(’hi’, 5, ’xy’)hixyx
rtrim(string text [, characters text ])textУдалить из конца строки, наибольшую подстроку, содержащую символы указанные в characters (по умолчанию пробел)rtrim(’testxxzx’, ’xyz’)test
split_part(string text, delimiter text, field int) textРазбить строку на разделителем delimiter и вернуть заданное поле (считая от единицы)split_part(’abc~@~def~@~ghi’, ’~@~’, 2)def
strpos(string, substring)intРасположение указанной подстроки (аналогично position(substring in string), но обратите внимание на обратный порядок аргументов)strpos(’high’, ’ig’)2
substr(string, from [, count ])textИзвлечь подстроку (так же, как substring(string from from for count))substr(’alphabet’, 3, 2)ph
starts_with(string, prefix)boolВозвращает true, если строка начинается с prefix.starts_with(’alphabet’, ’alph’)t
to_ascii(string text [, encoding text ])textПреобразовать строку в ASCII из другой кодировки (поддерживает только преобразование из LATIN1, LATIN2, LATIN9 и WIN1250)to_ascii(’Karel’)Karel
to_hex(number int or bigint)textПреобразовать число в его эквивалентное шестнадцатеричное представлениеto_hex(2147483647)7fffffff
translate(string text, from text, to text)textЛюбой символ в строке который соответствует символу из набора from заменяется соответствующим символом в наборе. Если значений from больше, чем to, вхождения дополнительных символов в from удаляются.translate(’12345’, ’143’, ’ax’)a2x5

Функции concat, concat_ws и format являются переменными, поэтому можно передавать значения для объединения или форматирования в виде массива, помеченного ключевым словом VARIADIC (см. раздел Функции SQL с переменным числом аргументов). Элементы массива обрабатываются так, как если бы они были отдельными обычными аргументами функции. Если аргумент массива variadic имеет значение NULL, concat и concat_ws возвращают NULL, но format рассматривает NULL как массив с нулевым элементом.

Смотрите также string_agg функцию string_agg в разделе Агрегатные функции.

Таблица 11. Встроенные преобразования

Имя конверсии1Кодировка источникаКодировка назначения
ascii_to_micSQL_ASCIIMULE_INTERNAL
ascii_to_utf8SQL_ASCIIUTF8
big5_to_euc_twBIG5EUC_TW
big5_to_micBIG5MULE_INTERNAL
big5_to_utf8BIG5UTF8
euc_cn_to_micEUC_CNMULE_INTERNAL
euc_cn_to_utf8EUC_CNUTF8
euc_jp_to_micEUC_JPMULE_INTERNAL
euc_jp_to_sjisEUC_JPSJIS
euc_jp_to_utf8EUC_JPUTF8
euc_kr_to_micEUC_KRMULE_INTERNAL
euc_kr_to_utf8EUC_KRUTF8
euc_tw_to_big5EUC_TWBIG5
euc_tw_to_micEUC_TWMULE_INTERNAL
euc_tw_to_utf8EUC_TWUTF8
gb18030_to_utf8GB18030UTF8
gbk_to_utf8GBKUTF8
iso_8859_10_to_utf8LATIN6UTF8
iso_8859_13_to_utf8LATIN7UTF8
iso_8859_14_to_utf8LATIN8UTF8
iso_8859_15_to_utf8LATIN9UTF8
iso_8859_16_to_utf8LATIN10UTF8
iso_8859_1_to_micLATIN1MULE_INTERNAL
iso_8859_1_to_utf8LATIN1UTF8
iso_8859_2_to_micLATIN2MULE_INTERNAL
iso_8859_2_to_utf8LATIN2UTF8
iso_8859_2_to_windows_1250LATIN2WIN1250
iso_8859_3_to_micLATIN3MULE_INTERNAL
iso_8859_3_to_utf8LATIN3UTF8
iso_8859_4_to_micLATIN4MULE_INTERNAL
iso_8859_4_to_utf8LATIN4UTF8
iso_8859_5_to_koi8_rISO_8859_5KOI8R
iso_8859_5_to_micISO_8859_5MULE_INTERNAL
iso_8859_5_to_utf8ISO_8859_5UTF8
iso_8859_5_to_windows_1251ISO_8859_5WIN1251
iso_8859_5_to_windows_866ISO_8859_5WIN866
iso_8859_6_to_utf8ISO_8859_6UTF8
iso_8859_7_to_utf8ISO_8859_7UTF8
iso_8859_8_to_utf8ISO_8859_8UTF8
iso_8859_9_to_utf8LATIN5UTF8
johab_to_utf8JOHABUTF8
koi8_r_to_iso_8859_5KOI8RISO_8859_5
koi8_r_to_micKOI8RMULE_INTERNAL
koi8_r_to_utf8KOI8RUTF8
koi8_r_to_windows_1251KOI8RWIN1251
koi8_r_to_windows_866KOI8RWIN866
koi8_u_to_utf8KOI8UUTF8
mic_to_asciiMULE_INTERNALSQL_ASCII
mic_to_big5MULE_INTERNALBIG5
mic_to_euc_cnMULE_INTERNALEUC_CN
mic_to_euc_jpMULE_INTERNALEUC_JP
mic_to_euc_krMULE_INTERNALEUC_KR
mic_to_euc_twMULE_INTERNALEUC_TW
mic_to_iso_8859_1MULE_INTERNALLATIN1
mic_to_iso_8859_2MULE_INTERNALLATIN2
mic_to_iso_8859_3MULE_INTERNALLATIN3
mic_to_iso_8859_4MULE_INTERNALLATIN4
mic_to_iso_8859_5MULE_INTERNALISO_8859_5
mic_to_koi8_rMULE_INTERNALKOI8R
mic_to_sjisMULE_INTERNALSJIS
mic_to_windows_1250MULE_INTERNALWIN1250
mic_to_windows_1251MULE_INTERNALWIN1251
mic_to_windows_866MULE_INTERNALWIN866
sjis_to_euc_jpSJISEUC_JP
sjis_to_micSJISMULE_INTERNAL
sjis_to_utf8SJISUTF8
windows_1258_to_utf8WIN1258UTF8
uhc_to_utf8UHCUTF8
utf8_to_asciiUTF8SQL_ASCII
utf8_to_big5UTF8BIG5
utf8_to_euc_cnUTF8EUC_CN
utf8_to_euc_jpUTF8EUC_JP
utf8_to_euc_krUTF8EUC_KR
utf8_to_euc_twUTF8EUC_TW
utf8_to_gb18030UTF8GB18030
utf8_to_gbkUTF8GBK
utf8_to_iso_8859_1UTF8LATIN1
utf8_to_iso_8859_10UTF8LATIN6
utf8_to_iso_8859_13UTF8LATIN7
utf8_to_iso_8859_14UTF8LATIN8
utf8_to_iso_8859_15UTF8LATIN9
utf8_to_iso_8859_16UTF8LATIN10
utf8_to_iso_8859_2UTF8LATIN2
utf8_to_iso_8859_3UTF8LATIN3
utf8_to_iso_8859_4UTF8LATIN4
utf8_to_iso_8859_5UTF8ISO_8859_5
utf8_to_iso_8859_6UTF8ISO_8859_6
utf8_to_iso_8859_7UTF8ISO_8859_7
utf8_to_iso_8859_8UTF8ISO_8859_8
utf8_to_iso_8859_9UTF8LATIN5
utf8_to_johabUTF8JOHAB
utf8_to_koi8_rUTF8KOI8R
utf8_to_koi8_uUTF8KOI8U
utf8_to_sjisUTF8SJIS
utf8_to_windows_1258UTF8WIN1258
utf8_to_uhcUTF8UHC
utf8_to_windows_1250UTF8WIN1250
utf8_to_windows_1251UTF8WIN1251
utf8_to_windows_1252UTF8WIN1252
utf8_to_windows_1253UTF8WIN1253
utf8_to_windows_1254UTF8WIN1254
utf8_to_windows_1255UTF8WIN1255
utf8_to_windows_1256UTF8WIN1256
utf8_to_windows_1257UTF8WIN1257
utf8_to_windows_866UTF8WIN866
utf8_to_windows_874UTF8WIN874
windows_1250_to_iso_8859_2WIN1250LATIN2
windows_1250_to_micWIN1250MULE_INTERNAL
windows_1250_to_utf8WIN1250UTF8
windows_1251_to_iso_8859_5WIN1251ISO_8859_5
windows_1251_to_koi8_rWIN1251KOI8R
windows_1251_to_micWIN1251MULE_INTERNAL
windows_1251_to_utf8WIN1251UTF8
windows_1251_to_windows_866WIN1251WIN866
windows_1252_to_utf8WIN1252UTF8
windows_1256_to_utf8WIN1256UTF8
windows_866_to_iso_8859_5WIN866ISO_8859_5
windows_866_to_koi8_rWIN866KOI8R
windows_866_to_micWIN866MULE_INTERNAL
windows_866_to_utf8WIN866UTF8
windows_866_to_windows_1251WIN866WIN
windows_874_to_utf8WIN874UTF8
euc_jis_2004_to_utf8EUC_JIS_2004UTF8
utf8_to_euc_jis_2004UTF8EUC_JIS_2004
shift_jis_2004_to_utf8SHIFT_JIS_2004UTF8
utf8_to_shift_jis_2004UTF8SHIFT_JIS_2004
euc_jis_2004_to_shift_jis_2004EUC_JIS_2004SHIFT_JIS_2004
shift_jis_2004_to_euc_jis_2004SHIFT_JIS_2004EUC_JIS_2004

FORMAT

Функция FORMAT создает выходные данные, отформатированные в соответствии со строкой формата, в стиле, аналогичном функции C sprintf.

format(formatstr text [, formatarg "any" [, ...] ])

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

Спецификаторы формата вводятся символом % и имеют форму

%[position][flags][width]type

где поля компонента:

position (необязательно)
Строка вида n$ где n - индекс аргумента для печати. Индекс 1 означает первый аргумент после formatstr. Если position опущена, по умолчанию используется следующий аргумент в последовательности.
flags (необязательно)
Дополнительные параметры, управляющие форматированием вывода спецификатора формата. В настоящее время единственным поддерживаемым флагом является знак минус (-), который приведет к выравниванию вывода спецификатора формата. Это не имеет никакого эффекта, если поле width также не указано.
width (необязательно)

Задает минимальное количество символов, которое используется для отображения выходных данных спецификатора формата. Выходные данные дополняются слева или справа (в зависимости от флага -) с пробелами, необходимыми для заполнения ширины. Слишком маленькая ширина не приводит к усечению вывода, а просто игнорируется. Ширина может быть указана с использованием любого из следующего: положительное целое число; звездочка (\*) для использования следующего аргумента функции в качестве ширины; или строка вида * n $ для использования аргумента n й функции в качестве ширины.

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

type (обязательно)

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

  • s форматирует значение аргумента как простую строку. Нулевое значение рассматривается как пустая строка.

  • I рассматриваю значение аргумента как идентификатор SQL, заключая его в двойные кавычки, если это необходимо. Ошибка в значении, quote_ident нулю (эквиваленту quote_ident).

  • L указывает значение аргумента как литерал SQL. Нулевое значение отображается в виде строки NULL, без кавычек (эквивалент quote_nullable).

В дополнение к описателям формата, описанным выше, специальная последовательность %% может использоваться для вывода буквального символа %.

Вот несколько примеров преобразования основных форматов:

SELECT format('Hello% s', 'World');
Result: Hello World

SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three');
Result: Testing one, two, three, %

SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
Result: INSERT INTO "Foo bar" VALUES('O''Reilly')

SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files');
Result: INSERT INTO locations VALUES('C:\Program Files')

Вот примеры использования полей width и флага -:

SELECT format('|%10s|', 'foo');
Result: |       foo|

SELECT format('|%-10s|', 'foo');
Result: |foo       |

SELECT format('|%*s|', 10, 'foo');
Result: |       foo|

SELECT format('|%*s|', -10, 'foo');
Result: |foo       |

SELECT format('|%-*s|', 10, 'foo');
Result: |foo       |

SELECT format('|%-*s|', -10, 'foo');
Result: |foo       |

Эти примеры показывают использование полей position:

SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three');
Result: Testing three, two, one

SELECT format('|%*2$s|', 'foo', 10, 'bar');
Result: |       bar|

SELECT format('|%1$*2$s|', 'foo', 10, 'bar');
Result: |       foo|

В отличие от стандартной функции C sprintf, функция форматирования QHB позволяет смешивать спецификаторы формата с полями position и без них в одной строке формата. Спецификатор формата без поля position всегда использует следующий аргумент после последнего использованного аргумента. Кроме того, функция format не требует использования всех аргументов функции в строке формата. Например:

SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
Result: Testing three, two, three

Спецификаторы формата %I и %L особенно полезны для безопасного построения динамических операторов SQL. См. Пример 42.1.

Двоичные строковые функции и операторы

В этом разделе описываются функции и операторы для изучения и манипулирования значениями типа bytea.

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

Заметка
В примере результатов, показанных на этой странице, предполагается, что параметр сервера bytea_output установлен на escape (традиционный формат QHB).

Таблица 12. Двоичные строковые функции и операторы SQL

ФункцияТип ответаОписаниепримерРезультат
string | | stringbyteaКонкатенация строк’\\Post’::bytea | | ’\047gres\000’::bytea\\Post’gres\000
octet_length(string)intКоличество байтов в двоичной строкеoctet_length(’jo\000se’::bytea)5
overlay(string placing string from int [ for int ])byteaЗаменить подстрокуoverlay(’Th\000omas’::bytea placing ’\002\003’::bytea from 2 for 3)T\\002\\003mas
position(substring in string)intРасположение указанной подстрокиposition(’\000om’::bytea in ’Th\000omas’::bytea)3
substring(string [ from int ] [ for int ])byteaИзвлечь подстрокуsubstring(’Th\000omas’::bytea from 2 for 3)h\000o
trim([ both ] bytes from string)byteaУдалить самую длинную строку, содержащую только байты, появляющиеся в bytes из начала и конца строкиtrim(’\000\001’::bytea from ’\000Tom\001’::bytea)Tom

Доступны дополнительные функции манипуляции с двоичными строками, которые перечислены в таблице 13. Некоторые из них используются для реализации стандартных строковых функций SQL, перечисленных в таблице 8.12.

Таблица 13. Другие бинарные строковые функции

ФункцияТип ответаОписаниеПримерРезультат
btrim(string bytea, bytes bytea)byteaУдалить самую длинную строку, содержащую только байты, появляющиеся в bytes из начала и конца string btrim(’\\000trim\\001’::bytea, ’\\000\\001’::bytea)trim
decode(string text, format text)byteaДекодировать двоичные данные из текстового представления в string. Параметры для format такие же, как в encode.decode(’123\\000456’, ’escape’)123\\000456
encode(data bytea, format text)textКодировать двоичные данные в текстовое представление. Поддерживаемые форматы: base64, hex, escape. escape преобразует нулевые байты и старшие биты в восьмеричные последовательности (\ nnn) и удваивает обратную косую черту.encode(’123\\000456’::bytea, ’escape’)123\\000456
get_bit(string, offset)intИзвлечь бит из строкиget_bit(’Th\\000omas’::bytea, 45)1
get_byte(string, offset)intИзвлечь байт из строкиget_byte(’Th\\000omas’::bytea, 4)109
length(string)intДлина двоичной строкиlength(’jo\\000se’::bytea)5
md5(string)textВычисляет хеш string MD5, возвращая результат в шестнадцатеричном видеmd5(’Th\\000omas’::bytea)8ab2d3c9689aaf18b4958c334c82d8b1
set_bit(string, offset, newvalue)byteaУстановить бит в строкеset_bit(’Th\\000omas’::bytea, 45, 0)Th\\000omAs
```set_byte(string, offset, newvalue)bytea```Установить байт в строкеset_byte(’Th\\000omas’::bytea, 4, 64)Th\\000o@as
sha224(bytea)byteaSHA-224 хешsha224(’abc’)\\x23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
sha256(bytea)byteaSHA-256 хешsha256(’abc’)\\xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
sha384(bytea)byteaSHA-384 хешsha384(’abc’)\\xcb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
sha512(bytea)byteaSHA-512 хешsha512(’abc’)\\xddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f

get_byte и set_byte нумеруют первый байт двоичной строки как байт 0. get_bit и set_bit нумеруют биты справа внутри каждого байта; например, бит 0 является младшим битом первого байта, а бит 15 является старшим битом второго байта.

Обратите внимание, что по историческим причинам функция md5 возвращает шестнадцатеричное значение типа text тогда как функции SHA-2 возвращают тип bytea. Используйте функции encode и decode для преобразования между ними, например, encode(sha256(’abc’), ’hex’) чтобы получить шестнадцатеричное текстовое представление.

См. Также агрегатную функцию string_agg в разделе Агрегатные функции и функции больших объектов в разделе Серверные функции.

Функции и операторы битовых строк

В этом разделе описываются функции и операторы для проверки и обработки битовых строк, то есть значений типов bit и bit varying. Помимо обычных операторов сравнения можно использовать операторы, показанные в таблице 8.14. Битовые операнды &, и # должны быть одинаковой длины. При сдвиге битов первоначальная длина строки сохраняется, как показано в примерах.

Таблица 14. Операторы битовых строк

ОператорОписаниеПримерРезультат
| |конкатенацияB’10001’ | | B’011’10001011
&побитовое ИB’10001’ & B’01101’00001
|побитовое ИЛИB’10001’ | B’01101’11101
#побитовый XORB’10001’ # B’01101’11100
~побитовое НЕ~ B’10001’01110
<<битовое смещение влевоB’10001’ << 301000
>>битовое смещение вправоB’10001’ >> 200100

Следующие стандартные функции SQL работают как с битовыми строками, так и с символьными строками: length, bit_length, octet_length, position, substring, overlay.

Следующие функции работают как с битовыми строками, так и с двоичными строками: get_bit, set_bit. При работе с битовой строкой эти функции нумеруют первый (самый левый) бит строки как бит 0.

Кроме того, можно приводить целочисленные значения к bit типа и из них. Несколько примеров:

44::bit(10)                    0000101100
44::bit(3)                     100
cast(-44 as bit(12))           111111010100
'1110'::bit(4)::integer        14

Обратите внимание, что приведение к bit означает приведение к bit(1) и, следовательно, выдаст только младший значащий бит целого числа.

Преобразование целого числа в bit(n) копирует самые правые n битов. Преобразование целого числа в битовую строку, ширина которой шире, чем само целое число, будет расширяться знаком слева.

Сопоставление с образцом

QHB предлагает три отдельных подхода к сопоставлению с образцом: традиционный оператор SQL LIKE, более поздний оператор SIMILAR TO (добавлен в SQL: 1999) и регулярные выражения в стиле POSIX. Помимо основного «эта строка соответствует этому шаблону?» Операторы, функции доступны для извлечения или замены соответствующих подстрок и для разделения строки в соответствующих местах.

Заметка
Если у вас есть потребности в сопоставлении с образцом, которые выходят за рамки этого, подумайте о написании пользовательской функции на Perl или Tcl.

Предостережение
Хотя большинство поисков по регулярным выражениям могут выполняться очень быстро, могут быть изобретены регулярные выражения, которые занимают произвольное количество времени и памяти для обработки. Остерегайтесь принятия шаблонов поиска регулярных выражений из неблагоприятных источников. Если вы должны сделать это, желательно установить тайм-аут заявления. Поиск с использованием шаблонов SIMILAR TO имеет те же угрозы безопасности, поскольку SIMILAR TO предоставляет многие из тех же возможностей, что и регулярные выражения в стиле POSIX. Поиски типа LIKE, которые намного проще двух других вариантов, безопаснее использовать с возможно неблагоприятными источниками паттернов.

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

LIKE

string LIKE pattern [ESCAPE escape-character]
  string NOT LIKE pattern [ESCAPE escape-character]

Выражение LIKE возвращает true, если string соответствует предоставленному pattern. (Как и ожидалось, выражение NOT LIKE возвращает false, если LIKE возвращает true, и наоборот. Эквивалентное выражение NOT (string LIKE pattern).)

Если pattern не содержит знаков процента или подчеркивания, то шаблон представляет только саму строку; в этом случае LIKE действует как оператор равенства. Подчеркивание (_) в pattern обозначает (соответствует) любой отдельный символ; знак процента (%) соответствует любой последовательности из нуля или более символов.

Несколько примеров:

'abc' LIKE 'abc'    true
'abc' LIKE 'a%'     true
'abc' LIKE '_b_'    true
'abc' LIKE 'c'      false

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

Чтобы сопоставить буквенное подчеркивание или знак процента без сопоставления с другими символами, соответствующему символу в pattern должен предшествовать escape-символ. Экранирующим символом по умолчанию является обратный слеш, но другой можно выбрать с помощью предложения ESCAPE. Чтобы соответствовать самому escape-символу, напишите два escape-символа.

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

Также можно выбрать не escape-символ, написав ESCAPE ''. Это эффективно отключает механизм выхода, что делает невозможным отключение специального значения знаков подчеркивания и процентов в шаблоне.

Ключевое слово ILIKE можно использовать вместо LIKE чтобы сопоставить регистр без учета регистра в соответствии с активной локалью. Это не в стандарте SQL, но является расширением QHB.

Оператор ~~ эквивалентен LIKE, а ~~* соответствует ILIKE. Также есть операторы !~~ и !~~* которые представляют NOT LIKE и NOT ILIKE соответственно. Все эти операторы специфичны для QHB.

Также есть префиксный оператор ^@ и соответствующая функция starts_with которая охватывает случаи, когда необходим только поиск по началу строки.

Регулярные выражения SIMILAR TO

string SIMILAR TO pattern [ESCAPE escape-character]
  string NOT SIMILAR TO pattern [ESCAPE escape-character]

Оператор SIMILAR TO возвращает true или false в зависимости от того, соответствует ли его шаблон заданной строке. Он похож на LIKE, за исключением того, что он интерпретирует шаблон, используя определение регулярного выражения в стандарте SQL. Регулярные выражения SQL представляют собой любопытную смесь между нотацией LIKE нотацией обычного регулярного выражения.

Как и LIKE, оператор SIMILAR TO успешно выполняется, только если его шаблон соответствует всей строке; это не похоже на обычное поведение регулярных выражений, когда шаблон может соответствовать любой части строки. Также как LIKE, SIMILAR TO использует символы _ и % качестве подстановочных символов, обозначающих любой отдельный символ и любую строку соответственно (они сопоставимы с . и .* в регулярных выражениях POSIX).

В дополнение к этим возможностям, заимствованным из LIKE, SIMILAR TO поддерживает метасимволы сопоставления с образцом, заимствованные из регулярных выражений POSIX:

  • | обозначает чередование (любой из двух вариантов).

  • * обозначает повторение предыдущего пункта ноль или более раз.

  • + обозначает повторение предыдущего пункта один или несколько раз.

  • ? обозначает повторение предыдущего пункта ноль или один раз.

  • {m} обозначает повторение предыдущего элемента ровно m раз.

  • {m,} обозначает повторение предыдущего элемента m или более раз.

  • {m,n} обозначает повторение предыдущего элемента не менее m и не более n раз.

  • Круглые скобки () могут использоваться для группировки элементов в один логический элемент.

  • Выражение в скобках [...] определяет класс символов, как в регулярных выражениях POSIX.

Обратите внимание, что точка (.) Не является метасимволом для SIMILAR TO.

Как и в случае с LIKE, обратная косая черта отключает специальное значение любого из этих метасимволов; или другой escape-символ может быть указан с помощью ESCAPE.

Несколько примеров:

'abc' SIMILAR TO 'abc'      true
'abc' SIMILAR TO 'a'        false
'abc' SIMILAR TO '%(b|d)%'  true
'abc' SIMILAR TO '(b|c)%'   false

Функция substring с тремя параметрами обеспечивает извлечение подстроки, которая соответствует шаблону регулярного выражения SQL. Функция может быть написана в соответствии с синтаксисом SQL99:

substring(string from pattern for escape-character)

или как простая функция с тремя аргументами:

substring(string, pattern, escape-character)

Как и в случае SIMILAR TO, указанный шаблон должен соответствовать всей строке данных, иначе функция завершится ошибкой и вернет значение NULL. Чтобы указать часть шаблона, для которой интересует соответствующая подстрока данных, шаблон должен содержать два вхождения escape-символа, за которым следует двойная кавычка ("). Текст, соответствующий части шаблона между этими разделителями: возвращается после успешного завершения сравнения.

Escape- символы двойные кавычки фактически делят шаблон substring на три независимых регулярных выражения; например, вертикальная черта (|) в любом из трех разделов влияет только на этот раздел. Кроме того, первое и третье из этих регулярных выражений определяются так, чтобы они соответствовали наименьшему возможному объему текста, а не самому большому, когда есть некоторая неоднозначность относительно того, какая часть строки данных соответствует какому шаблону. (На языке POSIX первое и третье регулярные выражения должны быть не жадными).

В качестве расширения стандарта SQL QHB позволяет использовать только один escape-разделитель с двойными кавычками, и в этом случае третье регулярное выражение считается пустым; или нет разделителей, и в этом случае первое и третье регулярные выражения считаются пустыми.

Несколько примеров с #" разделяющим возвращаемую строку:

substring('foobar' from '%#"o_b#"%' for '#')   oob
substring('foobar' from '#"o_b#"%' for '#')    NULL

Регулярные выражения POSIX

В таблице 15 перечислены доступные операторы для сопоставления с образцом с использованием регулярных выражений POSIX.

Таблица 15. Операторы соответствия регулярного выражения

ОператорОписаниеПример
~Соответствует регулярному выражению с учетом регистра’thomas’ ~ ’.*thomas.*’
~*Соответствует регулярному выражению без учета регистра’thomas’ ~* ’.*Thomas.*’
!~Не соответствует регулярному выражению, чувствительно к регистру’thomas’ !~ ’.*Thomas.*’
!~*Не соответствует регулярному выражению, без учета регистра’thomas’ !~* ’.*vadim.*’

Регулярные выражения POSIX предоставляют более мощные средства для сопоставления с образцом, чем операторы LIKE и SIMILAR TO. Многие инструменты Unix, такие как egrep, sed или awk используют язык сопоставления с шаблоном, который похож на описанный здесь.

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

Несколько примеров:

'abc' ~ 'abc'    true
'abc' ~ '^a'     true
'abc' ~ '(b|d)'  true
'abc' ~ '^(b|c)' false

Язык паттернов POSIX описан более подробно ниже.

Функция substring с двумя параметрами substring(string from pattern) обеспечивает извлечение подстроки, соответствующей шаблону регулярного выражения POSIX. Возвращает null, если совпадения нет, в противном случае та часть текста, которая соответствует шаблону. Но если шаблон содержит какие-либо круглые скобки, возвращается часть текста, которая соответствует первому подвыражению в скобках (та, чья левая скобка стоит первой). Вы можете поместить круглые скобки вокруг всего выражения, если хотите использовать внутри него круглые скобки, не вызывая этого исключения. Если вам нужны круглые скобки в шаблоне перед подвыражением, которое вы хотите извлечь, смотрите описанные ниже скобки без захвата.

Несколько примеров:

substring('foobar' from 'o.b')     oob
substring('foobar' from 'o(.)b')   o

Функция regexp_replace обеспечивает подстановку нового текста для подстрок, которые соответствуют шаблонам регулярных выражений POSIX. Он имеет синтаксис regexp_replace(source, pattern, replacement [, flags ]). source строка возвращается без изменений, если нет совпадения с pattern. Если есть совпадение, source строка возвращается с replacement строкой, заменяющей соответствующую подстроку. Строка replacement может содержать \n, где n 1 до 9, чтобы указать, что должна быть вставлена исходная подстрока, соответствующая n-му заключенному в скобки подвыражению шаблона, и она может содержать \& чтобы указать, что подстрока соответствия всему шаблону должна быть вставлена. Напишите \\ если вам нужно вставить буквальный слеш в тексте замены. Параметр flags представляет собой необязательную текстовую строку, содержащую ноль или более однобуквенных флагов, которые изменяют поведение функции. Флаг i указывает совпадение без учета регистра, а флаг g указывает замену каждой подходящей подстроки, а не только первой. Поддерживаемые флаги (хотя и не g) описаны в таблице 23.

Несколько примеров:

regexp_replace('foobarbaz', 'b..', 'X')
                                   fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
                                   fooXX
regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
                                   fooXarYXazY

Функция regexp_match возвращает текстовый массив захваченных подстрок, полученных в результате первого совпадения шаблона регулярного выражения POSIX со строкой. Он имеет синтаксис regexp_match(string, pattern [, flags ]). Если совпадений нет, результат равен NULL. Если совпадение найдено, и pattern содержит вложенные выражения в скобках, то результатом является текстовый массив из одного элемента, содержащий подстроку, соответствующую всему шаблону. Если совпадение найдено, и pattern содержит вложенные выражения, заключенные в скобки, то результатом является текстовый массив, чей n-й элемент является подстрокой, соответствующей вложенному выражению в скобках n-го pattern (не считая «не захватывающих» скобок; см. ниже). для деталей). Параметр flags представляет собой необязательную текстовую строку, содержащую ноль или более однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги описаны в таблице 23.

Несколько примеров:

SELECT regexp_match('foobarbequebaz', 'bar.*que');
 regexp_match
--------------
 {barbeque}
(1 row)

SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
 regexp_match
--------------
 {bar,beque}
(1 row)

В общем случае, когда вы просто хотите, чтобы вся совпадающая подстрока или NULL не совпадали, напишите что-то вроде

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
 regexp_match
--------------
 barbeque
(1 row)

Функция regexp_matches возвращает набор текстовых массивов захваченных подстрок, полученных в результате сопоставления шаблона регулярного выражения POSIX со строкой. Он имеет тот же синтаксис, что и regexp_match. Эта функция не возвращает ни одной строки, если совпадения нет, одна строка, если есть совпадение и флаг g не задан, или N строк, если есть N совпадений и задан флаг g. Каждая возвращаемая строка является текстовым массивом, содержащим всю совпавшую подстроку или подстроки, соответствующие заключенным в скобки подвыражениям pattern, как описано выше для regexp_match. regexp_matches принимает все флаги, показанные в таблице 23, плюс флаг g который выдает команду на возврат всех совпадений, а не только первого.

Несколько примеров:

SELECT regexp_matches('foo', 'not there');
 regexp_matches
----------------
(0 rows)

SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
 regexp_matches
----------------
 {bar,beque}
 {bazil,barf}
(2 rows)

Функция regexp_split_to_table разбивает строку, используя шаблон регулярного выражения POSIX в качестве разделителя. Он имеет синтаксис regexp_split_to_table(string, pattern [, flags ]). Если нет совпадения с pattern, функция возвращает string. Если найдется хотя бы одно совпадение, для каждого совпадения он возвращает текст с конца последнего совпадения (или начала строки) до начала совпадения. Когда совпадений больше нет, он возвращает текст от конца последнего совпадения до конца строки. Параметр flags представляет собой необязательную текстовую строку, содержащую ноль или более однобуквенных флагов, которые изменяют поведение функции. regexp_split_to_table поддерживает флаги, описанные в таблице 23.

Функция regexp_split_to_array ведет себя так же, как и regexp_split_to_table, за исключением того, что regexp_split_to_array возвращает свой результат в виде массива text. Он имеет синтаксис regexp_split_to_array(string, pattern [, flags ]). Параметры те же, что и для regexp_split_to_table.

Несколько примеров:


SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo;
  foo   
-------
 the    
 quick  
 brown  
 fox    
 jumps
 over   
 the    
 lazy   
 dog    
(9 rows)

SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
              regexp_split_to_array             
-----------------------------------------------
 {the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)

SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
 foo
-----
 t         
 h         
 e         
 q         
 u         
 i         
 c         
 k         
 b         
 r         
 o         
 w         
 n         
 f         
 o         
 x         
(16 rows)

Как показывает последний пример, функции разбиения regexp игнорируют совпадения нулевой длины, которые происходят в начале или конце строки или сразу после предыдущего совпадения. Это противоречит строгому определению соответствия регулярному выражению, которое реализуется с помощью regexp_match и regexp_matches, но обычно является наиболее удобным поведением на практике. Другие программные системы, такие как Perl, используют аналогичные определения.

Детали регулярных выражений

Регулярные выражения QHB реализованы с использованием программного пакета, написанного Генри Спенсером. Большая часть описания регулярных выражений ниже дословно скопирована из его руководства.

Регулярные выражения (RE), как определено в POSIX 1003.2, имеют две формы: расширенные RE или ERE (примерно такие же, как у egrep) и базовые RE или BRE (примерно те, что у ed). QHB поддерживает обе формы, а также реализует некоторые расширения, которые не входят в стандарт POSIX, но стали широко использоваться благодаря их доступности в таких языках программирования, как Perl и Tcl. RE, использующие эти расширения, отличные от POSIX, в данной документации называются расширенными RE или ARE. ARE являются почти точным набором ERE, но BRE имеют несколько обозначений несовместимости (а также гораздо более ограничены). Сначала мы опишем формы ARE и ERE, отметив функции, которые применяются только к ARE, а затем опишем, как отличаются BRE.

Заметка
QHB всегда изначально предполагает, что регулярное выражение следует правилам ARE. Однако более ограниченные правила ERE или BRE можно выбрать, добавив встроенную опцию к шаблону RE, как описано в разделе Метасинтаксис регулярных выражений. Это может быть полезно для совместимости с приложениями, которые ожидают в точности правил POSIX 1003.2.

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

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

Количественный атом — это атом, за которым может следовать один квантификатор. Без квантификатора он соответствует совпадению для атома. С квантификатором он может соответствовать некоторому количеству совпадений атома. Атом может быть любой из возможностей, показанных в таблице 16. Возможные квантификаторы и их значения приведены в таблице 8.17.

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

Таблица 16. Атомы регулярного выражения

АтомОписание
(re)(где re - любое регулярное выражение) соответствует совпадению для re, причем совпадение отмечено для возможного сообщения
(?: re)как указано выше, но совпадение не отмечено для отчетности (набор «без захвата» скобок) (только ARE)
.соответствует любому отдельному символу
[ chars ]выражение в скобках, соответствующее любому из chars (см. раздел Выражения в скобках для более подробной информации)
\ k(где k не алфавитно-цифровой символ) соответствует этому символу, взятому как обычный символ, например, \\ соответствует символу обратной косой черты
\ cгде c - буквенно-цифровой (возможно, за которым следуют другие символы) - escape, см. раздел Экранирование в регулярных выражениях (только ARE; в ERE и BRE это соответствует c)
{когда за ним следует символ, отличный от цифры, соответствует символу левой скобки {; после цифры следует начало bound (см. ниже)
xгде x - это один символ без другого значения, соответствует этому символу

RE не может заканчиваться обратной косой чертой (\).

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

Таблица 17. Квантификаторы регулярных выражений

КванторСовпадения
*последовательность из 0 или более совпадений атома
+последовательность из 1 или более совпадений атома
?последовательность из 0 или 1 совпадений атома
{m}последовательность ровно m совпадений атома
{m,}последовательность из m или более совпадений атома
{m,n}последовательность от m до n (включительно) совпадений атома; m не может превышать n
*?не жадная версия *
+?не жадная версия +
??не жадная версия ?
{m}?не жадная версия { m }
{m,}?не жадная версия { m,}
{m,n}?не жадная версия { m, n }

Формы, использующие {...}, называются границами. Числа m и n пределах являются десятичными целыми числами без знака с допустимыми значениями от 0 до 255 включительно.

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

Квантификатор не может сразу следовать за другим квантификатором, например, ** является недействительным. Квантор не может начинать выражение или подвыражение или следовать за ^ или |.

Таблица 18. Ограничения регулярного выражения

ОграниченияОписание
^соответствует началу строки
$совпадения в конце строки
(?= re)положительное совпадение в любой точке, где начинается повтор совпадения подстроки (только ARE)
(?! re)совпадения с отрицательным прогнозом в любой точке, где не начинается повтор совпадения подстрок (только ARE)
(?<= re)положительное совпадение за спиной в любой точке, где заканчивается совпадение подстроки (только ARE)
(?<! re)Отрицательное совпадение за спиной в любой точке, где нет совпадений подстроки (только ARE)

Ограничения Lookahead и Lookbehind не могут содержать обратных ссылок (см. раздел Экранирование в регулярных выражениях), и все скобки в них считаются не захватывающими.

Выражения в скобках

Выражение в скобках — это список символов, заключенных в []. Обычно он соответствует любому отдельному символу из списка (но см. ниже). Если список начинается с ^, он соответствует любому отдельному символу, не относящемуся к остальной части списка. Если два символа в списке разделены знаком -, это сокращение для полного диапазона символов между этими двумя (включительно) в последовательности сортировки, например, [0-9] в ASCII соответствует любой десятичной цифре. Недопустимо, чтобы два диапазона совместно использовали конечную точку, например, a-c-e. Диапазоны очень сильно зависят от последовательности сортировки, поэтому переносимые программы не должны полагаться на них.

Чтобы включить литерал ] в список, сделайте его первым символом (после ^, если он используется). Чтобы включить литерал -, сделайте его первым или последним символом или второй конечной точкой диапазона. Чтобы использовать литерал - в качестве первой конечной точки диапазона, заключите его в [. и .] сделать его упорядочивающим элементом (см. ниже). За исключением этих символов, некоторых комбинаций с использованием [ (см. следующие абзацы) и экранировок (только для ARE), все другие специальные символы теряют свое особое значение в выражении в скобках. В частности, \ не является особенным, когда следует правилам ERE или BRE, хотя он является особенным (как введение escape) в ARE.

Внутри выражения в скобках элемент сортировки (символ, многосимвольная последовательность, которая сопоставляется, как если бы это был один символ, или имя последовательности сопоставления для любого из них), заключенный в [. и .] обозначает последовательность символов этого элемента сортировки. Последовательность рассматривается как отдельный элемент списка выражения в скобках. Это позволяет выражению в скобках, содержащему многосимвольный элемент сортировки, соответствовать более чем одному символу, например, если последовательность сортировки включает в себя элемент сортировки ch, то RE [[.ch.]]*c соответствует первым пяти символам chchcc,

Заметка
В настоящее время QHB не поддерживает многосимвольные элементы сортировки. Эта информация описывает возможное будущее поведение.

В выражении в скобках элемент сортировки, заключенный в [= и =] является классом эквивалентности, обозначающим последовательности символов всех элементов сопоставления, эквивалентных этому элементу, включая самого себя. (Если нет других эквивалентных элементов сортировки, обработка выглядит так, как если бы в качестве разделителей использовались [. и .]). Например, если o и ^ являются членами класса эквивалентности, то [[=o=]], [[=^=]] и [o^] являются синонимами. Класс эквивалентности не может быть конечной точкой диапазона.

В выражении в скобках имя класса символов, заключенное в [: и :] обозначает список всех символов, принадлежащих этому классу. Класс символов не может использоваться в качестве конечной точки диапазона. Стандарт POSIX определяет следующие имена классов символов: alnum (буквы и цифры), alpha (буквы), blank (пробел и табуляция), cntrl (символы управления), digit (цифры), graph (печатные символы, кроме пробела), lower (строчные буквы), print (печатаемые символы, включая пробел), пунктуация (пунктуация), space (любой пробел), upper (заглавные буквы) и xdigit (шестнадцатеричные цифры). Поведение этих стандартных классов символов обычно одинаково для разных платформ для символов в 7-битном наборе ASCII. То, считается ли данный не-ASCII символ принадлежащим одному из этих классов, зависит от параметров сортировки, используемых для функции или оператора регулярного выражения (см. раздел Поддержка сортировки), или по умолчанию от настройки языка LC_CTYPE базы данных (см. раздел Поддержка локали). Классификация символов, отличных от ASCII, может варьироваться в зависимости от платформы даже в локалях с одинаковыми именами. (Но языковой стандарт C никогда не считает, что любые не-ASCII-символы принадлежат какому-либо из этих классов). В дополнение к этим стандартным классам символов QHB определяет класс символов ascii, который содержит ровно 7-битный набор ASCII.

Существует два особых случая выражений в скобках: выражения в скобках [[:<:]] и [[:>:]] являются ограничениями, соответствующими пустым строкам в начале и конце слова соответственно. Слово определяется как последовательность символов слова, которая не предшествует и не сопровождается символами слова. Символ слова — это символ alnum (как определено классом символов POSIX, описанным выше) или знак подчеркивания. Это расширение, совместимое с POSIX 1003.2, но не указанное в нем, и его следует использовать с осторожностью в программном обеспечении, предназначенном для переноса на другие системы. Описанные ниже экранирующие ограничения, обычно предпочтительнее; они не являются более стандартными, но их легче набирать.

Экранирование в регулярных выражениях

Экранирование — это специальные последовательности, начинающиеся с \ за которым следует буквенно-цифровой символ. Экраны могут быть нескольких видов: ввод символов, сокращения классов, экранирование ограничений и обратные ссылки. Символ \ сопровождаемый буквенно-цифровым символом, но не являющийся допустимым выходом, является недопустимым в ARE. В ERE нет выходов: вне выражения в скобках символ \ за которым следует буквенно-цифровой символ, просто обозначает этот символ как обычный символ, а внутри выражения в скобках \ - обычный символ. (Последнее является единственной фактической несовместимостью между ERE и ARE).

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

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

Экранирование ограничения — это ограничение, соответствующее пустой строке, если выполняются определенные условия, записываемое как escape. Они показаны в таблице 21.

Обратная ссылка (\n) соответствует той же строке, которая соответствует предыдущему заключенному в скобки подвыражению, указанному числом n (см. Таблицу 8.22). Например, ([bc])\1 соответствует bb или cc но не bc или cb. Подвыражение должно полностью предшествовать обратной ссылке в RE. Субэкспрессии нумеруются в порядке их ведущих скобок. Неполные скобки не определяют подвыражения.

Таблица 19. Регулярное выражение E-Entry Escape

ВыделениеОписание
\aпредупреждающий (звонок) символ, как в C
\bBackspace, как в C
\Bсиноним обратной косой черты (\), чтобы уменьшить необходимость удвоения обратной косой черты
\cX(где X - любой символ) символ, чьи 5 младших битов такие же, как у X, а все остальные биты равны нулю
\eсимвол с именем последовательности упорядочения ESC или, если это не так, символ с восьмеричным значением 033
\fподача формы, как в C
\nперевод строки, как в C
\rвозврат каретки, как в C
\tгоризонтальная вкладка, как в C
\uwxyz(где wxyz - ровно четыре шестнадцатеричные цифры) символ, шестнадцатеричное значение которого равно 0x wxyz
\Ustuvwxyz(где stuvwxyz ровно восемь шестнадцатеричных цифр) символ, шестнадцатеричное значение которого равно 0x stuvwxyz
\vвертикальная вкладка, как в C
\xhhh(где hhh - любая последовательность шестнадцатеричных цифр) символ, шестнадцатеричное значение которого равно 0x hhh (один символ независимо от того, сколько шестнадцатеричных цифр используется)
\0символ, значение которого равно 0 (нулевой байт)
\xy(где xy - это ровно две восьмеричные цифры, а не обратная ссылка) символ, восьмеричное значение которого равно 0 xy
\xyz(где xyz - ровно три восьмеричных цифры, а не обратная ссылка) символ, восьмеричное значение которого равно 0 xyz

Шестнадцатеричные цифры 0-9, a-f и A-F Восьмеричные цифры 0-7.

Цифровая символьная запись выходит за пределы, указывая значения вне диапазона ASCII (0-127), значения которых зависят от кодировки базы данных. Когда кодировка UTF-8, escape-значения эквивалентны кодовым точкам Unicode, например, \u1234 означает символ U+1234. Для других многобайтовых кодировок экранирование ввода символов обычно просто указывает конкатенацию байтовых значений для символа. Если escape-значение не соответствует никакому допустимому символу в кодировке базы данных, ошибка не возникает, но она никогда не будет соответствовать никаким данным.

Экранирование ввода символов всегда принимается как обычные символы. Например, \135 является ] в ASCII, но \135 не завершает выражение в скобках.

Таблица 20. Класс регулярных выражений - Сокращения

ВыделениеОписание
\d[[:digit:]]
\s[[:space:]]
\w[[:alnum:]_] (примечание подчеркивание включено)
\D[^[:digit:]]
\S[^[:space:]]
\W[^[:alnum:]_] (примечание подчеркивание включено)

В выражениях в скобках \d, \s и \w теряют свои внешние скобки, а \D, \S и \W недопустимы. (Так, например, [a-c\d] эквивалентно [a-c[:digit:]]. Кроме того, [a-c\D], что эквивалентно [a-c^[:digit:]], является недопустимым).

Таблица 21. Ограничение регулярных выражений

ВыделениеОписание
\Aсоответствует только в начале строки (см. раздел Правила сопоставления регулярных выражений о том, как это отличается от ^)
\mсоответствует только в начале слова
\Mсоответствует только в конце слова
\yсоответствует только в начале или конце слова
\Yсоответствует только в точке, которая не является началом или концом слова
\Zсоответствует только в конце строки (см. раздел Правила сопоставления регулярных выражений о том, как это отличается от $)

Слово определяется как в спецификации [[:<:]] и [[:>:]] выше. Экранирование ограничений в выражениях в скобках недопустимо.

Таблица 22. Регулярное выражение обратные ссылки

ВыделениеОписание
\m(где m - ненулевая цифра) обратная ссылка на m -е подвыражение
\mnn(где* m* - ненулевая цифра, а nn - еще несколько цифр, а десятичное значение mnn не больше, чем число закрывающих скобок, замеченных до сих пор) обратная ссылка на mnn -ый подвыражение

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

Метасинтаксис регулярных выражений

В дополнение к основному синтаксису, описанному выше, существуют некоторые специальные формы и различные синтаксические средства.

RE может начинаться с одного из двух специальных префиксов директора. Если RE начинается с ***:, остальная часть RE берется как ARE. (Это обычно не имеет никакого эффекта в QHB, поскольку предполагается, что RE являются ARE; но это имеет эффект, если параметром flags для функции regex был задан режим ERE или BRE). Если RE начинается с ***= остальная часть RE принимается за буквальную строку, причем все символы считаются обычными символами.

ARE может начинаться со встроенных опций: последовательность (?xyz) (где xyz - один или несколько буквенных символов) определяет опции, влияющие на остальную часть RE. Эти параметры переопределяют любые ранее определенные параметры - в частности, они могут переопределять поведение с учетом регистра, подразумеваемое оператором регулярного выражения, или параметр flags для функции регулярного выражения. Доступные буквы опций показаны в таблице 23. Обратите внимание, что эти же буквы параметров используются в параметрах флагов функций регулярных выражений.

Таблица 23. ARE символы с встроенными опциями

ВариантОписание
bОстальная часть RE - BRE
cСопоставление с учетом регистра (переопределяет тип оператора)
eОстальная часть RE — это ERE
iсопоставление без учета регистра (см. раздел Правила сопоставления регулярных выражений) (переопределяет тип оператора)
mисторический синоним для n
nсопоставление с учетом новой строки (см. раздел Правила сопоставления регулярных выражений)
pчастичное совпадение с учетом новой строки (см. раздел Правила сопоставления регулярных выражений)
qОстальная часть RE является литеральной («кавычкой») строкой, все обычные символы
sсопоставление, не зависящее от перевода строки (по умолчанию)
tжесткий синтаксис (по умолчанию; см. ниже)
wчастичное обратное частичное совпадение с учетом новой строки («странное») (см. раздел Правила сопоставления регулярных выражений)
xрасширенный синтаксис (см. ниже)

Встроенные параметры вступают в силу после завершения последовательности. Они могут появляться только в начале ARE (после директора ***: если таковой имеется).

В дополнение к обычному (строгому) синтаксису RE, в котором значимы все символы, существует расширенный синтаксис, доступный путем указания встроенной опции x. В расширенном синтаксисе символы пробела в RE игнорируются, как и все символы между # и следующей новой строкой (или концом RE). Это позволяет создавать абзацы и комментировать сложные RE. Из этого основного правила есть три исключения:

  • символ пробела или #, которому предшествует \, сохраняется

  • пробел или # в выражении в скобках сохраняется

  • пробел и комментарии не могут появляться в многосимвольных обозначениях, таких как (?:

Для этой цели пробелами являются пробелы, символы табуляции, перевода строки и любые символы, принадлежащие классу пробелов.

Наконец, в ARE, вне выражений в скобках, последовательность (?#ttt) (где ttt - любой текст, не содержащий )) — это комментарий, полностью игнорируемый. Опять же, это не допускается между символами многосимвольных обозначений, например (?:. Такие комментарии являются скорее историческим артефактом, чем полезным средством, и их использование не рекомендуется; вместо этого используйте расширенный синтаксис.

Ни одно из этих расширений метасинтаксиса не доступно, если начальный директор ***= указал, что ввод пользователя будет обрабатываться как литеральная строка, а не как RE.

Правила сопоставления регулярных выражений

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

Является ли RE жадным или нет, определяется следующими правилами:

  • Большинство атомов и все ограничения не имеют атрибута жадности (поскольку в любом случае они не могут соответствовать переменным объемам текста).

  • Добавление скобок вокруг RE не меняет его жадности.

  • Квантованный атом с квантификатором с фиксированным повторением ({m} или {m}?) Имеет такую же жадность (возможно, нет), как сам атом.

  • Количественный атом с другими нормальными квантификаторами (включая {m,n} с m, равным n) является жадным (предпочитает самое длинное совпадение).

  • Количественный атом с не жадным квантификатором (включая {m, n}? С m, равным n) не является жадным (предпочитает кратчайшее совпадение).

  • Ветвь - то есть RE, у которого нет верхнего уровня оператор - имеет ту же жадность, что и первый квантифицированный атом, имеющий атрибут жадности.

  • RE, состоящее из двух или более ветвей, соединенных оператор всегда жадный.

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

Пример того, что это значит:

SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
Result: 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Result: 1

В первом случае RE в целом жадный, потому что Y* жадный. Он может совпадать, начиная с Y, и соответствовать самой длинной строке, начинающейся там, то есть Y123. Выводом является часть этого в скобках, или 123. Во втором случае RE в целом не является жадным, потому что Y*? не жадный Он может совпадать, начиная с Y, и соответствовать самой короткой строке, начинающейся там, то есть Y1. Подвыражение [0-9]{1,3} является жадным, но не может изменить решение относительно общей длины совпадения; поэтому он вынужден совпадать только с 1.

Вкратце, когда RE содержит как жадные, так и не жадные подвыражения, общая длина совпадения либо максимально длинная, либо максимально короткая, в соответствии с атрибутом, назначенным всему RE. Атрибуты, назначенные подвыражениям, влияют только на то, сколько из этого соответствия им разрешено «съесть» относительно друг друга.

Квантификаторы {1,1} и {1,1}? могут быть использован, чтобы вызвать жадность или не жадность, соответственно, для подвыражения или целого RE. Это полезно, когда вам нужно, чтобы весь RE имел атрибут жадности, отличный от того, что выводится из его элементов. В качестве примера предположим, что мы пытаемся разделить строку, содержащую несколько цифр, на цифры и части до и после них. Мы можем попытаться сделать это так:

SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
Result: {abc0123,4,xyz}

Это не сработало: первый .* Жадный, поэтому он «съедает» столько, сколько может, оставляя \d+ совпадать с последним возможным местом, последней цифрой. Мы можем попытаться исправить это, сделав его не жадным:

SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
Result: {abc,0,""}

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

SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Result: {abc,01234,xyz}

Контроль общей жадности RE отдельно от жадности его компонентов обеспечивает большую гибкость при работе с образцами переменной длины.

При принятии решения о том, какое совпадение длиннее или короче, длины совпадений измеряются в символах, а не в элементах сортировки. Пустая строка считается более длинной, чем не совпадающей. Например: bb* соответствует трем средним символам abbbc; (week|wee) (night|knights) соответствует всем десяти символам weeknights; когда (.*).* сопоставляется с abc, подвыражение в скобках соответствует всем трем символам; и когда (a*)* сопоставляется с bc, и все RE, и подвыражение в скобках соответствуют пустой строке.

Если задано независимое от регистра совпадение, эффект будет таким же, как если бы все алфавитные различия исчезли из алфавита. Когда алфавит, существующий во многих случаях, появляется как обычный символ вне выражения в скобках, он фактически преобразуется в выражение в скобках, содержащее оба случая, например, x становится [xX]. Когда оно появляется внутри выражения в скобках, все его аналоги в регистре добавляются в выражение в скобках, например, [x] становится [xX] и [^x] становится [^xX].

Если указано совпадение с учетом новой строки, . и выражения в скобках, использующие ^, никогда не будут совпадать с символом новой строки (так что совпадения никогда не будут пересекать символы новой строки, если RE явно не упорядочит его), а ^ и $ будут совпадать с пустой строкой после и до новой строки соответственно, в дополнение к совпадению в начале и в конце строки соответственно. Но экранированные символы ARE \A и \Z продолжают соответствовать только началу или концу строки.

Если указано частичное совпадение с учетом новой строки, это влияние . и выражения в скобках, как при сопоставлении с учетом новой строки, но не ^ и $.

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

Пределы и совместимость

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

Единственная особенность ARE, которая на самом деле несовместима с POSIX ERE, заключается в том, что \ не теряет своего особого значения в выражениях в скобках. Все остальные функции ARE используют синтаксис, который является недопустимым или имеет неопределенные или неопределенные эффекты в ERE POSIX; *** синтаксис директоров также находится за пределами синтаксиса POSIX как для BRE, так и для ERE.

Многие из расширений ARE заимствованы из Perl, но некоторые были изменены, чтобы очистить их, а некоторые расширения Perl отсутствуют. Заметные несовместимости включают в себя \b, \B, отсутствие специальной обработки для завершающего символа новой строки, добавление дополненных выражений в скобках к тем вещам, на которые влияет сопоставление с учетом новой строки, ограничения на круглые скобки и обратные ссылки в ограничениях lookahead/lookbehind, и семантика соответствия самого длинного/самого короткого совпадения (а не первого совпадения).

Основные регулярные выражения

BRE отличаются от ERE в нескольких отношениях. В BREs, |, + и ? являются обычными символами, и их функциональность не имеет аналогов. Ограничителями для границ являются \{ и \}, причем { и } сами по себе являются обычными символами. Круглые скобки для вложенных подвыражений: \( и \), с ( и ) сами по себе обычными символами. ^ - обычный символ, за исключением начала RE или начала заключенного в скобки подвыражения, $ - обычный символ, за исключением конца RE или конца заключенного в скобки подвыражения, а * - обычный символ, если он появляется в начале RE или начале заключенного в скобки подвыражения (после возможного начала ^). Наконец, доступны однозначные обратные ссылки, и \< и \> являются синонимами для [[:<:]] и [[:>:]] соответственно; в BRE нет других выходов.

Отличия от XQuery (LIKE_REGEX)

Начиная с SQL: 2008, стандарт SQL включает в себя оператор LIKE_REGEX, который выполняет сопоставление с шаблоном в соответствии со стандартом регулярных выражений XQuery. QHB еще не реализует этот оператор, но вы можете получить очень похожее поведение, используя функцию regexp_match(), поскольку регулярные выражения XQuery довольно близки к синтаксису ARE, описанному выше.

Существенные различия между существующей функцией регулярных выражений на основе POSIX и регулярными выражениями XQuery включают:

  • Вычитание класса символов XQuery не поддерживается. Примером этой функции является использование следующего для соответствия только английским согласным: [a-z-[aeiou]].

  • Сокращения класса символов XQuery \c, \C, \i и \I не поддерживаются.

  • Элементы класса символов XQuery, использующие \p{UnicodeProperty} или обратное \P{UnicodeProperty}, не поддерживаются.

  • POSIX интерпретирует классы символов, такие как \w (см. таблицу 20), в соответствии с преобладающим языковым стандартом (которым вы можете управлять, прикрепляя предложение COLLATE к оператору или функции). XQuery определяет эти классы с помощью ссылок на свойства символов Unicode, поэтому эквивалентное поведение получается только с языком, который следует правилам Unicode.

  • Стандарт SQL (не сам XQuery) пытается обслуживать больше вариантов «новой строки», чем POSIX. Описанные выше варианты соответствия с учетом новой строки рассматривают только ASCII NL (\n) как новую строку, но SQL заставил бы нас рассматривать CR (\r), CRLF (\r\n) (новую строку в стиле Windows) и некоторые cимволы только для Unicode, такие как LINE SEPARATOR (U + 2028), а также перевод строки. Примечательно, что . и \s должен считаться \r\n как один символ, а не два в соответствии с SQL.

  • Из экранирования ввода символов, описанного в таблице 19, XQuery поддерживает только \n, \r и \t.

  • XQuery не поддерживает синтаксис [:name:] для классов символов в выражениях в скобках.

  • XQuery не имеет ограничений на просмотр или просмотр назад, а также не выходит за пределы ограничений, описанных в таблице 21.

  • Метасинтаксические формы, описанные в разделе Метасинтаксис регулярных выражений, не существуют в XQuery.

  • Буквы флагов регулярного выражения, определенные в XQuery, относятся к буквам опций для POSIX, но не совпадают с ними (Таблица 23). В то время как параметры i и q ведут себя одинаково, другие не делают:

  • Флаги XQuery (разрешить точку для совпадения с новой строкой) и m (разрешить совпадение ^ и $ для совпадения на новой строке) обеспечивают доступ к тем же режимам поведения, что и флаги POSIX n, p и w, но они не соответствуют поведению флагов POSIX s и m, В частности, обратите внимание, что точка-совпадение-новая строка является поведением по умолчанию в POSIX, но не в XQuery.

  • Флаг XQuery x (игнорировать пробелы в шаблоне) заметно отличается от флага расширенного режима POSIX. Флаг x POSIX также позволяет # начинать комментарий в шаблоне, и POSIX не будет игнорировать символ пробела после обратной косой черты.

Функции форматирования типов данных

Функции форматирования QHB предоставляют мощный набор инструментов для преобразования различных типов данных (дата / время, целые числа, числа с плавающей запятой, числовые) в форматированные строки и для преобразования форматированных строк в конкретные типы данных. Таблица 8.24 перечисляет их. Все эти функции следуют общему соглашению о вызовах: первый аргумент — это значение, которое нужно отформатировать, а второй аргумент — это шаблон, который определяет формат вывода или ввода.

Таблица 24. Функции форматирования

ФункцияТип ответаОписаниеПример
to_char(timestamp, text)textконвертировать метку времени в строкуto_char(current_timestamp, ’HH12:MI:SS’)
to_char(interval, text)textпреобразовать интервал в строкуto_char(interval ’15h 2m 12s’, ’HH24:MI:SS’)
to_char(int, text)textконвертировать целое число в строкуto_char(125, ’999’)
to_char (double precision, text)textпреобразовать реальную / двойную точность в строкуto_char(125.8::real, ’999D9’)
to_char(numeric, text)textпреобразовать число в строкуto_char(-125.8, ’999D99S’)
to_date(text, text)dateпреобразовать строку в датуto_date(’05 Dec 2000’, ’DD Mon YYYY’)
to_number(text, text)numericпреобразовать строку в числоto_number(’12,454.8-’, ’99G999D9S’)
to_timestamp(text, text)timestamp with time zoneпреобразовать строку в метку времениto_timestamp(’05 Dec 2000’, ’DD Mon YYYY’)

Заметка
Существует также функция to_timestamp с одним аргументом; см. таблицу 31.

Совет
Существуют to_timestamp и to_date для обработки входных форматов, которые нельзя преобразовать простым преобразованием. Для большинства стандартных форматов даты/времени работает простое приведение исходной строки к требуемому типу данных, и это намного проще. Аналогично, to_number не требуется для стандартных числовых представлений.

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

В таблице 25 показаны лекала шаблонов, доступные для форматирования значений даты и времени.

Таблица 25. Лекала шаблонов для форматирования даты / времени

ШаблонОписание
HHчас дня (01-12)
HH12час дня (01-12)
HH24час дня (00-23)
MIминута (00-59)
SSвторой (00-59)
MSмиллисекунда (000-999)
USмикросекунда (000000-999999)
SSSSсекунд после полуночи (0-86399)
AM, am, PM или pmиндикатор меридием (без периодов)
A.M., a.m., P.M. или p.m.индикатор меридием (с периодами)
Y,YYYгод (4 или более цифр) с запятой
YYYYгод (4 или более цифр)
YYYпоследние 3 цифры года
YYпоследние 2 цифры года
Yпоследняя цифра года
IYYYНедельный год нумерации ISO 8601 (4 или более цифр)
IYYпоследние 3 цифры года нумерации ISO 8601
IYпоследние 2 цифры года нумерации ISO 8601
Iпоследняя цифра ISO 8601 год нумерации недели
BC, bc, AD или adиндикатор эры (без периодов)
B.C., b.c., A.D. или a.d.индикатор эры (с периодами)
MONTHполное название месяца в верхнем регистре (с пробелами до 9 символов)
Monthполное заглавное название месяца (с пробелами до 9 символов)
monthполное название месяца в нижнем регистре (с пробелами до 9 символов)
MONсокращенное название месяца в верхнем регистре (3 буквы на английском языке, длина может отличаться)
Monсокращенное заглавное название месяца (3 буквы на английском языке, длина может отличаться)
monсокращенное название месяца в нижнем регистре (3 буквы в английском, длина может быть разной)
MMномер месяца (01-12)
DAYполное название дня в верхнем регистре (с пробелами до 9 символов)
Dayполное заглавное название дня (с пробелами до 9 символов)
dayполное название дня в нижнем регистре (с пробелами до 9 символов)
DYсокращенное название дня в верхнем регистре (3 буквы на английском языке, длина может отличаться)
Dyсокращенное заглавное название дня (3 буквы на английском языке, длина может быть разной)
dyсокращенное название дня в нижнем регистре (3 буквы на английском языке, длина может отличаться)
DDDдень года (001-366)
IDDDдень недели по номеру ISO 8601 (001-371; 1-й день года - понедельник первой недели ISO)
DDдень месяца (01-31)
Dдень недели, с воскресенья (1) по субботу (7)
IDISO 8601 день недели, с понедельника (1) по воскресенье (7)
Wнеделя месяца (1-5) (первая неделя начинается в первый день месяца)
WWномер недели в году (1-53) (первая неделя начинается в первый день года)
IWномер недели в году по номеру недели ISO 8601 (01-53; первый четверг года на первой неделе)
CCвек (2 цифры) (XXI век начинается с 2001-01-01)
JЮлианский день (целые дни с 24 ноября 4714 г. до н.э. в полночь UTC)
Qквартал
RMмесяц прописными буквами римскими цифрами (I-XII; I = январь)
rmмесяц строчными буквами римскими цифрами (i-xii; i = январь)
TZсокращение верхнего пояса в верхнем регистре (поддерживается только в to_char)
tzto_char сокращение часового пояса (поддерживается только в to_char)
TZHчасы часового пояса
TZMминуты часового пояса
OFсмещение часового пояса от UTC (поддерживается только в to_char)

Модификаторы можно применять к любому лекалу шаблона, чтобы изменить его поведение. Например, FMMonth — это шаблон Month с модификатором FM. В таблице 26 показаны шаблоны модификаторов для форматирования даты/времени.

Таблица 26. Модификаторы лекала шаблонов для форматирования даты / времени

МодификаторОписаниепример
Префикс FMрежим заполнения (подавление начальных нулей и отступов)FMMonth
Суффикс THсуффикс порядкового номера в верхнем регистреDDTH, например, 12
суффикс thстрочный суффикс порядкового номераDDth, например, 12th
Префикс FXглобальная опция фиксированного формата (см. примечания по использованию)FX Month DD Day
Префикс TMрежим перевода (печатать локализованные названия дней и месяцев на основе lc_time)TMMonth
Суффикс SPрежим заклинания (не реализован)DDSP

Замечания по использованию для форматирования даты / времени:

  • FM подавляет начальные нули и конечные пробелы, которые в противном случае были бы добавлены, чтобы сделать вывод шаблона фиксированной ширины. В QHB FM изменяет только следующую спецификацию, а в Oracle FM влияет на все последующие спецификации, а повторные модификаторы FM включают и выключают режим заполнения.

  • TM не включает в себя конечные заготовки. to_timestamp и to_date игнорируют модификатор TM .

    • to_timestamp* и to_date пропускают несколько пробелов в начале строки ввода и вокруг значений даты и времени, если не используется опция FX. Например, to_timestamp(’ 2000 JUN’, ’YYYY MON’) и to_timestamp(’2000 - JUN’, ’YYYY-MON’) работают, но to_timestamp('2000 JUN', 'FXYYYY MON') возвращает ошибку, поскольку to_timestamp ожидает только один пробел. FX должен быть указан как первый элемент в шаблоне.
  • Разделитель (пробел, или не буквенный / нецифровый символ) в строке шаблона to_timestamp и to_date соответствует любому отдельному разделителю во входной строке или пропускается, если не используется опция FX. Например, to_timestamp('2000JUN', 'YYYY///MON') и to_timestamp('2000/JUN', 'YYYY MON') работают, но to_timestamp('2000//JUN', 'YYYY/MON') возвращает ошибка, так как количество разделителей во входной строке превышает количество разделителей в шаблоне.

Если указан параметр FX, то разделитель в строке шаблона соответствует ровно одному символу во входной строке. Но обратите внимание, что символ входной строки не обязательно должен совпадать с разделителем из строки шаблона. Например, to_timestamp('2000/JUN', 'FXYYYY MON') работает, но to_timestamp('2000/JUN', 'FXYYYY MON') возвращает ошибку, поскольку второй пробел в строке шаблона занимает букву J из строки ввода.

  • Шаблон TZH может соответствовать номеру со знаком. Без опции FX знаки минус могут быть неоднозначными и могут интерпретироваться как разделитель. Эта неоднозначность разрешается следующим образом: если число разделителей перед TZH в строке шаблона меньше, чем число разделителей перед знаком минус во входной строке, знак минус интерпретируется как часть TZH. В противном случае знак минус считается разделителем между значениями. Например, to_timestamp('2000 -10', 'YYYY TZH') соответствует -10 для TZH, но to_timestamp('2000 -10', 'YYYY TZH') соответствует 10 для TZH.

  • Обычный текст разрешен в шаблонах to_char и будет выводиться буквально. Вы можете поместить подстроку в двойные кавычки, чтобы она интерпретировалась как буквальный текст, даже если она содержит шаблоны. Например, в '"Hello Year "YYYY', YYYY будет заменен данными года, а одиночный Y в Year не будет. В to_date, to_number и to_timestamp буквенный текст и строки в двойных кавычках приводят к пропуску количества символов, содержащихся в строке; например, "XX" пропускает два входных символа (независимо от того, являются ли они XX).

  • Если вы хотите, чтобы в выводе была двойная кавычка, вы должны поставить перед ней обратную косую черту, например '\"YYYY Month\"'. Обратные слеши не являются чем-то особенным вне строк в двойных кавычках. Внутри строки в двойных кавычках обратный слеш заставляет следующий символ восприниматься буквально, каким бы он ни был (но это не имеет особого эффекта, если следующий символ не является двойной кавычкой или другим обратным слешем).

  • В to_timestamp и to_date, если спецификация формата года меньше четырех цифр, например, YYY, а введенный год меньше четырех цифр, год будет скорректирован так, чтобы быть ближайшим к 2020 году, например, 95 станет 1995 годом.

  • В to_timestamp и to_date преобразование YYYY имеет ограничение при обработке лет с более чем 4 цифрами. Вы должны использовать какой-либо нецифровый символ или шаблон после YYYY, в противном случае год всегда интерпретируется как 4 цифры. Например (с 20000 годом): to_date('200001131', 'YYYYMMDD') будет интерпретироваться как год с 4 цифрами; вместо этого используйте разделитель без цифр после года, например to_date('20000-1131', 'YYYY-MMDD') или to_date('20000Nov31', 'YYYYMonDD').

  • В to_timestamp и to_date поле CC (столетие) принимается, но игнорируется, если есть поле YYY, YYYY или Y,YYY. Если CC используется с YY или Y то результат вычисляется как этот год в указанном столетии. Если указан век, а год - нет, то подразумевается первый год столетия.

  • В to_timestamp и to_date имена или номера дней недели (DAY, D и связанные типы полей) принимаются, но игнорируются для целей вычисления результата. То же самое верно для полей квартала (Q).

  • В to_timestamp и to_date дату нумерации недели ISO 8601 (в отличие от григорианской даты) можно указать одним из двух способов:

  • Год, номер недели и день недели: например, to_date('2006-42-4', 'IYYY-IW-ID') возвращает дату 2006-10-19. Если вы опускаете день недели, он считается равным 1 (понедельник).

  • Год и день года: например, to_date(’2006-291’, ’IYYY-IDDD’) также возвращает 2006-10-19.
    Попытка ввести дату, используя сочетание полей нумерации недели ISO 8601 и полей григорианской даты, не имеет смысла и приведет к ошибке. В контексте года нумерации по ISO 8601 понятие «месяц» или «день месяца» не имеет смысла. В контексте григорианского года неделя ИСО не имеет смысла.

Предостережение
В то время как to_date будет отклонять смесь полей даты нумерации недели по григорианскому стандарту и ISO, to_char не будет, поскольку могут быть полезны спецификации выходного формата, такие как YYYY-MM-DD (IYYY-IDDD). Но избегайте писать что-то вроде IYYY-MM-DD; это дало бы удивительные результаты в начале года. (См. раздел EXTRACT, date_part для получения дополнительной информации).

  • В to_timestamp, миллисекунды (MS) или микросекунды (US) используются как цифры секунд после десятичной точки. Например, to_timestamp('12.3', 'SS.MS') составляет не 3 миллисекунды, а 300, потому что преобразование обрабатывает его как 12 + 0,3 секунды. Таким образом, для формата SS.MS входные значения 12.3, 12.30 и 12.300 указывают одинаковое количество миллисекунд. Чтобы получить три миллисекунды, нужно записать 12.003, что для преобразования означает 12 + 0,003 = 12,003 секунды.
    Вот более сложный пример: to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') составляет 15 часов, 12 минут и 2 секунды + 20 миллисекунд + 1230 микросекунд = 2,021230 секунд,

  • Нумерация дня недели в to_char(..., ’ID’) соответствует функции extract(isodow from ...), а в to_char(..., ’D’) - не соответствует extract(dow from ...) день нумерации.

  • to_char(interval) форматирует HH и HH12 как показано на 12-часовых часах, например, ноль часов и 36 часов выводят как 12, в то время как HH24 выводит значение полного часа, которое может превышать 23 в значении interval.

В таблице 27 показаны лекала шаблонов, доступные для форматирования числовых значений.

Таблица 27. Лекала шаблонов для числового форматирования

ШаблонОписание
9цифровая позиция (может быть отброшена, если она незначительна)
0позиция цифры (не будет удалена, даже если она незначительна)
. (Точка)десятичная точка
, (запятая)разделитель групп (тысяч)
PRотрицательное значение в угловых скобках
Sзнак привязан к номеру (использует локаль)
Lсимвол валюты (использует локаль)
Dдесятичная точка (использует локаль)
Gразделитель группы (использует локаль)
MIзнак минус в указанной позиции (если число <0)
PLзнак плюс в указанной позиции (если число> 0)
SGзнак плюс / минус в указанной позиции
RNРимская цифра (ввод от 1 до 3999)
TH или thсуффикс порядкового номера
Vсдвинуть указанное количество цифр (см. примечания)
EEEEпоказатель для научной записи

Замечания по использованию для числового форматирования:

  • 0 указывает позицию цифры, которая будет всегда печататься, даже если она содержит начальный / конечный ноль. 9 также указывает позицию цифры, но если это ведущий ноль, то он будет заменен пробелом, а если это конечный ноль и указан режим заполнения, то он будет удален. (Для to_number() эти два символа шаблона эквивалентны).

  • Шаблонные символы S, L, D и G представляют знак, символ валюты, десятичную точку и символы разделителя тысяч, определенные текущей локалью (см. Lc_monetary и lc_numeric). Шаблон символов точки и запятая представляют эти точные символы со значениями десятичной точки и разделителя тысяч независимо от локали.

  • Если в to_char() явного положения не предусмотрено, для знака будет зарезервирован один столбец, и он будет привязан (отображается слева от номера). Если S появляется слева от некоторых из 9, он также будет привязан к числу.

  • Знак, отформатированный с использованием SG, PL или MI, не привязан к номеру; например, to_char(-12, 'MI9999') выдает '- 12' to_char(-12, 'S9999') выдает ' -12'. (Реализация Oracle не позволяет использовать MI до 9, а требует, чтобы 9 предшествовал MI).

  • TH не преобразует значения меньше нуля и не преобразует дробные числа.

  • PL, SG и TH являются расширениями QHB.

  • В to_number, если используются лекала шаблонов без данных, такие как L или TH, соответствующее количество входных символов пропускается независимо от того, соответствуют ли они шаблону шаблона, если только они не являются символами данных (то есть цифрами, знаком, десятичной точкой или запятой). Например, TH пропустит два символа без данных.

  • V с to_char умножает входные значения на 10^n, где n - количество цифр после V. V с to_number делится аналогичным образом. to_char и to_number не поддерживают использование V сочетании с десятичной точкой (например, 99.9V99 не допускается).

  • EEEE (научная запись) не может использоваться в сочетании с любым другим шаблоном форматирования или модификаторами, кроме шаблонов цифр и десятичных точек, и должен находиться в конце строки формата (например, 9.99EEEE является допустимым шаблоном).

Некоторые модификаторы могут быть применены к любому лекалу шаблона, чтобы изменить его поведение. Например, FM99.99 — это шаблон 99.99 с модификатором FM. В таблице 28 показаны шаблоны модификаторов для числового форматирования.

Таблица 28. Модификаторы шаблонов для числового форматирования

МодификаторОписаниепример
Префикс FMрежим заполнения (подавление концевых нулей и пробелов заполнения)FM99.99
Суффикс THсуффикс порядкового номера в верхнем регистре999TH
Суффикс thстрочный суффикс порядкового номера999th

В таблице 29 приведены некоторые примеры использования функции to_char.

Таблица 29. Примеры to_char

ВыражениеРезультат
to_char(current_timestamp, ’Day, DD HH12:MI:SS’)’Tuesday, 06 05:39:18’
to_char(current_timestamp, ’FMDay, FMDD HH12:MI:SS’)’Tuesday, 6 05:39:18’
to_char(-0.1, ’99.99’)’ -.10’
to_char(-0.1, ’FM9.99’)’-.1’
to_char(-0.1, ’FM90.99’)’-0.1’
to_char(0.1, ’0.9’)’ 0.1’
to_char(12, ’9990999.9’)' 0012.0'
to_char(12, ’FM9990999.9’)’0012.’
to_char(485, ’999’)’ 485’
to_char(-485, ’999’)’-485’
to_char(485, ’9 9 9’)’ 4 8 5’
to_char(1485, ’9,999’)’ 1,485’
to_char(1485, ’9G999’)’ 1 485’
to_char(148.5, ’999.999’)’ 148.500’
to_char(148.5, ’FM999.999’)’148.5’
to_char(148.5, ’FM999.990’)’148.500’
to_char(148.5, ’999D999’)’ 148,500’
to_char(3148.5, ’9G999D999’)’ 3 148,500’
to_char(-485, ’999S’)’485-’
to_char(-485, ’999MI’)’485-’
to_char(485, ’999MI’)’485 ’
to_char(485, ’FM999MI’)’485’
to_char(485, ’PL999’)’+485’
to_char(485, ’SG999’)’+485’
to_char(-485, ’SG999’)’-485’
to_char(-485, ’9SG99’)’4-85’
to_char(-485, ’999PR’)’<485>’
to_char(485, ’L999’)’DM 485’
to_char(485, ’RN’)' CDLXXXV'
to_char(485, ’FMRN’)’CDLXXXV’
to_char(5.2, ’FMRN’)’V’
to_char(482, ’999th’)’ 482nd’
to_char(485, ’"Good number:"999’)’Good number: 485’
to_char(485.8, ’"Pre:"999" Post:" .999’)’Pre: 485 Post: .800’
to_char(12, ’99V999’)’ 12000’
to_char(12.4, ’99V999’)’ 12400’
to_char(12.45, ’99V9’)’ 125’
to_char(0.0004859, ’9.99EEEE’)’ 4.86e-04’

Функции и операторы даты/времени

В таблице 31 показаны доступные функции для обработки значения даты/времени, подробности представлены в следующих подразделах. Таблица 8.30 иллюстрирует поведение основных арифметических операторов (+, * и т.д.). Функции форматирования см. в разделе Функции форматирования типов данных. Вы должны быть знакомы с исходной информацией о типах данных даты/времени из раздела Типы даты/времени.

Все функции и операторы, описанные ниже, которые принимают входные данные time или timestamp фактически бывают двух вариантов: один, который требует time with time zone или timestamp with time zone, и один, который требует time without time zone или timestamp without time zone. Для краткости эти варианты не показаны отдельно. Кроме того, операторы + и * входят в коммутативные пары (например, и дата + целое число и целое число + дата); мы показываем только одну из каждой такой пары.

Таблица 30. Операторы даты/времени

ОператорПримерРезультат
+date ’2001-09-28’ + integer ’7’date ’2001-10-05’
+date ’2001-09-28’ + interval ’1 hour’timestamp ’2001-09-28 01:00:00’
+date ’2001-09-28’ + time ’03:00’timestamp ’2001-09-28 03:00:00’
+interval ’1 day’ + interval ’1 hour’interval ’1 day 01:00:00’
+timestamp ’2001-09-28 01:00’ + interval ’23 hours’timestamp ’2001-09-29 00:00:00’
+time ’01:00’ + interval ’3 hours’time ’04:00:00’
-- interval ’23 hours’interval ’-23:00:00’
-date ’2001-10-01’ - date ’2001-09-28’integer ’3’ (дни)
-date ’2001-10-01’ - integer ’7’date ’2001-09-24’
-date ’2001-09-28’ - interval ’1 hour’timestamp ’2001-09-27 23:00:00’
-time ’05:00’ - time ’03:00’interval ’02:00:00’
-time ’05:00’ - interval ’2 hours’time ’03:00:00’
-timestamp ’2001-09-28 23:00’ - interval ’23 hours’timestamp ’2001-09-28 00:00:00’
-interval ’1 day’ - interval ’1 hour’interval ’1 day -01:00:00’
-timestamp ’2001-09-29 03:00’ - timestamp ’2001-09-27 12:00’interval ’1 day 15:00:00’
*900 * interval ’1 second’interval ’00:15:00’
*21 * interval ’1 day’interval ’21 days’
*double precision ’3.5’ * interval ’1 hour’interval ’03:30:00’
/interval ’1 hour’ / double precision ’1.5’interval ’00:40:00’

Таблица 31. Функции даты/времени

ФункцияТип ответаОписаниеПримерРезультат
age(timestamp, timestamp)intervalВычтите аргументы, получив «символический» результат, который использует годы и месяцы, а не дниage(timestamp ’2001-04-10’, timestamp ’1957-06-13’)43 years 9 mons 27 days
age(timestamp)intervalВычесть из current_date (в полночь)age(timestamp ’1957-06-13’)43 years 8 mons 3 days
clock_timestamp()timestamp with time zoneТекущая дата и время (изменения во время выполнения выписки); см. раздел Текущая дата / время
current_datedateТекущая дата см. раздел Текущая дата / время
current_timetime with time zoneТекущее время суток; см. раздел Текущая дата / время
current_timestamptimestamp with time zoneТекущая дата и время (начало текущей транзакции); см. раздел Текущая дата / время
date_part(text, timestamp)double precisionПолучить подполе (эквивалентное extract); см. раздел EXTRACT, date_partdate_part(’hour’, timestamp ’2001-02-16 20:38:40’)20
date_part(text, interval)double precisionПолучить подполе (эквивалентное extract); см. раздел EXTRACT, date_partdate_part(’month’, interval ’2 years 3 months’)3
date_trunc(text, timestamp)timestampУсечь до указанной точности; см. раздел date_truncdate_trunc(’hour’, timestamp ’2001-02-16 20:38:40’)2001-02-16 20:00:00
date_trunc(text, timestamp with time zone, text)timestamp with time zoneУсечь до указанной точности в указанном часовом поясе; см. раздел date_truncdate_trunc(’day’, timestamptz ’2001-02-16 20:38:40+00’, ’Australia/Sydney’)2001-02-16 13:00:00+00
date_trunc(text, interval)intervalУсечь до указанной точности; см. раздел date_truncdate_trunc(’hour’, interval ’2 days 3 hours 40 minutes’)2 days 03:00:00
extract (field from timestamp)double precisionПолучить подполе; см. раздел EXTRACT, date_partextract(hour from timestamp ’2001-02-16 20:38:40’)20
extract (field from interval)double precisionПолучить подполе; см см. раздел EXTRACT, date_partextract(month from interval ’2 years 3 months’)3
isfinite(date)booleanТест на конечную дату (не +/- бесконечность)isfinite(date ’2001-02-16’)true
isfinite(timestamp)booleanТест для конечной отметки времени (не +/- бесконечность)isfinite(timestamp ’2001-02-16 21:28:30’)true
isfinite(interval)booleanТест на конечный интервалisfinite(interval ’4 hours’)true
justify_days(interval)intervalНастройте интервал так, чтобы 30-дневные периоды времени представлялись в месяцахjustify_days(interval ’35 days’)1 mon 5 days
justify_hours(interval)intervalНастройте интервал, чтобы 24-часовой период времени был представлен в днях.justify_hours(interval ’27 hours’)1 day 03:00:00
justify_interval(interval)intervalОтрегулируйте интервал, используя justify_days и justify_hours, с дополнительными настройками знакаjustify_interval(interval ’1 mon -1 hour’)29 days 23:00:00
localtimetimeТекущее время суток; см. раздел Текущая дата / время
localtimestamptimestampТекущая дата и время (начало текущей транзакции); см. раздел Текущая дата / время
make_date(year int, month int, day int)dateСоздать дату из поля год, месяц и деньmake_date(2013, 7, 15)2013-07-15
make_interval(years int DEFAULT 0, months int DEFAULT 0, weeks int DEFAULT 0, days int DEFAULT 0, hours int DEFAULT 0, mins int DEFAULT 0, secs double precision DEFAULT 0.0)intervalСоздайте интервал из полей лет, месяцев, недель, дней, часов, минут и секундmake_interval(days => 10)10 days
make_time(hour int, min int, sec double precision)timeСоздать время из часовых, минутных и секундных полейmake_time(8, 15, 23.5)08:15:23.5
make_timestamp(year int, month int, day int, hour int, min int, sec double precision)timestampСоздать метку времени из полей год, месяц, день, час, минуты и секундыmake_timestamp(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5
make_timestamptz(year int, month int, day int, hour int, min int, sec double precision, [ timezone text ])timestamp with time zoneСоздать временную метку с часовым поясом из полей год, месяц, день, час, минуты и секунды; если timezone не указан, используется текущий часовой поясmake_timestamptz(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5+01
now()timestamp with time zoneТекущая дата и время (начало текущей транзакции); см. раздел Текущая дата / время
statement_timestamp()timestamp with time zoneТекущая дата и время (начало текущей выписки); см. раздел Текущая дата / время
timeofday()textТекущая дата и время (например, clock_timestamp, но в виде text строки); см. раздел Текущая дата / время
transaction_timestamp()timestamp with time zoneТекущая дата и время (начало текущей транзакции); см. раздел Текущая дата / время
to_timestamp(double precision)timestamp with time zoneПреобразовать эпоху Unix (секунды с 1970-01-01 00: 00: 00 + 00) в метку времениto_timestamp(1284352323)2010-09-13 04:32:03+00

В дополнение к этим функциям поддерживается оператор SQL OVERLAPS:

(start1, end1) OVERLAPS (start2, end2)
(start1, length1) OVERLAPS (start2, length2)

Это выражение дает истину, когда два периода времени (определенные их конечными точками) перекрываются, ложь, когда они не перекрываются. Конечные точки могут быть указаны как пары дат, времени или отметок времени; или как дата, время или отметка времени с последующим интервалом. Когда предоставляется пара значений, сначала можно записать начало или конец; OVERLAPS автоматически принимает более раннее значение пары в качестве начала. Каждый период времени считается представляющим начало полуоткрытого интервала start <= time < end если только start и end не равны, и в этом случае он представляет этот единственный момент времени. Это означает, например, что два периода времени с общей конечной точкой не перекрываются.

SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Result: false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Result: true

При добавлении значения interval к (или вычитании значения interval из) значению timestamp with time zone компонент дней увеличивает или уменьшает дату timestamp with time zone на указанное количество дней. В зависимости от изменения летнего времени (когда часовой пояс сеанса установлен на часовой пояс, который распознает летнее время), это означает, что interval '1 day' не обязательно равен interval '24 hours'. Например, если для часового пояса сеанса установлено значение CST7CDT, timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' будет выводитьtimestamp with time zone '2005-04-03 12:00-06', при добавлении interval '24 hours' к тому же начальному значению, получим timestamp with time zone '2005-04-03 13:00-06', поскольку в
часовом поясе CST7CDT происходит изменение летнего времени в 2005-04-03 02:00.

Обратите внимание, что может быть неоднозначность в поле months возвращаемом по age, потому что разные месяцы имеют разное количество дней. Подход QHB использует месяц от более ранней из двух дат при расчете неполных месяцев. Например, age('2004-06-01', '2004-04-30') использует апрель, чтобы получить 1 mon 1 day, в то время как использование мая даст 1 mon 2 days потому что май имеет 31 день, а апрель - только 30,

Вычитание дат и временных меток также может быть сложным. Один концептуально простой способ выполнить вычитание - преобразовать каждое значение в количество секунд, используя EXTRACT(EPOCH FROM ...), а затем вычесть результаты; это производит количество секунд между двумя значениями. Это позволит настроить количество дней в каждом месяце, изменения часового пояса и настройки летнего времени. Вычитание значений даты или метки времени с помощью оператора « - » возвращает количество дней (24 часа) и часов / минут / секунд между значениями, выполняя те же настройки. Функция age возвращает годы, месяцы, дни и часы / минуты / секунды, выполняя вычитание от поля к полю и затем корректируя отрицательные значения поля. Следующие запросы иллюстрируют различия в этих подходах. Результаты выборки были получены с timezone = ’US/Eastern’; существует переход на летнее время между двумя использованными датами:

SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
       EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
Result: 10537200
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
        EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
        / 60 / 60 / 24;
Result: 121.958333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
Result: 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
Result: 4 mons

EXTRACT, date_part

EXTRACT(field FROM source)

Функция extract извлекает подполя, такие как год или час, из значений даты / времени. source должен быть выражением значения типа timestamp, time или interval. (Выражения типа date приводятся к timestamp и поэтому могут также использоваться). field - это идентификатор или строка, которая выбирает, какое поле извлечь из исходного значения. Функция extract возвращает значения типа double precision. Ниже приведены допустимые имена полей:

Century

  • Век
SELECT EXTRACT(CENTURY FROM TIMESTAMP ’2000-12-16 12:21:13’);
Result: 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 21

Первый век начинается в 0001-01-01 00:00:00 нашей эры, хотя они не знали этого в то время. Это определение относится ко всем странам григорианского календаря. Нет века № 0, вы переходите от -1 века к 1 веку.

day

  • Для значений timestamp - поле дня (месяца) (1 - 31); для значений interval количество дней
SELECT EXTRACT(DAY FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 16
SELECT EXTRACT(DAY FROM INTERVAL ’40 days 1 minute’);
Result: 40

decade

– номер текущего десятилетия (поле года, разделенное на 10)

SELECT EXTRACT(DECADE FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 200

dow

  • день недели с воскресенья (0) по субботу (6)
SELECT EXTRACT(DOW FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 5

Обратите внимание, что нумерация дней недели в extract отличается от функции to_char(..., ’D’) .

doy

  • день года (1 - 365/366)
SELECT EXTRACT(DOY FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 47

epoch

  • эпоха UNIX. Для timestamp with time zone значениями timestamp with time zone - количество секунд с 1970-01-01 00:00:00 UTC (может быть отрицательным); для значений date и timestamp - количество секунд с 1970-01-01 по 00:00:00 по местному времени; для значений interval общее количество секунд в интервале
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE ’2001-02-16
20:38:40.12-08’);
Result: 982384720.12
SELECT EXTRACT(EPOCH FROM INTERVAL ’5 days 3 hours’);
Result: 442800

Вы можете преобразовать значение эпохи обратно во временную to_timestamp с помощью to_timestamp:

SELECT to_timestamp(982384720.12);
Result: 2001-02-17 04:38:40.12+00

hour

  • поле часа (0 - 23)
SELECT EXTRACT(HOUR FROM TIMESTAMP ’2001-02-16 20:38:40’);
Result: 20

isodow

  • день недели с понедельника (1) по воскресенье (7)
SELECT EXTRACT(ISODOW FROM TIMESTAMP ’2001-02-18 20:38:40’);
Result: 7

Идентично dow кроме воскресенья. Это соответствует дню нумерации недели по ISO 8601.

isoyear

  • годовой номер недели в ISO 8601, к которому относится дата (не относится к интервалам)

    SELECT EXTRACT(ISOYEAR FROM DATE ’2006-01-01’);
    Result: 2005
    SELECT EXTRACT(ISOYEAR FROM DATE ’2006-01-02’);
    Result: 2006
    

    Каждый год нумерации ISO 8601 начинается с понедельника недели, содержащей 4 января, поэтому в начале января или конце декабря год ISO может отличаться от григорианского года. Смотрите поле week для получения дополнительной информации.

microseconds

  • поле секунд, включая дробные части, умноженное на 1 000 000; обратите внимание, что это включает в себя полные секунды

    SELECT EXTRACT(MICROSECONDS FROM TIME ’17:12:28.5’);
    Result: 28500000
    

millennium

  • миллениум

    SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 3
    

    Годы в 1900-х годах во втором тысячелетии. Третье тысячелетие началось 1 января 2001 года.

milliseconds

  • поле секунд, включая дробные части, умножается на 1000. Обратите внимание, что это включает полные секунды.

    SELECT EXTRACT(MILLISECONDS FROM TIME ’17:12:28.5’);
    Result: 28500
    

minute

  • поле минут (0 - 59)

    SELECT EXTRACT(MINUTE FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 38
    

month

  • для значений timestamp - номер месяца в году (1 - 12); для interval значений число месяцев по модулю 12 (0 - 11)

    SELECT EXTRACT(MONTH FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 2
    SELECT EXTRACT(MONTH FROM INTERVAL ’2 years 3 months’);
    Result: 3
    SELECT EXTRACT(MONTH FROM INTERVAL ’2 years 13 months’);
    Result: 1
    

quarter

  • Квартал года (1 - 4)

    SELECT EXTRACT(QUARTER FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 1
    

second

  • поле секунд, включая дробные части (0 - 592)

    SELECT EXTRACT(SECOND FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 40
    SELECT EXTRACT(SECOND FROM TIME ’17:12:28.5’);
    Result: 28.5
    

timezone

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

timezone_hour

  • часовая составляющая смещения часового пояса

timezone_minute

  • минутная составляющая смещения часового пояса

week

  • номер недели в году по нумерации ISO 8601. По определению, недели ISO начинаются по понедельникам, а первая неделя года содержит 4 января этого года. Другими словами, первый четверг года - первая неделя этого года.

    В системе нумерации недель ИСО даты начала января могут быть частью 52-й или 53-й недели предыдущего года, а даты конца декабря - частью первой недели следующего года. Например, 2005-01-01 является частью 53-й недели 2004 года, а 2006-01-01 является частью 52-й недели 2005 года, а 2012-12-31 является частью первой недели 2013 года. Рекомендуется использовать поле isoyear вместе с week чтобы получить согласованные результаты.

    SELECT EXTRACT(WEEK FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 7
    

year

  • поле года. Имейте в виду, что отсутствует 0 год нашей эры (AD), поэтому вычитать годы до Р. Х. (BC) из лет после Р. Х. (AD) следует с осторожностью.

    SELECT EXTRACT(YEAR FROM TIMESTAMP ’2001-02-16 20:38:40’);
    Result: 2001
    

Заметка
Когда входное значение равно +/- Бесконечность, extract возвращает +/- Бесконечность для монотонно увеличивающихся полей (epoch, julian, year, isoyear, decade, century и millennium). Для других полей возвращается NULL.

Функция extract в первую очередь предназначена для вычислительной обработки. Форматирование значений даты / времени для отображения см. в разделе Функции форматирования типов данных.

Функция date_part смоделирована на традиционном Ingres, эквивалентном extract стандартной SQL- функции:

date_part('field', source)

Обратите внимание, что здесь параметр field должен быть строковым значением, а не именем. Допустимые имена полей для date_part такие же, как и для extract.

SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Result: 16

SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Result: 4

date_trunc

Функция date_trunc концептуально аналогична функции trunc для чисел.

date_trunc(field, source [, time_zone ])

source - это выражение значения типа timestamp, timestamp with time zone или interval. (Значения типа date и time автоматически timestamp в timestamp или interval, соответственно). field выбирает, с какой точностью обрезать входное значение. Возвращаемое значение также имеет тип timestamp, timestamp with time zone или interval, и оно имеет все поля, которые менее значимы, чем выбранное, установленное в ноль (или одно, для дня и месяца).

Допустимые значения для field:

microseconds
milliseconds
second
minute
hour
day
week
month
quarter
year
decade
century
millennium

Когда входное значение имеет тип timestamp with time zone, усечение выполняется относительно определенного часового пояса; например, усечение до day приводит к значению полуночи в этой зоне. По умолчанию усечение выполняется относительно текущей настройки TimeZone, но можно указать необязательный аргумент time_zone чтобы указать другой часовой пояс. Название часового пояса можно указать любым из способов, описанных в разделе Часовые пояса.

Часовой пояс не может быть указан при обработке timestamp without time zone ввода timestamp without time zone или interval.

Примеры (при условии, что местный часовой пояс - America/New_York):

SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-02-16 20:00:00

SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Result: 2001-01-01 00:00:00

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Result: 2001-02-16 00:00:00-05

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Result: 2001-02-16 08:00:00-05

SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Result: 3 days 02:00:00

AT TIME ZONE

AT TIME ZONE преобразует временную метку без временной зоны в/из временной метки с часовым поясом и значениями времени в разные часовые пояса. Таблица 32 показывает его варианты.

Таблица 32. AT TIME ZONE Варианты

ВыражениеТип ответаОписание
timestamp without time zone AT TIME ZONE zonetimestamp with time zoneРассматривать данную метку времени без часового пояса как расположенную в указанном часовом поясе
timestamp with time zone AT TIME ZONE zonetimestamp without time zoneПреобразовать данную временную метку с часовым поясом в новый часовой пояс без указания часового пояса
time with time zone AT TIME ZONE zonetime with time zoneПреобразовать данное время с часовым поясом в новый часовой пояс

В этих выражениях желаемый часовой пояс может быть указан либо в виде текстовой строки (например, ’America/Los_Angeles’), либо в качестве интервала (например, INTERVAL ’-08:00’). В текстовом случае имя часового пояса можно указать любым из способов, описанных в разделе Часовые пояса.

Примеры (при условии, что местным часовым поясом является America/Los_Angeles):

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
Result: 2001-02-16 19:38:40-08

SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
Result: 2001-02-16 18:38:40

SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
Result: 2001-02-16 05:38:40

В первом примере добавляется часовой пояс к значению, в котором он отсутствует, и отображает значение с использованием текущего параметра TimeZone. Во втором примере метка времени со значением часового пояса перемещается в указанный часовой пояс и возвращает значение без часового пояса. Это позволяет хранить и отображать значения, отличные от текущей настройки TimeZone. Третий пример переводит время Токио во время Чикаго. Преобразование значений времени в другие часовые пояса использует текущие действующие правила часовых поясов, поскольку дата не указана.

Функция timezone (zone, timestamp) эквивалентна timestamp AT TIME ZONE zone соответствующей конструкции SQL, в timestamp AT TIME ZONE zone.

Текущая дата / время

QHB предоставляет ряд функций, которые возвращают значения, связанные с текущей датой и временем. Все эти стандартные функции SQL возвращают значения, основанные на времени начала текущей транзакции:

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)

CURRENT_TIME и CURRENT_TIMESTAMP доставляют значения с часовым поясом; LOCALTIME и LOCALTIMESTAMP доставляют значения без часового пояса.

CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME и LOCALTIMESTAMP могут дополнительно принимать параметр точности, который приводит к тому, что результат округляется до такого количества дробных цифр в поле секунд. Без параметра точности результат дается с полной доступной точностью.

Несколько примеров:

SELECT CURRENT_TIME;
Result: 14:39:53.662522-05

SELECT CURRENT_DATE;
Result: 2001-12-23

SELECT CURRENT_TIMESTAMP;
Result: 2001-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
Result: 2001-12-23 14:39:53.66-05

SELECT LOCALTIMESTAMP;
Result: 2001-12-23 14:39:53.662522

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

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

transaction_timestamp()
statement_timestamp()
clock_timestamp()
timeofday()
now()
transaction_timestamp()эквивалентен CURRENT_TIMESTAMP, но назван так, чтобы четко отражать то, что он возвращает.
statement_timestamp()возвращает время начала текущего оператора (более конкретно, время получения последнего командного сообщения от клиента).
statement_timestamp() и transaction_timestamp()возвращают одно и то же значение во время первой команды транзакции, но могут отличаться во время последующих команд.
clock_timestamp()возвращает фактическое текущее время, поэтому его значение изменяется даже в пределах одной команды SQL.
timeofday()это историческая функция QHB. Как и clock_timestamp(), он возвращает фактическое текущее время, но в виде отформатированной text строки, а не как метка времени со значением часового пояса
now()это традиционный QHB, эквивалентный transaction_timestamp().

Все типы данных даты / времени также принимают специальное литеральное значение для указания текущей даты и времени (опять же, интерпретируется как время начала транзакции). Таким образом, все три следующие запроса возвращают один и тот же результат:

SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP ’now’; -- incorrect for use with DEFAULT

Задержка исполнения

Следующие функции доступны для задержки выполнения процесса сервера:

pg_sleep(seconds)
pg_sleep_for(interval)
pg_sleep_until(timestamp with time zone)

pg_sleep переводит процесс текущего сеанса в спящий режим до тех пор, пока не истекут указанные секунды. seconds это значение типа double precision, поэтому можно указать задержки в долях секунды. pg_sleep_for - это удобная функция для больших времен ожидания указанных в качестве интервала. pg_sleep_until - это удобная функция, когда требуется определенное время пробуждения. Например:

SELECT pg_sleep(1.5);
SELECT pg_sleep_for('5 minutes');
SELECT pg_sleep_until('tomorrow 03:00');

Эффективное разрешение интервала ожидания зависит от платформы; 0,01 секунды — это обычное значение. Задержка сна будет по крайней мере такой же, как указано. Это может быть дольше в зависимости от таких факторов, как нагрузка на сервер. В частности, pg_sleep_until не гарантированно проснется точно в указанное время, но не проснется раньше.

Убедитесь, что ваш сеанс не содержит больше блокировок, чем необходимо при вызове pg_sleep или его вариантов. В противном случае другим сеансам, возможно, придется ждать вашего спящего процесса, замедляя работу всей системы.

Функции поддержки Enum

Для типов enum (описанных в разделе Перечисляемые типы), есть несколько функций, которые позволяют более чистое программирование без жесткого кодирования определенных значений типа enum. Они перечислены в таблице 33. В примерах предполагается, что тип enum создан как:

CREATE TYPE rainbow AS ENUM (’red’, ’orange’, ’yellow’, ’green’, ’blue’, ’purple’);

Таблица 33. Функции поддержки Enum

ФункцияОписаниеПримерРезультат
enum_first(anyenum)Возвращает первое значение типа входного перечисленияenum_first(null::rainbow)red
enum_last(anyenum)Возвращает последнее значение типа входного перечисленияenum_last(null::rainbow)purple
enum_range(anyenum)Возвращает все значения типа входного перечисления в упорядоченном массивеenum_range(null::rainbow){red,orange,yellow,green,blue,purple}
enum_range(anyenum, anyenum)Возвращает диапазон между двумя заданными значениями перечисления в виде упорядоченного массива. Значения должны быть из того же типа перечисления. Если первый параметр имеет значение null, результат будет начинаться с первого значения типа enum. Если второй параметр имеет значение null, результат заканчивается последним значением типа enum.enum_range(’orange’::rainbow, ’green’::rainbow){orange,yellow,green}
enum_range(NULL, ’green’::rainbow){red,orange,yellow,green}
enum_range(’orange’::rainbow, NULL){orange,yellow,green,blue,purple}

Обратите внимание, что за исключением формы enum_range с двумя аргументами, эти функции игнорируют определенное значение, переданное им; они заботятся только о своем объявленном типе данных. Может быть передано либо нулевое, либо определенное значение типа с тем же результатом. Как правило, эти функции применяются к столбцу таблицы или аргументу функции, а не к имени типа с проводным подключением, как показано в примерах.

Геометрические функции и операторы

Геометрические типы point, box, lseg, line, path, polygon и circle имеют большой набор собственных вспомогательных функций и операторов, показанных в таблице 34, таблице 35 и таблице 36.

Предупреждение

Обратите внимание, что оператор «тот же, что и», ~=, представляет обычное понятие равенства для типов point, box, polygon и circle. Некоторые из этих типов также имеют оператор =, но = сравнивает только для равных областей. Другие скалярные операторы сравнения (<= и т. д.) также сравнивают области для этих типов.

Таблица 34. Геометрические операторы

ОператорОписаниеПример
+Переводbox ’((0,0),(1,1))’ + point ’(2.0,0)’
-Переводbox ’((0,0),(1,1))’ - point ’(2.0,0)’
*Масштабирование / поворотbox ’((0,0),(1,1))’ * point ’(2.0,0)’
/Масштабирование / поворотbox ’((0,0),(2,2))’ / point ’(2.0,0)’
#Точка или рамка пересеченияbox ’((1,-1),(-1,1))’ # box ’((1,1),(-2,-2))’
#Количество точек на пути или полигоне# path ’((1,0),(0,1),(-1,0))’
@-@Длина или окружность@-@ path ’((0,0),(1,0))’
@@Центр@@ circle ’((0,0),10)’
##Ближайшая точка к первому операнду второго операндаpoint ’(0,0)’ ## lseg ’((2,0),(0,2))’
<->Дистанция междуcircle ’((0,0),1)’ <-> circle ’((5,0),1)’
&&Совмещение? (Одна общая черта делает это правдой).box ’((0,0),(1,1))’ && box ’((0,0),(2,2))’
<<Строго осталось от?circle ’((0,0),1)’ << circle ’((5,0),1)’
>>Это строго право?circle ’((5,0),1)’ >> circle ’((0,0),1)’
&<Не распространяется на право?box ’((0,0),(1,1))’ &< box ’((0,0),(2,2))’
&>Не распространяется влево от?box ’((0,0),(3,3))’ &> box ’((0,0),(2,2))’
<<Строго ниже?box ’((0,0),(3,3))’ << box ’((3,4),(5,5))’
>>Строго выше?box ’((3,4),(5,5))’ >> box ’((0,0),(3,3))’
&<Не распространяется выше?box ’((0,0),(1,1))’ &< box ’((0,0),(2,2))’
&>Не распространяется ниже?box ’((0,0),(3,3))’ &> box ’((0,0),(2,2))’
<^Ниже (позволяет трогать)?circle ’((0,0),1)’ <^ circle ’((0,5),1)’
>^Выше (позволяет трогать)?circle ’((0,5),1)’ >^ circle ’((0,0),1)’
?#Intersects?lseg ’((-1,0),(1,0))’ ?# box ’((-2,-2),(2,2))’
?-Горизонтальный??- lseg ’((-1,0),(1,0))’
?-Выровнены по горизонтали?point ’(1,0)’ ?- point ’(0,0)’
?Вертикально?? lseg ’((-1,0),(1,0))’
?Выровнены по вертикали?point ’(0,1)’ ? point ’(0,0)’
?-Перпендикулярно?lseg ’((0,0),(0,1))’ ?- lseg ’((0,0),(1,0))’
?Параллельны?lseg ’((-1,0),(1,0))’ ? lseg ’((-1,2),(1,2))’
@>Содержит?circle ’((0,0),2)’ @> point ’(1,1)’
<@Содержится в или на?point ’(1,1)’ <@ circle ’((0,0),2)’
~=Такой же как?polygon ’((0,0),(1,1))’ ~= polygon ’((1,1),(0,0))’

Таблица 35. Геометрические функции

ФункцияТип ответаОписаниеПример
area(object)double precisionплощадьarea(box ’((0,0),(1,1))’)
center(object)pointцентрcenter(box ’((0,0),(1,2))’)
diameter(circle)double precisionдиаметр кругаdiameter(circle ’((0,0),2.0)’)
height(box)double precisionвертикальный размер коробкиheight(box ’((0,0),(1,1))’)
isclosed(path)booleanзакрытый путь?isclosed(path ’((0,0),(1,1),(2,0))’)
isopen(path)booleanоткрытый путь?isopen(path ’[(0,0),(1,1),(2,0)]’)
length(object)double precisionдлинаlength(path ’((-1,0),(1,0))’)
npoints(path)intколичество балловnpoints(path ’[(0,0),(1,1),(2,0)]’)
npoints(polygon)intколичество балловnpoints(polygon ’((1,1),(0,0))’)
pclose(path)pathпреобразовать путь в закрытыйpclose(path ’[(0,0),(1,1),(2,0)]’)
popen(path)pathпреобразовать путь в открытыйpopen(path ’((0,0),(1,1),(2,0))’)
radius(circle)double precisionрадиус кругаradius(circle ’((0,0),2.0)’)
width(box)double precisionгоризонтальный размер коробкиwidth(box ’((0,0),(1,1))’)

Таблица 36. Функции преобразования геометрических типов

ФункцияТип ответаОписаниеПример
box(circle)boxкруг к рамкеbox(circle ’((0,0),2.0)’)
box(point)boxуказать на пустое полеbox(point ’(0,0)’)
box(point, point)boxуказывает на рамкуbox(point ’(0,0)’, point ’(1,1)’)
box(polygon)boxполигон в рамкуbox(polygon ’((0,0),(1,1),(2,0))’)
bound_box(box, box)boxрамка к ограничительной рамкеbound_box(box ’((0,0),(1,1))’, box ’((3,3),(4,4))’)
circle(box)circleрамка в кругcircle(box ’((0,0),(1,1))’)
circle(point, double precision)circleцентр и радиус окружностиcircle(point ’(0,0)’, 2.0)
circle(polygon)circleмногоугольник в кругcircle(polygon ’((0,0),(1,1),(2,0))’)
line(point, point)lineуказывает на линиюline(point ’(-1,0)’, point ’(1,0)’)
lseg(box)lsegдиагональ прямоугольника к отрезкуlseg(box ’((-1,0),(1,0))’)
lseg(point, point)lsegуказывает на отрезокlseg(point ’(-1,0)’, point ’(1,0)’)
path(polygon)pathполигон к путиpath(polygon ’((0,0),(1,1),(2,0))’)
point (double precision, double precision)pointпостроить точкуpoint(23.4, -44.5)
point(box)pointцентр рамкиpoint(box ’((-1,0),(1,0))’)
point(circle)pointцентр кругаpoint(circle ’((0,0),2.0)’)
point(lseg)pointцентр отрезкаpoint(lseg ’((-1,0),(1,0))’)
point(polygon)pointцентр многоугольникаpoint(polygon ’((0,0),(1,1),(2,0))’)
polygon(box)polygonкоробка к 4-х точечному многоугольникуpolygon(box ’((0,0),(1,1))’)
polygon(circle)polygonокружность до 12-точечного многоугольникаpolygon(circle ’((0,0),2.0)’)
polygon(npts, circle)polygonокружность в npts -точечный многоугольникpolygon(12, circle ’((0,0),2.0)’)
polygon(path)polygonпуть к многоугольникуpolygon(path ’((0,0),(1,1),(2,0))’)

Можно получить доступ к двум номерам компонентов point как если бы точка была массивом с индексами 0 и 1. Например, если t.p является столбцом point то SELECT p\[0\] FROM t извлекает координату X и UPDATE t SET p[1] = ... изменяет координату Y. Таким же образом значение типа box или lseg можно рассматривать как массив из двух point значений.

Функция area работает для типов box, circle и path. Функция area работает только с типом данных path если точки в path не пересекаются. Например, path ’((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))’::PATH не будет работать; однако следующий визуально идентичный path ’((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))’::PATH будет работать. Если концепция пересекающегося и непересекающегося path вводит в заблуждение, нарисуйте оба вышеупомянутых path рядом на листе миллиметровки.

Функции и операторы сетевых адресов

В таблице 37 показаны операторы, доступные для типов cidr и inet. Операторы <<, <<=, >>, >>= и && проверяют наличие подсети. Они рассматривают только сетевые части двух адресов (игнорируя любую часть хоста) и определяют, является ли одна сеть идентичной или подсетью другой.

Таблица 37. cidr и inet

ОператорОписаниеПример
<меньше чемinet ’192.168.1.5’ < inet ’192.168.1.6’
<=меньше или равноinet ’192.168.1.5’ <= inet ’192.168.1.5’
=равноinet ’192.168.1.5’ = inet ’192.168.1.5’
>=больше или равноinet ’192.168.1.5’ >= inet ’192.168.1.5’
>больше, чемinet ’192.168.1.5’ > inet ’192.168.1.4’
<>не равноinet ’192.168.1.5’ <> inet ’192.168.1.4’
<<содержится вinet ’192.168.1.5’ << inet ’192.168.1/24’
<<=содержится или равноinet ’192.168.1/24’ <<= inet ’192.168.1/24’
>>содержитinet ’192.168.1/24’ >> inet ’192.168.1.5’
>>=содержит или равноinet ’192.168.1/24’ >>= inet ’192.168.1/24’
&&содержит или содержитсяinet ’192.168.1/24’ && inet ’192.168.1.80/28’
~поразрядно НЕ~ inet ’192.168.1.6’
&побитовое Иinet ’192.168.1.6’ & inet ’0.0.0.255’
побитовое ИЛИinet ’192.168.1.6’ inet ’0.0.0.255’
+прибавлениеinet ’192.168.1.6’ + 25
-вычитаниеinet ’192.168.1.43’ - 36
-вычитаниеinet ’192.168.1.43’ - inet ’192.168.1.19’

В таблице 38 показаны функции, доступные для использования с типам cidr и inet. Функции abbrev, host и text в первую очередь предназначены для предоставления альтернативных форматов отображения.

Таблица 38. cidr и inet

ФункцияТип ответаОписаниеПримерРезультат
abbrev(inet)textсокращенный формат отображения в виде текстаabbrev(inet ’10.1.0.0/16’)10.1.0.0/16
abbrev(cidr)textсокращенный формат отображения в виде текстаabbrev(cidr ’10.1.0.0/16’)10.1/16
broadcast(inet)inetшироковещательный адрес для сетиbroadcast(’192.168.1.5/24’)192.168.1.255/24
family(inet)intизвлечь семейство адресов; 4 для IPv4, 6 для IPv6family(’::1’)6
host(inet)textизвлечь IP-адрес в виде текстаhost(’192.168.1.5/24’)192.168.1.5
hostmask(inet)inetпостроить маску хоста для сетиhostmask(’192.168.23.20/30’)0.0.0.3
masklen(inet)intизвлекать длину маскиmasklen(’192.168.1.5/24’)24
netmask(inet)inetпостроить сетевую маску для сетиnetmask(’192.168.1.5/24’)255.255.255.0
network(inet)cidrизвлечь сетевую часть адресаnetwork(’192.168.1.5/24’)192.168.1.0/24
set_masklen(inet, int)inetустановить длину маски для значения inetset_masklen(’192.168.1.5/24’, 16)192.168.1.5/16
set_masklen(cidr, int)cidrустановить длину маски маски для значения cidrset_masklen(’192.168.1.0/24’::cidr, 16)192.168.0.0/16
text(inet)textизвлечь IP-адрес и длину маски в виде текстаtext(inet ’192.168.1.5’)192.168.1.5/32
inet_same_family(inet, inet)booleanадреса из одной семьи?inet_same_family(’192.168.1.5/24’, ’::1’)false
inet_merge(inet, inet)cidrсамая маленькая сеть, которая включает в себя обе из указанных сетейinet_merge(’192.168.1.5/24’, ’192.168.2.5/24’)192.168.0.0/22

Любое значение cidr может быть приведено к inet неявно или явно; следовательно, функции, показанные выше, как работающие с inet также работают со значениями cidr. (Там, где есть отдельные функции для inet и cidr, это происходит потому, что поведение должно отличаться для двух случаев). Кроме того, разрешено приводить значение inet к cidr. Когда это будет сделано, любые биты справа от маски маски будут cidr обнулены для создания действительного значения cidr. Кроме того, вы можете преобразовать текстовое значение в inet или cidr используя обычный синтаксис приведения: например, inet(expression) или colname::cidr.

В таблице 39 показаны функции, доступные для использования с типом macaddr. Функция trunc(macaddr) возвращает MAC-адрес с последними 3 байтами, установленными в ноль. Это может быть использовано для связи оставшегося префикса с производителем.

Таблица 39. Функции macaddr

ФункцияТип ответаОписаниеПримерРезультат
trunc(macaddr)macaddrустановить последние 3 байта в нольtrunc(macaddr ’12:34:56:78:90:ab’)12:34:56:00:00:00

Тип macaddr также поддерживает стандартные реляционные операторы (>, <= и т. Д). Для лексикографического упорядочения и побитовые арифметические операторы (~, & и ) для NOT, AND и OR.

В таблице 40 показаны функции, доступные для использования с типом macaddr8. Функция trunc(macaddr8) возвращает MAC-адрес с последними 5 байтами, установленными в ноль. Это может быть использовано для связи оставшегося префикса с производителем.

Таблица 40. Функции macaddr8

ФункцияТип ответаОписаниеПримерРезультат
trunc(macaddr8)macaddr8установить последние 5 байтов в нольtrunc(macaddr8 ’12:34:56:78:90:ab:cd:ef’)12:34:56:00:00:00:00:00
macaddr8_set7bit(macaddr8)macaddr8установите 7-й бит в единицу, также известный как модифицированный EUI-64, для включения в адрес IPv6macaddr8_set7bit(macaddr8 ’00:34:56:ab:cd:ef’)02:34:56:ff:fe:ab:cd:ef

Тип macaddr8 также поддерживает стандартные реляционные операторы (>, <= и т. д). Для упорядочения и побитовые арифметические операторы (~, & и ) для NOT, AND и OR.

Функции текстового поиска и операторы

В таблице 41, таблице 42 и таблице 43 обобщены функции и операторы, которые предоставляются для полнотекстового поиска.

Таблица 41. Операторы текстового поиска

ОператорТип ответаОписаниеПримерРезультат
@@booleantsvector соответствует tsquery ?to_tsvector(’fat cats ate rats’) @@ to_tsquery(’cat & rat’)t
@@@booleanустарел синоним @@to_tsvector(’fat cats ate rats’) @@@ to_tsquery(’cat & rat’)t
tsvectortsvector с’a:1 b:2’::tsvector ’c:1 d:2 b:3’::tsvector’a’:1 ’b’:2,5 ’c’:3 ’d’:4
&&tsqueryИ tsquery с вместе’fat rat’::tsquery && ’cat’::tsquery(’fat’ ’rat’) & ’cat’
tsqueryИЛИ tsquery с вместе’fat rat’::tsquery ’cat’::tsquery(’fat’ ’rat’) ’cat’
!!tsqueryотрицать tsquery!! ’cat’::tsquery!’cat’
<->tsquerytsquery последующим tsqueryto_tsquery(’fat’) <-> to_tsquery(’rat’)’fat’ <-> ’rat’
@>booleantsquery содержит другое?’cat’::tsquery @> ’cat & rat’::tsqueryf
<@booleantsquery содержится в?’cat’::tsquery <@ ’cat & rat’::tsqueryt

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

В дополнение к операторам, показанным в таблице, обычные операторы сравнения B-деревьев (=, < и т.д.). Определены для типов tsvector и tsquery. Они не очень полезны для текстового поиска, но позволяют, например, создавать уникальные индексы на столбцах этих типов.

Таблица 42. Функции текстового поиска

ФункцияТип ответаОписаниепримерРезультат
array_to_tsvector (text[])tsvectorконвертировать массив лексем в tsvectorarray_to_tsvector(’{fat,cat,rat}’::text[])’cat’ ’fat’ ’rat’
get_current_ts_config()regconfigполучить конфигурацию текстового поиска по умолчаниюget_current_ts_config()english
length (tsvector)integerколичество лексем в tsvectorlength(’fat:2,4 cat:3 rat:5A’::tsvector)3
numnode (tsquery)integerколичество лексем плюс операторов в tsquerynumnode(’(fat & rat) cat’::tsquery)5
plainto_tsquery ([ config regconfig, ] query text)tsqueryпроизводить tsquery игнорируя пунктуациюplainto_tsquery(’english’, ’The Fat Rats’)’fat’ & ’rat’
phraseto_tsquery ([ config regconfig, ] query text)tsqueryпроизводить tsquery который ищет фразу, игнорируя пунктуациюphraseto_tsquery(’english’, ’The Fat Rats’)’fat’ <-> ’rat’
websearch_to_tsquery ([ config regconfig, ] query text)tsqueryсоздать tsquery из запроса в стиле веб-поискаwebsearch_to_tsquery(’english’, ’"fat rat" or rat’)’fat’ <-> ’rat’ ’rat’
querytree(query tsquery)textполучить индексируемую часть tsqueryquerytree(’foo & ! bar’::tsquery)’foo’
setweight(vector tsvector, weight "char")tsvectorназначить weight каждому элементу vectorsetweight(’fat:2,4 cat:3 rat:5B’::tsvector, ’A’)’cat’:3A ’fat’:2A,4A ’rat’:5A
setweight(vector tsvector, weight "char", lexemes text[])tsvectorприсваивать weight элементам vector, перечисленным в lexemessetweight(’fat:2,4 cat:3 rat:5B’::tsvector, ’A’, ’{cat,rat}’)’cat’:3A ’fat’:2,4 ’rat’:5A
strip(tsvector)tsvectorубрать позиции и веса с tsvectorstrip(’fat:2,4 cat:3 rat:5A’::tsvector)’cat’ ’fat’ ’rat’
to_tsquery([ config regconfig, ] query text)tsqueryнормализуйте слова и конвертируйте в tsqueryto_tsquery(’english’, ’The & Fat & Rats’)’fat’ & ’rat’
to_tsvector([ config regconfig, ] document text)tsvectorуменьшить текст документа до tsvectorto_tsvector(’english’, ’The Fat Rats’)’fat’:2 ’rat’:3
to_tsvector([ config regconfig, ] document json(b))tsvectorуменьшите каждое строковое значение в документе до tsvector, а затем tsvector их в порядке документа для получения одного tsvectorto_tsvector(’english’, ’{"a": "The Fat Rats"}’::json)’fat’:2 ’rat’:3
json(b)_to_tsvector([ config regconfig, ] document json(b), filter json(b))tsvectorуменьшите каждое значение в документе, заданном filter до tsvector, а затем tsvector их в порядке документа, чтобы получить один tsvector. filter - это массив jsonb, который перечисляет, какие элементы должны быть включены в результирующий tsvector. Возможные значения для filter: "string" (чтобы включить все строковые значения), "numeric" (чтобы включить все числовые значения в строковом формате), "boolean" (чтобы включить все логические значения в строковом формате "true" / "false"), "key" (чтобы включить все ключи) или "all" (чтобы включить все выше). Эти значения можно объединить, чтобы включить, например, все строковые и числовые значения.json_to_tsvector(’english’, ’{"a": "The Fat Rats", "b": 123}’::json, ’["string", "numeric"]’)’123’:5 ’fat’:2 ’rat’:3
ts_delete(vector tsvector, lexeme text)tsvectorудалить данную lexeme из vectorts_delete(’fat:2,4 cat:3 rat:5A’::tsvector, ’fat’)’cat’:3 ’rat’:5A
ts_delete(vector tsvector, lexemes text[])tsvectorудалить любое вхождение лексем в lexemes из vectorts_delete(’fat:2,4 cat:3 rat:5A’::tsvector, ARRAY[’fat’,’rat’]) ’cat’:3
ts_filter(vector tsvector, weights "char"[])tsvectorвыбрать только элементы с заданными weights из vectorts_filter(’fat:2,4 cat:3b rat:5A’::tsvector, ’{a,b}’)’cat’:3B ’rat’:5A
ts_headline([ config regconfig, ] document text, query tsquery [, options text ])textотобразить соответствие запросаts_headline(’xy z’, ’z’::tsquery)xy <b>z</b>
ts_headline([ config regconfig, ] document json(b), query tsquery [, options text ])textотобразить соответствие запросаts_headline(’{"a":"xyz"}’::json, ’z’::tsquery){"a":"xy <b>z</b>"}
ts_rank([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ])float4ранжировать документ по запросуts_rank(textsearch, query)0.818
ts_rank_cd([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ])float4ранжировать документ для запроса с использованием плотности покрытияts_rank_cd(’{0.1, 0.2, 0.4, 1.0}’, textsearch, query)2.01317
ts_rewrite(query tsquery, target tsquery, substitute tsquery)tsqueryзаменить target substitute в запросеts_rewrite(’a & b’::tsquery, ’a’::tsquery, ’foobar’::tsquery)’b’ & (’foo’ ’bar’)
ts_rewrite(query tsquery, select text)tsqueryзаменить, используя цели и замены из команды SELECTSELECT ts_rewrite(’a & b’::tsquery, ’SELECT t,s FROM aliases’)’b’ & (’foo’ ’bar’)
tsquery_phrase(query1 tsquery, query2 tsquery)tsqueryсоздать запрос, который ищет query1 за которым следует query2 (аналогично оператору <->)tsquery_phrase(to_tsquery(’fat’), to_tsquery(’cat’))’fat’ <-> ’cat’
tsquery_phrase(query1 tsquery, query2 tsquery, distance integer)tsqueryсоздать запрос, который ищет query1 за которым следует query2 на distancetsquery_phrase(to_tsquery(’fat’), to_tsquery(’cat’), 10)’fat’ <10> ’cat’
tsvector_to_array(tsvector)text[]конвертировать tsvector в массив лексемtsvector_to_array(’fat:2,4 cat:3 rat:5A’::tsvector){cat,fat,rat}
tsvector_update_trigger()triggerфункция триггера для автоматического обновления столбца tsvectorCREATE TRIGGER ... tsvector_update_trigger(tsvcol, ’pg_catalog.swedish’, title, body)
tsvector_update_trigger_column()triggerфункция триггера для автоматического обновления столбца tsvectorCREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, configcol, title, body)
unnest(tsvector, OUT lexeme text, OUT positions smallint[], OUT weights text)setof recordразверните tsvector до набора строкunnest(’fat:2,4 cat:3 rat:5A’::tsvector)(cat,{3},{D}) ...

Все функции текстового поиска, которые принимают необязательный аргумент regconfig будут использовать конфигурацию, заданную параметром default_text_search_config, когда этот аргумент пропущен.

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

Таблица 43. Функции отладки текстового поиска

ФункцияТип ответаОписаниеПримерРезультат
ts_debug(\[ config regconfig, \] document text, OUT alias text, OUT description text, OUT token text, OUT dictionaries regdictionary\[\], OUT dictionary regdictionary, OUT lexemes text\[\])setof recordпротестировать конфигурациюts_debug (’english’, ’The Brightest supernovaes’)(asciiword,"Word, all ASCII",The, {english_stem}, english_stem,{}) ...
ts_lexize(dict regdictionary, token text)text[]проверить словарьts_lexize (’english_stem’, ’stars’){star}
ts_parse(parser_name text, document text, OUT tokid integer, OUT token text)setof recordпроверить парсерts_parse (’default’, ’foo - bar’)(1,foo) ...
ts_parse(parser_oid oid, document text, OUT tokid integer, OUT token text)setof recordпроверить парсерts_parse (3722, ’foo - bar’)(1,foo) ...
ts_token_type(parser_name text, OUT tokid integer, OUT alias text, OUT description text)setof recordполучить типы токенов, определенные парсеромts_token_type (’default’)(1,asciiword, "Word, all ASCII") ...
ts_token_type(parser_oid oid, OUT tokid integer, OUT alias text, OUT description text)setof recordполучить типы токенов, определенные парсеромts_token_type (3722)(1,asciiword, "Word, all ASCII") ...
ts_stat(sqlquery text, \[ weights text, \] OUT word text, OUT ndoc integer, OUT nentry integer)setof recordполучить статистику столбца tsvectorts_stat (’SELECT vector from apod’)(foo,10,15) ...

Функции XML

Функции и функционально-подобные выражения, описанные в этом разделе, работают со значениями типа xml. См. раздел Тип XML для получения информации о типе xml. Функциональные выражения xmlparse и xmlserialize для преобразования в тип xml и из него описаны там, а не в этом разделе.

Использование большинства этих функций требует, чтобы QHB был собран с помощью configure --with-libxml.

Создание XML-контента

Набор функций и функциональных выражений доступен для создания XML-контента из данных SQL. Как таковые, они особенно подходят для форматирования результатов запросов в XML-документы для обработки в клиентских приложениях.

xmlcomment

xmlcomment(text)

Функция xmlcomment создает значение XML, содержащее комментарий XML с указанным текстом в качестве содержимого. Текст не может содержать «--» или заканчиваться на «-», поэтому полученная конструкция является допустимым комментарием XML. Если аргумент равен нулю, результат равен нулю.

Пример:

SELECT xmlcomment('hello');

  xmlcomment
--------------
 <!--hello-->

xmlconcat

xmlconcat(xml[, ...])

Функция xmlconcat объединяет список отдельных значений XML, чтобы создать одно значение, содержащее фрагмент содержимого XML. Нулевые значения опущены; результат будет нулевым, если нет ненулевых аргументов.

Пример:

SELECT xmlconcat('<abc/>', '<bar>foo</bar>');

      xmlconcat
----------------------
 <abc/><bar>foo</bar>

Объявления XML, если они есть, объединяются следующим образом. Если все значения аргументов имеют одно и то же объявление версии XML, эта версия используется в результате, иначе версия не используется. Если все значения аргумента имеют отдельное значение объявления «да», то это значение используется в результате. Если все значения аргумента имеют отдельное значение объявления и по крайней мере одно - «нет», то это используется в результате. В противном случае результат не будет иметь отдельной декларации. Если для результата определено, что требуется отдельное объявление, но нет объявления версии, будет использоваться объявление версии с версией 1.0, поскольку для XML требуется, чтобы объявление XML содержало объявление версии. Декларации кодирования игнорируются и удаляются во всех случаях.

Пример:

SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');

             xmlconcat
-----------------------------------
 <?xml version="1.1"?><foo/><bar/>

xmlelement

xmlelement(name name [, xmlattributes(value [AS attname] [, ... ])] [, content, ...])

Выражение xmlelement создает элемент XML с заданным именем, атрибутами и содержимым.

Примеры:

SELECT xmlelement(name foo);

 xmlelement
------------
 <foo/>

SELECT xmlelement(name foo, xmlattributes('xyz' as bar));

    xmlelement
------------------
 <foo bar="xyz"/>

SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');

             xmlelement
-------------------------------------
 <foo bar="2007-01-26">content</foo>

Имена элементов и атрибутов, которые не являются допустимыми именами XML, экранируются путем замены нарушающих символов последовательностью _x HHHH _, где HHHH - это HHHH Unicode символа в шестнадцатеричной записи. Например:

SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));

            xmlelement
----------------------------------
 <foo_x0024_bar a_x0026_b="xyz"/>

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

CREATE TABLE test (a xml, b xml);
SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;

Но это не так:

SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;

Содержимое элемента, если оно указано, будет отформатировано в соответствии с его типом данных. Если сам контент имеет тип xml, можно создавать сложные XML-документы. Например:

SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
                            xmlelement(name abc),
                            xmlcomment('test'),
                            xmlelement(name xyz));

                  xmlelement
----------------------------------------------
 <foo bar="xyz"><abc/><!--test--><xyz/></foo>

Содержимое других типов будет отформатировано в допустимые символьные данные XML. В частности, это означает, что символы <,> и & будут преобразованы в объекты. Двоичные данные (тип данных bytea) будут представлены в bytea base64 или hex, в зависимости от настройки параметра конфигурации xmlbinary. Ожидается, что конкретное поведение для отдельных типов данных будет развиваться, чтобы выровнять сопоставления QHB с сопоставлениями, указанными в SQL: 2006 и более поздних версия.

xmlforest

xmlforest(content [AS name] [, ...])

Выражение xmlforest создает XML-лес (последовательность) элементов с использованием заданных имен и содержимого.

Примеры:

SELECT xmlforest('abc' AS foo, 123 AS bar);

          xmlforest
------------------------------
 <foo>abc</foo><bar>123</bar>


SELECT xmlforest(table_name, column_name)
FROM information_schema.columns
WHERE table_schema = 'pg_catalog';

                                         xmlforest
-------------------------------------------------------------------------------------------
 <table_name>pg_authid</table_name><column_name>rolname</column_name>
 <table_name>pg_authid</table_name><column_name>rolsuper</column_name>
 ...

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

Имена элементов, которые не являются допустимыми именами XML, экранируются, как показано выше для xmlelement. Точно так же данные содержимого экранируются для создания допустимого содержимого XML, если оно уже не имеет тип xml.

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

xmlpi

xmlpi(name target [, content])

Выражение xmlpi создает инструкцию обработки XML. Содержимое, если оно присутствует, не должно содержать последовательность символов ?>.

Пример:

SELECT xmlpi(name php, 'echo "hello world";');

            xmlpi
-----------------------------
 <?php echo "hello world";?>

xmlroot

xmlroot(xml, version text | no value [, standalone yes|no|no value])

Выражение xmlroot изменяет свойства корневого узла значения XML. Если указана версия, она заменяет значение в объявлении версии корневого узла; если указан автономный параметр, он заменяет значение в автономном объявлении корневого узла.

SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
               version '1.0', standalone yes);

                xmlroot
----------------------------------------
 <?xml version="1.0" standalone="yes"?>
 <content>abc</content>

xmlagg

xmlagg(xml)

Функция xmlagg, в отличие от других функций, описанных здесь, является агрегатной функцией. Он объединяет входные значения с вызовом агрегатной функции, во многом как xmlconcat, за исключением того, что объединение происходит по строкам, а не по выражениям в одной строке. См. раздел Агрегатные функции для получения дополнительной информации о агрегатных функциях.

Пример:

CREATE TABLE test (y int, x xml);
INSERT INTO test VALUES (1, '<foo>abc</foo>');
INSERT INTO test VALUES (2, '<bar/>');
SELECT xmlagg(x) FROM test;
        xmlagg
----------------------
 <foo>abc</foo><bar/>

Чтобы определить порядок объединения, в совокупный вызов может быть добавлено предложение ORDER BY как описано в разделе Агрегатные выражения. Например:

SELECT xmlagg(x ORDER BY y DESC) FROM test;
        xmlagg
----------------------
 <bar/><foo>abc</foo>

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

SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
        xmlagg
----------------------
 <bar/><foo>abc</foo>

Предикаты XML

Выражения, описанные в этом разделе, проверяют свойства значений xml.

IS DOCUMENT

xml IS DOCUMENT

Выражение IS DOCUMENT возвращает значение true, если значение аргумента XML является правильным документом XML, значение false, если это не так (то есть фрагмент содержимого), или значение null, если аргумент равен null. См. раздел Тип XML о разнице между документами и фрагментами контента.

IS NOT DOCUMENT

xml IS NOT DOCUMENT

Выражение IS NOT DOCUMENT возвращает значение false, если значение аргумента XML является правильным документом XML, значение true, если это не так (то есть фрагмент содержимого), или значение NULL, если аргумент равен NULL.

XMLEXISTS

XMLEXISTS(text PASSING [BY { REF | VALUE }] xml [BY { REF | VALUE }])

Функция xmlexists оценивает выражение XPath 1.0 (первый аргумент) с переданным значением XML в качестве элемента контекста. Функция возвращает false, если в результате этой оценки получен пустой набор узлов, true, если она возвращает любое другое значение. Функция возвращает ноль, если любой аргумент равен нулю. Ненулевое значение, передаваемое в качестве элемента контекста, должно быть документом XML, а не фрагментом содержимого или любым не-XML-значением.

Пример:

SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');

 xmlexists
------------
 t
(1 row)

Предложения BY REF и BY VALUE принимаются в QHB, но игнорируются. В стандарте SQL функция xmlexists оценивает выражение на языке XML Query, но QHB допускает только выражение XPath 1.0.

xml_is_well_formed

xml_is_well_formed(text)
xml_is_well_formed_document(text)
xml_is_well_formed_content(text)

Эти функции проверяют, является ли text строка правильно сформированным XML, возвращая логический результат. xml_is_well_formed_document проверяет правильно сформированный документ, а xml_is_well_formed_content проверяет правильно сформированный контент. xml_is_well_formed выполняет первое, если для параметра конфигурации xmloption задано значение DOCUMENT, или второе, если для него задано CONTENT. Это означает, что xml_is_well_formed полезен для определения успешности простого приведения к типу xml, тогда как две другие функции полезны для определения того, будут ли успешными соответствующие варианты XMLPARSE.

Примеры:

SET xmloption TO DOCUMENT;
SELECT xml_is_well_formed('<>');
 xml_is_well_formed
--------------------
 f
(1 row)

SELECT xml_is_well_formed('<abc/>');
 xml_is_well_formed
--------------------
 t
(1 row)

SET xmloption TO CONTENT;
SELECT xml_is_well_formed('abc');
 xml_is_well_formed
--------------------
 t
(1 row)

SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
 xml_is_well_formed_document
-----------------------------
 t
(1 row)

SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
 xml_is_well_formed_document
-----------------------------
 f
(1 row)

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

Обработка XML

Для обработки значений типа данных xml QHB предлагает функции xpath и xpath_exists, которые оценивают выражения XPath 1.0, и XMLTABLE функцию XMLTABLE.

xpath

xpath(xpath, xml [, nsarray])

Функция xpath вычисляет выражение XPath 1.0 xpath (text значение) по отношению к XML-значению xml. Он возвращает массив XML-значений, соответствующих набору узлов, созданному выражением XPath. Если выражение XPath возвращает скалярное значение, а не набор узлов, то возвращается массив из одного элемента.

Второй аргумент должен быть правильно сформированным документом XML. В частности, он должен иметь один элемент корневого узла.

Необязательный третий аргумент функции — это массив отображений пространства имен. Этот массив должен быть двумерным text массивом с длиной второй оси, равной 2 (т.е. это должен быть массив массивов, каждый из которых состоит ровно из 2 элементов). Первый элемент каждой записи массива — это имя пространства имен (псевдоним), второй - URI пространства имен. Не требуется, чтобы псевдонимы, предоставленные в этом массиве, были такими же, как и используемые в самом документе XML (другими словами, как в документе XML, так и в контексте функции xpath, псевдонимы являются локальными).

Пример:

SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
             ARRAY[ARRAY['my', 'http://example.com']]);

 xpath  
--------
 {test}
(1 row)

Чтобы работать с пространствами имен по умолчанию (анонимными), сделайте что-то вроде этого:

SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
             ARRAY[ARRAY['mydefns', 'http://example.com']]);

 xpath
--------
 {test}
(1 row)

xpath_exists {#}

xpath_exists(xpath, xml [, nsarray])

Функция xpath_exists является специализированной формой функции xpath. Вместо того чтобы возвращать отдельные значения XML, которые удовлетворяют выражению XPath 1.0, эта функция возвращает логическое значение, указывающее, был ли выполнен запрос или нет (в частности, было ли получено какое-либо значение, отличное от пустого набора узлов). Эта функция эквивалентна предикату XMLEXISTS, за исключением того, что она также поддерживает аргумент сопоставления пространства имен.

Пример:

SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
                     ARRAY[ARRAY['my', 'http://example.com']]);

 xpath_exists  
--------------
 t
(1 row)

xmltable

xmltable( [XMLNAMESPACES(namespace uri AS namespace name[, ...]), ]
          row_expression PASSING [BY { REF | VALUE }] document_expression [BY { REF | VALUE }]
          COLUMNS name { type [PATH column_expression] [DEFAULT default_expression] [NOT NULL | NULL]
                        | FOR ORDINALITY }
                   [, ...]
)

Функция xmltable создает таблицу на основе заданного значения XML, фильтра XPath для извлечения строк и набора определений столбцов.

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

Обязательный аргумент row_expression — это выражение XPath 1.0, которое оценивается, передавая document_expression в качестве элемента контекста, для получения набора узлов XML. Эти узлы - то, что xmltable превращает в выходные строки. Строки не будут создаваться, если document_expression имеет значение null, а также если row_expression создает пустой набор узлов или любое значение, отличное от набора узлов.

document_expression предоставляет элемент контекста для row_expression. Это должен быть правильно сформированный XML-документ; фрагменты/леса не принимаются. Предложения BY REF и BY VALUE принимаются, но игнорируются. В стандарте SQL функция xmltable оценивает выражения на языке XML Query, но QHB допускает только выражения XPath 1.0.

Обязательное предложение COLUMNS указывает список столбцов в выходной таблице. Каждая запись описывает один столбец. Смотрите краткое описание синтаксиса для формата выше. Имя и тип столбца обязательны; предложения path, default и nullability являются необязательными.

Столбец, помеченный FOR ORDINALITY будет заполнен номерами строк, начиная с 1, в порядке узлов, полученных из результирующего набора строк row_expression. Максимум один столбец может быть помечен FOR ORDINALITY.

column_expression для столбца — это выражение XPath 1.0, которое оценивается для каждой строки, с текущим узлом из результата row_expression качестве элемента контекста, чтобы найти значение столбца. Если column_expression не указано, то имя столбца используется как неявный путь.

Если выражение XPath столбца возвращает не XML-значение (ограничено строкой, логическим или двойным в XPath 1.0) и столбец имеет тип QHB, отличный от xml, столбец будет установлен так, как если бы строковое представление значения было присвоено типу QHB. (Если значение является логическим, его строковое представление принимается равным 1 или 0 если категория типа выходного столбца является числовой, в противном случае - true или false).

Если выражение XPath столбца возвращает непустой набор узлов XML и тип столбца QHB - xml, столбцу будет точно присвоен результат выражения, если он имеет форму документа или содержимого3.

Результат не в формате XML, назначенный выходному столбцу xml создает содержимое, отдельный текстовый узел со строковым значением результата. Результат XML, назначенный столбцу любого другого типа, может содержать не более одного узла, или возникает ошибка. Если существует ровно один узел, столбец будет установлен так, как если бы он присваивал строковое значение узла (как определено для string функции XPath 1.0) типу QHB.

Строковое значение элемента XML представляет собой объединение в порядке документа всех текстовых узлов, содержащихся в этом элементе и его потомках. Строковое значение элемента без текстовых узлов-потомков является пустой строкой (не NULL). Любые атрибуты xsi:nil игнорируются. Обратите внимание, что text() только для пробелов text() узел text() между двумя нетекстовыми элементами сохраняется, а начальные пробелы в text() узле не сглаживаются. string функция XPath 1.0 может использоваться для правил, определяющих строковое значение других типов узлов XML и не-XML-значений.

Представленные здесь правила преобразования не совсем соответствуют стандарту SQL.

Если выражение пути возвращает пустой набор узлов (обычно, когда он не совпадает) для данной строки, столбцу будет присвоено NULL, если не указано default_expression; затем используется значение, полученное в результате оценки этого выражения.

Столбцы могут быть помечены как NOT NULL. Если column_expression для столбца NOT NULL ничего не соответствует и отсутствует DEFAULT или default_expression также имеет значение null, выдается сообщение об ошибке.

default_expression вместо немедленной оценки при xmltable оценивается каждый раз, когда для столбца требуется значение по умолчанию. Если выражение квалифицируется как стабильное или неизменное, повторная оценка может быть пропущена. Это означает, что вы можете с пользой использовать изменчивые функции, такие как nextval в default_expression.

Примеры:

CREATE TABLE xmldata AS SELECT
xml $$
<ROWS>
  <ROW id="1">
    <COUNTRY_ID>AU</COUNTRY_ID>
    <COUNTRY_NAME>Australia</COUNTRY_NAME>
  </ROW>
  <ROW id="5">
    <COUNTRY_ID>JP</COUNTRY_ID>
    <COUNTRY_NAME>Japan</COUNTRY_NAME>
    <PREMIER_NAME>Shinzo Abe</PREMIER_NAME>
    <SIZE unit="sq_mi">145935</SIZE>
  </ROW>
  <ROW id="6">
    <COUNTRY_ID>SG</COUNTRY_ID>
    <COUNTRY_NAME>Singapore</COUNTRY_NAME>
    <SIZE unit="sq_km">697</SIZE>
  </ROW>
</ROWS>
$$ AS data;

SELECT xmltable.*
  FROM xmldata,
       XMLTABLE('//ROWS/ROW'
                PASSING data
                COLUMNS id int PATH '@id',
                        ordinality FOR ORDINALITY,
                        "COUNTRY_NAME" text,
                        country_id text PATH 'COUNTRY_ID',
                        size_sq_km float PATH 'SIZE[@unit = "sq_km"]',
                        size_other text PATH
                             'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)',
                        premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') ;

 id | ordinality | COUNTRY_NAME | country_id | size_sq_km |  size_other  | premier_name  
----+------------+--------------+------------+------------+--------------+---------------
  1 |          1 | Australia    | AU         |            |              | not specified
  5 |          2 | Japan        | JP         |            | 145935 sq_mi | Shinzo Abe
  6 |          3 | Singapore    | SG         |        697 |              | not specified

В следующем примере показано объединение нескольких узлов text (), использование имени столбца в качестве фильтра XPath, а также обработка пробелов, комментариев XML и инструкций по обработке:

REATE TABLE xmlelements AS SELECT
xml $$
  <root>
   <element>  Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x-->  bbb<x>xxx</x>CC  </element>
  </root>
$$ AS data;

SELECT xmltable.*
  FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
         element         
-------------------------
   Hello2a2   bbbxxxCC  

В следующем примере показано, как можно использовать предложение XMLNAMESPACES для указания списка пространств имен, используемых в документе XML, а также в выражениях XPath:

WITH xmldata(data) AS (VALUES ('
<example xmlns="http://example.com/myns" xmlns:B="http://example.com/b">
 <item foo="1" B:bar="2"/>
 <item foo="3" B:bar="4"/>
 <item foo="4" B:bar="5"/>
</example>'::xml)
)
SELECT xmltable.*
  FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x,
                              'http://example.com/b' AS "B"),
             '/x:example/x:item'
                PASSING (SELECT data FROM xmldata)
                COLUMNS foo int PATH '@foo',
                  bar int PATH '@B:bar');
 foo | bar
-----+-----
   1 |   2
   3 |   4
   4 |   5
(3 rows)

Отображение таблиц в XML

Следующие функции отображают содержимое реляционных таблиц в значения XML. Их можно рассматривать как функцию экспорта XML:

table_to_xml(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xml(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xml(cursor refcursor, count int, nulls boolean,
              tableforest boolean, targetns text)

Тип ответа каждой функции - xml.

table_to_xml отображает содержимое именованной таблицы, передаваемой как параметр tbl. Тип regclass принимает строки, идентифицирующие таблицы, используя обычные обозначения, включая необязательные квалификации схемы и двойные кавычки. query_to_xml выполняет запрос, текст которого передается как query параметра, и отображает набор результатов. cursor_to_xml извлекает указанное количество строк из курсора, указанного параметром cursor. Этот вариант рекомендуется, если необходимо сопоставить большие таблицы, поскольку значение результата создается в памяти каждой функцией.

Если tableforest имеет значение false, итоговый XML-документ выглядит следующим образом:

<tablename>
  <row>
    <columnname1>data</columnname1>
    <columnname2>data</columnname2>
  </row>

  <row>
    ...
  </row>

  ...
</tablename>

Если tableforest имеет значение true, результатом является фрагмент содержимого XML, который выглядит следующим образом:

<tablename>
  <columnname1>data</columnname1>
  <columnname2>data</columnname2>
</tablename>

<tablename>
  ...
</tablename>

...

Если имя таблицы недоступно, то есть при отображении запроса или курсора table строк используется в первом формате, row во втором.

Выбор между этими форматами остается за пользователем. Первый формат — это правильный XML-документ, который будет важен во многих приложениях. Второй формат имеет тенденцию быть более полезным в функции cursor_to_xml если значения результата должны быть впоследствии собраны в один документ. Обсуждаемые выше функции для создания содержимого XML, в частности xmlelement, могут использоваться для изменения результатов по вкусу.

Значения данных отображаются так же, как описано выше для функции xmlelement.

Параметр nulls определяет, должны ли нулевые значения быть включены в выходные данные. Если true, нулевые значения в столбцах представлены как:

<columnname xsi:nil="true"/>

где xsi - префикс пространства имен XML для экземпляра схемы XML. Соответствующее объявление пространства имен будет добавлено к значению результата. Если false, столбцы, содержащие нулевые значения, просто не включаются в вывод.

Параметр targetns указывает желаемое пространство имен XML для результата. Если конкретное пространство имен не требуется, должна быть передана пустая строка.

Следующие функции возвращают документы схемы XML, описывающие сопоставления, выполняемые соответствующими функциями выше:

table_to_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)
cursor_to_xmlschema(cursor refcursor, nulls boolean, tableforest boolean, targetns text)

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

Следующие функции создают сопоставления данных XML и соответствующую схему XML в одном документе (или лесу), связанных вместе. Они могут быть полезны, когда требуются автономные и самоописываемые результаты:

table_to_xml_and_xmlschema(tbl regclass, nulls boolean, tableforest boolean, targetns text)
query_to_xml_and_xmlschema(query text, nulls boolean, tableforest boolean, targetns text)

Кроме того, доступны следующие функции для создания аналогичных отображений всей схемы или всей текущей базы данных:

schema_to_xml(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)
schema_to_xml_and_xmlschema(schema name, nulls boolean, tableforest boolean, targetns text)

database_to_xml(nulls boolean, tableforest boolean, targetns text)
database_to_xmlschema(nulls boolean, tableforest boolean, targetns text)
database_to_xml_and_xmlschema(nulls boolean, tableforest boolean, targetns text)

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

Результат отображения содержимого схемы выглядит следующим образом:

<schemaname>

table1-mapping

table2-mapping

...

</schemaname>

где формат отображения таблицы зависит от параметра tableforest как описано выше.

Результат отображения содержимого базы данных выглядит следующим образом:

<dbname>

<schema1name>
  ...
</schema1name>

<schema2name>
  ...
</schema2name>

...

</dbname>

где отображение схемы такое же, как указано выше.

В качестве примера использования выходных данных, создаваемых этими функциями, на рисунке 1 показана table_to_xml_and_xmlschema стилей XSLT, которая преобразует выходные данные table_to_xml_and_xmlschema в документ HTML, содержащий табличное представление данных таблицы. Аналогичным образом результаты этих функций могут быть преобразованы в другие форматы на основе XML.

Рисунок 1. Таблица стилей XSLT для преобразования вывода SQL/XML в HTML

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.w3.org/1999/xhtml"
>

  <xsl:output method="xml"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
      doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
      indent="yes"/>

  <xsl:template match="/*">
    <xsl:variable name="schema" select="//xsd:schema"/>
    <xsl:variable name="tabletypename"
                  select="$schema/xsd:element[@name=name(current())]/@type"/>
    <xsl:variable name="rowtypename"
                  select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>

    <html>
      <head>
        <title><xsl:value-of select="name(current())"/></title>
      </head>
      <body>
        <table>
          <tr>
            <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
              <th><xsl:value-of select="."/></th>
            </xsl:for-each>
          </tr>

          <xsl:for-each select="row">
            <tr>
              <xsl:for-each select="*">
                <td><xsl:value-of select="."/></td>
              </xsl:for-each>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

Функции и операторы JSON

Этот раздел описывает:

  • функции и операторы для обработки и создания данных JSON

  • язык путей SQL/JSON

Чтобы узнать больше о стандарте SQL/JSON, обратитесь к стандарту ISO/IEC TR 19075-6.

Обработка и создание данных JSON

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

Таблица 44. jsonb и jsonb Операторы

ОператорТип правого операндаТип ответаОписаниеПримерРезультат
->intjson или
jsonb
Получить элемент массива JSON (индексируется с нуля, отрицательные целые числа считаются с конца)'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2{"c":"baz"}
->textjson или
jsonb
Получить поле объекта JSON по ключу'{"a": {"b":"foo"}}'::json-&gt;'a'{"b":"foo"}
->>inttextПолучить элемент массива JSON в виде text'[1,2,3]'::json->>23
->>texttextПолучить поле объекта JSON как text'{"a":1,"b":2}'::json->>'b'2
#>text[]json или
jsonb
Получить объект JSON по указанному пути'{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}'{"c": "foo"}
#>>text[]textПолучить объект JSON по указанному пути в виде text'{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'3

Существуют параллельные варианты этих операторов для типов json и jsonb. Операторы извлечения поля/элемента/пути возвращают тот же тип, что и их левый ввод (json или jsonb), за исключением тех, которые указаны как возвращающий text, которые приводят значение к тексту. Операторы извлечения поля/элемента/пути возвращают NULL вместо сбоя, если вход JSON не имеет правильной структуры, соответствующей запросу; например, если такого элемента не существует. Все операторы извлечения поля/элемента/пути, которые принимают индексы целочисленных JSON-массивов, поддерживают отрицательную подписку с конца массивов.

Стандартные операторы сравнения, показанные в таблице 1, доступны для jsonb, но не для json. Они следуют правилам упорядочения операций B-дерева, изложенным в разделе Индексирование jsonb.

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

Таблица 45. Дополнительные операторы jsonb

ОператорТип правого операндаОписаниеПример
@>jsonbСодержит ли левое значение JSON правильные записи пути / значения JSON на верхнем уровне?’{"a":1, "b":2}’::jsonb @> ’{"b":2}’::jsonb
<@jsonbСодержатся ли левые записи пути / значения JSON на верхнем уровне в правом значении JSON?’{"b":2}’::jsonb <@ ’{"a":1, "b":2}’::jsonb
?textСуществует ли строка как ключ верхнего уровня в значении JSON?’{"a":1, "b":2}’::jsonb ? ’b’
?text[]Существуют ли какие-либо из этих строк массива в качестве ключей верхнего уровня?’{"a":1, "b":2, "c":3}’::jsonb ? array[’b’, ’c’]
?&text[]Все ли эти строки массива существуют как ключи верхнего уровня?’["a", "b"]’::jsonb ?& array[’a’, ’b’]
jsonbjsonb два значения jsonb в новое значение jsonb’["a", "b"]’::jsonb ’["c", "d"]’::jsonb
-textУдалить пару ключ / значение или строковый элемент из левого операнда. Пары ключ / значение сопоставляются на основе их значения ключа.’{"a": "b"}’::jsonb - ’a’
-text[]Удалите несколько пар ключ / значение или строковые элементы из левого операнда. Пары ключ / значение сопоставляются на основе их значения ключа.’{"a": "b", "c": "d"}’::jsonb - ’{a,c}’::text[]
-integerУдалить элемент массива с указанным индексом (отрицательные целые числа считаются с конца). Выдает ошибку, если контейнер верхнего уровня не является массивом.’["a", "b"]’::jsonb - 1
#-text[]Удалить поле или элемент с указанным путем (для массивов JSON отрицательные целые числа считаются с конца)’["a", {"b":1}]’::jsonb #- ’{1,b}’
@?jsonpathВозвращает ли путь JSON какой-либо элемент для указанного значения JSON?’{"a":[1,2,3,4,5]}’::jsonb @? ’$.a[*] ? (@ > 2)’
@@jsonpathВозвращает результат проверки предиката пути JSON для указанного значения JSON. Только первый элемент результата учитывается. Если результат не является логическим, возвращается null.’{"a":[1,2,3,4,5]}’::jsonb @@ ’$.a[*] > 2’

Оператор ||» объединяет элементы на верхнем уровне каждого из своих операндов. Он не работает рекурсивно. Например, если оба операнда являются объектами с именем поля общего ключа, значением поля в результате будет просто значение из правого операнда.

Операторы «@?» и «@@» подавляют следующие ошибки: отсутствие поля объекта или элемента массива, непредвиденный тип элемента JSON и числовые ошибки. Это может быть полезно при поиске в коллекциях документов JSON различной структуры.

В таблице 46 показаны функции, доступные для создания значений json и jsonb. (Не существует эквивалентных функций для jsonb, функций row_to_json и array_to_json. Однако функция to_jsonb предоставляет практически те же функции, что и эти функции).

Таблица 46. Функции создания JSON

Функция Описание Пример Результат
to_json(anyelement) to_jsonb(anyelement) Возвращает значение в виде json или jsonb. Массивы и композиты преобразуются (рекурсивно) в массивы и объекты; в противном случае, если приведение приведено к типу json, функция преобразования будет использована для выполнения преобразования; в противном случае получается скалярное значение. Для любого скалярного типа, отличного от числа, логического или нулевого значения, будет использоваться текстовое представление таким образом, чтобы оно было допустимым значением json или jsonb. to_json (’Fred said "Hi."’::text) "Fred said \"Hi.\""
array_to_json(anyarray [, pretty_bool]) Возвращает массив в виде массива JSON. Многомерный массив QHB становится массивом массивов JSON. pretty_bool строки будет добавлен между элементами измерения 1, если pretty_bool имеет значение true. array_to_json (’{{1,5},{99,100}}’::int[]) [[1,5],[99,100]]
row_to_json(record [, pretty_bool]) Возвращает строку в виде объекта JSON. pretty_bool строки будет добавлен между элементами уровня 1, если pretty_bool имеет значение true. row_to_json (row(1,’foo’)) {"f1":1,"f2":"foo"}
json_build_array(VARIADIC "any") jsonb_build_array(VARIADIC "any") Создает возможно разнородный тип JSON-массива из списка переменных аргументов. json_build_array (1,2,’3’,4,5) [1, 2, "3", 4, 5]
json_build_object(VARIADIC "any") jsonb_build_object(VARIADIC "any") Создает объект JSON из списка переменных аргументов. По соглашению список аргументов состоит из чередующихся ключей и значений. json_build_object (’foo’,1,’bar’,2) {"foo": 1, "bar": 2}
json_object(text[]) jsonb_object(text[]) Создает объект JSON из текстового массива. Массив должен иметь либо одно измерение с четным числом элементов, в этом случае они рассматриваются как чередующиеся пары ключ / значение, либо два измерения, так что каждый внутренний массив имеет ровно два элемента, которые принимаются как пара ключ / значение., json_object (’{a, 1, b, "def", c, 3.5}’)

json_object (’{{a, 1},{b, "def"},{c, 3.5}}’)

{"a": "1", "b": "def", "c": "3.5"}
json_object(keys text[], values text[]) jsonb_object(keys text[], values text[]) Эта форма json_object получает ключи и значения попарно из двух отдельных массивов. Во всем остальном он идентичен форме с одним аргументом. json_object (’{a, b}’, ’{1,2}’) {"a": "1", "b": "2"}

Примечание
array_to_json и row_to_json ведут себя так же, как to_json за исключением того, что предлагают красивую опцию печати. Поведение, описанное для to_json также применимо к каждому отдельному значению, преобразованному другими функциями создания JSON.

Примечание
Расширение hstore имеет приведение от hstore к json, поэтому значения hstore преобразованные с помощью функций создания JSON, будут представлены как объекты JSON, а не как примитивные строковые значения.

В таблице 47 показаны функции, доступные для обработки значений json и jsonb.

Таблица 47. Функции обработки JSON

ФункцияТип результатаОписаниеПримерРезультат

json_array_length(json)

jsonb_array_length(jsonb)

intВозвращает число элементов во внешнем массиве JSON.json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')5

json_each(json)

jsonb_each(jsonb)

setof key text, value json

setof key text, value jsonb

Разворачивает внешний объект JSON в набор пар ключ/значение (key/value).select * from json_each('{"a":"foo", "b":"bar"}')
 key | value
-----+-------
 a   | "foo"
 b   | "bar"

json_each_text(json)

jsonb_each_text(jsonb)

setof key text, value textРазворачивает внешний объект JSON в набор пар ключ/значение (key/value). Возвращаемые значения будут иметь тип text.select * from json_each_text('{"a":"foo", "b":"bar"}')
 key | value
-----+-------
 a   | foo
 b   | bar

json_extract_path(from_json json, VARIADIC path_elems text[])

jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[])

json

jsonb

Возвращает значение JSON по пути, заданному элементами пути (path_elems) (равнозначно оператору #> operator).json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4'){"f5":99,"f6":"foo"}

json_extract_path_text(from_json json, VARIADIC path_elems text[])

jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])

textВозвращает значение JSON по пути, заданному элементами пути path_elems, как text (равнозначно оператору #>>).json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6')foo

json_object_keys(json)

jsonb_object_keys(jsonb)

setof textВозвращает набор ключей во внешнем объекте JSON.json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')
 json_object_keys
-----------------
 f1
 f2

json_populate_record(base anyelement, from_json json)

jsonb_populate_record(base anyelement, from_json jsonb)

anyelementРазворачивает объект из from_json в табличную строку, в которой столбцы соответствуют типу строки, заданному параметром base (см. примечания ниже).

create type myrowtype as (a int, b json, c json);

select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}}')

 a |   b       |      c
---+-----------+-------------
 1 | {2,"a b"} | (4,"a b c")

json_populate_recordset(base anyelement, from_json json)

jsonb_populate_recordset(base anyelement, from_json jsonb)

setof anyelementРазворачивает внешний массив объектов из from_json в набор табличных строк, в котором столбцы соответствуют типу строки, заданному параметром base (см. примечания ниже).

create type myrowtype as (a int, b int);

select * from json_populate_recordset(null::myrowtype, '[{"a":1,"b":2},{"a":3,"b":4}]') as (a int, b int)

 a | b
---+---
 1 | 2
 3 | 4

json_array_elements(json)

jsonb_array_elements(jsonb)

setof json

setof jsonb

Разворачивает массив JSON в набор значений JSON.select * from json_array_elements('[1,true, [2,false]]')
   value
-----------
 1
 true
 [2,false]

json_array_elements_text(json)

jsonb_array_elements_text(jsonb)

setof textРазворачивает массив JSON в набор значений text.select * from json_array_elements_text('["foo", "bar"]')
   value
-----------
 foo
 bar

json_typeof(json)

jsonb_typeof(jsonb)

textВозвращает тип внешнего значения JSON в виде текстовой строки. Возможные типы: object, array, string, number, boolean и null.json_typeof('-123.4')number

json_to_record(json)

jsonb_to_record(jsonb)

recordФормирует обычную запись из объекта JSON (см. примечания ниже). Как и со всеми функциями, возвращающими record, при вызове необходимо явно определить структуру записи с помощью предложения AS.

create type myrowtype as (a int, b text);

select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype)

 a |    b    |    c    | d |       r
---+---------+---------+---+---------------
 1 | [1,2,3] | {1,2,3} |   | (123,"a b c")

json_to_recordset(json)

jsonb_to_recordset(jsonb)

setof recordФормирует обычный набор записей из массива объекта JSON (см. примечания ниже). Как и со всеми функциями, возвращающими record, при вызове необходимо явно определить структуру записи с помощью предложения AS.select * from json_to_recordset('[{"a":1,"b":"foo"},{"a":"2","c":"bar"}]') as x(a int, b text);
 a |  b
---+-----
 1 | foo
 2 |

json_strip_nulls(from_json json)

jsonb_strip_nulls(from_json jsonb)

json

jsonb

Возвращает значение from_json, из которого исключаются все поля объекта, содержащие значения NULL. Другие значения NULL остаются нетронутыми.json_strip_nulls('[{"f1":1,"f2":null},2,null,3]')[{"f1":1},2,null,3]

jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])

jsonb

Возвращает значение target, в котором раздел с заданным путём (path) заменяется новым значением (new_value), либо в него добавляется значение new_value, если аргумент create_missing равен true (это значение по умолчанию) и элемент, на который ссылается path, не существует. Как и с операторами, рассчитанными на пути, отрицательные числа в пути (path) обозначают отсчёт от конца массивов JSON.

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false)

jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}','[2,3,4]')

[{"f1":[2,3,4],"f2":null},2,null,3]

[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]

jsonb_insert(target jsonb, path text[], new_value jsonb [, insert_after boolean])

jsonb

Возвращает значение target с вставленным в него новым значением new_value. Если место в target, выбранное путём path, оказывается в массиве JSONB, new_value будет вставлен до (по умолчанию) или после (если параметр insert_after равен true) выбранной позиции. Если место в target, выбранное путём path, оказывается в объекте JSONB, значение new_value будет вставлено в него, только если заданный путь path не существует. Как и с операторами, рассчитанными на пути, отрицательные числа в пути (path) обозначают отсчёт от конца массивов JSON.

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')

jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true)

{"a": [0, "new_value", 1, 2]}

{"a": [0, 1, "new_value", 2]}

jsonb_pretty(from_json jsonb)

text

Возвращает значение from_json в виде текста JSON с отступами.jsonb_pretty('[{"f1":1,"f2":null},2,null,3]')
[
    {
        "f1": 1,
        "f2": null
    },
    2,
    null,
    3
]

jsonb_path_exists(target jsonb, path jsonpath [, vars jsonb [, silent bool]])

booleanОпределяет, выдаёт ли путь JSON какой-либо элемент при заданном значении JSON.

jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}')

true

jsonb_path_match(target jsonb, path jsonpath [, vars jsonb [, silent bool]])

booleanВозвращает результат проверки предиката пути JSON для заданного значения JSON. При этом учитывается только первый элемент результата. Если результат не является булевским, возвращается null.

jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2,"max":4}')

true

jsonb_path_query(target jsonb, path jsonpath [, vars jsonb [, silent bool]])

setof jsonbВозвращает все элементы JSON, которые выдаёт путь JSON для заданного значения JSON.

select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}');

 jsonb_path_query
------------------
 2
 3
 4

jsonb_path_query_array(target jsonb, path jsonpath [, vars jsonb [, silent bool]])

jsonbВозвращает все элементы JSON, которые выдаёт путь JSON для заданного значения JSON, оборачивая их в массив.

jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}')

[2, 3, 4]

jsonb_path_query_first(target jsonb, path jsonpath [, vars jsonb [, silent bool]])

jsonbВозвращает первый элемент JSON, который выдаётся выражением пути для заданного значения JSON. В случае отсутствия результатов возвращает NULL.

jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}')

2

Примечание
Многие из этих функций и операторов преобразуют экранирование Unicode в строках JSON в соответствующий одиночный символ. Это не проблема, если вход имеет тип jsonb, потому что преобразование уже выполнено; но для ввода json это может привести к ошибке, как отмечено в разделе Типы JSON.

Примечание
Функции json[b]_populate_record, json[b]_populate_recordset, json[b]_to_record и json[b]_to_recordset работают с объектом JSON или массивом объектов и извлекают значения, связанные с ключами, имена которых соответствуют именам столбцов тип выходной строки. Поля объекта, которые не соответствуют ни одному имени выходного столбца, игнорируются, а выходные столбцы, которые не соответствуют ни одному полю объекта, будут заполнены пустыми значениями. Для преобразования значения JSON в тип SQL выходного столбца последовательно применяются следующие правила:

  • NULL значение JSON во всех случаях преобразуется в нулевое значение SQL.
  • Если выходной столбец имеет тип json или jsonb, значение JSON точно воспроизводится.
  • Если выходной столбец является составным (строковым) типом, а значение JSON является JSON-объектом, поля объекта преобразуются в столбцы выходного строкового типа путем рекурсивного применения этих правил.
  • Аналогично, если выходной столбец является типом массива, а значение JSON является массивом JSON, элементы массива JSON преобразуются в элементы выходного массива путем рекурсивного применения этих правил.
  • В противном случае, если значение JSON является строковым литералом, содержимое строки передается в функцию преобразования ввода для типа данных столбца.
  • В противном случае обычное текстовое представление значения JSON подается в функцию преобразования ввода для типа данных столбца. Хотя в примерах для этих функций используются константы, обычно используется ссылка на таблицу в предложении FROM и использование одного из ее столбцов json или jsonb в качестве аргумента функции. Затем на извлеченные значения ключей можно ссылаться в других частях запроса, таких как WHERE и целевые списки. Таким образом, извлечение нескольких значений может повысить производительность по сравнению с извлечением их отдельно с помощью ключевых операторов.

Примечание
Все элементы параметра path jsonb_set а также jsonb_insert кроме последнего, должны присутствовать в target. Если create_missing имеет значение false, должны присутствовать все элементы параметра path jsonb_set. Если эти условия не выполнены, target возвращается без изменений.

Примечание
Если последний элемент пути является ключом объекта, он будет создан, если он отсутствует, и ему будет присвоено новое значение. Если последний элемент пути является индексом массива, если он положительный, то элемент для установки определяется путем подсчета слева, а если отрицательный - путем подсчета справа - -1 обозначает самый правый элемент и так далее. Если элемент выходит за пределы диапазона -array_length .. array_length -1, а create_missing имеет значение true, новое значение добавляется в начало массива, если элемент отрицательный, и в конец массива, если он положительный.

Примечание
json_typeof возвращаемое значение функции json_typeof не следует путать с SQL NULL. В то время как вызов json_typeof(’null’::json) вернет null, вызов json_typeof(NULL::json) вернет SQL NULL.

Примечание
Если аргумент json_strip_nulls содержит повторяющиеся имена полей в любом объекте, результат может быть семантически несколько другим, в зависимости от порядка их появления. Это не проблема для jsonb_strip_nulls так jsonb значения jsonb никогда не имеют повторяющихся имен полей объекта.

Примечание
Функции jsonb_path_exists, jsonb_path_match, jsonb_path_query, jsonb_path_query_array и jsonb_path_query_first имеют необязательные vars и silent аргументы. Если указан аргумент vars, он предоставляет объект, содержащий именованные переменные, для подстановки в выражение jsonpath.Если silent аргумент указан и имеет true значение, эти функции подавляют те же ошибки, что и @? и @@ операторы.

См. также раздел Агрегатные функции, где приведена агрегатная функция json_agg которая агрегирует значения записей в виде JSON, и агрегатная функция json_object_agg которая агрегирует пары значений в объект JSON и их эквиваленты jsonb_agg, jsonb_agg и jsonb_object_agg.

Язык путей SQL/JSON

Выражения пути SQL/JSON задают элементы, которые нужно извлечь из данных JSON, аналогично выражениям XPath, используемым для доступа SQL к XML. В QHB выражения пути реализованы как тип данных jsonpath и могут использовать любые элементы, описанные в разделе Тип jsonpath.

Функции и операторы запросов JSON передают предоставленное выражение пути механизму пути для оценки. Если выражение соответствует запрашиваемым данным JSON, возвращается соответствующий элемент SQL/JSON. Выражения пути написаны на языке путей SQL/JSON и могут также включать арифметические выражения и функции. Функции запросов обрабатывают предоставленное выражение как текстовую строку, поэтому оно должно быть заключено в одинарные кавычки.

Выражение пути состоит из последовательности элементов, разрешенных типом данных jsonpath. Выражение пути оценивается слева направо, но вы можете использовать скобки, чтобы изменить порядок операций. Если оценка прошла успешно, создается последовательность элементов SQL/JSON (последовательность SQL/JSON), и результат оценки возвращается в функцию запроса JSON, которая завершает указанное вычисление.

Чтобы сослаться на данные JSON, которые нужно запросить (элемент контекста), используйте знак $ в выражении пути. За ним могут следовать один или несколько операторов доступа, которые понижают структуру структуры JSON уровень за уровнем для получения содержимого элемента контекста. Каждый следующий оператор имеет дело с результатом предыдущего шага оценки.

Например, предположим, у вас есть некоторые данные JSON с GPS-трекера, которые вы хотели бы проанализировать, например:

{
  "track": {
    "segments": [
      {
        "location": [ 47.763, 13.4034 ],
        "start time": "2018-10-14 10:05:14",
        "HR": 73
      },
      {
        "location": [ 47.706, 13.2635 ],
        "start time": "2018-10-14 10:39:21",
        "HR": 135
      }
    ]
  }
}

Чтобы получить доступные сегменты дорожки, вам нужно использовать. оператор доступа .key для всех предыдущих объектов JSON:

'$.track.segments'

Если элемент для извлечения является элементом массива, вы должны удалить этот массив с помощью оператора [*]. Например, следующий путь вернет координаты местоположения для всех доступных сегментов дорожки:

'$.track.segments[*].location'

Чтобы вернуть координаты только первого сегмента, вы можете указать соответствующий индекс в операторе доступа []. Обратите внимание, что массивы SQL/JSON являются 0-относительными:

'$.track.segments[0].location'

Результат каждого шага оценки пути может обрабатываться одним или несколькими операторами и методами jsonpath, перечисленными в разделе Операторы пути и методы SQL/JSON. Каждому имени метода должна предшествовать точка. Например, вы можете получить размер массива:

'$.track.segments.size()'

Дополнительные примеры использования операторов и методов jsonpath в выражениях пути см. раздел Операторы пути и методы SQL/JSON.

При определении пути вы также можете использовать одно или несколько выражений фильтра, которые работают аналогично WHERE в SQL. Выражение фильтра начинается со знака вопроса и содержит условие в скобках:

? (condition)

Выражения фильтра должны быть указаны сразу после шага оценки пути, к которому они применяются. Результат этого шага фильтруется, чтобы включить только те элементы, которые удовлетворяют предоставленному условию. SQL/JSON определяет трехзначную логику, поэтому условие может быть true, false или unknown. unknown значение играет ту же роль, что и SQL NULL и его можно проверить с помощью неизвестного предиката. Дальнейшие шаги оценки пути используют только те элементы, для которых выражения фильтра возвращают true.

Функции и операторы, которые можно использовать в выражениях фильтра, перечислены в таблице 49. Результат оценки пути, подлежащий фильтрации, обозначается переменной @. Чтобы сослаться на элемент JSON, хранящийся на более низком уровне вложенности, добавьте один или несколько операторов доступа после @.

Предположим, вы хотите получить все значения сердечного ритма, превышающие 130. Это можно сделать с помощью следующего выражения:

'$.track.segments[*].HR ? (@ > 130)'

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

'$.track.segments[*] ? (@.HR > 130)."start time"'

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

'$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"'

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

'$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)'`

Вы также можете вкладывать выражения фильтра друг в друга:

'$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()'`

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

Реализация QHB языка путей SQL/JSON имеет следующие отклонения от стандарта SQL/JSON:

  • Метод элемента .datetime() еще не реализован, главным образом потому, что неизменяемые функции и операторы jsonpath не могут ссылаться на часовой пояс сеанса, который используется в некоторых операциях datetime. Поддержка даты и времени будет добавлена в jsonpath в будущих версиях QHB.

  • Выражение пути может быть логическим предикатом, хотя стандарт SQL/JSON допускает предикаты только в фильтрах. Это необходимо для реализации оператора @@. Например, следующее выражение jsonpath допустимо в QHB:

'$.track.segments[*].HR < 70'
  • Существуют небольшие различия в интерпретации шаблонов регулярных выражений, используемых в фильтрах like_regex, как описано в разделе Регулярные выражения.

Строгий и слабый режимы

При запросе данных JSON выражение пути может не соответствовать фактической структуре данных JSON. Попытка получить доступ к несуществующему члену объекта или элемента массива приводит к структурной ошибке. У выражений пути SQL/JSON есть два режима обработки структурных ошибок:

  • lax (по умолчанию) - механизм пути неявно адаптирует запрошенные данные к указанному пути. Все оставшиеся структурные ошибки подавляются и преобразуются в пустые последовательности SQL/JSON.

  • strict - при возникновении структурной ошибки формируется ошибка.

Режим lax облегчает сопоставление структуры документа JSON и выражения пути, если данные JSON не соответствуют ожидаемой схеме. Если операнд не соответствует требованиям конкретной операции, он может быть автоматически упакован в массив SQL/JSON или развернут путем преобразования его элементов в последовательность SQL/JSON перед выполнением этой операции. Кроме того, операторы сравнения автоматически распаковывают свои операнды в режиме lax, поэтому вы можете сравнивать массивы SQL/JSON "из коробки". Массив размером 1 считается равным своему единственному элементу. Автоматическое развертывание не выполняется только тогда, когда:

  • Выражение пути содержит методы type() или size() которые возвращают тип и количество элементов в массиве соответственно.

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

Например, при запросе данных GPS, перечисленных выше, вы можете абстрагироваться от того факта, что при использовании режима lax он хранит массив сегментов:

lax $.track.segments.location’

В строгом strict режиме указанный путь должен точно соответствовать структуре запрашиваемого документа JSON, чтобы вернуть элемент SQL/JSON, поэтому использование этого выражения пути приведет к ошибке. Чтобы получить тот же результат, что и в режиме lax, вы должны явно развернуть массив segments:

’strict $.track.segments\[\*\].location’

Регулярные выражения

Выражения пути SQL/JSON позволяют сопоставлять текст с регулярным выражением с помощью фильтра like_regex. Например, следующий запрос пути SQL/JSON будет без учета регистра совпадать со всеми строками в массиве, которые начинаются с английской гласной:

'$[*] ? (@ like_regex "^[aeiou]" flag "i")'

Необязательная строка флага может включать один или несколько символов i для соответствия без учета регистра, m для разрешения ^ и $ для соответствия в новых строках, s для разрешения, чтобы соответствовать новой строке и q, чтобы процитировать весь шаблон (сводя поведение к простому совпадению подстроки).

Стандарт SQL/JSON заимствует свое определение для регулярных выражений из оператора LIKE_REGEX, который, в свою очередь, использует стандарт XQuery. QHB в настоящее время не поддерживает оператор LIKE_REGEX. Поэтому фильтр like_regex реализован с использованием механизма регулярных выражений POSIX, описанного в разделе Регулярные выражения POSIX. Это приводит к различным незначительным несоответствиям стандартного поведения SQL/JSON, которые каталогизированы в разделе Отличия от XQuery (LIKE_REGEX). Однако обратите внимание, что описанные здесь несовместимости флаговых букв не применяются к SQL/JSON, поскольку он переводит буквенные символы XQuery в соответствие с тем, что ожидает механизм POSIX.

Имейте в виду, что аргумент шаблона like_regex является строковым литералом пути JSON, написанным в соответствии с правилами, приведенными в разделе Тип jsonpath. В частности, это означает, что любые обратные слеши, которые вы хотите использовать в регулярном выражении, должны быть удвоены. Например, чтобы сопоставить строки, содержащие только цифры:

'$ ? (@ like_regex "^\\d+$")'

Операторы пути и методы SQL/JSON

В таблице 48 показаны операторы и методы, доступные в jsonpath. Таблица 49 показывает доступные элементы выражения фильтра.

Таблица 48. Операторы и методы jsonpath

Оператор / МетодОписаниеПример JSONПример запросаРезультат
+ (одинарный)Плюс оператор, который выполняет итерацию по последовательности SQL/JSON{"x": [2.85, -14.7, -9.4]}+ $.x.floor()2, -15, -10
- (одинарный)Оператор минус, который перебирает последовательность SQL/JSON{"x": [2.85, -14.7, -9.4]}- $.x.floor()-2, 15, 10
+ (двоичный)прибавление[2]2 + $[0]4
- (двоичный)Вычитание[2]4 - $[0]2
*умножение[4]2 * $[0]8
/разделение[8]$[0] / 24
%модуль[32]$[0] % 102
type()Тип элемента SQL/JSON[1, "2", {}]$[*].type()"number", "string", "object"
size()Размер элемента SQL/JSON{"m": [11, 15]}$.m.size()2
double()Приблизительное число с плавающей точкой, преобразованное из числа SQL/JSON или строки{"len": "1.9"}$.len.double() * 23.8
ceiling()Ближайшее целое число больше или равно номеру SQL/JSON{"h": 1.3}$.h.ceiling()2
floor()Ближайшее целое число меньше или равно номеру SQL/JSON{"h": 1.3}$.h.floor()1
abs()Абсолютное значение числа SQL/JSON{"z": -0.3}$.z.abs()0.3
keyvalue()Последовательность пар ключ-значение объекта, представленная в виде массива элементов, содержащего три поля ("key", "value" и "id"). "id" - это уникальный идентификатор пары «ключ-значение», которой принадлежит объект.{"x": "20", "y": 32}$.keyvalue(){"key": "x", "value": "20", "id": 0}, {"key": "y", "value": 32, "id": 0}

Таблица 49. Элементы выражения фильтра jsonpath

Значение / PredicateОписаниеПример JSONПример запросаРезультат
==Оператор равенства[1, 2, 1, 3]$[*] ? (@ == 1)1, 1
!=Оператор неравенства[1, 2, 1, 3]$[*] ? (@ != 1)2, 3
<>Оператор неравенства (такой же как !=)[1, 2, 1, 3]$[*] ? (@ <> 1)2, 3
<Менее чем оператор[1, 2, 3]$[*] ? (@ < 2)1
<=Оператор "меньше или равно"[1, 2, 3]$[*] ? (@ <= 2)1, 2
>Больше чем оператор[1, 2, 3]$[*] ? (@ > 2)3
>=Оператор «больше чем или равно»[1, 2, 3]$[*] ? (@ >= 2)2, 3
trueЗначение, используемое для сравнения с true литералом JSON[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]$[*] ? (@.parent == true){"name": "Chris", "parent": true}
falseЗначение, используемое для сравнения с false литералом JSON[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]$[*] ? (@.parent == false){"name": "John", "parent": false}
nullЗначение, используемое для сравнения с null значением JSON[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]$[*] ? (@.job == null) .name"Mary"
&&Логическое И[1, 3, 7]$[*] ? (@ > 1 && @ < 5)3
Логическое ИЛИ[1, 3, 7]$[*] ? (@ < 1 @ > 5)7
!Логическое НЕ[1, 3, 7]$[*] ? (!(@ < 5))7
like_regexПроверяет, соответствует ли первый операнд регулярному выражению, данному вторым операндом, при необходимости с изменениями, описанными строкой flag символов (см. п. 4.1.15.2.2)["abc", "abd", "aBdC", "abdacb", "babc"]$[*] ? (@ like_regex "^ab.*c" flag "i")"abc", "aBdC", "abdacb"
starts withПроверяет, является ли второй операнд начальной подстрокой первого операнда["John Smith", "Mary Stone", "Bob Johnson"]$[*] ? (@ starts with "John")"John Smith"
existsПроверяет, соответствует ли выражение пути хотя бы одному элементу SQL/JSON{"x": [1, 2], "y": [2, 4]}strict $.* ? (exists (@ ? (@[*] > 2)))2, 4
is unknownПроверяет, неизвестно ли логическое условие[-1, 2, 7, "infinity"]$[*] ? ((@ > 0) is unknown)"infinity"

Функции управления последовательностями

В этом разделе описываются функции для работы с объектами последовательности, также называемыми генераторами последовательностей или просто последовательностями. Объекты последовательности — это специальные однорядные таблицы, созданные с помощью CREATE SEQUENCE. Объекты последовательности обычно используются для генерации уникальных идентификаторов для строк таблицы. Функции последовательности, перечисленные в таблице 50, предоставляют простые, многопользовательские безопасные методы для получения последовательных значений последовательности из объектов последовательности.

Таблица 50. Функции последовательности

ФункцияТип ответаОписание
currval(regclass)bigintВозвращаемое значение, полученное последним с помощью nextval для указанной последовательности
lastval()bigintВозвращаемое значение, полученное последним с помощью nextval для любой последовательности
nextval(regclass)bigintПрогрессировать последовательность и вернуть новое значение
setval(regclass, bigint)bigintУстановить текущее значение последовательности
setval(regclass, bigint, boolean)bigintУстановить текущее значение последовательности и флаг is_called

Последовательность, которой должна управлять функция последовательности, задается аргументом regclass, который является просто OID последовательности в системном каталоге pg_class. Однако вам не нужно искать OID вручную, так как преобразователь ввода типа данных regclass сделает всю работу за вас. Просто напишите имя последовательности, заключенное в одинарные кавычки, чтобы оно выглядело как буквальная константа. Для совместимости с обработкой обычных имен SQL строка будет преобразована в нижний регистр, если она не содержит двойных кавычек вокруг имени последовательности. Таким образом:

nextval(’foo’) operates on sequence foo
nextval(’FOO’) operates on sequence foo
nextval(’"Foo"’) operates on sequence Foo

При необходимости имя последовательности может быть дополнено схемой:

nextval(’myschema.foo’) operates on myschema.foo
nextval(’"myschema".foo’) same as above
nextval(’foo’) searches search path for foo

См. раздел Типы идентификаторов объектов для получения дополнительной информации о regclass.

Конечно, аргумент функции последовательности может быть как выражением, так и константой. Если это текстовое выражение, то неявное приведение приведет к поиску во время выполнения.

Доступны следующие функции последовательности:

nextval

Переместите объект последовательности к следующему значению и верните это значение. Это делается атомарно: даже если несколько сессий выполняются nextval одновременно, каждый из них безопасно получит отдельное значение последовательности. Если объект последовательности был создан с параметрами по умолчанию, последовательные вызовы nextval будут возвращать последовательные значения, начинающиеся с 1. Другие варианты поведения могут быть получены с помощью специальных параметров в команде CREATE SEQUENCE; см. справочную страницу команд для получения дополнительной информации.

Важно!!!
Чтобы избежать блокировки параллельных транзакций, которые получают числа из той же последовательности, операция nextval никогда не откатывается; то есть, как только значение было получено, оно считается использованным и больше не будет возвращено. Это верно, даже если окружающая транзакция позднее прерывается, или если вызывающий запрос заканчивается тем, что не использует значение. Например, INSERT с предложением ON CONFLICT будет вычислять вставляемый кортеж, включая выполнение любых необходимых вызовов nextval, прежде чем обнаруживать любой конфликт, который заставит его следовать правилу ON CONFLICT. Такие случаи оставят неиспользованные «дыры» в последовательности назначенных значений. Таким образом, объекты последовательностей QHB не могут использоваться для получения последовательностей «без промежутков». Эта функция требует привилегии USAGE или UPDATE для последовательности.

currval

Вернуть значение, полученное последним значением nextval для этой последовательности в текущем сеансе. (Сообщается об ошибке, если nextval никогда не вызывался для этой последовательности в этом сеансе). Поскольку он возвращает локальное значение сеанса, он дает предсказуемый ответ, выполняли ли другие сеансы nextval после текущего сеанса. Эта функция требует привилегии USAGE или SELECT для последовательности.

lastval

Вернуть значение, которое было возвращено последним значением nextval в текущем сеансе. Эта функция идентична currval, за исключением того, что вместо того, чтобы принимать имя последовательности в качестве аргумента, она ссылается на любую nextval последовательность, к которой nextval был применен в текущем сеансе. lastval будет lastval если nextval еще не был вызван в текущем сеансе. Эта функция требует привилегии USAGE или SELECT для последней использованной последовательности.

setval

Сброс значения счетчика объекта последовательности. last_value форма устанавливает в поле last_value последовательности указанное значение и устанавливает для его поля is_called значение true, что означает, что следующий nextval будет продвигать последовательность перед возвратом значения. Значение, сообщаемое currval, также устанавливается на указанное значение. В форме с тремя параметрами is_called может быть установлен в true или false. true имеет тот же эффект, что и форма с двумя параметрами. Если для этого параметра установлено значение false, следующее следующее значение вернет точно указанное значение, и продвижение последовательности начинается со следующего следующего nextval. Кроме того, значение, сообщаемое currval, в этом случае не изменяется. Например,

SELECT setval(’foo’, 42); Next nextval will return 43
SELECT setval(’foo’, 42, true); Same as above
SELECT setval(’foo’, 42, false); Next nextval will return 42

Результат, возвращаемый setval является просто значением его второго аргумента.

Важно!!!
Поскольку последовательности не являются транзакционными, изменения, сделанные setval, не отменяются, если транзакция откатывается. Эта функция требует привилегии UPDATE для последовательности.

Условные выражения

В этом разделе описываются SQL- совместимые условные выражения, доступные в QHB

Хотя COALESCE, GREATEST и LEAST синтаксически похожи на функции, они не являются обычными функциями и поэтому не могут использоваться с явными VARIADIC массива VARIADIC.

CASE

Выражение SQL CASE является общим условным выражением, аналогичным операторам if/else в других языках программирования:

CASE WHEN condition THEN result
   [WHEN ...]
   [ELSE result]
END

CASE могут использоваться везде, где выражение допустимо. Каждое условие «condition» является выражением, которое возвращает логический результат. Если результат условия равен true, значением выражения CASE является result, следующий за условием, а остальная часть выражения CASE не обрабатывается. Если результат условия неверен, любые последующие предложения WHEN проверяются таким же образом. Если условия WHEN не возвращает true, значением выражения CASE является результатом предложения ELSE. Если предложение ELSE опущено и ни одно из условий не является истинным, результат будет нулевым.

Пример:

SELECT * FROM test;

 a
---
 1
 2
 3


SELECT a,
       CASE WHEN a=1 THEN 'one'
            WHEN a=2 THEN 'two'
            ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

Типы данных всех выражений result должны быть преобразованы в один тип вывода.

Существует «простая» форма выражения CASE которая является вариантом общей формы выше:

CASE expression
    WHEN value THEN result
  [WHEN ...]
  [ELSE result]
END

Первое expression вычисляется, затем сравнивается с каждым из выражений value в предложениях WHEN пока не будет найдено одно значение, равное ему. Если совпадений не найдено, возвращается result предложения ELSE (или нулевое значение). Это похоже на оператор switch в C.

Приведенный выше пример может быть написан с использованием простого синтаксиса CASE:

SELECT a,
       CASE a WHEN 1 THEN 'one'
              WHEN 2 THEN 'two'
              ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

Выражение CASE не оценивает какие-либо подвыражения, которые не нужны для определения результата. Например, это возможный способ избежать сбоя деления на ноль:

SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;`

Как описано в разделе Правила вычисления выражений, существуют различные ситуации, в которых подвыражения выражения оцениваются в разное время, поэтому принцип «CASE оценивает только необходимые подвыражения» не является гарантированным. Например, постоянное подвыражение 1/0 обычно приводит к сбою деления на ноль во время планирования, даже если он находится внутри плеча CASE, которое никогда не будет задействовано во время выполнения.

COALESCE

COALESCE(value [, ...])

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

SELECT COALESCE(description, short_description, '(none)') ...

Это возвращает description если оно не равно нулю, иначе short_description если оно не равно нулю, иначе (none).

Как и выражение CASE, COALESCE оценивает только те аргументы, которые необходимы для определения результата; то есть аргументы справа от первого ненулевого аргумента не оцениваются. Эта стандартная функция SQL предоставляет возможности, аналогичные NVL и IFNULL, которые используются в некоторых других системах баз данных.

NULLIF

NULLIF(value1, value2)

Функция NULLIF возвращает нулевое значение, если value1 равно value2; в противном случае он возвращает value1. Это может быть использовано для выполнения обратной операции примера COALESCE приведенного выше:

SELECT NULLIF(value, ’(none)’) ...

В этом примере, если value равно (none), возвращается значение null, в противном случае возвращается значение value.

GREATEST и LEAST

GREATEST(value [, ...])

LEAST(value [, ...])

Функции GREATEST и LEAST выбирают наибольшее или наименьшее значение из списка любого числа выражений. Все выражения должны быть преобразованы в общий тип данных, который будет типом результата . Значения NULL в списке игнорируются. Результатом будет NULL, только если все выражения оцениваются как NULL.

Обратите внимание, что GREATEST и LEAST не входят в стандарт SQL, но являются распространенным расширением. Некоторые другие базы данных заставляют их возвращать NULL, если любой аргумент равен NULL, а не только тогда, когда все имеют значение NULL.

Функции и операторы массива

В таблице 51 показаны операторы, доступные для типов массивов.

Таблица 51. Операторы массива

ОператорОписаниеПримерРезультат
=равныйARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]t
<>не равныйARRAY[1,2,3] <> ARRAY[1,2,4]t
<меньше, чемARRAY[1,2,3] < ARRAY[1,2,4]t
>больше чемARRAY[1,4,3] > ARRAY[1,2,4]t
<=меньше или равноARRAY[1,2,3] <= ARRAY[1,2,3]t
>=больше или равноARRAY[1,4,3] >= ARRAY[1,4,3]t
@>содержитARRAY[1,4,3] @> ARRAY[3,1,3]t
<@содержится вARRAY[2,2,7] <@ ARRAY[1,7,4,2,6]t
&&перекрытия (имеют общие элементы)ARRAY[1,4,3] && ARRAY[2,1]t
||конкатенация между массивамиARRAY[1,2,3] || ARRAY[4,5,6]{1,2,3,4,5,6}
||конкатенация между массивамиARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]{{1,2,3},{4,5,6},{7,8,9}}
||объединение элементов в массив3 || ARRAY[4,5,6]{3,4,5,6}
||конкатенация массивов к элементамARRAY[4,5,6] || 7{4,5,6,7}

Операторы упорядочения массива (<, >= и т.д.) сравнивают содержимое массива поэлементно, используя функцию сравнения B-дерева по умолчанию для типа данных элемента, и сортируют на основе первого различия. В многомерных массивах элементы посещаются в главном порядке строк (последний индекс изменяется наиболее быстро). Если содержимое двух массивов одинаково, но размерность отличается, первое различие в информации о размерности определяет порядок сортировки.

Операторы содержания массива (<@ и @>) считают, что один массив должен содержаться в другом, если каждый из его элементов появляется в другом. Дубликаты специально не обрабатываются, поэтому считается, что ARRAY[1] и ARRAY[1,1] содержат друг друга.

См. раздел Массивы для более подробной информации о поведении оператора массива. См. раздел Типы индексов для более подробной информации о том, какие операторы поддерживают индексированные операции.

В таблице 52 показаны функции, доступные для использования с типами массивов. См. раздел Массивы для получения дополнительной информации и примеров использования этих функций.

Таблица 52. Функции массива

Функция Тип ответа Описание Пример Результат
array_append(anyarray, anyelement) anyarray добавить элемент в конец массива array_append (ARRAY [1,2], 3) {1,2,3}
array_cat(anyarray, anyarray) anyarray объединить два массива array_cat (ARRAY [1,2,3], ARRAY[4,5]) {1,2,3,4,5}
array_ndims(anyarray) int возвращает количество измерений массива array_ndims (ARRAY [[1,2,3], [4,5,6]]) 2
array_dims(anyarray) text возвращает текстовое представление размеров массива array_dims (ARRAY [[1,2,3], [4,5,6]]) [1:2][1:3]
array_fill(anyelement, int[] [, int[]]) anyarray возвращает массив, инициализированный с предоставленными значением и размерами, необязательно с нижними границами, отличными от 1 array_fill (7, ARRAY[3], ARRAY[2]) [2:4]={7,7,7}
array_length(anyarray, int) int возвращает длину запрошенного размера массива array_length (array[1,2,3], 1) 3
array_lower(anyarray, int) int возвращает нижнюю границу запрошенного размера массива array_lower (’[0:2]= {1,2,3}’::int[], 1) 0
array_position(anyarray, anyelement [, int]) int возвращает индекс первого вхождения второго аргумента в массиве, начиная с элемента, указанного третьим аргументом, или с первого элемента (массив должен быть одномерным) array_position (ARRAY [’sun’,’mon’,’tue’,’wed’,’thu’,’fri’, ’sat’], ’mon’) 2
array_positions(anyarray, anyelement) int[] возвращает массив индексов всех вхождений второго аргумента в массиве, заданного в качестве первого аргумента (массив должен быть одномерным) array_positions (ARRAY [’A’,’A’,’B’,’A’], ’A’) {1,2,4}
array_prepend(anyelement, anyarray) anyarray добавить элемент в начало массива array_prepend (1, ARRAY[2,3]) {1,2,3}
array_remove(anyarray, anyelement) anyarray удалить все элементы, равные заданному значению, из массива (массив должен быть одномерным) array_remove (ARRAY[1,2,3,2], 2) {1,3}
array_replace(anyarray, anyelement, anyelement) anyarray заменить каждый элемент массива, равный заданному значению, новым значением array_replace (ARRAY[1,2,5,4], 5, 3) {1,2,3,4}
array_to_string(anyarray, text [, text]) text объединяет элементы массива, используя предоставленный разделитель и необязательную пустую строку array_to_string (ARRAY[1, 2, 3, NULL, 5], ’,’, ’*’) 1,2,3,*,5
array_upper(anyarray, int) int возвращает верхнюю границу запрошенного размера массива array_upper (ARRAY[1,8,3,7], 1) 4
cardinality(anyarray) int возвращает общее количество элементов в массиве или 0, если массив пуст Cardinality (ARRAY[[1,2],[3,4]]) 4
string_to_array(text, text [, text]) text[] разбивает строку на элементы массива, используя предоставленный разделитель и необязательную пустую строку string_to_array (’xx~^~yy~^~zz’, ’~^~’, ’yy’) {xx,NULL,zz}

unnest(anyarray)

setof anyelement

расширить массив до набора строк

unnest(ARRAY[1,2])

1

2

(2 rows)

unnest(anyarray, anyarray [, ...])

setof anyelement, anyelement [, ...]

разверните несколько массивов (возможно, разных типов) до набора строк. Это разрешено только в предложении FROM; см. раздел 6.2.1.4

Unnest (ARRAY[1,2], ARRAY[’foo’,’bar’,’baz’])

1 foo

2 bar

NULL baz

(3 rows)

В array_position и array_positions каждый элемент массива сравнивается с искомым значением с использованием семантики IS NOT DISTINCT FROM.

В array_position возвращается NULL если значение не найдено.

В array_positions NULL возвращается, только если массив NULL; если значение не найдено в массиве, вместо него возвращается пустой массив.

В string_to_array, если параметр разделителя равен NULL, каждый символ во входной строке станет отдельным элементом в результирующем массиве. Если разделитель является пустой строкой, тогда вся входная строка возвращается как массив из одного элемента. В противном случае входная строка разделяется при каждом появлении строки-разделителя.

В string_to_array, если параметр null-string пропущен или равен NULL, ни одна из подстрок ввода не будет заменена на NULL. В array_to_string, если параметр null-string опущен или равен NULL, любые нулевые элементы в массиве просто пропускаются и не представляются в выходной строке.

См. также раздел Агрегатные функции для использования с массивами агрегатной функции array_agg.

Функции диапазона и операторы

См. раздел Типы диапазонов для обзора типов диапазонов.

В таблице 53 показаны операторы, доступные для типов диапазона.

Таблица 53. Операторы диапазона

ОператорОписаниеПримерРезультат
=равныйint4range(1,5) = ’[1,4]’::int4ranget
<>не равныйnumrange(1.1,2.2) <> numrange(1.1,2.3)t
<меньше, чемint4range(1,10) < int4range(2,3)t
>больше чемint4range(1,10) > int4range(1,5)t
<=меньше или равноnumrange(1.1,2.2) <= numrange(1.1,2.2)t
>=больше или равноnumrange(1.1,2.2) >= numrange(1.1,2.0)t
@>содержит диапазонint4range(2,4) @> int4range(2,3)t
@>содержит элемент’[2011-01-01,2011-03-01)’::tsrange @> ’2011-01-10’::timestampt
<@диапазон содержитint4range(2,4) <@ int4range(1,7)t
<@элемент содержится42 <@ int4range(1,7)f
&&перекрытия (есть общие точки)int8range(3,7) && int8range(4,12)t
<<строго слева отint8range(1,10) << int8range(100,110)t
>>строго правоint8range(50,60) >> int8range(20,30)t
&<не распространяется на правоint8range(1,20) &< int8range(18,20)t
&>не распространяется слева отint8range(7,20) &> int8range(5,10)t
--соседствует сnumrange(1.1,2.2) -- numrange(2.2,3.3)t
+союзnumrange(5,15) + numrange(10,20)[5,20)
*пересечениеint8range(5,15) * int8range(10,20)[10,15)
-разницаint8range(5,15) - int8range(10,20)[5,10)

Простые операторы сравнения <, >, <= и >= сначала сравнивают нижние границы, и только если они равны, сравнивают верхние границы. Эти сравнения обычно не очень полезны для диапазонов, но предоставлены, чтобы позволить строить B-деревья на диапазонах.

Операторы left-of/right-of/adjacent всегда возвращают false, когда задействован пустой диапазон; то есть пустой диапазон не считается ни до, ни после любого другого диапазона.

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

В таблице 54 показаны функции, доступные для использования с типами диапазонов.

Таблица 54. Функции диапазона

ФункцияТип ответаОписаниеПримерРезультат
lower (anyrange)тип элемента диапазонанижняя граница диапазонаlower(numrange(1.1,2.2))1.1
upper (anyrange)тип элемента диапазонаверхняя граница диапазонаupper(numrange(1.1,2.2))2.2
isempty (anyrange)booleanдиапазон пуст?isempty(numrange(1.1,2.2))false
lower_inc (anyrange)booleanнижняя граница включительно?lower_inc(numrange(1.1,2.2))true
upper_inc (anyrange)booleanверхняя граница включительно?upper_inc(numrange(1.1,2.2))false
lower_inf (anyrange)booleanнижняя граница бесконечна?lower_inf(’(,)’::daterange)true
upper_inf (anyrange)booleanверхняя граница бесконечна?upper_inf(’(,)’::daterange)true
range_merge (anyrange, anyrange)anyrangeнаименьший диапазон, который включает оба из указанных диапазоновrange_merge(’[1,2)’::int4range, ’[3,4)’::int4range)[1,4)

lower и upper функции возвращают ноль, если диапазон пуст или запрошенная граница бесконечна. Функции lower_inc, upper_inc, lower_inf и upper_inf возвращают false для пустого диапазона.

Агрегатные функции

Агрегатные функции вычисляют один результат из набора входных значений. Встроенные агрегатные функции общего назначения перечислены в таблице 8.55, а статистические агрегаты - в таблице 56. Встроенные внутригрупповые агрегатные функции упорядоченного набора перечислены в таблице 57, а встроенные внутригрупповые гипотетически заданные функции - в таблице 58. Операции группировки, которые тесно связаны с агрегатными функциями, перечислены в таблице 59. Особые синтаксические соображения для агрегатных функций описаны в «Руководстве пользователя» в разделе Агрегатные выражения. Обратитесь к разделу руководства "Агрегатные функции" за дополнительной вводной информацией.

Таблица 55. Агрегатные функции общего назначения

ФункцияТип аргумента (ов)Тип ответаЧастичный режимОписание
array_agg(expression)любой не массивмассив типа аргументанетвходные значения, включая нули, объединяются в массив
array_agg(expression)любой тип массиватакой же как тип данных аргументанетвходные массивы объединяются в массив одного более высокого измерения (все входные данные должны иметь одинаковую размерность и не могут быть пустыми или нулевыми)
avg(expression)smallint, int, bigint, real, double precision, numeric или intervalnumeric для любого аргумента целочисленного типа, double precision для аргумента с плавающей запятой, в остальном такой же, как тип данных аргументадасреднее (среднее арифметическое) всех ненулевых входных значений
bit_and(expression)smallint, int, bigint или bitтакой же как тип данных аргументадапобитовое И всех ненулевых входных значений или ноль, если нет
bit_or(expression)smallint, int, bigint или bitтакой же как тип данных аргументадапобитовое ИЛИ всех ненулевых входных значений или ноль, если нет
bool_and(expression)boolboolдаистина, если все входные значения верны, иначе ложь
bool_or(expression)boolboolдаистина, если хотя бы одно входное значение истинно, иначе ложь
count(*)bigintдаколичество входных строк
count(expression)Любыеbigintдаколичество входных строк, для которых значение expression не равно нулю
every(expression)boolboolдаэквивалентно bool_and
json_agg(expression)anyjsonнетагрегирует значения, включая нули, в виде массива JSON
jsonb_agg(expression)anyjsonbнетагрегирует значения, включая нули, в виде массива JSON
json_object_agg(name, value)(any, any)jsonнетобъединяет пары имя / значение в виде объекта JSON; значения могут быть нулевыми, но не именами
jsonb_object_agg(name, value)(any, any)jsonbнетобъединяет пары имя / значение в виде объекта JSON; значения могут быть нулевыми, но не именами
max(expression)любой числовой, строковый, дата / время, тип сети или перечисления или массивы этих типовтакой же как тип аргументадамаксимальное значение expression для всех ненулевых входных значений
min(expression)любой числовой, строковый, дата / время, тип сети или перечисления или массивы этих типовтакой же как тип аргументадаминимальное значение expression для всех ненулевых входных значений
string_agg(expression, delimiter)(text, text) или (bytea, bytea)такой же как типы аргументовнетненулевые входные значения объединяются в строку, разделенные разделителем
sum(expression)smallint, int, bigint, real, double precision, numeric, interval или moneybigint для аргументов smallint или int, numeric для аргументов bigint, в остальном совпадает с типом данных аргументадасумма expression по всем ненулевым входным значениям
xmlagg(expression)xmlxmlнетконкатенация ненулевых значений XML (см. также раздел xmlagg )

Следует отметить, что кроме count эти функции возвращают нулевое значение, когда строки не выбраны. В частности, sum без строк возвращает null, а не ноль, как можно было ожидать, и array_agg возвращает null, а не пустой массив, когда нет входных строк. Функция coalesce может использоваться для замены нуля или пустого массива на ноль при необходимости.

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

Агрегатные функции array_agg, json_agg, jsonb_agg, json_object_agg, jsonb_object_agg, string_agg и xmlagg, а также аналогичные пользовательские агрегатные функции выдают значимо разные значения результата в зависимости от порядка входных значений. Этот порядок не указан по умолчанию, но им можно управлять, написав предложение ORDER BY в совокупном вызове, как показано в «Руководстве пользователя» в разделе Агрегатные выражения. Альтернативно, подача входных значений из отсортированного подзапроса обычно работает. Например:

SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;

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

В таблице 56 показаны агрегатные функции, обычно используемые в статистическом анализе. (Они отделены просто для того, чтобы избежать загромождения списка наиболее часто используемых агрегатов). Если в описании упоминается N, это означает количество входных строк, для которых все входные выражения не равны NULL. Во всех случаях ноль возвращается, если вычисление не имеет смысла, например, когда N равно нулю.

Таблица 56. Агрегатные функции для статистики

ФункцияТип аргументаТип ответаЧастичный режимОписание
corr(Y, X)double precisiondouble precisionдакоэффициент корреляции
covar_pop(Y, X)double precisiondouble precisionдаковариация населения
covar_samp(Y, X)double precisiondouble precisionдаковариация образца
regr_avgx(Y, X)double precisiondouble precisionдасреднее значение независимой переменной (sum(X)/ N)
regr_avgy(Y, X)double precisiondouble precisionдасреднее значение зависимой переменной (sum(Y)/ N)
regr_count(Y, X)double precisionbigintдаколичество строк ввода, в которых оба выражения не равны нулю
regr_intercept(Y, X)double precisiondouble precisionдаy-пересечение линейного уравнения с наименьшими квадратами, определяемого парами (X, Y)
regr_r2(Y, X)double precisiondouble precisionдаквадрат коэффициента корреляции
regr_slope(Y, X)double precisiondouble precisionданаклон линейного уравнения с наименьшими квадратами, определяемый парами (X, Y)
regr_sxx(Y, X)double precisiondouble precisionдаsum(X ^2) - sum(X)^2/ N (« сумма квадратов » независимой переменной)
regr_sxy(Y, X)double precisiondouble precisionдаsum(X * Y) - sum(X) * sum(Y)/ N (« сумма произведений » независимой переменной, зависящей от времени)
regr_syy(Y, X)double precisiondouble precisionдаsum(Y ^2) - sum(Y)^2/ N (« сумма квадратов » зависимой переменной)
stddev(expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдаисторический псевдоним для stddev_samp
stddev_pop(expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдапопуляционное стандартное отклонение входных значений
stddev_samp(expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдавыборочное стандартное отклонение входных значений
variance (expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдаисторический псевдоним для var_samp
var_pop (expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдаПопуляционная дисперсия входных значений (квадрат стандартного отклонения населения)
var_samp (expression)smallint, int, bigint, real, double precision или numericdouble precision для аргументов с плавающей точкой, иначе numericдавыборочная дисперсия входных значений (квадрат стандартного отклонения выборки)

В таблице 57 показаны некоторые агрегатные функции, которые используют синтаксис упорядоченного набора. Эти функции иногда называют функциями «обратного распределения».

Таблица 57. Упорядоченные-совокупные функции

ФункцияТип (ы) прямого аргументаТип агрегированных аргументовТип ответаЧастичный режимОписание
mode() WITHIN GROUP (ORDER BY sort_expression)любой сортируемый типтакое же как выражение сортировкинетвозвращает наиболее частое входное значение (произвольно выбирая первое, если есть несколько одинаково частых результатов)
percentile_cont(fraction) WITHIN GROUP (ORDER BY sort_expression)double precisiondouble precision или intervalтакое же как выражение сортировкинетнепрерывный процентиль: возвращает значение, соответствующее указанной дроби в порядке, при необходимости интерполируя между смежными входными элементами
percentile_cont(fractions) WITHIN GROUP (ORDER BY sort_expression)double precision\[\]double precision или intervalмассив типа выражения сортировкинетмножественный непрерывный процентиль: возвращает массив результатов, соответствующих форме параметра fractions, причем каждый ненулевой элемент заменяется значением, соответствующим этому процентилю
percentile_disc(fraction) WITHIN GROUP (ORDER BY sort_expression)double precisionлюбой сортируемый типтакое же как выражение сортировкинетдискретный процентиль: возвращает первое входное значение, позиция которого в заказе равна или превышает указанную дробь
percentile_disc(fractions) WITHIN GROUP (ORDER BY sort_expression)double precision\[\]любой сортируемый типмассив типа выражения сортировкинетмножественный дискретный процентиль: возвращает массив результатов, соответствующих форме параметра fractions, при этом каждый ненулевой элемент заменяется входным значением, соответствующим этому процентилю

Все агрегаты, перечисленные в таблице 57, игнорируют нулевые значения в своих отсортированных входных данных. Для тех, которые принимают параметр дроби, значение дроби должно быть между 0 и 1; если нет, то возникает ошибка. Однако нулевое значение дроби дает просто нулевой результат.

Каждый из агрегатов, перечисленных в таблице 58, связан с оконной функцией с тем же именем, определенной в разделе Оконные функции. В каждом случае совокупный результат — это значение, которое соответствующая оконная функция возвратила бы для «гипотетической» строки, построенной из args, если бы такая строка была добавлена в отсортированную группу строк, вычисленную из sorted_args.

Таблица 58. Агрегатные функции гипотетического множества

ФункцияТип (ы) прямого аргументаТип агрегированных аргументовТип ответаЧастичный режимОписание
rank(args) WITHIN GROUP (ORDER BY sorted_args)VARIADIC "any"VARIADIC "any"bigintнетранг гипотетического ряда с пробелами для повторяющихся рядов
dense_rank(args) WITHIN GROUP (ORDER BY sorted_args)VARIADIC "any"VARIADIC "any"bigintнетранг гипотетического ряда, без пробелов
percent_rank(args) WITHIN GROUP (ORDER BY sorted_args)VARIADIC "any"VARIADIC "any"double precisionнетотносительный ранг гипотетического ряда, от 0 до 1
cume_dist(args) WITHIN GROUP (ORDER BY sorted_args)VARIADIC "any"VARIADIC "any"double precisionнетотносительный ранг гипотетического ряда, варьирующийся от 1 / N до 1

Для каждого из этих агрегатов гипотетического набора список прямых аргументов, указанных в args должен соответствовать количеству и типам агрегированных аргументов, указанных в sorted_args. В отличие от большинства встроенных агрегатов, эти агрегаты не являются строгими, то есть они не отбрасывают входные строки, содержащие nulls. Пустые значения сортируются в соответствии с правилом, указанным в предложении ORDER BY.

Таблица 59. Группировка операций

ФункцияТип ответаОписание
GROUPING(args...)integerЦелочисленная битовая маска, указывающая, какие аргументы не включены в текущий набор группировки

Операции группировки используются вместе с наборами группировки (см. раздел GROUPING SETS, CUBE и ROLLUP) для различения строк результатов. Аргументы операции группировки фактически не вычисляются, но они должны точно соответствовать выражениям, приведенным в предложении GROUP BY соответствующего уровня запроса. Биты назначаются с самым правым аргументом, являющимся младшим значащим битом; каждый бит равен 0, если соответствующее выражение включено в критерии группировки набора групп, генерирующего строку результата, и 1, если это не так. Например:

=> SELECT * FROM items_sold;
 make  | model | sales
-------+-------+-------
 Foo   | GT    |  10
 Foo   | Tour  |  20
 Bar   | City  |  15
 Bar   | Sport |  5
(4 rows)

=> SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model);
 make  | model | grouping | sum
-------+-------+----------+-----
 Foo   | GT    |        0 | 10
 Foo   | Tour  |        0 | 20
 Bar   | City  |        0 | 15
 Bar   | Sport |        0 | 5
 Foo   |       |        1 | 30
 Bar   |       |        1 | 20
       |       |        3 | 50
(7 rows)

Оконные функции

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

Встроенные функции окна перечислены в таблице 60. Обратите внимание, что эти функции должны вызываться с использованием синтаксиса оконной функции, то есть требуется предложение OVER.

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

Таблица 60. Универсальные оконные функции

ФункцияТип ответаОписание
row_number()bigintномер текущей строки в его партиции, считая от 1
rank()bigintранг текущей строки с пробелами; такой же, как row_number его первого партнера
dense_rank()bigintранг текущей строки без пробелов; эта функция считает группы пиров
percent_rank()double precisionотносительный ранг текущей строки: (rank - 1)/(всего строк в партиции - 1)
cume_dist()double precisionкумулятивное распределение: (количество предшествующих или равных строк разделов)/общее количество строк разделов
ntile(num_buckets integer)integerцелое число в диапазоне от 1 до значения аргумента, делающее раздел как можно более равномерно
lag(value anyelement [, offset integer [, default anyelement ]])same type as valueвозвращает value оцененное в строке, которая offset строки перед текущей строкой в партиции; если такой строки нет, вместо этого возвращаем default (который должен быть того же типа, что и value). И offset и default оцениваются относительно текущей строки. Если опущено, offset умолчанию равно 1 и по default равно нулю
lead(value anyelement [, offset integer [, default anyelement ]])same type as valueвозвращает value оцененное в строке, которая является offset строкой после текущей строки в разделе; если такой строки нет, вместо этого возвращаем default (который должен быть того же типа, что и value). И offset и default оцениваются относительно текущей строки. Если опущено, offset умолчанию равно 1 и по default равно нулю
first_value(value any)same type as valueвозвращает value оцененное в строке, являющейся первой строкой оконного фрейма
last_value(value any)same type as valueвозвращает value оцененное в строке, которая является последней строкой оконного фрейма
nth_value(value any, nth integer)same type as valueвозвращает value оцененное в строке, которая является nth строкой оконного фрейма (считая от 1); ноль, если такой строки нет

Все функции, перечисленные в таблице 60, зависят от порядка сортировки, указанного в предложении ORDER BY соответствующего определения окна. Строки, которые не различаются при рассмотрении только столбцов ORDER BY называются равноправными. Четыре функции ранжирования (включая cume_dist) определены так, чтобы они давали одинаковый ответ для всех одноранговых строк.

Обратите внимание, что first_value, last_value и nth_value учитывают только строки в «кадре окна», который по умолчанию содержит строки от начала раздела до последнего узла текущей строки. Это может дать бесполезные результаты для last_value а иногда и nth_value. Вы можете переопределить кадр, добавив подходящую спецификацию кадра (RANGE, ROWS или GROUPS) в предложение OVER. См. раздел Вызовы оконных функций для получения дополнительной информации о спецификациях кадров.

Когда агрегатная функция используется в качестве оконной функции, она агрегирует по строкам в рамке окна текущей строки. Агрегат, используемый с ORDER BY и определением кадра окна по умолчанию, создает тип поведения «промежуточная сумма», который может соответствовать или не соответствовать желаемому. Чтобы получить агрегацию по всему разделу, опустите ORDER BY или используйте ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING Другие характеристики кадра могут быть использованы для получения других эффектов.

cume_dist вычисляет долю строк раздела, которые меньше или равны текущей строке, тогда как percent_rank вычисляет долю строк раздела, которые меньше текущей строки, предполагая, что текущая строка не существует в разделе.

Выражения подзапроса

В этом разделе описываются SQL- совместимые выражения подзапроса, доступные в QHB. Все формы выражений, описанные в этом разделе, возвращают логические (true/false) результаты.

EXISTS

EXISTS (subquery)

Аргумент EXISTS — это произвольный оператор SELECT или подзапрос. Подзапрос оценивается, чтобы определить, возвращает ли он какие-либо строки. Если он возвращает хотя бы одну строку, результат EXISTS равен true; если подзапрос не возвращает строк, результатом EXISTS будет false.

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

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

Поскольку результат зависит только от того, возвращаются ли какие-либо строки, а не от содержимого этих строк, выходной список подзапроса обычно не важен. Обычное соглашение о кодировании - записывать все тесты EXISTS в форме EXISTS(SELECT 1 WHERE ...). Однако есть исключения из этого правила, такие как подзапросы, которые используют INTERSECT.

Этот простой пример похож на внутреннее соединение по col2, но он генерирует не более одной выходной строки для каждой строки tab1, даже если есть несколько совпадающих строк tab2:

SELECT col1
FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);

IN

expression IN (subquery)

Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно один столбец. Левое выражение оценивается и сравнивается с каждой строкой результата подзапроса. Результатом IN является «истина», если найдена какая-либо одинаковая строка подзапроса. Результатом является «ложь», если не найдено ни одной равной строки (включая случай, когда подзапрос не возвращает строк).

Обратите внимание, что если левое выражение возвращает null или если нет равных правых значений и хотя бы одна правая строка возвращает null, результатом конструкции IN будет null, а не ложь. Это соответствует нормальным правилам SQL для логических комбинаций null значений.

Как и в случае с EXISTS, неразумно предполагать, что подзапрос будет оценен полностью.

row_constructor IN (subquery)

Левая часть этой формы IN является конструктором строки, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в левой строке. Левые выражения оцениваются и сравниваются построчно с каждой строкой результата подзапроса. Результатом IN является «истина», если найдена какая-либо одинаковая строка подзапроса. Результатом является «ложь», если не найдено ни одной равной строки (включая случай, когда подзапрос не возвращает строк).

Как обычно, null значения в строках объединяются в соответствии с обычными правилами логических выражений SQL. Две строки считаются равными, если все их соответствующие члены ненулевые и равные; строки являются неравными, если любые соответствующие члены ненулевые и неравные; в противном случае результат сравнения строк неизвестен (null). Если все результаты для каждой строки являются неравными или null, хотя бы с одним null, то результат IN является null.

NOT IN

expression NOT IN (subquery)

Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно один столбец. Левое выражение оценивается и сравнивается с каждой строкой результата подзапроса. Результатом NOT IN является «истина», если найдены только неравные строки подзапроса (включая случай, когда подзапрос не возвращает строк). Результатом является «ложь», если найдена какая-либо равная строка.

Обратите внимание, что если левое выражение возвращает null или если нет равных правых значений и хотя бы одна правая строка дает null, результатом конструкции NOT IN будет null, а не истина. Это соответствует нормальным правилам SQL для логических комбинаций null значений.

Как и в случае с EXISTS, неразумно предполагать, что подзапрос будет оценен полностью.

row_constructor NOT IN (subquery)

Левая часть этой формы NOT IN является конструктором строки, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в левой строке. Левые выражения оцениваются и сравниваются построчно с каждой строкой результата подзапроса. Результатом NOT IN является «истина», если найдены только неравные строки подзапроса (включая случай, когда подзапрос не возвращает строк). Результатом является «ложь», если найдена какая-либо равная строка.

Как обычно, null значения в строках объединяются в соответствии с обычными правилами логических выражений SQL. Две строки считаются равными, если все их соответствующие члены ненулевые и равные; строки являются неравными, если любые соответствующие члены ненулевые и неравные; в противном случае результат сравнения строк неизвестен (null). Если все результаты для каждой строки являются неравными или null, хотя бы с одним null, то результат NOT IN будет null.

ANY/SOME

expression operator ANY (subquery)

expression operator SOME (subquery)

Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно один столбец. Левое выражение оценивается и сравнивается с каждой строкой результата подзапроса с использованием данного оператора, который должен давать логический результат. Результат ANY является «истинным», если получен какой-либо истинный результат. Результатом является «ложь», если истинный результат не найден (включая случай, когда подзапрос не возвращает строк).

SOME является синонимом для ANY. IN эквивалентно = ANY.

Обратите внимание, что, если нет никаких успехов, и хотя бы одна правая строка возвращает null для результата оператора, результат ANY конструкции будет null, а не ложным. Это соответствует нормальным правилам SQL для логических комбинаций null значений.

Как и в случае с EXISTS, неразумно предполагать, что подзапрос будет оценен полностью.

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

Левая часть этой формы ANY является конструктором строки, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в левой строке. Левые выражения оцениваются и сравниваются построчно с каждой строкой результата подзапроса, используя данный оператор. Результатом ANY является true, если сравнение возвращает true для любой строки подзапроса. Результат - «ложь», если сравнение возвращает ложь для каждой строки подзапроса (включая случай, когда подзапрос не возвращает строк). Результат равен NULL, если сравнение со строкой подзапроса не возвращает true, и хотя бы одно сравнение возвращает NULL.

См. раздел Сравнение конструкторов строк для получения подробной информации о значении сравнения конструктора строки.

ALL

expression operator ALL (subquery)

Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно один столбец. Левое выражение оценивается и сравнивается с каждой строкой результата подзапроса с использованием данного оператора, который должен давать логический результат. Результатом ALL является true, если все строки возвращают true (включая случай, когда подзапрос не возвращает строк). Результат «ложь», если найден какой-либо ложный результат. Результат равен NULL, если сравнение со строкой подзапроса не возвращает false, и хотя бы одно сравнение возвращает NULL.

NOT IN эквивалентно <> ALL.

Как и в случае с EXISTS, неразумно предполагать, что подзапрос будет оценен полностью.

row_constructor operator ALL (subquery)

Левая часть этой формы ALL является конструктором строк, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в левой строке. Левые выражения оцениваются и сравниваются построчно с каждой строкой результата подзапроса, используя данный оператор. Результатом ALL является true, если сравнение возвращает true для всех строк подзапроса (включая случай, когда подзапрос не возвращает строк). Результатом является «ложь», если сравнение возвращает ложь для любой строки подзапроса. Результат равен NULL, если сравнение со строкой подзапроса не возвращает false, и хотя бы одно сравнение возвращает NULL.

См. раздел Сравнение конструкторов строк для получения подробной информации о значении сравнения конструктора строки.

Сравнение по одной строке

row_constructor operator (subquery)

Левая часть — это конструктор строк, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Правая часть — это вложенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в левой строке. Кроме того, подзапрос не может возвращать более одной строки. (Если он возвращает ноль строк, результат принимается равным null). Левая часть вычисляется и сравнивается по строкам с одной строкой результата подзапроса.

См. раздел Сравнение конструкторов строк для получения подробной информации о значении сравнения конструктора строки.

Сравнение строк и массивов

В этом разделе описывается несколько специализированных конструкций для множественных сравнений между группами значений. Эти формы синтаксически связаны с формами подзапросов предыдущего раздела, но не включают подзапросы. Формы, включающие подвыражения массива, являются расширениями QHB; Остальные SQL- совместимы. Все формы выражений, описанные в этом разделе, возвращают логические (true/false) результаты.

IN

expression IN (value [, ...])

Правая часть — это заключенный в скобки список скалярных выражений. Результат true, если результат левого выражения равен любому из правых выражений. Это сокращенное обозначение для

expression = value1
OR
expression = value2
OR
...

Обратите внимание, что если левое выражение возвращает null или если нет равных правых значений и хотя бы одно правое выражение дает null, результатом конструкции IN будет null, а не ложь. Это соответствует нормальным правилам SQL для логических комбинаций null значений.

NOT IN

expression NOT IN (value [, ...])

Правая часть — это заключенный в скобки список скалярных выражений. Результат true, если результат левого выражения не равен всем правым выражениям. Это сокращенное обозначение для

expression <> value1
AND
expression <> value2
AND
...

Обратите внимание, что если левое выражение возвращает null или если нет равных правых значений и хотя бы одно правое выражение возвращает null, результат конструкции NOT IN будет null, а не истинным, как можно было ожидать. Это соответствует нормальным правилам SQL для логических комбинаций null значений.

x NOT IN y во всех случаях эквивалентно NOT (x IN y). Тем не менее, нулевые значения гораздо чаще приводят в замешательство новичка при работе с NOT IN чем при работе с IN. Лучше всего выразить ваше состояние положительно, если это возможно.

ANY/SOME (массив)

expression operator ANY (array expression)
expression operator SOME (array expression)

Правая часть — это выражение в скобках, которое должно давать значение массива. Левое выражение вычисляется и сравнивается с каждым элементом массива с использованием данного оператора, который должен давать логический результат. Результат ANY является «истинным», если получен какой-либо истинный результат. Результатом является «ложь», если истинный результат не найден (включая случай, когда массив имеет нулевые элементы).

Если выражение массива дает null массив, результат ANY будет null. Если левое выражение возвращает null, то результат ANY обычно равен null (хотя оператор нестрогого сравнения может привести к другому результату). Кроме того, если правый массив содержит какие-либо null элементы и не получен истинный результат сравнения, результат ANY будет null, а не ложным (опять-таки, предполагая оператор строгого сравнения). Это соответствует нормальным правилам SQL для логических комбинаций null значений.

SOME является синонимом для ANY.

ALL (массив)

expression operator ALL (array expression)

Правая часть — это выражение в скобках, которое должно давать значение массива. Левое выражение вычисляется и сравнивается с каждым элементом массива с использованием данного оператора, который должен давать логический результат. Результатом ALL является «истина», если все сравнения дают истину (включая случай, когда массив имеет нулевые элементы). Результат «ложь», если найден какой-либо ложный результат.

Если выражение массива дает null массив, результат ALL будет null. Если левое выражение возвращает null, результат ALL обычно равен null (хотя оператор нестрогого сравнения может привести к другому результату). Кроме того, если правый массив содержит какие-либо null элементы и не получен ложный результат сравнения, результат ALL будет null, а не истинным (опять-таки, при условии использования оператора строгого сравнения). Это соответствует нормальным правилам SQL для логических комбинаций null значений.

Сравнение конструкторов строк

row_constructor operator row_constructor

Каждая сторона является конструктором строки, как описано в «Руководстве пользователя» в разделе Конструкторы строк. Два значения строки должны иметь одинаковое количество полей. Каждая сторона оценивается, и они сравниваются по строкам. Сравнение конструкторов строк допускается, когда оператором является =, &lt;&gt;, &lt;, &lt;=, &gt; или &gt;= . Каждый элемент строки должен иметь тип, который имеет класс оператора B-дерева по умолчанию, иначе попытка сравнения может вызвать ошибку.

Случаи = и <> работают немного по-другому. Две строки считаются равными, если все их соответствующие члены ненулевые и равные; строки являются неравными, если любые соответствующие члены ненулевые и неравные; в противном случае результат сравнения строк неизвестен (null).

Для случаев <, <=, > и >= элементы строки сравниваются слева направо, останавливаясь, как только обнаруживается неравная или null пара элементов. Если любой из этой пары элементов является null, результат сравнения строк неизвестен (null); в противном случае сравнение этой пары элементов определяет результат. Например, ROW(1,2,NULL) &lt; ROW(1,3,0) дает значение true, а не null, поскольку третья пара элементов не рассматривается.

row_constructor IS DISTINCT FROM row_constructor

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

row_constructor IS NOT DISTINCT FROM row_constructor

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

Сравнение составных типов

record operator record

Спецификация SQL требует сравнения строк для возврата NULL, если результат зависит от сравнения двух значений NULL или NULL и не NULL. QHB делает это только при сравнении результатов двух конструкторов строк (как в разделе Сравнение конструкторов строк) или при сравнении конструктора строк с выходными данными подзапроса (как в разделе Выражения подзапроса). В других контекстах, где сравниваются два значения составного типа, два значения поля NULL считаются равными, а NULL считается большим, чем ненулевое. Это необходимо для согласованного поведения сортировки и индексации составных типов.

Каждая сторона оценивается, и они сравниваются по строкам. Сравнения составных типов допускаются, когда оператором является =, <>, <, <=, > или >= или имеет семантику, аналогичную одной из них. (Точнее говоря, оператор может быть оператором сравнения строк, если он является членом класса операторов B-дерева или является отрицателем члена = класса операторов B-дерева). Поведение по умолчанию вышеупомянутых операторов такое же, как для IS [NOT] DISTINCT FROM для конструкторов строк (см. раздел Сравнение конструкторов строк).

Для поддержки сопоставления строк, которые включают элементы без класса операторов B-дерева по умолчанию, для сравнения составных типов определены следующие операторы: *=, *<>, *<, *<=, *> и *>=. Эти операторы сравнивают внутреннее двоичное представление двух строк. Две строки могут иметь различное двоичное представление, даже если сравнение двух строк с оператором равенства верно. Порядок строк в этих операторах сравнения является детерминированным, но не имеет иного смысла. Эти операторы используются внутри для материализованных представлений и могут быть полезны для других специализированных целей, таких как репликация, но не предназначены для общего использования при написании запросов.

Функции возврата наборов (SET)

В этом разделе описываются функции, которые могут возвращать более одной строки. Наиболее широко используемые функции в этом классе — это функции, генерирующие ряды, как подробно описано в таблице 61 и таблице 62. Другие, более специализированные функции, возвращающие множество, описаны в «Руководстве пользователя», например в разделе Табличные функции приведены способы объединения нескольких функций возврата набора.

Таблица 61. Функции генерации серий

ФункцияТип аргументаТип ответаОписание
generate_series(start, stop)int, bigint или numericsetof int, setof bigint или setof numeric (аналогично типу аргумента)Создайте серию значений от start до stop с размером шага один
generate_series(start, stop, step)int, bigint или numericsetof int, setof bigint или setof numeric (аналогично типу аргумента)Генерация серии значений от start до stop с шагом step
generate_series(start, stop, step interval)timestamp или timestamp with time zonesetof timestamp или setof timestamp with time zone (такой же, как тип аргумента)Генерация серии значений от start до stop с шагом step

Если шаг положителен, возвращается ноль строк, если start больше, чем stop. И наоборот, когда шаг отрицательный, нулевые строки возвращаются, если start меньше stop. Нулевые строки также возвращаются для NULL входных данных. Это ошибка, когда шаг равен нулю. Вот несколько примеров:

SELECT * FROM generate_series(2,4);
 generate_series
-----------------
               2
               3
               4
(3 rows)

SELECT * FROM generate_series(5,1,-2);
 generate_series
-----------------
               5
               3
               1
(3 rows)

SELECT * FROM generate_series(4,3);
 generate_series
-----------------
(0 rows)

SELECT generate_series(1.1, 4, 1.3);
 generate_series
-----------------
             1.1
             2.4
             3.7
(3 rows)

-- this example relies on the date-plus-integer operator
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
   dates
------------
 2004-02-05
 2004-02-12
 2004-02-19
(3 rows)

SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
                              '2008-03-04 12:00', '10 hours');
   generate_series   
---------------------
 2008-03-01 00:00:00
 2008-03-01 10:00:00
 2008-03-01 20:00:00
 2008-03-02 06:00:00
 2008-03-02 16:00:00
 2008-03-03 02:00:00
 2008-03-03 12:00:00
 2008-03-03 22:00:00
 2008-03-04 08:00:00
(9 rows)

Таблица 62. Функции генерации нижнего индекса

ФункцияТип ответаОписание
generate_subscripts(array anyarray, dim int)setof intСоздайте серию, содержащую индексы данного массива.
generate_subscripts(array anyarray, dim int, reverse boolean)setof intСоздайте серию, содержащую индексы данного массива. Когда reverse верно, серия возвращается в обратном порядке.

generate_subscripts — это вспомогательная функция, которая генерирует набор допустимых подписок для указанного измерения данного массива. Нулевые строки возвращаются для массивов, у которых нет запрошенного измерения, или для массивов NULL (но действительные индексы возвращаются для элементов массива NULL). Вот несколько примеров:

-- basic usage
SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;
 s
---
 1
 2
 3
 4
(4 rows)

-- presenting an array, the subscript and the subscripted
-- value requires a subquery
SELECT * FROM arrays;
         a          
--------------------
 {-1,-2}
 {100,200,300}
(2 rows)

SELECT a AS array, s AS subscript, a[s] AS value
FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;
     array     | subscript | value
---------------+-----------+-------
 {-1,-2}       |         1 |    -1
 {-1,-2}       |         2 |    -2
 {100,200,300} |         1 |   100
 {100,200,300} |         2 |   200
 {100,200,300} |         3 |   300
(5 rows)

-- unnest a 2D array
CREATE OR REPLACE FUNCTION unnest2(anyarray)
RETURNS SETOF anyelement AS $$
select $1[i][j]
   from generate_subscripts($1,1) g1(i),
        generate_subscripts($1,2) g2(j);
$$ LANGUAGE sql IMMUTABLE;
CREATE FUNCTION
SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);
 unnest2
---------
       1
       2
       3
       4
(4 rows)

Когда к функции в предложении FROM добавляется суффикс WITH ORDINALITY, к bigint добавляется столбец WITH ORDINALITY, который начинается с 1 и увеличивается на 1 для каждой строки вывода функции. Это наиболее полезно в случае набора возвращающих функций, таких как unnest().

-- set returning function WITH ORDINALITY
SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
       ls        | n
-----------------+----
 pg_serial       |  1
 pg_twophase     |  2
 postmaster.opts |  3
 pg_notify       |  4
 qhb.conf        |  5
 pg_tblspc       |  6
 logfile         |  7
 base            |  8
 qhbmaster.pid   |  9
 qhb_ident.conf  | 10
 global          | 11
 pg_xact         | 12
 pg_snapshots    | 13
 pg_multixact    | 14
 QHB_VERSION     | 15
 pg_wal          | 16
 qhb_hba.conf    | 17
 pg_stat_tmp     | 18
 pg_subtrans     | 19
(19 rows)

Системные информационные функции и операторы

Таблица 63 показывает несколько функций, которые извлекают информацию о сеансе и системе.

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

Таблица 63. Информационные функции сеанса

ИмяТип ответаОписание
current_catalognameимя текущей базы данных (в стандарте SQL называется « каталог »)
current_database()nameназвание текущей базы данных
current_query()textтекст текущего выполняемого запроса, отправленный клиентом (может содержать более одного оператора)
current_rolenameэквивалентно current_user
current_schema [()]nameимя текущей схемы
current_schemas(boolean)name[]имена схем в пути поиска, необязательно включая неявные схемы
current_usernameимя пользователя текущего контекста выполнения
inet_client_addr()inetадрес удаленного соединения
inet_client_port()intпорт удаленного подключения
inet_server_addr()inetадрес локальной связи
inet_server_port()intпорт локальной связи
pg_backend_pid()intИдентификатор процесса сервера, присоединенного к текущему сеансу
pg_blocking_pids(int)int[]Идентификаторы процесса, которые блокируют указанный идентификатор процесса сервера от получения блокировки
pg_conf_load_time()timestamp with time zoneвремя загрузки конфигурации
pg_current_logfile([ text ])textОсновное имя файла журнала или журнал в запрошенном формате, который в данный момент используется сборщиком журналов.
pg_my_temp_schema()oidOID временной схемы сеанса или 0, если нет
pg_is_other_temp_schema(oid)booleanСхема временная схема другого сеанса?
pg_jit_available()booleanдоступна ли компиляция JIT в этом сеансе? Возвращает false если для jit установлено значение false.
pg_listening_channels()setof textназвания каналов, которые слушает в данный момент сеанс
pg_notification_queue_usage()doubleдоля асинхронной очереди уведомлений, занятой в данный момент (0-1)
pg_postmaster_start_time()timestamp with time zoneвремя запуска сервера
pg_safe_snapshot_blocking_pids(int)int[]Идентификаторы процессов, которые блокируют указанный идентификатор процесса сервера от получения безопасного снимка
pg_trigger_depth()intтекущий уровень вложенности триггеров QHB (0, если не вызывается, прямо или косвенно, из триггера)
session_usernameимя пользователя сеанса
usernameэквивалентно current_user
version()textИнформация о версии QHB. Смотрите также server_version_num для машиночитаемой версии.

current_catalog, current_role, current_schema, current_user, session_user и user имеют специальный синтаксический статус в SQL: они должны вызываться без завершающих скобок. (В QHB скобки можно использовать с current_schema, но не с остальными).

session_user обычно является пользователем, который инициировал текущее соединение с базой данных; но суперпользователи могут изменить эту настройку с помощью SET SESSION AUTHORIZATION. current_user — это идентификатор пользователя, который применим для проверки прав доступа. Обычно он равен пользователю сеанса, но его можно изменить с помощью SET ROLE. Он также изменяется во время выполнения функций с атрибутом SECURITY DEFINER. На языке Unix пользователь сеанса - это «реальный пользователь», а текущий пользователь - «эффективный пользователь». current_role и user являются синонимами для current_user. (Стандарт SQL проводит различие между current_role и current_user, но QHB этого не делает, поскольку объединяет пользователей и роли в единый вид сущностей).

current_schema возвращает имя схемы, которая является первой в пути поиска (или нулевое значение, если путь поиска пуст). Это схема, которая будет использоваться для любых таблиц или других именованных объектов, которые создаются без указания целевой схемы. current_schemas(boolean) возвращает массив имен всех схем, присутствующих в настоящее время в пути поиска. Опция Boolean определяет, включены ли в возвращаемый путь поиска неявно включенные системные схемы, такие как pg_catalog.

inet_client_addr возвращает IP-адрес текущего клиента, а inet_client_port возвращает номер порта. inet_server_addr возвращает IP-адрес, на котором сервер принял текущее соединение, а inet_server_port возвращает номер порта. Все эти функции возвращают NULL, если текущее соединение происходит через сокет Unix-домена.

pg_blocking_pids возвращает массив идентификаторов процессов сеансов, которые блокируют серверный процесс с указанным идентификатором процесса, или пустой массив, если такого серверного процесса нет или он не заблокирован. Один серверный процесс блокирует другой, если он либо содержит блокировку, которая конфликтует с запросом блокировки заблокированного процесса (жесткий блок), либо ожидает блокировку, которая будет конфликтовать с запросом блокировки заблокированного процесса, и находится впереди него в очереди ожидания (мягкий блок). При использовании параллельных запросов результат всегда содержит видимые клиентом идентификаторы процессов (то есть результаты pg_backend_pid), даже если фактическая блокировка удерживается или ожидается дочерним рабочим процессом. Соответственно в результате могут быть продублированы идентификаторы PID. Также обратите внимание, когда подготовленная транзакция содержит конфликтующую блокировку, она будет представлена нулевым идентификатором процесса в результате выполнения этой функции. Частые вызовы этой функции могут оказать некоторое влияние на производительность базы данных, поскольку для нее требуется кратковременный эксклюзивный доступ к общему состоянию диспетчера блокировки.

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

pg_current_logfile возвращает в виде текста путь к файлам журналов, которые в данный момент используются сборщиком журналов. Путь включает каталог log_directory и имя файла журнала. Сбор журнала должен быть включен или возвращаемое значение равно NULL. Когда существует несколько файлов журнала, каждый в своем формате, pg_current_logfile вызываемый без аргументов, возвращает путь к файлу с первым форматом, найденным в упорядоченном списке: stderr, csvlog. NULL возвращается, когда ни один файл журнала не имеет ни одного из этих форматов. Чтобы запросить конкретный формат файла, укажите текстовое значение csvlog или stderr в качестве значения необязательного параметра. Возвращаемое значение равно NULL если запрошенный формат журнала не настроен как log_destination. pg_current_logfile отражает содержимое файла current_logfiles.

pg_my_temp_schema возвращает OID временной схемы текущего сеанса или ноль, если ее нет (потому что она не создала никаких временных таблиц). pg_is_other_temp_schema возвращает true, если данный OID является OID временной схемы другого сеанса. (Это может быть полезно, например, для исключения временных таблиц других сеансов из каталога).

pg_listening_channels возвращает набор имен асинхронных каналов уведомлений, которые прослушивает текущий сеанс. pg_notification_queue_usage возвращает долю от общего доступного пространства для уведомлений, которое в данный момент занято уведомлениями, ожидающими обработки, в виде double в диапазоне 0-1. См LISTEN и NOTIFY для получения дополнительной информации.

pg_postmaster_start_time возвращает временную метку с часовым поясом при запуске сервера.

pg_safe_snapshot_blocking_pids возвращает массив идентификаторов процессов сеансов, которые блокируют процесс сервера с указанным идентификатором процесса от получения безопасного снимка, или пустой массив, если такого серверного процесса нет или он не заблокирован. Сеанс, выполняющий транзакцию SERIALIZABLE блокирует транзакцию SERIALIZABLE READ ONLY DEFERRABLE от получения моментального снимка до тех пор, пока последний не определит, что безопасно избегать любых предикатных блокировок. См. раздел Уровень изоляции Serializable для получения дополнительной информации о сериализуемых и отложенных транзакциях. Частые вызовы этой функции могут оказать некоторое влияние на производительность базы данных, поскольку для нее требуется кратковременный доступ к общему состоянию менеджера блокировки предикатов.

version возвращает строку, описывающую версию сервера QHB. Вы также можете получить эту информацию из server_version или для машиночитаемой версии server_version_num. Разработчики программного обеспечения должны использовать server_version_num или PQserverVersion вместо анализа текстовой версии.

В таблице 64 перечислены функции, которые позволяют пользователю запрашивать привилегии доступа к объекту программным способом. См. раздел Привилегии для получения дополнительной информации о привилегиях.

Таблица 64. Доступ к функциям запроса привилегий

ИмяТип ответаОписание
has_any_column_privilege(user, table, privilege)booleanимеет ли пользователь привилегию для любого столбца таблицы
has_any_column_privilege (table, privilege)booleanимеет ли текущий пользователь привилегию для любого столбца таблицы
has_column_privilege (user, table, column, privilege)booleanимеет ли пользователь привилегию для столбца
has_column_privilege (table, column, privilege)booleanимеет ли текущий пользователь привилегию для столбца
has_database_privilege (user, database, privilege)booleanимеет ли пользователь привилегию для базы данных
has_database_privilege (database, privilege)booleanимеет ли текущий пользователь привилегию для базы данных
has_foreign_data_wrapper_privilege (user, fdw, privilege)booleanимеет ли пользователь привилегию для обёртки сторонних данных
has_foreign_data_wrapper_privilege (fdw, privilege)booleanимеет ли текущий пользователь привилегию для обёртки сторонних данных
has_function_privilege (user, function, privilege)booleanимеет ли пользователь привилегию для функции
has_function_privilege (function, privilege)booleanимеет ли текущий пользователь привилегию для функции
has_language_privilege (user, language, privilege)booleanимеет ли пользователь право на язык
has_language_privilege (language, privilege)booleanимеет ли текущий пользователь привилегию для языка
has_schema_privilege (user, schema, privilege)booleanимеет ли пользователь привилегию для схемы
has_schema_privilege (schema, privilege)booleanимеет ли текущий пользователь привилегию для схемы
has_sequence_privilege (user, sequence, privilege)booleanимеет ли пользователь привилегию для последовательности
has_sequence_privilege (sequence, privilege)booleanимеет ли текущий пользователь привилегию для последовательности
has_server_privilege (user, server, privilege)booleanимеет ли пользователь привилегию для стороннего сервера
has_server_privilege (server, privilege)booleanимеет ли текущий пользователь привилегию для стороннего сервера
has_table_privilege (user, table, privilege)booleanимеет ли пользователь привилегию для таблицы
has_table_privilege (table, privilege)booleanимеет ли текущий пользователь привилегию для таблицы
has_tablespace_privilege (user, tablespace, privilege)booleanимеет ли пользователь привилегию для табличного пространства
has_tablespace_privilege (tablespace, privilege)booleanимеет ли текущий пользователь привилегию для табличного пространства
has_type_privilege (user, type, privilege)booleanимеет ли пользователь привилегию для типа
has_type_privilege (type, privilege)booleanимеет ли текущий пользователь привилегию для типа
pg_has_role (user, role, privilege)booleanимеет ли пользователь право на роль
pg_has_role (role, privilege)booleanимеет ли текущий пользователь право на роль
row_security_active (table)booleanу текущего пользователя активна защита на уровне строк для таблицы

has_table_privilege проверяет, может ли пользователь получить доступ к таблице определенным образом. Пользователь может быть указан по имени, по OID (pg_authid.oid), public чтобы указать псевдоролевую роль PUBLIC, или, если аргумент опущен, предполагается current_user. Таблица может быть указана по имени или по OID. (Таким образом, на самом деле существует шесть вариантов has_table_privilege, которые можно различить по количеству и типам их аргументов). При указании по имени имя может быть дополнено схемой при необходимости. Требуемый тип привилегий доступа указывается текстовой строкой, которая должна принимать одно из значений SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES или TRIGGER. Опционально, с WITH GRANT OPTION можно добавить тип привилегии, чтобы проверить, удерживается ли привилегия с опцией grant. Кроме того, несколько типов привилегий могут быть перечислены через запятую, и в этом случае результат будет true если удерживается какая-либо из перечисленных привилегий. (Случай строки привилегий не имеет значения, и допускается наличие дополнительного пробела между именами привилегий, но не внутри них). Некоторые примеры:

SELECT has_table_privilege('myschema.mytable', 'select');
SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');

has_sequence_privilege проверяет, может ли пользователь получить доступ к последовательности определенным образом. Возможности его аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен оцениваться как USAGE, SELECT или UPDATE.

has_any_column_privilege проверяет, может ли пользователь получить доступ к любому столбцу таблицы определенным образом. Возможности его аргументов аналогичны has_table_privilege, за исключением того, что требуемый тип привилегий доступа должен соответствовать некоторой комбинации SELECT, INSERT, UPDATE или REFERENCES. Обратите внимание, что наличие любой из этих привилегий на уровне таблицы неявно предоставляет ее для каждого столбца таблицы, поэтому has_any_column_privilege всегда будет возвращать true если has_table_privilege делает для это тех же аргументов. Но has_any_column_privilege также успешно выполняется если существует предоставление привилегии на уровне столбца хотя бы для одного столбца.

has_column_privilege проверяет, может ли пользователь получить доступ к столбцу определенным образом. Возможности его аргументов аналогичны has_table_privilege, с добавлением, что столбец может быть указан либо по имени, либо по номеру атрибута. Требуемый тип привилегий доступа должен соответствовать некоторой комбинации SELECT, INSERT, UPDATE или REFERENCES. Обратите внимание, что наличие любой из этих привилегий на уровне таблицы неявно предоставляет ее для каждого столбца таблицы.

has_database_privilege проверяет, может ли пользователь получить доступ к базе данных определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен соответствовать некоторой комбинации CREATE, CONNECT, TEMPORARY или TEMP (которая эквивалентна TEMPORARY).

has_function_privilege проверяет, может ли пользователь получить доступ к функции определенным образом. Возможности аргументов аналогичны has_table_privilege. При указании функции текстовой строкой, а не OID, допустимый ввод такой же, как для типа данных regprocedure (см. раздел Типы идентификаторов объектов). Требуемый тип привилегий доступа должен оцениваться как EXECUTE. Примером является:

SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');

has_foreign_data_wrapper_privilege проверяет, может ли пользователь получить доступ к оболочке внешних данных определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен быть USAGE.

has_language_privilege проверяет, может ли пользователь получить доступ к процедурному языку определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен быть USAGE.

has_schema_privilege проверяет, может ли пользователь получить доступ к схеме определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен соответствовать некоторой комбинации CREATE или USAGE.

has_server_privilege проверяет, может ли пользователь получить доступ к внешнему серверу определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен быть USAGE.

has_tablespace_privilege проверяет, может ли пользователь получить доступ к табличному пространству определенным образом. Возможности аргументов аналогичны has_table_privilege. Требуемый тип привилегий доступа должен оцениваться как CREATE.

has_type_privilege проверяет, может ли пользователь получить доступ к типу определенным образом. Возможности аргументов аналогичны has_table_privilege. При указании типа текстовой строкой, а не OID, допустимый ввод такой же, как для типа данных regtype (см. раздел Типы идентификаторов объектов). Требуемый тип привилегий доступа должен быть USAGE.

pg_has_role проверяет, может ли пользователь получить доступ к роли определенным образом. Возможности его аргументов аналогичны has_table_privilege, за исключением того, что public не допускается в качестве имени пользователя. Требуемый тип привилегий доступа должен соответствовать некоторой комбинации MEMBER или USAGE. MEMBER обозначает прямое или косвенное членство в роли (то есть право делать SET ROLE), а USAGE обозначает, доступны ли привилегии роли немедленно без выполнения SET ROLE.

row_security_active проверяет, активна ли защита на уровне строк для указанной таблицы в контексте current_user и среды. Таблица может быть указана по имени или по OID.

В таблице 65 показаны операторы, доступные для типа aclitem, который представляет собой представление прав доступа в каталоге. См. раздел Привилегии для получения информации о том, как читать значения привилегий доступа.

Таблица 65. Операторы aclitem

ОператорОписаниеПримерРезультат
=равный’calvin=r*w/hobbes’::aclitem = ’calvin=r*w*/hobbes’::aclitemf
@>содержит элемент’{calvin=r*w/hobbes, hobbes=r*w*/postgres}’::aclitem[] @> ’calvin=r*w/hobbes’::aclitemt
~содержит элемент’{calvin=r*w/hobbes, hobbes=r*w*/postgres}’::aclitem[] ~ ’calvin=r*w/hobbes’::aclitemt

В таблице 66 показаны некоторые дополнительные функции для управления типом aclitem.

Таблица 66. Функции aclitem

ИмяТип ответаОписание
acldefault (type, ownerId)aclitem[]получить права доступа по умолчанию для объекта, принадлежащего ownerId
aclexplode (aclitem[])setof recordполучить массив aclitem виде кортежей
makeaclitem (grantee, grantor, privilege, grantable)aclitemпостроить aclitem из ввода

acldefault возвращает встроенные права доступа по умолчанию для объекта типа type принадлежащего роли ownerId. Они представляют привилегии доступа, которые будут приняты, когда запись ACL объекта равна нулю. (Права доступа по умолчанию описаны в разделе Привилегии). Типом параметра является CHAR: напишите ’c’ для COLUMN, ’r’ для TABLE и табличных объектов, ’s’ для SEQUENCE, ’d’ для DATABASE, ’f’ для FUNCTION или PROCEDURE, ’l’ для LANGUAGE, ’L’ для LARGE OBJECT, ’n для SCHEMA,’t ’ для TABLESPACE, ’F’ для FOREIGN DATA WRAPPER, ’S’ для FOREIGN SERVER или ’T' для TYPE или DOMAIN.

aclexplode возвращает массив aclitem в виде набора строк. В качестве выходных столбцов указываются oid grantor, oid grantee (0 для PUBLIC), предоставляется привилегия в виде текста (SELECT, ...) и является ли привилегия логически допустимой. makeaclitem выполняет обратную операцию.

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

SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);

Таблица 67. Функции запроса видимости схемы

ИмяТип ответаОписание
pg_collation_is_visible(collation_oid)booleanсортировка видна в пути поиска
pg_conversion_is_visible(conversion_oid)booleanконверсия видна в пути поиска
pg_function_is_visible(function_oid)booleanфункция видна в пути поиска
pg_opclass_is_visible(opclass_oid)booleanкласс оператора виден в пути поиска
pg_operator_is_visible(operator_oid)booleanоператор виден в пути поиска
pg_opfamily_is_visible(opclass_oid)booleanвидно ли семейство операторов в пути поиска
pg_statistics_obj_is_visible(stat_oid)booleanвиден ли объект статистики в пути поиска
pg_table_is_visible(table_oid)booleanтаблица видна в пути поиска
pg_ts_config_is_visible(config_oid)booleanвидна ли конфигурация текстового поиска в пути поиска
pg_ts_dict_is_visible(dict_oid)booleanвиден словарь текстового поиска в пути поиска
pg_ts_parser_is_visible(parser_oid)booleanвиден ли анализатор текстового поиска в пути поиска
pg_ts_template_is_visible(template_oid)booleanвиден ли шаблон текстового поиска в пути поиска
pg_type_is_visible(type_oid)booleanтип (или домен) виден в пути поиска

Каждая функция выполняет проверку видимости для одного типа объекта базы данных. Обратите внимание, что pg_table_is_visible также может использоваться с представлениями, материализованными представлениями, индексами, последовательностями и внешними таблицами; pg_function_is_visible также может использоваться с процедурами и агрегатами; pg_type_is_visible также может использоваться с доменами. Для функций и операторов объект в пути поиска виден, если ранее в пути нет объекта с таким же именем и типом данных аргумента. Для классов операторов рассматриваются как имя, так и связанный метод доступа к индексу.

Все эти функции требуют OID объекта для идентификации объекта, подлежащего проверке. Если вы хотите проверить объект по имени, удобно использовать псевдонимы OID (regclass, regtype, regprocedure, regoperator, regconfig или regdictionary), например:

SELECT pg_type_is_visible('myschema.widget'::regtype);

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

В таблице 68 перечислены функции, которые извлекают информацию из системных каталогов.

Таблица 68. Информационные функции системного каталога

ИмяТип ответаОписание
format_type(type_oid, typemod)textполучить имя SQL типа данных
pg_get_constraintdef(constraint_oid)textполучить определение ограничения
pg_get_constraintdef(constraint_oid, pretty_bool)textполучить определение ограничения
pg_get_expr(pg_node_tree, relation_oid)textдекомпилировать внутреннюю форму выражения, предполагая, что любые переменные в нем относятся к отношению, указанному вторым параметром
pg_get_expr(pg_node_tree, relation_oid, pretty_bool)textдекомпилировать внутреннюю форму выражения, предполагая, что любые переменные в нем относятся к отношению, указанному вторым параметром
pg_get_functiondef(func_oid)textполучить определение функции или процедуры
pg_get_function_arguments(func_oid)textполучить список аргументов определения функции или процедуры (со значениями по умолчанию)
pg_get_function_identity_arguments(func_oid)textполучить список аргументов для идентификации функции или процедуры (без значений по умолчанию)
pg_get_function_result(func_oid)textполучить предложение RETURNS для функции (возвращает ноль для процедуры)
pg_get_indexdef(index_oid)textполучить команду CREATE INDEX для индекса
pg_get_indexdef(index_oid, column_no, pretty_bool)textполучить команду CREATE INDEX для индекса или определение только одного столбца индекса, когда column_no не равно нулю
pg_get_keywords()setof recordполучить список ключевых слов SQL и их категорий
pg_get_ruledef(rule_oid)textполучить команду CREATE RULE для правила
pg_get_ruledef(rule_oid, pretty_bool)textполучить команду CREATE RULE для правила
pg_get_serial_sequence(table_name, column_name)textполучить имя последовательности, которую использует столбец серийного номера или идентификатора
pg_get_statisticsobjdef(statobj_oid)textполучить команду CREATE STATISTICS для объекта расширенной статистики
pg_get_triggerdef (trigger_oid)textCREATE [ CONSTRAINT ] TRIGGER get CREATE [ CONSTRAINT ] TRIGGER для триггера
pg_get_triggerdef (trigger_oid, pretty_bool)textCREATE [ CONSTRAINT ] TRIGGER get CREATE [ CONSTRAINT ] TRIGGER для триггера
pg_get_userbyid(role_oid)nameполучить имя роли с заданным OID
pg_get_viewdef(view_name)textполучить базовую команду SELECT для представления или материализованного представления (устарело)
pg_get_viewdef(view_name, pretty_bool)textполучить базовую команду SELECT для представления или материализованного представления (устарело)
pg_get_viewdef(view_oid)textполучить базовую команду SELECT для представления или материализованного представления
pg_get_viewdef(view_oid, pretty_bool)textполучить базовую команду SELECT для представления или материализованного представления
pg_get_viewdef(view_oid, wrap_column_int)textполучить базовую команду SELECT для представления или материализованного представления; строки с полями переносятся в указанное количество столбцов, подразумевается симпатичная печать
pg_index_column_has_property(index_oid, column_no, prop_name)booleanпроверить, имеет ли столбец индекса указанное свойство
pg_index_has_property(index_oid, prop_name)booleanпроверить, имеет ли индекс указанное свойство
pg_indexam_has_property(am_oid, prop_name)booleanпроверить, есть ли у метода доступа к индексу указанное свойство
pg_options_to_table(reloptions)setof recordполучить набор пар имя / значение опции хранения
pg_tablespace_databases(tablespace_oid)setof oidполучить набор OID базы данных, которые имеют объекты в табличном пространстве
pg_tablespace_location(tablespace_oid)textполучить путь в файловой системе, в которой находится это табличное пространство
pg_typeof(any)regtypeполучить тип данных любого значения
collation for (any)textполучить сопоставление аргумента
to_regclass(rel_name)regclassполучить OID названного отношения
to_regproc(func_name)regprocполучить OID названной функции
to_regprocedure(func_name)regprocedureполучить OID названной функции
to_regoper(operator_name)regoperполучить OID указанного оператора
to_regoperator(operator_name)regoperatorполучить OID указанного оператора
to_regtype(type_name)regtypeполучить OID названного типа
to_regnamespace(schema_name)regnamespaceполучить OID названной схемы
to_regrole(role_name)regroleполучить OID указанной роли

format_type возвращает имя SQL типа данных, идентифицируемого его типом OID и, возможно, модификатором типа. Передайте NULL для модификатора типа, если конкретный модификатор не известен.

pg_get_keywords возвращает набор записей, описывающих ключевые слова SQL, распознаваемые сервером. Столбец word содержит ключевое слово. catcode содержит код категории: U для незарезервированного, C для имени столбца, T для имени типа или функции или R для зарезервированного. catdesc содержит возможно локализованную строку, описывающую категорию.

pg_get_constraintdef, pg_get_indexdef, pg_get_ruledef, pg_get_statisticsobjdef и pg_get_triggerdef соответственно восстанавливают команду создания для ограничения, индекса, правила, расширенного объекта статистики или триггера. (Обратите внимание, что это декомпилированная реконструкция, а не исходный текст команды). pg_get_expr декомпилирует внутреннюю форму отдельного выражения, например значение по умолчанию для столбца. Это может быть полезно при проверке содержимого системных каталогов. Если выражение может содержать Vars, укажите OID отношения, на которое они ссылаются, как на второй параметр; если не ожидаются Vars, достаточно нуля. pg_get_viewdef восстанавливает запрос SELECT который определяет представление. Большинство этих функций представлены в двух вариантах, один из которых может при желании «красиво распечатать» результат. Формат pretty-printed более читабелен, но формат по умолчанию, скорее всего, будет интерпретирован аналогичным образом в будущих версиях QHB; Избегайте использования pretty-printed вывода для дампа. Передача значения false для параметра pretty-print дает тот же результат, что и для варианта, в котором этот параметр вообще отсутствует.

pg_get_functiondef возвращает полный оператор CREATE OR REPLACE FUNCTION для функции. pg_get_function_arguments возвращает список аргументов функции в той форме, в которой она должна отображаться в CREATE FUNCTION. pg_get_function_result аналогичным образом возвращает соответствующее предложение RETURNS для функции. pg_get_function_identity_arguments возвращает список аргументов, необходимый для идентификации функции, например, в той форме, в которой она должна отображаться в ALTER FUNCTION. Эта форма опускает значения по умолчанию.

pg_get_serial_sequence возвращает имя последовательности, связанной со столбцом, или NULL, если последовательность не связана со столбцом. Если столбец является столбцом идентификаторов, связанная последовательность представляет собой последовательность, внутренне созданную для столбца идентификаторов. Для столбцов, созданных с использованием одного из серийных типов (serial, smallserial, bigserial), это последовательность, созданная для этого определения последовательного столбца. В последнем случае эта связь может быть изменена или удалена с помощью команды ALTER SEQUENCE OWNED BY. Первый входной параметр — это имя таблицы с необязательной схемой, а второй параметр - имя столбца. Поскольку первый параметр потенциально является схемой и таблицей, он не обрабатывается как идентификатор в двойных кавычках, то есть по умолчанию он находится в нижнем регистре, а второй параметр, являющийся просто именем столбца, рассматривается как дважды заключенный в кавычки и его регистр сохраняется. Функция возвращает значение, соответствующим образом отформатированное для передачи в функции последовательности (см. раздел Функции управления последовательностями). Типичное использование - чтение текущего значения последовательности для идентификатора или последовательного столбца, например:

SELECT currval(pg_get_serial_sequence('sometable', 'id'));

pg_get_userbyid извлекает имя роли с учетом ее OID.

pg_index_column_has_property, pg_index_has_property и pg_indexam_has_property возвращают, обладает ли указанный столбец индекса, метод индекса или метод доступа к индексу указанным свойством. NULL возвращается, если имя свойства неизвестно или не относится к конкретному объекту, или если OID или номер столбца не идентифицируют допустимый объект. См. Таблицу 8.69 для свойств столбца, Таблицу 8.70 для свойств индекса и Таблицу 8.71 для свойств метода доступа. (Обратите внимание, что методы доступа расширения могут определять дополнительные имена свойств для своих индексов).

Таблица 69. Свойства столбца индекса

ИмяОписание
ascСортирует ли столбец в порядке возрастания при сканировании вперед?
descСортирует ли столбец в порядке убывания при сканировании вперед?
nulls_firstСортирует ли столбец сначала пустые значения при сканировании вперед?
nulls_lastСортируется ли столбец с нулями в последний раз при сканировании вперед?
orderableИмеет ли столбец какой-либо определенный порядок сортировки?
distance_orderableМожет ли столбец сканироваться по порядку оператором « расстояния », например, ORDER BY col <-> constant ?
returnableМожет ли значение столбца быть возвращено при сканировании только по индексу?
search_arrayПоддерживает ли данный столбец поиск col = ANY(array) ?
search_nullsПоддерживает ли столбец поиск IS NULL и IS NOT NULL ?

Таблица 70. Свойства индекса

ИмяОписание
clusterableМожно ли использовать индекс в команде CLUSTER ?
index_scanПоддерживает ли индекс обычное (не растровое) сканирование?
bitmap_scanИндекс поддерживает растровое сканирование?
backward_scanМожно ли изменить направление сканирования в середине сканирования (для поддержки FETCH BACKWARD на курсоре без необходимости материализации)?

Таблица 71. Свойства метода доступа индекса

ИмяОписание
can_orderПоддерживает ли метод доступа ASC, DESC и связанные ключевые слова в CREATE INDEX ?
can_uniqueПоддерживает ли метод доступа уникальные индексы?
can_multi_colПоддерживает ли метод доступа индексы с несколькими столбцами?
can_excludeПоддерживает ли метод доступа ограничения исключения?
can_includeПоддерживает ли метод доступа предложение INCLUDE в CREATE INDEX ?

pg_options_to_table возвращает набор пар имя/значение параметра хранения (option_name/option_value) при передаче pg_class.reloptions или pg_attribute.attoptions.

pg_tablespace_databases позволяет исследовать табличное пространство. Он возвращает набор OID баз данных, имеющих объекты, хранящиеся в табличном пространстве. Если эта функция возвращает какие-либо строки, табличное пространство не является пустым и не может быть удалено. Для отображения конкретных объектов, заполняющих табличное пространство, вам необходимо подключиться к базам данных, идентифицированным pg_tablespace_databases и запросить их каталоги pg_class.

pg_typeof возвращает OID типа данных переданного ему значения. Это может быть полезно для устранения неполадок или динамического построения запросов SQL. Функция объявлена как возвращающая regtype, который является типом псевдонима OID (см. раздел Типы идентификаторов объектов); это означает, что он совпадает с OID для сравнения, но отображается как имя типа. Например:

SELECT pg_typeof(33);

 pg_typeof
-----------
 integer
(1 row)

SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
 typlen
--------
      4
(1 row)

Выражение collation for возвращает сличение переданного ему значения. Пример:

SELECT collation for (description) FROM pg_description LIMIT 1;
 pg_collation_for
------------------
 "default"
(1 row)

SELECT collation for ('foo' COLLATE "de_DE");
 pg_collation_for
------------------
 "de_DE"
(1 row)

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

Функции to_regclass, to_regproc, to_regprocedure, to_regoper, to_regoperator, to_regtype, to_regnamespace и to_regrole выполняют преобразование имен отношений, функций, операторов, типов, схем, и ролей (заданных в виде текста) в объекты типа regclass, regproc, regprocedure, regoper, regoperator, regtype, regnamespace и regrole соответственно. Эти функции отличаются от преобразования из текста тем, что они не принимают числовой OID, и что они возвращают null а не выдают ошибку, если имя не найдено (или, например, to_regproc и to_regoper, если данное имя соответствует нескольким объектам).

В таблице 72 перечислены функции, связанные с идентификацией и адресацией объекта базы данных.

Таблица 72. Информация об объекте и функции адресации

ИмяТип ответаОписание
pg_describe_object(classid oid, objid oid, objsubid integer)textполучить описание объекта базы данных
pg_identify_object(classid oid, objid oid, objsubid integer)type text, text schema text name text identityполучить идентификатор объекта базы данных
pg_identify_object_as_address(classid oid, objid oid, objsubid integer)type text, object_names text[], object_args text[]получить внешнее представление адреса объекта базы данных
pg_get_object_address(type text, object_names text[], object_args text[])classid, objid, objsubid integerполучить адрес объекта базы данных из его внешнего представления

pg_describe_object возвращает текстовое описание объекта базы данных, указанного в OID каталога, OID объекта и идентификаторе pg_describe_object (например, номер столбца в таблице; идентификатор подобъекта равен нулю при обращении к целому объекту). Это описание предназначено для чтения человеком и может быть переведено в зависимости от конфигурации сервера. Это полезно для определения идентичности объекта, хранящегося в каталоге pg_depend.

pg_identify_object возвращает строку, содержащую достаточно информации для уникальной идентификации объекта базы данных, указанного в OID каталога, OID объекта и идентификатора pg_identify_object. Эта информация предназначена для машинного чтения и никогда не переводится. type определяет тип объекта базы данных; schema - это имя схемы, к которой принадлежит объект, или NULL для типов объектов, которые не принадлежат схемам; name - это имя объекта, которое при необходимости указывается в кавычках, если имя (вместе с именем схемы, если это уместно) достаточно для однозначной идентификации объекта, в противном случае NULL; identity - это полная идентичность объекта, с точным форматом, зависящим от типа объекта, и каждое имя в формате уточняется схемой и при необходимости указывается в кавычках.

pg_identify_object_as_address возвращает строку, содержащую достаточно информации, чтобы однозначно идентифицировать объект базы данных, указанный в OID каталога, OID объекта и ID подобъекта. Возвращаемая информация не зависит от текущего сервера, то есть ее можно использовать для идентификации объекта с таким же именем на другом сервере. type определяет тип объекта базы данных; object_names и object_args - это текстовые массивы, которые вместе образуют ссылку на объект. Эти три значения могут быть переданы в pg_get_object_address для получения внутреннего адреса объекта. Эта функция является обратной к pg_get_object_address.

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

  • это те, которые будут использоваться в системных каталогах, таких как pg_depend, и могут быть переданы другим системным функциям, таким как pg_identify_object или pg_describe_object. classid - OID системного каталога, содержащего объект; objid - это OID самого объекта, а objsubid
  • это идентификатор подобъекта, или ноль, если его нет. Эта функция является обратной к pg_identify_object_as_address.

Функции, показанные в таблице 73, извлекают комментарии, ранее сохраненные с помощью команды COMMENT. Возвращается нулевое значение, если для указанных параметров не найдено ни одного комментария.

Таблица 73. Comment Information Functions

ИмяТип ответаОписание
col_description(table_oid, column_number)textполучить комментарий к столбцу таблицы
obj_description(object_oid, catalog_name)textполучить комментарий для объекта базы данных
obj_description(object_oid)textполучить комментарий для объекта базы данных (не рекомендуется)
shobj_description(object_oid, catalog_name)textполучить комментарий для общего объекта базы данных

col_description возвращает комментарий для столбца таблицы, который определяется OID ее таблицы и номером столбца. (obj_description нельзя использовать для столбцов таблицы, поскольку столбцы не имеют собственных идентификаторов OID).

Двухпараметрическая форма bj_description возвращает комментарий для объекта базы данных, указанного его OID и именем содержащего системный каталог. Например, obj_description (123456, ’pg_class’) извлекает комментарий для таблицы с OID 123456. Форма obj_description с одним параметром требует только OID объекта. Он не рекомендуется, поскольку нет гарантии, что OID уникальны в разных системных каталогах; следовательно, может быть возвращен неверный комментарий.

shobj_description используется точно так же, как obj_description, за исключением того, что он используется для получения комментариев к общим объектам. Некоторые системные каталоги являются глобальными для всех баз данных в каждом кластере, и описания объектов в них также хранятся глобально.

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

Таблица 74. Идентификаторы транзакций и снимки

ИмяТип ответаОписание
txid_current()bigintполучить идентификатор текущей транзакции, назначив новый, если у текущей транзакции его нет
txid_current_if_assigned()bigintто же самое, что и txid_current (), но возвращает ноль вместо назначения нового идентификатора транзакции, если ни один уже не назначен
txid_current_snapshot()txid_snapshotполучить текущий снимок
txid_snapshot_xip(txid_snapshot)setof bigintполучить текущие идентификаторы транзакций в снимке
txid_snapshot_xmax(txid_snapshot)bigintполучить xmax снимка
txid_snapshot_xmin(txid_snapshot)bigintполучить xmin снимка
txid_visible_in_snapshot(bigint, txid_snapshot)booleanвиден идентификатор транзакции в снимке? (не используйте с идентификаторами субтранзакций)
txid_status(bigint)textсообщить о статусе данной транзакции: зафиксировано, прервано, выполняется или пусто, если идентификатор транзакции слишком старый

Внутренний тип идентификатора транзакции (xid) имеет ширину 32 бита и охватывает каждые 4 миллиарда транзакций. Тем не менее, эти функции экспортируют 64-битный формат, который расширен счетчиком «эпох», поэтому он не будет меняться в течение срока службы установки. Тип данных, используемый этими функциями, txid_snapshot, хранит информацию о видимости идентификатора транзакции в определенный момент времени. Его компоненты описаны в таблице 75.

Таблица 75. Компоненты снимка

ИмяОписание
xminСамый ранний идентификатор транзакции (txid), который все еще активен. Все более ранние транзакции будут либо зафиксированы и видимы, либо отменены.
xmaxПервый пока не назначенный txid. Все txids, больше или равные этому, еще не запущены на момент моментального снимка и поэтому невидимы.
xip_listАктивные txids во время снимка. Список включает только те активные txids между xmin и xmax; там могут быть активные txids выше, чем xmax. Txid с xmin <= txid <xmax, которого нет в этом списке, уже был завершен во время моментального снимка и, таким образом, либо видим, либо мертв в соответствии с его состоянием фиксации. Список не включает txids субтранзакций.

Текстовое представление txid_snapshot - это xmin: xmax: xip_list. Например, 10: 20: 10,14,15 означает *xmin = 10, xmax = 20, xip_list = 10, 14, 15.

txid_status (bigint) сообщает о состоянии фиксации недавней транзакции. Приложения могут использовать его для определения того, была ли транзакция совершена или прервана, когда сервер приложений и базы данных отключился во время выполнения COMMIT. О статусе транзакции будет сообщено как о том, что она выполняется, зафиксирована или прервана, при условии, что транзакция достаточно недавняя, чтобы система сохранила статус фиксации этой транзакции. Если статус достаточно стар, чтобы в системе не сохранилось ни одной ссылки на эту транзакцию, а информация о состоянии фиксации была отброшена, эта функция вернет NULL. Обратите внимание, что подготовленные транзакции отображаются как выполняемые; приложения должны проверить pg_prepared_xacts, если им нужно определить, является ли txid подготовленной транзакцией.

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

Таблица 76. Информация о совершенной транзакции

ИмяТип ответаОписание
pg_xact_commit_timestamp(xid)timestamp with time zoneполучить фиксацию времени транзакции
pg_last_committed_xact()xid xid, timestamp timestamp with time zoneполучить идентификатор транзакции и метку времени последней совершенной транзакции

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

Таблица 77. Функции управления данными

ИмяТип ответаОписание
pg_control_checkpoint()recordВозвращает информацию о текущем состоянии контрольной точки.
pg_control_system()recordВозвращает информацию о текущем состоянии контрольного файла.
pg_control_init()recordВозвращает информацию о состоянии инициализации кластера.
pg_control_recovery()recordВозвращает информацию о состоянии восстановления.

pg_control_checkpoint возвращает запись, показанную в таблице 78

Таблица 78. pg_control_checkpoint Columns

Имя столбцаТип данных
checkpoint_lsnpg_lsn
redo_lsnpg_lsn
redo_wal_filetext
timeline_idinteger
prev_timeline_idinteger
full_page_writesboolean
next_xidtext
next_oidoid
next_multixact_idxid
next_multi_offsetxid
oldest_xidxid
oldest_xid_dbidoid
oldest_active_xidxid
oldest_multi_xidxid
oldest_multi_dbidoid
oldest_commit_ts_xidxid
newest_commit_ts_xidxid
checkpoint_timetimestamp with time zone

pg_control_system возвращает запись, показанную в таблице 79

Таблица 79. Столбцы pg_control_system

Имя столбцаТип данных
pg_control_versioninteger
catalog_version_nointeger
system_identifierbigint
pg_control_last_modifiedtimestamp with time zone

pg_control_init возвращает запись, показанную в таблице 80

Таблица 80. Столбцы pg_control_init

Имя столбцаТип данных
max_data_alignmentinteger
database_block_sizeinteger
blocks_per_segmentinteger
wal_block_sizeinteger
bytes_per_wal_segmentinteger
max_identifier_lengthinteger
max_index_columnsinteger
max_toast_chunk_sizeinteger
large_object_chunk_sizeinteger
float4_pass_by_valueboolean
float8_pass_by_valueboolean
data_page_checksum_versioninteger

pg_control_recovery возвращает запись, показанную в таблице 81

Таблица 81. Столбцы pg_control_recovery

Имя столбцаТип данных
min_recovery_end_lsnpg_lsn
min_recovery_end_timelineinteger
backup_start_lsnpg_lsn
backup_end_lsnpg_lsn
end_of_backup_record_requiredboolean

Функции системного администрирования

Функции, описанные в этом разделе, используются для контроля и мониторинга установки QHB.

Функции настройки конфигурации

В таблице 82 показаны функции, доступные для запроса и изменения параметров конфигурации во время выполнения.

Таблица 82. Функции настройки конфигурации

ИмяТип ответаОписание
current_setting(setting_name [, missing_ok ])textполучить текущее значение настройки
set_config(setting_name, new_value, is_local)textустановить параметр и вернуть новое значение

Функция current_setting выдает текущее значение параметра setting_name. Это соответствует команде SQL SHOW. Пример:

SELECT current_setting('datestyle');

 current_setting
-----------------
 ISO, MDY
(1 row)

Если параметр с именем setting_name отсутствует, current_setting выдает ошибку, если не указано значение missing_ok и значение true.

set_config устанавливает параметр setting_name в new_value. Если is_local имеет значение true, новое значение будет применяться только к текущей транзакции. Если вы хотите, чтобы новое значение применялось к текущему сеансу, используйте вместо этого false. Функция соответствует SQL-команде SET. Пример:

SELECT set_config('log_statement_stats', 'off', false);

 set_config
------------
 off
(1 row)

Функции сигнализации сервера

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

Таблица 83. Функции сигнализации сервера

ИмяТип ответаОписание
pg_cancel_backend(pid int)booleanОтмените текущий запрос бэкэнда. Это также допустимо, если вызывающая роль является членом роли, бэкэнд которой отменяется, или вызывающая роль была предоставлена pg_signal_backend, однако только суперпользователи могут отменять pg_signal_backend суперпользователя.
pg_reload_conf()booleanЗаставить процессы сервера перезагрузить свои файлы конфигурации
pg_rotate_logfile()booleanПовернуть файл журнала сервера
pg_terminate_backend(pid int)booleanЗавершить бэкэнд. Это также разрешено, если вызывающая роль является членом роли, бэкэнд которой завершается, или вызывающей роли был предоставлен pg_signal_backend, однако только суперпользователи могут завершить pg_signal_backend суперпользователя.

Каждая из этих функций возвращает true случае успеха и false противном случае.

  • pg_cancel_backend и pg_terminate_backend отправляют сигналы (SIGINT или SIGTERM соответственно) на внутренние процессы, идентифицируемые по идентификатору процесса. Идентификатор процесса активного бэкэнда можно найти в столбце pid представления pg_stat_activity или в списке процессов qhb на сервере (используя ps в Unix). Роль активного бэкенда можно найти в столбце usename представления pg_stat_activity.

  • pg_reload_conf отправляет сигнал SIGHUP на сервер, вызывая перезагрузку файлов конфигурации всеми процессами сервера.

  • pg_rotate_logfile сигнализирует менеджеру файлов журнала о немедленном переключении на новый выходной файл. Это работает, только когда работает встроенный сборщик журналов, так как в противном случае нет подпроцесса менеджера файлов журнала.

Функции управления резервным копированием

Функции, показанные в таблице 84, помогают создавать резервные копии в режиме онлайн. Эти функции не могут быть выполнены во время восстановления (кроме неисключительных pg_start_backup, неисключительных pg_stop_backup, pg_is_in_backup, pg_backup_start_time и pg_wal_lsn_diff).

Таблица 84. Функции управления резервным копированием

ИмяТип ответаОписание
pg_create_restore_point(name text)pg_lsnСоздать именованную точку для выполнения восстановления (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции).
pg_current_wal_flush_lsn()pg_lsnПолучить текущее местоположение для записи журнала впереди
pg_current_wal_insert_lsn()pg_lsnПолучить текущее местоположение вставки журнала записи
pg_current_wal_lsn()pg_lsnПолучить текущее местоположение записи в журнал записи
pg_start_backup(label text [, fast boolean [, exclusive boolean ] ])pg_lsnПодготовьтесь к выполнению резервного копирования в онлайн-хранилище (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции)
pg_stop_backup()pg_lsnЗавершите выполнение эксклюзивного резервного копирования в онлайн-хранилище (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции)
pg_stop_backup(exclusive boolean [, wait_for_archive boolean ])setof recordЗавершите выполнение эксклюзивного или неисключительного резервного копирования в режиме онлайн (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции)
pg_is_in_backup()boolИстинно, если онлайновое эксклюзивное резервное копирование все еще выполняется.
pg_backup_start_time()timestamp with time zoneПолучите время запуска эксклюзивного резервного копирования онлайн.
pg_switch_wal()pg_lsnПринудительное переключение на новый файл журнала с опережением записи (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено EXECUTE для запуска функции).
pg_walfile_name(lsn pg_lsn)textПреобразовать местоположение журнала записи вперед в имя файла
pg_walfile_name_offset(lsn pg_lsn)text, integerПреобразовать местоположение журнала упреждающей записи в имя файла и десятичное смещение байта в файле
pg_wal_lsn_diff(lsn pg_lsn, lsn pg_lsn)numericРассчитайте разницу между двумя местоположениями журнала записи

pg_start_backup принимает произвольную пользовательскую метку для резервной копии. (Обычно это имя, под которым будет сохранен файл резервного дампа). При использовании в монопольном режиме функция записывает файл метки резервной копии (backup_label) и, если есть какие-либо ссылки в каталоге pg_tblspc/, карты табличного пространства (tablespace_map) в каталог данных кластера базы данных, выполняет контрольную точку, а затем возвращает начальное местоположение резервной копии журнала упреждающей записи в виде текста. Пользователь может игнорировать это значение результата, но оно предоставляется в случае, если оно полезно. При использовании в неисключительном режиме содержимое этих файлов вместо этого возвращается функцией pg_stop_backup и должно быть записано вызывающей стороной в резервную копию.

qhb=# select pg_start_backup('label_goes_here');
 pg_start_backup
-----------------
 0/D4445B8
(1 row)

Существует необязательный второй параметр типа boolean. Если true, это указывает на выполнение pg_start_backup как можно быстрее. Это форсирует немедленную контрольную точку, которая вызовет всплеск операций ввода-вывода, замедляя любые параллельно выполняющиеся запросы.

В исключительной резервной копии pg_stop_backup удаляет файл метки и, если он существует, файл tablespace_map созданный pg_start_backup. В неисключительной резервной копии содержимое backup_label и ablespace_map возвращается в результате работы функции и должно быть записано в файлы резервной копии (а не в каталог данных). Существует необязательный второй параметр типа boolean. Если false, pg_stop_backup вернется сразу после завершения резервного копирования, не дожидаясь архивирования WAL. Такое поведение полезно только для программного обеспечения резервного копирования, которое независимо контролирует архивирование WAL. В противном случае WAL, необходимый для обеспечения согласованности резервного копирования, может отсутствовать и сделать резервную копию бесполезной. Если для этого параметра установлено значение true, pg_stop_backup будет ожидать архивирования WAL, когда включено архивирование; в режиме ожидания это означает, что он будет ждать только, когда archive_mode = always. Если активность записи на основной стороне низкая, может быть полезно запустить pg_switch_wal на основной стороне, чтобы инициировать немедленное переключение сегмента.

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

pg_switch_wal переходит к следующему файлу журнала с опережением записи, что позволяет архивировать текущий файл (при условии, что вы используете непрерывное архивирование). Возвращаемое значение - конечное местоположение журнала записи с опережением + 1 в только что завершенном файле журнала записи с опережением. Если с момента последнего переключения журнала с опережением записи не было никаких действий с опережением записи, pg_switch_wal ничего не делает и возвращает начальное местоположение файла журнала с опережением записи, который используется в данный момент.

pg_create_restore_point создает именованную запись журнала предварительной записи, которую можно использовать в качестве цели восстановления, и возвращает соответствующее местоположение журнала предварительной записи. Затем указанное имя можно использовать с recovery_target_name, чтобы указать точку, до которой будет продолжаться восстановление. Избегайте создания нескольких точек восстановления с одним и тем же именем, поскольку восстановление остановится на первой точке, имя которой соответствует цели восстановления.

pg_current_wal_lsn отображает текущее местоположение записи в журнал записи вперед в том же формате, что и вышеуказанные функции. Аналогично, pg_current_wal_insert_lsn отображает текущее местоположение вставки журнала с опережением записи, а pg_current_wal_flush_lsn отображает текущее местоположение pg_current_wal_flush_lsn журнала с опережением записи. Место вставки является «логическим» концом журнала упреждающей записи в любой момент, тогда как место записи — это конец того, что было фактически записано из внутренних буферов сервера, а место сброса — это место, которое гарантированно будет записано в долговременный место хранения. Расположение записи — это конец того, что можно проверить извне сервера, и обычно это то, что вам нужно, если вы заинтересованы в архивировании частично полных файлов журнала с опережением записи. Места для вставки и сброса доступны главным образом для отладки сервера. Обе эти операции предназначены только для чтения и не требуют прав суперпользователя.

Вы можете использовать pg_walfile_name_offset для извлечения соответствующего имени файла журнала записи с опережением записи и смещения байтов из результатов любой из вышеперечисленных функций. Например:

qhb=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
        file_name         | file_offset
--------------------------+-------------
 00000001000000000000000D |     4039624
(1 row)

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

pg_wal_lsn_diff вычисляет разницу в байтах между двумя местоположениями журнала записи с опережением. Его можно использовать с pg_stat_replication или некоторыми функциями, показанными в таблице 4.84, для получения задержки репликации.

Подробнее о правильном использовании этих функций см. в разделе Непрерывное архивирование и восстановление на момент времени.

Функции управления восстановлением

Функции, показанные в таблице 85, предоставляют информацию о текущем состоянии режима ожидания. Эти функции могут выполняться как во время восстановления, так и в нормальном режиме.

Таблица 85. Функции восстановления информации

ИмяТип ответаОписание
pg_is_in_recovery()boolВерно, если восстановление все еще продолжается.
pg_last_wal_receive_lsn()pg_lsnПолучите последнее местоположение журнала предварительной записи, полученное и синхронизированное на диск потоковой репликацией. Пока идет потоковая репликация, она будет монотонно возрастать. Если восстановление завершено, оно останется неизменным со значением последней записи WAL, полученной и синхронизированной с диском во время восстановления. Если потоковая репликация отключена или она еще не запущена, функция возвращает NULL.
pg_last_wal_replay_lsn()pg_lsnПолучите последнюю запись журнала перед воспроизведением во время восстановления. Если восстановление еще продолжается, оно будет монотонно возрастать. Если восстановление завершено, то это значение останется неизменным на уровне последней записи WAL, примененной во время этого восстановления. Когда сервер был запущен нормально без восстановления, функция возвращает NULL.
pg_last_xact_replay_timestamp()timestamp with time zoneПолучить метку времени последней транзакции, воспроизведенной во время восстановления. Это время, когда на первичном сервере была сгенерирована запись WAL для этой транзакции. Если ни одна транзакция не была воспроизведена во время восстановления, эта функция возвращает NULL. В противном случае, если восстановление еще продолжается, оно будет увеличиваться монотонно. Если восстановление завершено, то это значение останется неизменным на уровне последней транзакции, примененной во время этого восстановления. Когда сервер был запущен нормально без восстановления, функция возвращает NULL.

Функции, показанные в таблице 86, контролируют ход восстановления. Эти функции могут быть выполнены только во время восстановления.

Таблица 86. Функции управления восстановлением

ИмяТип ответаОписание
pg_is_wal_replay_paused()boolИстинно, если восстановление приостановлено.
pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60)booleanПродвигает физический резервный сервер. Если для параметра wait установлено значение true (по умолчанию), функция ожидает, пока продвижение будет завершено или wait_seconds секунды wait_seconds, и возвращает true если продвижение прошло успешно, и false противном случае. Если для wait установлено значение false, функция возвращает значение true сразу после отправки сообщения SIGUSR1 администратору почты, чтобы запустить повышение. По умолчанию эта функция доступна только суперпользователям, но другим пользователям может быть предоставлено разрешение EXECUTE для ее запуска.
pg_wal_replay_pause()voidНемедленно приостанавливает восстановление (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции).
pg_wal_replay_resume()voidПерезапускает восстановление, если оно было приостановлено (по умолчанию ограничено суперпользователями, но другим пользователям может быть предоставлено разрешение EXECUTE для запуска функции).

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

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

Функции синхронизации снимков

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

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

Снимки экспортируются с pg_export_snapshot функции pg_export_snapshot, показанной в таблице 87, и импортируются с помощью команды SET TRANSACTION.

Таблица 87. Функции синхронизации снимков

ИмяТип ответаОписание
pg_export_snapshot()textСохранить текущий снимок и вернуть его идентификатор

Функция pg_export_snapshot сохраняет текущий снимок и возвращает text строку, идентифицирующую снимок. Эта строка должна быть передана (вне базы данных) клиентам, которые хотят импортировать снимок. Снимок доступен для импорта только до конца транзакции, которая его экспортировала. Транзакция может экспортировать более одного снимка, если это необходимо. Обратите внимание, что это полезно только в транзакциях READ COMMITTED, поскольку в REPEATABLE READ и на более высоких уровнях изоляции транзакции используют один и тот же моментальный снимок в течение всего срока службы. После того, как транзакция экспортировала какие-либо моментальные снимки, ее нельзя подготовить с помощью PREPARE TRANSACTION.

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

Функции репликации

Функции, показанные в таблице 88, предназначены для управления функциями репликации и взаимодействия с ними.

Использование функций для начала репликации разрешено только суперпользователям. Использование функций для слота репликации ограничено суперпользователями и пользователями, имеющими привилегию REPLICATION.

Функции, описанные в разделе Функции управления резервным копированием, разделе Функции управления восстановлением и разделе Функции синхронизации снимков, также имеют отношение к репликации.

Таблица 88. Функции SQL репликации

ФункцияТип ответаОписание
pg_create_physical_replication_slot(slot_name name [, immediately_reserve boolean, temporary boolean ])(name slot_name, lsn pg_lsn)Создает новый физический слот репликации с именем slot_name. Необязательный второй параметр, если он равен true, указывает, что LSN для этого слота репликации будет зарезервирован немедленно; в противном случае номер LSN зарезервирован при первом подключении от клиента потоковой репликации. Потоковые изменения из физического слота возможны только с протоколом потоковой репликации. Необязательный третий параметр temporary, если он установлен в значение true, указывает, что слот не должен постоянно храниться на диске и предназначен только для использования в текущем сеансе. Временные слоты также освобождаются при любой ошибке. Эта функция соответствует команде протокола репликации CREATE_REPLICATION_SLOT ... PHYSICAL.
pg_drop_replication_slot(slot_name name)voidУдаляет физический или логический слот репликации с именем slot_name. То же, что команда протокола репликации DROP_REPLICATION_SLOT. Для логических слотов это должно вызываться при подключении к той же базе данных, в которой был создан слот.
pg_create_logical_replication_slot(slot_name name, plugin name [, temporary boolean ])(name slot_name, lsn pg_lsn)Создает новый логический (декодирующий) слот репликации с именем slot_name используя плагин вывода plugin. Необязательный третий параметр temporary, если он установлен в значение true, указывает, что слот не должен постоянно храниться на диске и предназначен только для использования в текущем сеансе. Временные слоты также освобождаются при любой ошибке. Вызов этой функции имеет тот же эффект, что и команда протокола репликации CREATE_REPLICATION_SLOT ... LOGICAL.
pg_copy_physical_replication_slot(src_slot_name name, dst_slot_name name [, temporary boolean ])(name slot_name, lsn pg_lsn)Копирует существующий физический слот репликации с именем src_slot_name в физический слот репликации с именем dst_slot_name. Скопированный физический слот начинает резервировать WAL из того же LSN, что и исходный слот. temporary является обязательным. Если temporary опущено, используется то же значение, что и для исходного слота.
pg_copy_logical_replication_slot(src_slot_name name, dst_slot_name name [, temporary boolean [, plugin name ] ])(name slot_name, lsn pg_lsn)Копирует существующее имя слота логической репликации src_slot_name в слот логической репликации с именем dst_slot_name, изменяя выходной плагин и постоянство. Скопированный логический слот начинается с того же номера LSN, что и исходный логический слот. И temporary и plugin являются обязательными. Если temporary или plugin не указан, используются те же значения, что и для исходного логического слота.
pg_logical_slot_get_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])(lsn pg_lsn, xid xid, text data)Возвращает изменения в слоте slot_name, начиная с точки, с которой изменения использовались последними. Если upto_lsn и upto_nchanges равны NULL, логическое декодирование будет продолжаться до конца WAL. Если upto_lsn не NULL, декодирование будет включать только те транзакции, которые совершаются до указанного LSN. Если upto_nchanges равен NULL, декодирование остановится, когда число строк, полученных в результате декодирования, превысит указанное значение. Однако обратите внимание, что фактическое количество возвращаемых строк может быть больше, поскольку этот предел проверяется только после добавления строк, полученных при декодировании каждой новой транзакции.
pg_logical_slot_peek_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])(lsn pg_lsn, xid xid, text data)Ведет себя так же, как pg_logical_slot_get_changes(), за исключением того, что изменения не используются; то есть они будут возвращены снова при будущих вызовах.
pg_logical_slot_get_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])(lsn pg_lsn, xid xid, data bytea)Работает так же, как pg_logical_slot_get_changes(), за исключением того, что изменения возвращаются как bytea.
pg_logical_slot_peek_binary_changes(slot_name name, upto_lsn pg_lsn, upto_nchanges int, VARIADIC options text[])(lsn pg_lsn, xid xid, data bytea)Ведет себя так же, как pg_logical_slot_get_changes(), за исключением того, что изменения возвращаются как bytea и что изменения не используются; то есть они будут возвращены снова при будущих вызовах.
pg_replication_slot_advance(slot_name name, upto_lsn pg_lsn)(name slot_name, end_lsn pg_lsn) boolПродвигает текущую подтвержденную позицию слота репликации с именем slot_name. Слот не будет перемещен назад, и он не будет перемещен за пределы текущей позиции вставки. Возвращает название слота и реальную позицию, до которой он был продвинут.
pg_replication_origin_create(node_name text)oidСоздайте источник репликации с заданным внешним именем и верните присвоенный ему внутренний идентификатор.
pg_replication_origin_drop(node_name text)voidУдалите ранее созданный источник репликации, включая любой связанный процесс воспроизведения.
pg_replication_origin_oid(node_name text)oidНайдите источник репликации по имени и верните внутренний идентификатор. Если соответствующий источник репликации не найден, выдается ошибка.
pg_replication_origin_session_setup(node_name text)voidПометить текущий сеанс как воспроизведение с заданным источником, позволяя отслеживать ход воспроизведения. Используйте pg_replication_origin_session_reset чтобы вернуться. Может использоваться, только если не настроено предыдущее происхождение.
pg_replication_origin_session_reset()voidОтмените эффекты pg_replication_origin_session_setup().
pg_replication_origin_session_is_setup()boolБыл ли настроен источник репликации в текущем сеансе?
pg_replication_origin_session_progress(flush bool)pg_lsnВерните местоположение воспроизведения для источника репликации, настроенного в текущем сеансе. Параметр flush определяет, будет ли соответствующая локальная транзакция записана на диск или нет.
pg_replication_origin_xact_setup(origin_lsn pg_lsn, origin_timestamp timestamptz)voidПометить текущую транзакцию как воспроизведение транзакции, которая зафиксирована в данном LSN и отметке времени. Может вызываться только в том случае, если источник репликации был предварительно настроен с помощью pg_replication_origin_session_setup().
pg_replication_origin_xact_reset()voidОтмените эффекты pg_replication_origin_xact_setup().
pg_replication_origin_advance (node_name text, lsn pg_lsn)voidУстановить процесс репликации для данного узла в заданном месте. Это в первую очередь полезно для настройки исходного местоположения или нового местоположения после изменений конфигурации и т.п. Помните, что неосторожное использование этой функции может привести к непоследовательному копированию данных.
pg_replication_origin_progress(node_name text, flush bool)pg_lsnВернуть местоположение воспроизведения для данного источника репликации. Параметр flush определяет, будет ли соответствующая локальная транзакция записана на диск или нет.
pg_logical_emit_message(transactional bool, prefix text, content text)pg_lsnВыдать текстовое логическое сообщение декодирования. Это можно использовать для передачи общих сообщений в плагины логического декодирования через WAL. Параметр transactional указывает, должно ли сообщение быть частью текущей транзакции или оно должно быть записано немедленно и декодировано, как только логическое декодирование прочитает запись. prefix - это текстовый префикс, используемый плагинами логического декодирования для простого распознавания для них интересных сообщений. content - это текст сообщения.
pg_logical_emit_message(transactional bool, prefix text, content bytea)pg_lsnИздайте двоичное сообщение логического декодирования. Это можно использовать для передачи общих сообщений в плагины логического декодирования через WAL. Параметр transactional указывает, должно ли сообщение быть частью текущей транзакции или оно должно быть записано немедленно и декодировано, как только логическое декодирование прочитает запись. prefix - это текстовый префикс, используемый плагинами логического декодирования для простого распознавания для них интересных сообщений. content - это двоичное содержимое сообщения.

Функции управления объектами базы данных

Функции, показанные в таблице 89, рассчитывают использование дискового пространства объектов базы данных.

Таблица 89. Функции размера объекта базы данных

ИмяТип ответаОписание
pg_column_size(any)intКоличество байтов, используемых для хранения определенного значения (возможно сжатого)
pg_database_size(oid)bigintДисковое пространство, используемое базой данных с указанным OID
pg_database_size(name)bigintДисковое пространство, используемое базой данных с указанным именем
pg_indexes_size(regclass)bigintОбщее дисковое пространство, используемое индексами, прикрепленными к указанной таблице
pg_relation_size(relation regclass, fork text)bigintДисковое пространство, используемое указанным ответвлением (’main’, ’fsm’, ’vm’ или ’init’) указанной таблицы или индекса
pg_relation_size(relation regclass)bigintpg_relation_size(..., ’main’) для pg_relation_size(..., ’main’)
pg_size_bytes(text)bigintПреобразует размер в удобочитаемом формате с единицами измерения размера в байтах
pg_size_pretty(bigint)textПреобразует размер в байтах, выраженный как 64-разрядное целое число, в читаемый человеком формат с единицами размера
pg_size_pretty(numeric)textПреобразует размер в байтах, выраженный в виде числового значения, в удобочитаемый формат с единицами измерения размера
pg_table_size(regclass)bigintДисковое пространство, используемое указанной таблицей, за исключением индексов (но включая TOAST, карту свободного пространства и карту видимости)
pg_tablespace_size(oid)bigintДисковое пространство, используемое табличным пространством с указанным OID
pg_tablespace_size(name)bigintДисковое пространство, используемое табличным пространством с указанным именем
pg_total_relation_size(regclass)bigintОбщее дисковое пространство, используемое указанной таблицей, включая все индексы и данные TOAST

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

pg_total_relation_size принимает OID или имя таблицы или таблицы тостов и возвращает общее дисковое пространство, используемое для этой таблицы, включая все связанные индексы. Эта функция эквивалентна pg_table_size + pg_indexes_size.

pg_table_size принимает OID или имя таблицы и возвращает дисковое пространство, необходимое для этой таблицы, исключая индексы. (TOAST space, карта свободного пространства и карта видимости включены).

pg_indexes_size принимает OID или имя таблицы и возвращает общее дисковое пространство, используемое всеми индексами, прикрепленными к этой таблице.

pg_database_size и pg_tablespace_size принимают OID или имя базы данных или табличного пространства и возвращают общее дисковое пространство, используемое в них. Чтобы использовать pg_database_size, вы должны иметь разрешение CONNECT для указанной базы данных (которая предоставляется по умолчанию) или быть членом роли pg_read_all_stats. Чтобы использовать pg_tablespace_size, вы должны иметь разрешение CREATE для указанного табличного пространства или быть членом роли pg_read_all_stats если только это не табличное пространство по умолчанию для текущей базы данных.

pg_relation_size принимает OID или имя таблицы, индекса или таблицы тостов и возвращает размер на диске в байтах одного разветвления этого отношения. (Обратите внимание, что для большинства целей удобнее использовать функции более высокого уровня pg_total_relation_size или pg_table_size, которые суммируют размеры всех вилок). С одним аргументом он возвращает размер основного форка данных отношения. Второй аргумент может быть предоставлен, чтобы указать, какой форк нужно исследовать:

  • ’main’ возвращает размер основного ответвления данных отношения.

  • ’fsm’ возвращает размер карты свободного пространства (см. раздел Карта свободного пространства ), связанной с отношением.

  • ’vm’ возвращает размер карты видимости (см. раздел Карта видимости), связанной с отношением.

  • ’init’ возвращает размер форка инициализации, если он есть, связанный с отношением.

pg_size_pretty может использоваться для форматирования результата одной из других функций в удобочитаемом виде с использованием байтов, КБ, МБ, ГБ или ТБ в зависимости от ситуации.

pg_size_bytes может использоваться для получения размера в байтах из строки в удобочитаемом формате. Входные данные могут иметь единицы байтов, кБ, МБ, ГБ или ТБ и анализируются без учета регистра. Если единицы не указаны, подразумеваются байты.

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

Если OID, который не представляет существующий объект, передается в качестве аргумента одной из вышеуказанных функций, возвращается NULL.

Функции, показанные в таблице 90, помогают идентифицировать конкретные файлы на диске, связанные с объектами базы данных.

Таблица 90. Функции расположения объектов базы данных

ИмяТип ответаОписание
pg_relation_filenode(relation regclass)oidНомер файлового узла указанного отношения
pg_relation_filepath(relation regclass)textПуть к файлу с указанным отношением
pg_filenode_relation(tablespace oid, filenode oid)regclassНайти отношение, связанное с данным табличным пространством и файловым узлом

pg_relation_filenode принимает OID или имя таблицы, индекса, последовательности или таблицы тостов и возвращает номер «файлового узла», назначенный в данный момент. FileNode — это базовый компонент имен файлов, используемых для отношения (см. раздел Структура файлов базы данных для получения дополнительной информации). Для большинства таблиц результат такой же, как у pg_class. relfilenode, но для некоторых системных каталогов relfilenode равен нулю, и эту функцию необходимо использовать для получения правильного значения. Функция возвращает NULL, если передано отношение, которое не имеет хранилища, такое как представление.

pg_relation_filepath похож на pg_relation_filenode, но возвращает полное имя пути файла (относительно каталога данных кластера базы данных PGDATA) отношения.

pg_filenode_relation является противоположностью pg_relation_filenode. При наличии OID «табличного пространства» и «filenode» он возвращает OID связанного отношения. Для таблицы в табличном пространстве базы данных по умолчанию табличное пространство может быть указано как 0.

В таблице 91 перечислены функции, используемые для управления сопоставлениями.

Таблица 91. Функции управления сопоставлением

ИмяТип ответаОписание
pg_collation_actual_version(oid)textВернуть актуальную версию сличения из операционной системы
pg_import_system_collations(schema regnamespace)integerИмпорт сопоставлений операционной системы

pg_collation_actual_version возвращает актуальную версию объекта сортировки, так как он в настоящее время установлен в операционной системе. Если это отличается от значения в pg_collation.collversion, то объекты, зависящие от параметров сортировки, возможно, потребуется перестроить. Смотрите также ALTER COLLATION.

pg_import_system_collations добавляет параметры сортировки в системный каталог pg_collation на основе всех локалей, найденных в операционной системе. Это то, что использует initdb; см. раздел Управление сортировкой для более подробной информации-->. Если впоследствии в операционную систему будут установлены дополнительные локали, эту функцию можно будет запустить снова, чтобы добавить параметры сортировки для новых локалей. Локали, соответствующие существующим записям в pg_collation будут пропущены. (Но объекты сопоставления, основанные на локалях, которых больше нет в операционной системе, не удаляются этой функцией). Параметром schema обычно будет pg_catalog, но это не является обязательным требованием; параметры сортировки могут быть установлены и в другую схему. Функция возвращает количество новых созданных объектов сопоставления.

Таблица 92. Функции разделения информации

ИмяТип ответаОписание
pg_partition_tree(regclass)setof recordВывести информацию о таблицах или индексах в дереве разделов для данной разделенной таблицы или разделенного индекса, с одной строкой для каждого раздела. Предоставленная информация включает имя раздела, имя его непосредственного родителя, логическое значение, указывающее, является ли раздел листом, и целое число, указывающее его уровень в иерархии. Значение уровня начинается с 0 для входной таблицы или индекса в его роли в качестве корня дерева разделов, 1 для его разделов, 2 для их разделов и т. Д.
pg_partition_ancestors(regclass)setof regclassПеречислите отношения предков данного раздела, включая сам раздел.
pg_partition_root(regclass)regclassВернуть самого верхнего родителя дерева разделов, которому принадлежит данное отношение.

Чтобы проверить общий размер данных, содержащихся в таблице измерений, описанной в разделе Пример декларативного партицирования, можно использовать следующий запрос:

=# SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
     FROM pg_partition_tree('measurement');
 total_size
------------
 24 kB
(1 row)

Функции обслуживания индекса

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

Таблица 93. Функции обслуживания индекса

ИмяТип ответаОписание
brin_summarize_new_values(index regclass)integerсуммировать диапазоны страниц, еще не суммированные
brin_summarize_range(index regclass, blockNumber bigint)integerсуммировать диапазон страниц, охватывающий данный блок, если он еще не суммирован
brin_desummarize_range(index regclass, blockNumber bigint)integerразбиение диапазона страниц, охватывающих данный блок, если он суммирован
gin_clean_pending_list(index regclass)bigintпереместить записи из списка ожидания GIN в основную структуру индекса

brin_summarize_new_values принимает OID или имя индекса BRIN и проверяет индекс, чтобы найти диапазоны страниц в базовой таблице, которые в данный момент не суммируются индексом; для любого такого диапазона он создает новый кортеж сводного индекса путем сканирования страниц таблицы. Возвращает количество новых сводок диапазона страниц, которые были вставлены в индекс. brin_summarize_range делает то же самое, за исключением того, что он только суммирует диапазон, который охватывает данный номер блока.

gin_clean_pending_list принимает OID или имя индекса GIN и очищает ожидающий список указанного индекса, перемещая записи в нем в основную структуру данных GIN. Возвращает количество страниц, удаленных из списка ожидания. Обратите внимание, если аргумент является индексом GIN, созданным с отключенной опцией fastupdate, очистка не происходит, и возвращаемое значение равно 0, поскольку у индекса нет списка ожидания. Пожалуйста, смотрите раздел Быстрое обновление GIN и раздел GIN советы и хитрости для получения подробной информации об ожидающем списке и опции fastupdate.

Общие функции доступа к файлам

Функции, показанные в таблице 94, предоставляют собственный доступ к файлам на компьютере, на котором размещен сервер. Только файлы в каталоге кластера базы данных и log_directory могут быть доступны, если пользователю не назначена роль pg_read_server_files. Используйте относительный путь для файлов в каталоге кластера и путь, соответствующий параметру конфигурации log_directory для файлов журнала.

Обратите внимание, что предоставление пользователям привилегии EXECUTE для pg_read_file () или связанных функций дает им возможность читать любой файл на сервере, который может прочитать база данных, и что эти чтения обходят все проверки привилегий в базе данных. Это означает, что, помимо прочего, пользователь с таким доступом может читать содержимое таблицы pg_authid, в которой содержится информация для аутентификации, а также читать любой файл в базе данных. Поэтому предоставление доступа к этим функциям должно быть тщательно продумано.

Таблица 94. Общие функции доступа к файлам

ИмяТип ответаОписание
pg_ls_dir(dirname text [, missing_ok boolean, include_dot_dirs boolean])setof textСписок содержимого каталога. По умолчанию ограничен суперпользователями, но другим пользователям может быть предоставлено EXECUTE для запуска функции.
pg_ls_logdir()setof recordУкажите имя, размер и время последнего изменения файлов в каталоге журнала. Доступ предоставляется членам роли pg_monitor и может предоставляться другим ролям, не являющимся суперпользователем.
pg_ls_waldir()setof recordУкажите имя, размер и время последнего изменения файлов в каталоге WAL. Доступ предоставляется членам роли pg_monitor и может предоставляться другим ролям, не являющимся суперпользователем.
pg_ls_archive_statusdir()setof recordУкажите имя, размер и время последнего изменения файлов в каталоге состояния архива WAL. Доступ предоставляется членам роли pg_monitor и может предоставляться другим ролям, не являющимся суперпользователем.
pg_ls_tmpdir([tablespace oid])setof recordУкажите имя, размер и время последнего изменения файлов во временном каталоге табличного пространства. Если табличное пространство не предусмотрено, используется табличное пространство pg_default. Доступ предоставляется членам роли pg_monitor и может предоставляться другим ролям, не являющимся суперпользователем.
pg_read_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ])textВернуть содержимое текстового файла. По умолчанию ограничен суперпользователями, но другим пользователям может быть предоставлено EXECUTE для запуска функции.
pg_read_binary_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ])byteaВернуть содержимое файла. По умолчанию ограничен суперпользователями, но другим пользователям может быть предоставлено EXECUTE для запуска функции.
pg_stat_file(filename text[, missing_ok boolean])recordВернуть информацию о файле. По умолчанию ограничен суперпользователями, но другим пользователям может быть предоставлено EXECUTE для запуска функции.

Некоторые из этих функций принимают необязательный параметр missing_ok, который определяет поведение, когда файл или каталог не существует. Если true, функция возвращает NULL (кроме pg_ls_dir, который возвращает пустой набор результатов). Если false, возникает ошибка. По умолчанию установлено значение false.

pg_ls_dir возвращает имена всех файлов (и каталогов и других специальных файлов) в указанном каталоге. Include_dot_dirs указывает, включены ли «.» И «..» в набор результатов. По умолчанию они исключаются (ложь), но их включение может быть полезно, если для параметра missing_ok задано значение true, чтобы отличать пустой каталог от несуществующего каталога.

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

pg_ls_waldir возвращает имя, размер и время последнего изменения (mtime) каждого файла в каталоге WAL. По умолчанию только суперпользователи и члены роли pg_monitor могут использовать эту функцию. Доступ может быть предоставлен другим лицам, использующим GRANT.

pg_ls_archive_statusdir возвращает имя, размер и время последнего изменения (mtime) каждого файла в каталоге состояния архива WAL pg_wal / archive_status. По умолчанию только суперпользователи и члены роли pg_monitor могут использовать эту функцию. Доступ может быть предоставлен другим лицам, использующим GRANT.

pg_ls_tmpdir возвращает имя, размер и время последнего изменения (mtime) каждого файла во временном каталоге файлов для указанного табличного пространства. Если табличное пространство не предусмотрено, используется табличное пространство pg_default. По умолчанию только суперпользователи и члены роли pg_monitor могут использовать эту функцию. Доступ может быть предоставлен другим лицам, использующим GRANT.

pg_read_file возвращает часть текстового файла, начиная с заданного смещения, возвращая не более байтов длины (меньше, если конец файла достигнут первым). Если смещение отрицательно, это относительно конца файла. Если смещение и длина не указаны, возвращается весь файл. Считанные из файла байты интерпретируются как строка в кодировке сервера; выдается ошибка, если они недопустимы в этой кодировке.

pg_read_binary_file похож на pg_read_file, за исключением того, что результатом является значение bytea; соответственно проверки кодирования не выполняются. В сочетании с функцией convert_from эту функцию можно использовать для чтения файла в указанной кодировке:

SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8');

pg_stat_file возвращает запись, содержащую размер файла, отметку времени последнего доступа, отметку времени последнего изменения, отметку времени последнего изменения статуса файла (только для платформ Unix), отметку времени создания файла (только для Windows) и boolean указание, является ли он каталогом. Типичные использования включают в себя:

SELECT * FROM pg_stat_file ('имя файла');
SELECT (pg_stat_file ('filename')). Модификация;

Функции консультативных блокировок

Функции, показанные в таблице 95, управляют консультативными блокировками. Подробнее о правильном использовании этих функций см. в разделе Консультативные блокировки.

Таблица 95. Консультативные функции блокировки

ИмяТип ответаОписание
pg_advisory_lock(key bigint)voidПолучить эксклюзивную блокировку на уровне сеанса
pg_advisory_lock(key1 int, key2 int)voidПолучить эксклюзивную блокировку на уровне сеанса
pg_advisory_lock_shared(key bigint)voidПолучить общую блокировку на уровне сеанса
pg_advisory_lock_shared(key1 int, key2 int)voidПолучить общую блокировку на уровне сеанса
pg_advisory_unlock(key bigint)booleanОсвободить эксклюзивную блокировку на уровне сеанса
pg_advisory_unlock(key1 int, key2 int)booleanОсвободить эксклюзивную блокировку на уровне сеанса
pg_advisory_unlock_all()voidОсвободить все консультативные блокировки уровня сеанса, удерживаемые текущим сеансом
pg_advisory_unlock_shared(key bigint)booleanОсвободить общую блокировку на уровне сеанса
pg_advisory_unlock_shared(key1 int, key2 int)booleanОсвободить общую блокировку на уровне сеанса
pg_advisory_xact_lock(key bigint)voidПолучите эксклюзивную блокировку на уровне транзакции
pg_advisory_xact_lock(key1 int, key2 int)voidПолучите эксклюзивную блокировку на уровне транзакции
pg_advisory_xact_lock_shared(key bigint)voidПолучить общую блокировку на уровне транзакций
pg_advisory_xact_lock_shared(key1 int, key2 int)voidПолучить общую блокировку на уровне транзакций
pg_try_advisory_lock(key bigint)booleanПолучите эксклюзивную блокировку на уровне сеанса, если она доступна
pg_try_advisory_lock(key1 int, key2 int)booleanПолучите эксклюзивную блокировку на уровне сеанса, если она доступна
pg_try_advisory_lock_shared(key bigint)booleanПолучите общую блокировку на уровне сеанса, если она доступна
pg_try_advisory_lock_shared(key1 int, key2 int)booleanПолучите общую блокировку на уровне сеанса, если она доступна
pg_try_advisory_xact_lock(key bigint)booleanПолучите эксклюзивную консультативную блокировку уровня транзакции, если она доступна
pg_try_advisory_xact_lock(key1 int, key2 int)booleanПолучите эксклюзивную консультативную блокировку уровня транзакции, если она доступна
pg_try_advisory_xact_lock_shared(key bigint)booleanПолучите совместную блокировку уровня транзакции, если она доступна
pg_try_advisory_xact_lock_shared(key1 int, key2 int)booleanПолучите совместную блокировку уровня транзакции, если она доступна

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

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

pg_try_advisory_lock аналогична pg_advisory_lock, за исключением того, что функция не будет ожидать, когда блокировка станет доступной. Он либо получит блокировку немедленно и вернет true, либо вернет false, если блокировка не может быть получена немедленно.

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

pg_advisory_unlock снимет ранее приобретенную эксклюзивную консультативную блокировку уровня сеанса. Возвращает true, если блокировка успешно снята. Если блокировка не была удержана, она вернет false и, кроме того, сервер сообщит о предупреждении SQL.

pg_advisory_unlock_shared работает так же, как и pg_advisory_unlock, за исключением того, что освобождает общую консультативную блокировку на уровне сеанса.

pg_advisory_unlock_all освободит все консультативные блокировки уровня сеанса, удерживаемые текущим сеансом. (Эта функция неявно вызывается в конце сеанса, даже если клиент отключается некорректно).

pg_advisory_xact_lock работает так же, как и pg_advisory_lock, за исключением того, что блокировка автоматически снимается в конце текущей транзакции.

pg_advisory_xact_lock_shared работает так же, как pg_advisory_lock_shared, за исключением того, что блокировка автоматически снимается в конце текущей транзакции и не может быть снята явно.

pg_try_advisory_xact_lock работает так же, как и pg_try_advisory_lock, за исключением того, что блокировка, если она получена, автоматически снимается в конце текущей транзакции и не может быть снята явно.

pg_try_advisory_xact_lock_shared работает так же, как и pg_try_advisory_lock_shared, за исключением того, что блокировка, если она получена, автоматически снимается в конце текущей транзакции и не может быть разблокирована явно.

Отправка метрик и аннотаций

Отправка метрики таймера

qhb_timer_report <name> <value>, где <name> — имя метрики (text), <value> — значение таймера в наносекундах (int8).

Увеличение значения "счётчика"

qhb_counter_increase_by <name> <value>, где <name> — имя метрики (text), <value> — значение (int8), на которое надо увеличить значение счётчика.

Увеличение значения типа "gauge"

qhb_gauge_add <name> <value>, где <name> — имя метрики (text), <value> — значение (int8), на которое надо увеличить значение "gauge".

Уменьшение значения типа "gauge"

qhb_gauge_sub <name> <value>, где <name> — имя метрики (text), <value> — значение (int8), на которое надо уменьшить значение "gauge".

Установка значение типа "gauge"

qhb_gauge_update <name> <value>, где <name> — имя метрики (text), <value> — значение (int8), в которое надо установить значение "gauge".

Отправка аннотации в графану

qhb_annotation <text> [<tag> ...], где <text> — текст аннотации для графаны, <tag> — опциональное значение тега (или тегов) для аннотации; можно указать произвольное количество тегов.

Триггерные функции

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

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

Функция suppress_redundant_updates_trigger может быть добавлена в таблицу следующим образом:

CREATE TRIGGER z_min_update
BEFORE UPDATE ON tablename
FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger();

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

Для получения дополнительной информации о создании триггеров см. CREATE TRIGGER.

Функции запуска событий

QHB предоставляет эти вспомогательные функции для извлечения информации из триггеров событий.

Для получения дополнительной информации о триггерах событий см. главу Триггеры событий.

Захват изменений в конце команды

pg_event_trigger_ddl_commands возвращает список команд DDL, выполняемых каждым действием пользователя при вызове в функции, связанной с триггером события ddl_command_end. Если вызывается в любом другом контексте, возникает ошибка. pg_event_trigger_ddl_commands возвращает одну строку для каждой выполненной базовой команды; некоторые команды, представляющие собой одно предложение SQL, могут возвращать более одной строки. Эта функция возвращает следующие столбцы:

ИмяТипОписание
classidoidOID каталога, в который входит объект
objidoidOID самого объекта
objsubidintegerИдентификатор подобъекта (например, номер атрибута для столбца)
command_tagtextКомандный тег
object_typetextТип объекта
schema_nametextИмя схемы, к которой принадлежит объект, если есть; в противном случае NULL. Цитирование не применяется.
object_identitytextТекстовое отображение идентификатора объекта, дополненное схемой. Каждый идентификатор, включенный в личность, указывается в случае необходимости.
in_extensionbooltrue, если команда является частью сценария расширения
commandpg_ddl_commandПолное представление команды, во внутреннем формате. Это не может быть выведено напрямую, но может быть передано другим функциям для получения различной информации о команде.

Обработка объектов, отброшенных командой DDL

pg_event_trigger_dropped_objects возвращает список всех объектов, удаленных командой, для которой вызывается событие sql_drop. Если вызвано в любом другом контексте, pg_event_trigger_dropped_objects вызывает ошибку. pg_event_trigger_dropped_objects возвращает следующие столбцы:

ИмяТипОписание
classidoidOID каталога, в котором находился объект
objidoidOID самого объекта
objsubidintegerИдентификатор подобъекта (например, номер атрибута для столбца)
originalboolИстинно, если это был один из корневых объектов удаления
normalboolИстинно, если в графе зависимостей было нормальное отношение зависимости, ведущее к этому объекту
is_temporarybooltrue, если это был временный объект
object_typetextТип объекта
schema_nametextИмя схемы, к которой принадлежит объект, если есть; в противном случае NULL. Цитирование не применяется.
object_nametextИмя объекта, если комбинация схемы и имени может использоваться в качестве уникального идентификатора для объекта; в противном случае NULL. Кавычки не применяются, а имя никогда не указывается в схеме.
object_identitytextТекстовое отображение идентификатора объекта, дополненное схемой. Каждый идентификатор, включенный в личность, указывается в случае необходимости.
address_namestext[]Массив, который вместе с object_type и address_args может использоваться pg_get_object_address() для воссоздания адреса объекта на удаленном сервере, содержащем объект с таким же именем того же вида
address_argstext[]Дополнение для address_names

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

CREATE FUNCTION test_event_trigger_for_drops()
        RETURNS event_trigger LANGUAGE plpgsql AS $$
DECLARE
    obj record;
BEGIN
    FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
    LOOP
        RAISE NOTICE '% dropped object: % %.% %',
                     tg_tag,
                     obj.object_type,
                     obj.schema_name,
                     obj.object_name,
                     obj.object_identity;
    END LOOP;
END
$$;
CREATE EVENT TRIGGER test_event_trigger_for_drops
   ON sql_drop
   EXECUTE FUNCTION test_event_trigger_for_drops();

Обработка события перезаписи таблицы

Функции, показанные в таблице 96, предоставляют информацию о таблице, для которой только что было вызвано событие table_rewrite. Если вызывается в любом другом контексте, возникает ошибка.

Таблица 96. Информация перезаписи таблицы

ИмяТип ответаОписание
pg_event_trigger_table_rewrite_oid()OidOID таблицы, которая должна быть переписана.
pg_event_trigger_table_rewrite_reason()intКод (ы) причины, объясняющие причину перезаписи. Точное значение кодов зависит от версии.

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

CREATE FUNCTION test_event_trigger_table_rewrite_oid()
 RETURNS event_trigger
 LANGUAGE plpgsql AS
$$
BEGIN
  RAISE NOTICE 'rewriting table % for reason %',
                pg_event_trigger_table_rewrite_oid()::regclass,
                pg_event_trigger_table_rewrite_reason();
END;
$$;

CREATE EVENT TRIGGER test_table_rewrite_oid
                  ON table_rewrite
   EXECUTE FUNCTION test_event_trigger_table_rewrite_oid();

Функции статистической информации

QHB предоставляет функцию для проверки сложной статистики, определенной с помощью команды CREATE STATISTICS.

Проверка списков MCV

pg_mcv_list_items возвращает список всех элементов, хранящихся в многостолбцовом списке MCV, и возвращает следующие столбцы:

ИмяТипОписание
indexintиндекс элемента в списке MCV
valuestext[]значения, хранящиеся в элементе MCV
nullsboolean[]флаги, идентифицирующие значения NULL
frequencydouble precisionчастота этого элемента MCV
base_frequencydouble precisionбазовая частота этого элемента MCV

pg_mcv_list_items можно использовать так:

SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
                pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts';

Значения pg_mcv_list могут быть получены только из столбца pg_statistic_ext_data.stxdmcv.

1

Имена преобразований следуют стандартной схеме именования: официальное имя исходной кодировки со всеми не алфавитно-цифровыми символами, замененными подчеркиванием, за которым следует _to_, за которым следует аналогично обработанное имя кодировки назначения. Следовательно, имена могут отличаться от обычных имен кодирования.

2

60, если операционная система реализует дополнительные секунды

3

Результат, содержащий более одного узла элемента на верхнем уровне, или непробельный текст вне элемента, является примером формы содержимого. Результат XPath не может иметь форму, например, если он возвращает узел атрибута, выбранный из элемента, который его содержит. Такой результат будет помещен в форму содержимого, где каждый такой запрещенный узел будет заменен его строковым значением, как определено для string функции XPath 1.0.