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

QHB предоставляет огромное количество функций и операторов для встроенных типов данных. В этой главе описаны основные из них, тогда как некоторые специальные функции описываются в соответствующих разделах данного руководства. Кроме того, пользователи могут определять свои собственные функции и операторы, как описано в главе Серверное программирование. Для вывода списка всех доступных функций и операторов можно воспользоваться командами psql \df и \do соответственно.

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

repeat ( text, integer ) → text

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

repeat('Pg', 4) → PgPgPgPg

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

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

Среди логических операторов доступны обычные:

boolean AND boolean → boolean
boolean OR boolean → boolean
NOT boolean → boolean

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Меньше
тип_данных > тип_данных → booleanБольше
тип_данных <= тип_данных → booleanМеньше или равно
тип_данных >= тип_данных → booleanБольше или равно
тип_данных = тип_данных → booleanРавно
тип_данных <> тип_данных → booleanНе равно
тип_данных != тип_данных → booleanНе равно

Примечание
Запись <> принята в стандарте SQL для условия «не равно». Запись != является псевдонимом, который преобразуется в <> на самом раннем этапе синтаксического анализа. Как следствие, реализовать операторы != и <> так, чтобы они работали по-разному, невозможно.

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

Обычно также можно сравнивать значения связанных типов данных; например, возможно сравнение integer > bigint. Некоторые подобные операции реализуются непосредственно «межтиповыми» операторами сравнения, но если такой оператор недоступен, синтаксический анализатор принудительно приведет менее распространенные тип к более распространенному и применит подходящий для последнего оператор сравнения.

Как показано выше, все операторы сравнения являются бинарными операторами, которые возвращают значения типа boolean. Таким образом, выражения типа 1 < 2 < 3 недопустимы (потому что нет оператора < для сравнения логического значения с 3). Для проверки принадлежности диапазону используйте предикат BETWEEN, описанный ниже

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

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

Предикат

Описание

Пример(ы)

тип_данных BETWEEN тип_данных AND тип_данных → boolean

Между (включая границы диапазона).

2 BETWEEN 1 AND 3 → t

2 BETWEEN 3 AND 1 → f

тип_данных NOT BETWEEN тип_данных AND тип_данных → boolean

Не между (обратное к BETWEEN).

2 NOT BETWEEN 1 AND 3 → f

тип_данных BETWEEN SYMMETRIC тип_данных AND тип_данных → boolean

Между, после сортировки граничных значений.

2 BETWEEN SYMMETRIC 3 AND 1 → t

тип_данных NOT BETWEEN SYMMETRIC тип_данных AND тип_данных → boolean

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

2 NOT BETWEEN SYMMETRIC 3 AND 1 → f

тип_данных IS DISTINCT FROM тип_данных → boolean

Не равно, при этом рассматривая NULL как обычное значение.

1 IS DISTINCT FROM NULL → t (а не NULL)

NULL IS DISTINCT FROM NULL → f (а не NULL)

тип_данных IS NOT DISTINCT FROM тип_данных → boolean

Равно, при этом рассматривая NULL как обычное значение.

1 IS NOT DISTINCT FROM NULL → f (а не NULL)

NULL IS NOT DISTINCT FROM NULL → t (а не NULL)

тип_данных IS NULL → boolean

Проверяет, равно ли значение NULL.

1.5 IS NULL → f

тип_данных IS NOT NULL → boolean

Проверяет, отличается ли значение от NULL.

'null' IS NOT NULL → t

тип_данных ISNULL → boolean

Проверяет, равно ли значение NULL (нестандартный синтаксис).

тип_данных NOTNULL → boolean

Проверяет, отличается ли значение от NULL (нестандартный синтаксис).

boolean IS TRUE → boolean

Проверяет, является ли результат логического выражения значением true.

true IS TRUE → t

NULL::boolean IS TRUE → f (а не NULL)

boolean IS NOT TRUE → boolean

Проверяет, является ли результат логического выражения значением false или неизвестным.

true IS NOT TRUE → f

NULL::boolean IS NOT TRUE → t (а не NULL)

boolean IS FALSE → boolean

Проверяет, является ли результат логического выражения значением false.

true IS FALSE → f

NULL::boolean IS FALSE → f (а не NULL)

boolean IS NOT FALSE → boolean

Проверяет, является ли результат логического выражения значением true или неизвестным.

true IS NOT FALSE → t

NULL::boolean IS NOT FALSE → t (а не NULL)

boolean IS UNKNOWN → boolean

Проверяет, является ли результат логического выражения неизвестным значением.

true IS UNKNOWN → f

NULL::boolean IS UNKNOWN → t (а не NULL)

boolean IS NOT UNKNOWN → boolean

Проверяет, является ли результат логического выражения значением true или false.

true IS NOT UNKNOWN → t

NULL::boolean IS NOT UNKNOWN → f (а не NULL)

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

a BETWEEN x AND y

равнозначно

a >= x AND a <= y

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

Различные варианты BETWEEN реализуются посредством обычных операторов сравнения, и поэтому они будут работать с любыми типами данных, которые можно сравнивать.

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

Обычные операторы сравнения выдают NULL (что означает «неопределенность»), а не true или false, когда любой из аргументов 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 был нормальным значением данных, а не «неопределенным».

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

выражение IS NULL
выражение IS NOT NULL

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

выражение ISNULL
выражение NOTNULL

Не пишите выражение = NULL, потому что NULL «не равно» NULL. (Значение NULL представляет неопределенность, и неизвестно, равны ли два неопределенных значения).

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

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

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

логическое_выражение IS TRUE
логическое_выражение IS NOT TRUE
логическое_выражение IS FALSE
логическое_выражение IS NOT FALSE
логическое_выражение IS UNKNOWN
логическое_выражение IS NOT UNKNOWN

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

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

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

Функция

Описание

Пример(ы)

num_nonnulls ( VARIADIC "any" ) → integer

Возвращает количество аргументов, отличных от NULL

num_nonnulls(1, NULL, 2) → 2

num_nulls ( VARIADIC "any" ) → integer

Возвращает количество аргументов NULL

num_nulls(1, NULL, 2) → 1

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

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

В Таблице 4 перечислены математические операторы, доступные для стандартных числовых типов. Если не указано иное, операторы, показанные как принимающие числовой_тип, доступны для типов smallint, integer, bigint, numeric, real и double precision. Операторы, показанные как принимающие целочисленный_тип, доступны для типов smallint, integer и bigint. За исключением отмеченных случаев, все формы операторов возвращают тот же тип данных, какой имеет их аргумент (или аргументы). Вызовы с неодинаковыми типами аргументов, например integer + numeric, разрешаются использованием типа, идущего в этих списках последним.

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

Оператор

Описание

Пример(ы)

числовой_тип + числовой_типчисловой_тип

Сложение

2 + 3 → 5

+ числовой_типчисловой_тип

Унарный плюс (нет операции)

+ 3.5 → 3.5

числовой_тип - числовой_типчисловой_тип

Вычитание

2 - 3 → -1

- числовой_типчисловой_тип

Смена знака

- (-4) → 4

числовой_тип * числовой_типчисловой_тип

Умножение

2 * 3 → 6

числовой_тип / числовой_типчисловой_тип

Деление (при делении целочисленных типов результат округляется в сторону нуля)

5.0 / 2 → 2.5000000000000000

5 / 2 → 2

(-5) / 2 → -2

числовой_тип % числовой_типчисловой_тип

Остаток целочисленного деления (по модулю); доступен для типов smallint, integer, bigint и numeric

5 % 4 → 1

numeric ^ numeric → numeric

double precision ^ double precision → double precision

Возведение в степень

2 ^ 3 → 8

В отличие от обычной математической практики, ^ по умолчанию вычисляется слева направо:

2 ^ 3 ^ 3 → 512

2 ^ (3 ^ 3) → 134217728

|/ double precision → double precision

Квадратный корень

|/ 25.0 → 5

||/ double precision → double precision

Кубический корень

||/ 64.0 → 4

@ числовой_типчисловой_тип

Абсолютное значение (модуль)

@ -5.0 → 5

целочисленный_тип & целочисленный_типцелочисленный_тип

Битовое И

91 & 15 → 11

целочисленный_тип | целочисленный_типцелочисленный_тип

Битовое ИЛИ

32 | 3 → 35

целочисленный_тип # целочисленный_типцелочисленный_тип

Битовое исключающее ИЛИ

17 # 5 → 20

~ целочисленный_типцелочисленный_тип

Битовое НЕ

~1 → -2

целочисленный_тип << integer → целочисленный_тип

Битовый сдвиг влево

1 << 4 → 16

целочисленный_тип >> integer → целочисленный_тип

Битовый сдвиг вправо

8 >> 2 → 2

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

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

Функция

Описание

Пример(ы)

abs ( числовой_тип ) → числовой_тип

Абсолютное значение (модуль)

abs(-17.4) → 17.4

cbrt ( double precision ) → double precision

Кубический корень

cbrt(64.0) → 4

ceil ( numeric ) → numeric

ceil ( double precision ) → double precision

Ближайшее целое число, большее или равное аргументу

ceil(42.2) → 43

ceil(-42.8) → -42

ceiling ( numeric ) → numeric

ceiling ( double precision ) → double precision

Ближайшее целое число, большее или равное аргументу (то же, что и ceil)

ceiling(95.3) → 96

degrees ( double precision ) → double precision

Преобразует радианы в градусы

degrees(0.5) → 28.64788975654116

div ( y numeric, x numeric ) → numeric

Целочисленное частное y/x (округленное в сторону нуля)

div(9, 4) → 2

exp ( numeric ) → numeric

exp ( double precision ) → double precision

Экспоненциал (e возводится в заданную степень)

exp(1.0) → 2.7182818284590452

factorial ( bigint ) → numeric

Факториал

factorial(5) → 120

floor ( numeric ) → numeric

floor ( double precision ) → double precision

Ближайшее целое число, меньшее или равное аргументу

floor(42.8) → 42

floor(-42.8) → -43

gcd ( числовой_тип, числовой_тип ) → числовой\_тип

Наибольший общий делитель (наибольшее положительное число, на которое оба аргумента делятся без остатка); возвращает 0, если оба аргумента равны нулю; доступно для типов integer, bigint и numeric

gcd(1071, 462) → 21

lcm ( числовой_тип, числовой_тип ) → числовой_тип

Наименьшее общее кратное (наименьшее строго положительное число, которое делится на оба аргумента без остатка; возвращает 0, если оба аргумента равны нулю; доступно для типов integer, bigint и numeric

lcm(1071, 462) → 23562

ln ( numeric ) → numeric

ln ( double precision ) → double precision

Натуральный логарифм

ln(2.0) → 0.6931471805599453

log ( numeric ) → numeric

log ( double precision ) → double precision

Десятичный логарифм

log(100) → 2

log10 ( numeric ) → numeric

log10 ( double precision ) → double precision

Десятичный логарифм (то же, что и log)

log10(1000) → 3

log ( b numeric, x numeric ) → numeric

Логарифм x по основанию b

log(2.0, 64.0) → 6.0000000000

min_scale ( numeric ) → integer

Минимальный масштаб (количество цифр в дробной части), необходимый для точного представления заданного значения

min_scale(8.4100) → 2

mod ( y числовой_тип, x числовой_тип ) → числовой_тип

Остаток от y/x; доступно для типов integer, bigint и numeric

mod(9, 4) → 1

pi ( ) → double precision

Примерное значение π

pi() → 3.141592653589793

power ( a numeric, b numeric ) → numeric

power ( a double precision, b double precision ) → double precision

a возводится в степень b

power(9, 3) → 729

radians ( double precision ) → double precision

Преобразует градусы в радианы

radians(45.0) → 0.7853981633974483

round ( numeric ) → numeric

round ( double precision ) → double precision

Округляет до ближайшего целого числа. Для numeric половина (.5) округляется до одного по модулю. Для double precision способ округление половины зависит от платформы, но, как правило, выполняется «округление до ближайшего четного».

round(42.4) → 42

round ( v numeric, s integer ) → numeric

Округляет v до s десятичных знаков. Половина (.5) округляется до одного по модулю.

round(42.4382, 2) → 42.44

scale ( numeric ) → integer

Масштаб аргумента (количество десятичных цифр в дробной части)

scale(8.4100) → 4

sign ( numeric ) → numeric

sign ( double precision ) → double precision

Знак аргумента (-1, 0 или +1)

sign(-8.4) → -1

sqrt ( numeric ) → numeric

sqrt ( double precision ) → double precision

Квадратный корень

sqrt(2) → 1.4142135623730951

trim_scale ( numeric ) → numeric

Сокращает масштаб значения (количество десятичных цифр в дробной части), убирая конечные нули

trim_scale(8.4100) → 8.41

trunc ( numeric ) → numeric

trunc ( double precision ) → double precision

Округляет до целого (в сторону нуля)

trunc(42.8) → 42

trunc(-42.8) → -42

trunc ( v numeric, s integer ) → numeric

Округляет v до s десятичных знаков

trunc(42.4382, 2) → 42.43

width_bucket ( операнд numeric, нижний numeric, верхний numeric, число integer ) → integer

width_bucket ( операнд double precision, нижний double precision, верхний double precision, число integer ) → integer

Возвращает номер блока, в который попадает операнд в гистограмме с заданным числом блоков равного размера, расположенных в диапазоне от нижний до верхний. Возвращает 0 или число+1, если операнд лежит вне этого диапазона.

width_bucket(5.35, 0.024, 10.06, 5) → 3

width_bucket ( операнд anycompatible, границы anycompatiblearray ) → integer

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

width_bucket(now(), array['yesterday', 'today', 'tomorrow']::timestamptz[]) → 2

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

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

Функция

Описание

Пример(ы)

random ( ) → double precision

Возвращает случайное значение в диапазоне 0.0 <= x < 1.0

random() → 0.897124072839091

setseed ( double precision ) → void

Задает начальное значение для последующих вызовов random(); аргументом должно быть число от -1.0 до 1.0, включая границы

setseed(0.12345)

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

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

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

Функция

Описание

Пример(ы)

acos ( double precision ) → double precision

Арккосинус в радианах

acos(1) → 0

acosd ( double precision ) → double precision

Арккосинус в градусах

acosd(0.5) → 60

asin ( double precision ) → double precision

Арксинус в радианах

asin(1) → 1.5707963267948966

asind ( double precision ) → double precision

Арксинус в градусах

asind(0.5) → 30

atan ( double precision ) → double precision

Арктангенс в радианах

atan(1) → 0.7853981633974483

atand ( double precision ) → double precision

Арктангенс в градусах

atand(1) → 45

atan2 ( y double precision, x double precision ) → double precision

Арктангенс отношения y/x в радианах

atan2(1, 0) → 1.5707963267948966

atan2d ( y double precision, x double precision ) → double precision

Арктангенс отношения y/x в градусах

atan2d(1, 0) → 90

cos ( double precision ) → double precision

Косинус в радианах

cos(0) → 1

cosd ( double precision ) → double precision

Косинус в градусах

cosd(60) → 0.5

cot ( double precision ) → double precision

Котангенс в радианах

cot(0.5) → 1.830487721712452

cotd ( double precision ) → double precision

Котангенс в градусах

cotd(45) → 1

sin ( double precision ) → double precision

Синус в радианах

sin(1) → 0.8414709848078965

sind ( double precision ) → double precision

Синус в градусах

sind(30) → 0.5

tan ( double precision ) → double precision

Тангенс в радианах

tan(1) → 1.5574077246549023

tand ( double precision ) → double precision

Тангенс в градусах

tand(45) → 1

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

В Таблице 8 перечислены доступные гиперболические функции.

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

Функция

Описание

Пример(ы)

sinh ( double precision ) → double precision

Гиперболический синус

sinh(1) → 1.1752011936438014

cosh ( double precision ) → double precision

Гиперболический косинус

cosh(0) → 1

tanh ( double precision ) → double precision

Гиперболический тангенс

tanh(1) → 0.7615941559557649

asinh ( double precision ) → double precision

Ареасинус

asinh(1) → 0.881373587019543

acosh ( double precision ) → double precision

Ареакосинус

acosh(1) → 0

atanh ( double precision ) → double precision

Ареатангенс

atanh(0.5) → 0.5493061443340548

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

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

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

Примечание
Оператор конкатенации строк (\|\|) примет нестроковый аргумент, если хотя бы один аргумент имеет строковый тип, как показано в Таблице 9. В других случаях, чтобы оператор принял нестроковый аргумент, можно использовать явное преобразование в text.

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

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

Описание

Пример(ы)

text || text → text

Конкатенирует две строки.

'Quan' || 'tum' → Quantum

text || anynonarray → text

anynonarray || text → text

Преобразует нестроковый аргумент в текст, а затем конкатенирует две строки. (Нестроковый аргумент не может быть типом-массивом, поскольку это может вызвать неоднозначность с операторами массивов ||. Если требуется конкатенировать эквивалент текста в массиве, следует явно привести его к типу text.)

'Value: ' || 42 → Value: 42

text IS [NOT] [форма] NORMALIZED → boolean

Проверяет, соответствует ли строка определенной форме нормализации Unicode. Форма указывается в необязательном ключевом слове форма: NFC (по умолчанию), NFD, NFKC или NFKD. Это выражение можно использовать, только если кодировка сервера — UTF8. Обратите внимание, что проверка нормализации с помощью этого выражения зачастую бывает быстрее, чем нормализация уже, возможно, нормализованных строк.

U&'\0061\0308bc' IS NFD NORMALIZED → t

bit_length ( text ) → integer

Возвращает количество битов в строке (это число в 8 раз больше octet_length).

bit_length('jose') → 32

char_length ( text ) → integer

character_length ( text ) → integer

Возвращает количество символов в строке.

char_length('josé') → 4

lower ( text ) → text

Переводит символы строки в нижний регистр в соответствии с правилами локали базы данных.

lower('TOM') → tom

normalize ( text [, форма ] ) → text

Преобразует строку в заданную форму нормализации Unicode. Форма указывается в необязательном ключевом слове форма: NFC (по умолчанию), NFD, NFKC или NFKD. Эту функцию можно использовать, только если кодировка сервера — UTF8.

normalize(U&'\0061\0308bc', NFC) → U&'\00E4bc'

octet_length ( text ) → integer

Возвращает количество байтов в строке.

octet_length('josé') → 5 (если кодировка сервера — UTF8)

octet_length ( character ) → integer

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

octet_length('abc '::character(4)) → 4

overlay ( строка text PLACING новая_подстрока text FROM начало integer [FOR число integer] ) → text

Заменяет подстроку в строке, начиная с символа на позиции начало, длиной в число символов, на новую_подстроку. Если число опущено, по умолчанию количество заменяемых символов определяется длиной новой_подстроки.

overlay('Txxxxas' placing 'hom' from 2 for 4) → Thomas

position ( подстрока text IN строка text ) → integer

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

position('om' in 'Thomas') → 3

substring ( строка text [ FROM начало integer ] [ FOR число integer ] ) → text

Извлекает из строки подстроку, начиная с символа на позиции начало (если таковая указана) и останавливаясь после заданного числа символов (если оно указано). Должен присутствовать хотя бы один из параметров: начало или число.

substring('Thomas' from 2 for 3) → hom

substring('Thomas' from 3) → omas

substring('Thomas' for 2) → Th

substring ( строка text FROM шаблон text ) → text

Извлекает первую подстроку, соответствующую регулярному выражению POSIX; см. подраздел Регулярные выражения POSIX.

substring('Thomas' from '...$') → mas

substring ( строка text SIMILAR шаблон text ESCAPE управляющий_символ text ) → text

substring ( строка text FROM шаблон text FOR управляющий_символ text ) → text

Извлекает первую подстроку, соответствующую регулярному выражению SQL; см. подраздел Регулярные выражения SIMILAR TO. Первая форма была определена в стандарте, начиная с SQL:2003; вторая форма существовала только в стандарте SQL:1999, и ее следует считать устаревшей.

substring('Thomas' similar '%#"o_a#"_' escape '#') → oma

trim ( [LEADING | TRAILING | BOTH] [символы text] FROM строка text ) → text

Удаляет самую длинную подстроку, содержащую только заданные символы (по умолчанию пробелы), с начала, конца или с обеих сторон (по умолчанию последнее — BOTH) строки.

trim(both 'xyz' from 'yxTomxx') → Tom

trim ( [ LEADING | TRAILING | BOTH ] [ FROM ] строка text [, символы text ] ) → text

Это нестандартный синтаксис для trim().

trim(both 'xyz' from 'yxTomxx') → Tom

upper ( text ) → text

Переводит символы строки в верхний регистр в соответствии с правилами локали базы данных.

upper('tom') → TOM

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

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

Функция

Описание

Пример(ы)

ascii ( text ) → integer

Возвращает числовой код первого символа аргумента. Для кодировки UTF8 возвращает код символа в Unicode. Для других многобайтовых кодировок аргумент должен быть символом ASCII.

ascii('x') → 120

btrim ( строка text [, символы text ] ) → text

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

btrim('xyxtrimyyx', 'xyz') → trim

chr ( integer ) → text

Возвращает символ с заданным кодом. Для кодировки UTF8 возвращает код символа в Unicode. Для других многобайтовых кодировок аргумент должен быть символом ASCII. Эта функция не может выдать chr(0), поскольку этот символ нельзя сохранить в текстовых типах данных.

chr(65) → A

concat ( знач1 "any" [, знач2 "any" [, ...] ] ) → text

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

concat('abcde', 2, NULL, 22) → abcde222

concat_ws ( разд text, знач1 "any" [, знач2 "any" [, ...] ] ) → text

Конкатенирует все аргументы, кроме первого, с разделителями. Первый аргумент используется как строка-разделитель и должен быть отличен от NULL. Другие аргументы NULL игнорируются.

concat_ws(',', 'abcde', 2, NULL, 22) → abcde,2,22

format ( стр_формата text [, форматир_аргумент "any" [, ...] ] ) → text

Форматирует аргументы в соответствии со строкой формата; см. подраздел format. Эта функция схожа с функцией sprintf в языке C.

format('Hello %s, %1$s', 'World') → Hello World, World

initcap ( text ) → text

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

initcap('hi THOMAS') → Hi Thomas

left ( строка text, n integer ) → text

Возвращает первые n символов в строке или, если n — отрицательное число, возвращает все символы, кроме последних |n| символов.

left('abcde', 2) → ab

length ( text ) → integer

Возвращает количество символов в строке.

length('jose') → 4

lpad ( строка text, длина integer [, наполнитель text ] ) → text

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

lpad('hi', 5, 'xy') → xyxhi

ltrim ( строка text [, символы text ] ) → text

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

ltrim('zzzytest', 'xyz') → test

md5 ( text ) → text

Вычисляет MD5-хэш аргумента с результатом, написанным в шестнадцатеричном формате.

md5('abc') → 900150983cd24fb0​d6963f7d28e17f72

parse_ident ( полный_идентификатор text [, строгий_режим boolean DEFAULT true ] ) → text[]

Разделяет полный_идентификатор на массив идентификаторов, удаляя кавычки, в которые заключены отдельные идентификаторы. По умолчанию лишние символы после последнего идентификатора считаются ошибкой, но если установить второй параметр в false, то такие лишние символы игнорируются. (Это поведение полезно для синтаксического анализа имен таких объектов, как функции.) Обратите внимание, что эта функция не усекает чрезмерно длинные идентификаторы. Если есть необходимость в усеченных именах, можно привести результат к name[].

parse_ident('"SomeSchema".someTable') → {SomeSchema,sometable}

pg_client_encoding ( ) → name

Возвращает имя текущей кодировки клиента.

pg_client_encoding() → UTF8

quote_ident ( text ) → text

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

quote_ident('Foo bar') → "Foo bar"

quote_literal ( text ) → text

Возвращает заданную строку, надлежащим образом подготовленную для использования в качестве строкового литерала в строке оператора SQL. Апострофы и обратные слэши, уже содержащиеся в строке, дублируются. Обратите внимание, что quote_literal возвращает NULL, когда входящее значение NULL; если аргумент может оказаться NULL, то зачастую лучше вызвать quote_nullable. См также пример Заключение в кавычки значений в динамических запросах.

quote_literal(E'O\'Reilly') → 'O''Reilly'

quote_literal ( anyelement ) → text

Преобразует заданное значение в текст, а затем заключает в апострофы как литерал. Апострофы и обратные слэши, уже содержащиеся в значении, дублируются.

quote_literal(42.5) → '42.5'

quote_nullable ( text ) → text

Возвращает заданную строку, подходящим образом подготовленную для использования в качестве строкового литерала в строке оператора SQL, или, если аргумент NULL, возвращает NULL. Апострофы и обратные слэши, уже содержащиеся в строке, дублируются. См. также пример Заключение в кавычки значений в динамических запросах.

quote_nullable(NULL) → NULL

quote_nullable ( anyelement ) → text

Преобразует заданное значение в текст, а затем заключает в апострофы как литерал или, если аргумент NULL, возвращает NULL. Апострофы и обратные слэши, уже содержащиеся в значении, дублируются.

quote_nullable(42.5) → '42.5'

regexp_match ( строка text, шаблон text [, флаги text ] ) → text[]

Возвращает фиксированные подстроки, полученные из первого вхождения регулярного выражения POSIX в строке; см. подраздел Регулярные выражения POSIX.

regexp_match('foobarbequebaz', '(bar)(beque)') → {bar,beque}

regexp_matches ( строка text, шаблон text [, флаги text ] ) → setof text[]

Возвращает фиксированные подстроки, полученные из первого вхождения регулярного выражения POSIX в строке или из нескольких вхождений, если используется флаг g; см. подраздел Регулярные выражения POSIX.


    regexp_matches('foobarbequebaz', 'ba.', 'g') →
         {bar}
         {baz}

regexp_replace ( строка text, шаблон text, замена text [, флаги text ] ) → text

Заменяет подстроки, полученные из первого вхождения регулярного выражения POSIX в строке или из нескольких вхождений подстроки, если используется флаг g; см. подраздел Регулярные выражения POSIX.

regexp_replace('Thomas', '.[mN]a.', 'M') → ThM

regexp_split_to_array ( строка text, шаблон text [, флаги text ] ) → text[]

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

regexp_split_to_array('hello world', '\s+') → {hello,world}

regexp_split_to_table ( строка text, шаблон text [, флаги text ] ) → setof text

Разделяет строку, используя в качестве разделителя регулярное выражение POSIX и выдавая набор результатов; см. подраздел Регулярные выражения POSIX.


    regexp_split_to_table('hello world', '\s+') →
         hello
         world

repeat ( строка text, число integer ) → text

Повторяет строку заданное число раз.

repeat('Pg', 4) → PgPgPgPg

replace ( строка text, цель text, замена text ) → text

Заменяет все вхождения в строку подстроки цель подстрокой замена.

replace('abcdefabcdef', 'cd', 'XX') → abXXefabXXef

reverse ( text ) → text

Переставляет символы в строке в обратном порядке.

reverse('abcde') → edcba

right ( строка text, n integer ) → text

Возвращает последние n символов в строке или, когда n — отрицательное число, возвращает все символы, кроме первых |n| символов.

right('abcde', 2) → de

rpad ( строка text, длина integer [, наполнитель text ] ) → text

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

rpad('hi', 5, 'xy') → hixyx

rtrim ( строка text [, символы text ] ) → text

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

rtrim('testxxzx', 'xyz') → test

split_part ( строка text, разделитель text, n integer ) → text

Разделяет строку по разделителю и возвращает n-ое поле (считая с первого) или, когда n — отрицательное число, возвращает |n|-ое поле с конца.

split_part('abc~@~def~@~ghi', '~@~', 2) → def

split_part('abc,def,ghi,jkl', ',', -2) → ghi

strpos ( строка text, подстрока text ) → integer

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

strpos('high', 'ig') → 2

substr ( строка text, начало integer [, число integer ] ) → text

Извлекает из строки подстроку, начиная с символа на позиции начало и длиной в число символов, если это значение указано. (То же, что и функция substring(строка from начало for число).)

substr('alphabet', 3) → phabet

substr('alphabet', 3, 2) → ph

starts_with ( строка text, префикс text ) → boolean

Возвращает true, если строка начинается с префикса.

starts_with('alphabet', 'alph') → t

string_to_array ( строка text, разделитель text [, нулевая_строка text ] ) → text[]

Разделяет строку по разделителю и формирует из результирующих полей текстовый массив. Если в разделителе передается NULL, каждый символ в строке станет отдельным элементом массива. Если в разделителе передается пустая строка, то вся строка рассматривается как одно поле. Если задана нулевая_строка и она отлична от NULL, то поля, соответствующие этой строке, заменяются значениями NULL.

string_to_array('xx~yy~zz', '~', 'yy') → {xx,NULL,zz}

string_to_table ( строка text, разделитель text [, нулевая_строка text ] ) → setof text

Разделяет строку по разделителю и возвращает результирующие поля в виде набора текстовых строк. Если в разделителе передается NULL, каждый символ в строке станет отдельной строкой результата. Если в разделителе передается пустая строка, то вся строка рассматривается как одно поле. Если задана нулевая_строка и она отлична от NULL, то поля, соответствующие этой строке, заменяются значениями NULL.


    string_to_table('xx~^~yy~^~zz', '~^~', 'yy') →
         xx
         NULL
         zz

to_ascii ( строка text ) → text

to_ascii ( строка text, кодировка name ) → text

to_ascii ( строка text, кодировка integer ) → text

Преобразует строку в ASCII из другой кодировки, которая может задаваться по имени или по номеру. Если кодировка опущена, подразумевается кодировка базы данных (что на практике является единственным полезным вариантом). В основном преобразование сводится к отбрасыванию диакритических знаков. Преобразование поддерживается только для кодировок LATIN1, LATIN2, LATIN9 и WIN1250. (Другое, более гибкое, решение реализовано в модуле unaccent.)

to_ascii('Karél') → Karel

to_hex ( integer ) → text

to_hex ( bigint ) → text

Преобразует число в равнозначное ему шестнадцатеричное представление.

to_hex(2147483647) → 7fffffff

translate ( строка text, цель text, замена text ) → text

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

translate('12345', '143', 'ax') → a2x5

unistr ( text ) → text

Определяет управляющие символы Unicode в аргументе. Символы Unicode можно задать в виде \XXXX (4 шестнадцатеричные цифры), \+XXXXXX (6 шестнадцатеричных цифр), \uXXXX (4 шестнадцатеричные цифры) или \UXXXXXXXX (8 шестнадцатеричных цифр). Чтобы указать обратный слэш, напишите два обратных слэша. Все остальные символы берутся буквально.
Если кодировка сервера не UTF-8, символ с кодом Unicode, заданный одной из этих управляющих последовательностей, преобразуется в фактическую кодировку сервера; если это невозможно, выдается ошибка.
Эта функция предоставляет (нестандартную) альтернативу строковым константам с управляющими последовательностями Unicode (см. подраздел Строковые константы с экранированием Unicode).

unistr('d\0061t\+000061') → data

unistr('d\u0061t\U00000061') → data

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

Также обратите внимание на агрегатную функцию string_agg в разделе Агрегатные функции и функции для преобразования текста в bytea и наоборот в Таблице 13.

format

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

format(стр_формата text [, форматир_аргумент "any" [, ...] ])

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

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

%[позиция][флаги][ширина]тип

где полями компонентов являются:

позиция (необязательный)
Строка вида n$, где n — индекс выводимого аргумента. Индекс, равный 1, означает первый аргумент после стр_формата. Если поле позиция опущено, по умолчанию используется следующий аргумент в последовательности.

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

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

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

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

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

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

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

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

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

SELECT format('Hello% s', 'World');
Результат: Hello World

SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three');
Результат: Testing one, two, three, %

SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
Результат: INSERT INTO "Foo bar" VALUES('O''Reilly')

SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files');
Результат: INSERT INTO locations VALUES('C:\Program Files')

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

SELECT format('|%10s|', 'foo');
Результат: |       foo|

SELECT format('|%-10s|', 'foo');
Результат: |foo       |

SELECT format('|%*s|', 10, 'foo');
Результат: |       foo|

SELECT format('|%*s|', -10, 'foo');
Результат: |foo       |

SELECT format('|%-*s|', 10, 'foo');
Результат: |foo       |

SELECT format('|%-*s|', -10, 'foo');
Результат: |foo       |

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

SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three');
Результат: Testing three, two, one

SELECT format('|%*2$s|', 'foo', 10, 'bar');
Результат: |       bar|

SELECT format('|%1$*2$s|', 'foo', 10, 'bar');
Результат: |       foo|

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

SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
Результат: Testing three, two, three

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

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

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

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

Таблица 11. Функции и операторы SQL для двоичных строк

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

Описание

Пример(ы)

bytea || bytea → bytea

Конкатенирует две двоичные строки.

'\x123456'::bytea || '\x789a00bcde'::bytea → \x123456789a00bcde

bit_length ( bytea ) → integer

Возвращает количество битов в двоичной строке (это число в 8 раз больше octet_length).

bit_length('\x123456'::bytea) → 24

octet_length ( bytea ) → integer

Возвращает количество байтов в двоичной строке.

octet_length('\x123456'::bytea) → 3

overlay ( двоичная_строка bytea PLACING новая_подстрока bytea FROM начало integer [ FOR число integer ] ) → bytea

Заменяет подстроку в двоичной_строке, начиная с байта на позиции начало и длиной в число байтов, на новую_подстроку. Если число опущено, по умолчанию количество заменяемых байтов определяется длиной новой_подстроки.

overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) → \x12020390

position ( подстрока bytea IN двоичная_строка bytea ) → integer

Возвращает начальную позицию первого вхождения заданной подстроки в двоичной_строке или ноль, если такого вхождения нет.

position('\x5678'::bytea in '\x1234567890'::bytea) → 3

substring ( двоичная_строка bytea [ FROM начало integer ] [ FOR число integer ] ) → bytea

Извлекает из двоичной_строки подстроку, начиная с байта на позиции начало (если таковая указана) и останавливаясь после заданного числа байтов, если оно указано. Должен присутствовать хотя бы один из параметров: начало или число.

substring('\x1234567890'::bytea from 3 for 2) → \x5678

trim ( [ LEADING | TRAILING | BOTH ] удаляемые_байты bytea FROM двоичная_строка bytea ) → bytea

Удаляет самую длинную подстроку, содержащую только байты, заданные в аргументе удаляемые_байты, с начала, конца или обеих сторон (по умолчанию подразумевается последнее — BOTH) двоичной_строки.

trim('\x9012'::bytea from '\x1234567890'::bytea) → \x345678

trim ( [ LEADING | TRAILING | BOTH ] [ FROM ] двоичная_строка bytea, удаляемые_байты bytea ) → bytea

Это нестандартный синтаксис функции trim().

trim(both from '\x1234567890'::bytea, '\x9012'::bytea) → \x345678

В QHB доступны также дополнительные функции для обработки двоичных строк, перечисленные в Таблице 12. Некоторые из них используются для внутренней реализации стандартных строковых функций SQL, перечисленных в Таблице 11.

Таблица 12. Другие функции для двоичных строк

Функция

Описание

Пример(ы)

bit_count ( двоичная_строка bytea ) → bigint

Возвращает количество установленных битов (единиц) в двоичной строке (эта операция также известна как «popcount»).

bit_count('\x1234567890'::bytea) → 15

btrim ( двоичная_строка bytea, удаляемые_байты bytea ) → bytea

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

btrim('\x1234567890'::bytea, '\x9012'::bytea) → \x345678

get_bit ( двоичная_строка bytea, n bigint ) → integer

Извлекает n бит из двоичной строки.

get_bit('\x1234567890'::bytea, 30) → 1

get_byte ( двоичная_строка bytea, n integer ) → integer

Извлекает n байт из двоичной строки.

get_byte('\x1234567890'::bytea, 4) → 144

length ( bytea ) → integer

Возвращает количество байтов в двоичной строке.

length('\x1234567890'::bytea) → 5

length ( двоичная_строка bytea, кодировка name ) → integer

Возвращает количество символов в двоичной строке, предполагая, что она содержит текст в заданной кодировке.

length('jose'::bytea, 'UTF8') → 4

ltrim ( двоичная_строка bytea, удаляемые_байты bytea ) → bytea

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

ltrim('\x1234567890'::bytea, '\x9012'::bytea) → \x34567890

md5 ( bytea ) → text

Вычисляет MD5-хэш двоичной строки с результатом в шестнадцатеричном виде.

md5('Th\000omas'::bytea) → 8ab2d3c9689aaf18​b4958c334c82d8b1

rtrim ( двоичная_строка bytea, удаляемые_байты bytea ) → bytea

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

rtrim('\x1234567890'::bytea, '\x9012'::bytea) → \x12345678

set_bit ( двоичная_строка bytea, n bigint, новое_значение integer ) → bytea

Задает для n-го бита в двоичной строке новое_значение.

set_bit('\x1234567890'::bytea, 30, 0) → \x1234563890

set_byte ( двоичная_строка bytea, n integer, новое_значение integer ) → bytea

Задает для n-го байта в двоичной строке новое_значение.

set_byte('\x1234567890'::bytea, 4, 64) → \x1234567840

sha224 ( bytea ) → bytea

Вычисляет хэш SHA-224 для двоичной строки.

sha224('abc'::bytea) → \x23097d223405d8228642a477bda2​55b32aadbce4bda0b3f7e36c9da7

sha256 ( bytea ) → bytea

Вычисляет хэш SHA-256 для двоичной строки.

sha256('abc'::bytea) → \xba7816bf8f01cfea414140de5dae2223​b00361a396177a9cb410ff61f20015ad

sha384 ( bytea ) → bytea

Вычисляет хэш SHA-384 для двоичной строки.

sha384('abc'::bytea) → \xcb00753f45a35e8bb5a03d699ac65007​272c32ab0eded1631a8b605a43ff5bed​8086072ba1e7cc2358baeca134c825a7

sha512 ( bytea ) → bytea

Вычисляет хэш SHA-512 для двоичной строки.

sha512('abc'::bytea) → \xddaf35a193617abacc417349ae204131​12e6fa4e89a97ea20a9eeee64b55d39a​2192992a274fc1a836ba3c23a3feebbd​454d4423643ce80e2a9ac94fa54ca49f

substr ( двоичная_строка bytea, начало integer [, число integer ] ) → bytea

Извлекает из двоичной_строки подстроку, начиная с байта на позиции начало, длиной в число байт, если оно указано. (То же, что и функция substring(двоичная_строка from начало for число).)

substr('\x1234567890'::bytea, 3, 2) → \x5678

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

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

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

Таблица 13. Функции для преобразования текстовых/двоичных строк

Функция

Описание

Пример(ы)

convert ( двоичная_строка bytea, исходная_кодировка name, целевая_кодировка name ) → bytea

Преобразует двоичную строку, представляющую текст в кодировке исходная_кодировка, в двоичную строку в кодировке целевая_кодировка (допустимые преобразования см. в подразделе Доступные перекодировки).

convert('text_in_utf8', 'UTF8', 'LATIN1') → \x746578745f696e5f75746638

convert_from ( двоичная_строка bytea, исходная_кодировка name ) → text

Преобразует двоичную строку, представляющую текст в кодировке исходная_кодировка, в текст в кодировке базы данных (допустимые преобразования см. в подразделе Доступные перекодировки).

convert_from('text_in_utf8', 'UTF8') → text_in_utf8

convert_to ( строка text, целевая_кодировка name ) → bytea

Преобразует строку типа text (в кодировке базы данных) в двоичную строку в кодировке целевая_кодировка (допустимые преобразования см. в подразделе Доступные перекодировки).

convert_to('some_text', 'UTF8') → \x736f6d655f74657874

encode ( двоичная_строка bytea, формат text ) → text

Кодирует двоичные данные в текстовое представление; поддерживаются следующие значения формата: base64, escape, hex.

encode('123\000\001', 'base64') → MTIzAAE=

decode ( строка text, формат text ) → bytea

Декодирует двоичные данные из текстового представления; поддерживаются те же значения формата, что и для функции encode.

decode('MTIzAAE=', 'base64') → \x3132330001

Функции encode и decode поддерживают следующие текстовые форматы:

base64
Формат base64 описан в RFC 2045, разделе 6.8. Согласно этому RFC, закодированные строки разбиваются по 76 символов. Однако вместо маркеров CRLF (как положено по стандарту MIME) строки завершаются только символом новой строки. Функция decode игнорирует символы возврата каретки, новой строки, пробелы и табуляции. В иных случаях если на вход decode поступают некорректные данные base64, возникает ошибка — в том числе, когда некорректно завершающее заполнение.

escape
Формат escape преобразует нулевые байты и байты с установленным старшим битом в восьмеричные экранированные последовательности (\nnn), а обратные слэши дублируются. Другие байтовые значения представляются в буквальном виде. Если за обратным слэшем не следует еще один обратный слэш или три восьмеричных цифры, функция decode выдаст ошибку; другие байтовые значения она принимает без изменений

hex
Формат hex представляет каждые 4 бита данных в виде одной шестнадцатеричной цифры, от 0 до f, первой записывая старший бит каждого байта. Функция encode выводит шестнадцатеричные цифры a-f в нижнем регистре. Поскольку наименьшая единица данных — 8 битов, функция encode всегда возвращает четное количество символов. Функция decode принимает символы a-f либо в верхнем, либо в нижнем регистре. Если на вход decode поступают некорректные шестнадцатеричные данные, возникает ошибка — в том числе, когда вводится нечетное количество символов.

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

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

В этом разделе описываются функции и операторы для проверки и обработки битовых строк, то есть значений типов bit и bit varying. (Хотя в этих таблицах упоминается только тип bit, вместо них можно использовать значения типа bit varying) Битовые строки поддерживают обычные операторы сравнения, показанные в Таблице 1, а также операторы, перечисленные в Таблице 14.

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

Оператор

Описание

Пример(ы)

bit || bit → bit

Конкатенация

B'10001' || B'011' → 10001011

bit & bit → bit

Побитовое И (операнды должны быть одинаковой длины)

B'10001' & B'01101' → 00001

bit | bit → bit

Побитовое ИЛИ (операнды должны быть одинаковой длины)

B'10001' | B'01101' → 11101

bit # bit → bit

Побитовое исключающее ИЛИ (операнды должны быть одинаковой длины)

B'10001' # B'01101' → 11100

~ bit → bit

Побитовое НЕ

~ B'10001' → 01110

bit << integer → bit

Битовый сдвиг влево (с сохранением длины строки)

B'10001' << 3 → 01000

bit >> integer → bit

Битовый сдвиг вправо (с сохранением длины строки)

B'10001' >> 2 → 00100

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

Таблица 15. Функции для битовых строк

Функция

Описание

Пример(ы)

bit_count ( bit ) → bigint

Возвращает количество установленных битов (единиц) в битовой строке (эта операция также известна как «popcount»).

bit_count(B'10111') → 4

bit_length ( bit ) → integer

Возвращает количество битов в битовой строке.

bit_length(B'10111') → 5

length ( bit ) → integer

Возвращает количество битов в битовой строке.

length(B'10111') → 5

octet_length ( bit ) → integer

Возвращает количество байтов в битовой строке.

octet_length(B'1011111011') → 2

overlay ( битовая_строка bit PLACING новая_подстрока bit FROM начало integer [ FOR число integer ] ) → bit

Заменяет подстроку в битовой\_строке, начиная с бита на позиции начало, длиной в число битов, на новую_подстроку. Если число опущено, по умолчанию количество заменяемых битов определяется длиной новой_подстроки.

overlay(B'01010101010101010' placing B'11111' from 2 for 3) → 0111110101010101010

position ( подстрока bit IN битовая_строка bit ) → integer

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

position(B'010' in B'000001101011') → 8

substring ( битовая_строка bit [ FROM начало integer ] [ FOR число integer ] ) → bit

Извлекает из битовой_строки подстроку, начиная с бита на позиции начало, если таковая указана, и заканчивая после заданного числа битов, если оно указано. Должен присутствовать хотя бы один из параметров: начало или число.

substring(B'110010111111' from 3 for 2) → 00

get_bit ( битовая_строка bit, n integer ) → integer

Извлекает из битовой строки n-й бит; первый (самый левый) бит имеет номер 0.

get_bit(B'101010101010101010', 6) → 1

set_bit ( битовая_строка bit, n integer, новое_значение integer ) → bit

Устанавливает для n-го бита в битовой строке новое_значение; первый (самый левый) бит имеет номер 0.

set_bit(B'101010101010101010', 6, 0) → 101010001010101010

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

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

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

Сопоставление с шаблоном

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

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

ВНИМАНИЕ!
Хотя по большей части поиск по регулярным выражениям может выполняться очень быстро, есть вероятность создания регулярных выражений, обработка которых занимает некоторое количество времени и памяти. Остерегайтесь шаблонов поиска по регулярным выражениям, поступающих из неблагоприятных источников. Если вам приходится это делать, рекомендуется установить тайм-аут для операторов.

Поиск с использованием шаблонов SIMILAR TO сопряжен с теми же угрозами безопасности, поскольку SIMILAR TO во многом предоставляет те же возможности, что и регулярные выражения в стиле POSIX.

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

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

LIKE

строка LIKE шаблон [ESCAPE управляющий_символ]
строка NOT LIKE шаблон [ESCAPE управляющий_символ]

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

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

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

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

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

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

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

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

Согласно стандарту SQL, отсутствие указания ESCAPE означает, что управляющий символ не определен (а не становится по умолчанию обратным слэшем), а пустое значение в ESCAPE не допускается. Таким образом, в этом отношении поведение QHB значительно отличается от стандартного.

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

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

Фразы LIKE, ILIKE, NOT LIKE и NOT ILIKE в синтаксисе QHB обычно обрабатываются как операторы; например, их можно использовать в конструкциях выражение оператор ANY (подзапрос), хотя предложение ESCAPE сюда включить нельзя. В некоторых сложных случаях может понадобиться использовать вместо них имена нижележащих операторов.

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

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

строка SIMILAR TO шаблон [ESCAPE управляющий_символ]
строка NOT SIMILAR TO шаблон [ESCAPE управляющий_символ]

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

Как и 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 ''.

Согласно стандарту SQL, отсутствие указания ESCAPE означает, что управляющий символ не определен (а не становится по умолчанию обратным слэшем), а пустое значение в ESCAPE не допускается. Таким образом, в этом отношении поведение QHB значительно отличается от стандартного.

Еще одно нестандартное расширение заключается в том, что следующая за управляющим символом буква или цифра открывает доступ к управляющим последовательностям, определенным для регулярных выражений POSIX; см. Таблицу 20, Таблицу 21 и Таблицу 22 ниже.

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

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

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

substring(строка similar шаблон escape управляющий_символ)

или используя синтаксис ныне устаревшего SQL:1999:

substring(строка from шаблон for управляющий_символ)

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

substring(строка, шаблон, управляющий_символ)

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

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

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

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

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

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

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

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

Оператор

Описание

Пример(ы)

text ~ text → boolean

Строка соответствует регулярному выражению, с учетом регистра

'thomas' ~ 't.*ma' → t

text ~* text → boolean

Строка соответствует регулярному выражению, без учета регистра

'thomas' ~* 'T.*ma' → t

text !~ text → boolean

Строка не соответствует регулярному выражению, с учетом регистра

'thomas' !~ 't.*max' → t

text !~* text → boolean

Строка не соответствует регулярному выражению, без учета регистра

'thomas' !~* 'T.*ma' → f

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

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

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

'abcd' ~ 'bc'     true
'abcd' ~ 'a.c'    true — точка соответствует любому символу
'abcd' ~ 'a.*d'   true — * повторяет предыдущий элемент шаблона
'abcd' ~ '(b|x)'  true — | означает ИЛИ для группы в скобках
'abcd' ~ '^a'     true — ^ привязывает шаблон к началу строки
'abcd' ~ '^(b|c)' false — совпадение не найдено по причине привязки

Более подробно язык шаблонов POSIX описан ниже.

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

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

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

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

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

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(строка, шаблон [, флаги ]). Если совпадений нет, результатом будет NULL. Если совпадение найдено и шаблон не содержит подвыражений в скобках, то результатом будет текстовый массив из одного элемента, содержащий подстроку, соответствующую всему шаблону. Если совпадение найдено и шаблон содержит подвыражения в скобках, то результатом будет текстовый массив, чей n-й элемент является подстрокой, соответствующей n-му подвыражению в скобках шаблона (не считая «не захватывающих» скобок; подробности см. ниже). Параметр флаги представляет собой необязательную текстовую строку, содержащую ноль или более однобуквенных флагов, изменяющих поведение функции. Поддерживаемые флаги описаны в Таблице 24.

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

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. Каждая возвращаемая строка является текстовым массивом, содержащим всю сопоставляемую подстроку или подстроки, соответствующие подвыражениям в скобках шаблона, как описано выше для regexp_match. Функция regexp_matches принимает все флаги, перечисленные в Таблице 24, плюс флаг 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(строка, шаблон [, флаги ]). Если нет совпадения с шаблоном, функция возвращает строку. Если найдено хотя бы одно совпадение, для каждого его вхождения она возвращает текст от конца предыдущего вхождения (или начала строки) до начала этого вхождения. Дойдя до последнего вхождения, она возвращает текст от конца этого последнего вхождения до конца строки. Параметр флаги представляет собой необязательную текстовую строку, содержащую ноль или более однобуквенных флагов, изменяющих поведение функции. regexp_split_to_table поддерживает флаги, описанные в Таблице 24.

Функция regexp_split_to_array ведет себя так же, как regexp_split_to_table, за исключением того, что regexp_split_to_array возвращает свой результат в виде массива элементов типа text. Она имеет синтаксис regexp_split_to_array(строка, шаблон [, флаги ]). Параметры те же, что и для 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_match и regexp_matches, но обычно на практике является наиболее удобным поведением. Аналогичные определения используют и другие программные системы, например Perl.

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

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

Регулярные выражения (Regular expression, 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.

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

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

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

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

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

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

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

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

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

КвантификаторСовпадения
*последовательность из 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) соответствуют тем же возможностям, что и их соответствующие нормальные (жадные) аналоги, но предпочитают наименьшее, а не наибольшее количество совпадений. Более подробную информацию см. в подразделе Правила сопоставления регулярных выражений.

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

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

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

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

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

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

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

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

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

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

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

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

Управляющие символы в регулярных выражениях

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

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

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

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

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

Таблица 20. Особые обозначения символов в регулярных выражениях

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

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

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

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

Таблица 21. Коды классов в регулярных выражениях

Управляющий символОписание
\dсоответствует любой цифре; равнозначно [[:digit:]]
\sсоответствует любому пробельному символу; равнозначно [[:space:]]
\wсоответствует любому словообразующему символу; равнозначно [[:word:]]
\Dсоответствует любому нецифровому символу; равнозначно [^[:digit:]]
\Sсоответствует любому непробельному символу; равнозначно [^[:space:]]
\Wсоответствует любому несловообразующему символу; равнозначно [^[:word:]]

Коды классов также работают в выражениях в квадратных скобках, хотя показанные выше определения не вполне синтаксически допустимы в этом контексте. Например, выражение [a-c\d] равнозначно [a-c[:digit:]].

Таблица 22. Символы ограничений в регулярных выражениях

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

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

Таблица 23. Обратные ссылки в регулярных выражениях

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

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

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

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

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

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

Таблица 24. Буквы встроенных параметров 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. Из этого основного правила есть три исключения:

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

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

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

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

Наконец, в 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. Атрибуты, назначенные подвыражениям, влияют только на то, сколько из этого вхождения им разрешено «съесть» относительно друг друга.

Чтобы задать атрибут жадности или нежадности для подвыражения или целого RE, можно использовать квантификаторы {1,1} и {1,1}? соответственно. Это полезно, когда требуется, чтобы весь 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 продолжают соответствовать только началу или концу строки. Кроме того, коды классов символов \D и \W будут соответствовать переводу строки независимо от этого режима. (В старых версиях QHB они не соответствовали переводу строки в режиме с учетом перевода строк. Для включения старого поведения напишите [^[:digit:]] или [^[:word:]].)

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

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

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

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

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

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

Базовые регулярные выражения

BRE отличаются от ERE в нескольких отношениях. В BRE |, + и ? являются обычными символами, и их функциональность не имеет аналогов. Разделителями для границ являются \{ и \}, причем сами по себе { и } — обычные символы. Скобками для вложенных подвыражений являются \( и \), а сами по себе ( и ) — обычные символы. ^ — обычный символ, если не стоит в начале RE или в начале подвыражения в скобках, $ — обычный символ, если не стоит в конце RE или в конце подвыражения в скобках, а * — обычный символ, если находится в начале RE или в начале подвыражения в скобках (возможно, после начального ^). Наконец, в BRE доступны обратные ссылки с одной цифрой, а \< и \> являются синонимами для [[:<:]] и [[:>:]] соответственно; в 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 (см. Таблицу 21), интерпретируются в соответствии с преобладающей локалью (которой можно управлять, добавляя предложение COLLATE к оператору или функции). В XQuery эти классы определяются с помощью ссылок на свойства символов Unicode, поэтому равнозначное поведение возможно только с локалью, подчиняющейся правилам Unicode.

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

  • Из особых обозначений символов, описанных в Таблице 20, XQuery поддерживает только \n, \r и \t.

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

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

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

  • Буквы флагов регулярного выражения, определенные в XQuery, имеют нечто общее с буквами параметров для POSIX (Таблица 24), но отличаются них. Только параметры i и q одинаковы, остальные ведут себя совершенно по-другому:

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

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

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

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

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

Функция

Описание

Пример(ы)

to_char ( timestamp, text ) → text

to_char ( timestamp with time zone, text ) → text

Преобразует метку времени в строку согласно заданному формату.

to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS') → 05:31:12

to_char ( interval, text ) → text

Преобразует интервал в строку согласно заданному формату.

to_char(interval '15h 2m 12s', 'HH24:MI:SS') → 15:02:12

to_char ( числовой_тип, text ) → text

Преобразует число в строку согласно заданному формату; доступно для типов integer, bigint, numeric, real, double precision.

to_char(125, '999') → 125

to_char(125.8::real, '999D9') → 125.8

to_char(-125.8, '999D99S') → 125.80-

to_date ( text, text ) → date

Преобразует строку в дату согласно заданному формату.

to_date('05 Dec 2000', 'DD Mon YYYY') → 2000-12-05

to_number ( text, text ) → numeric

Преобразует строку в число согласно заданному формату.

to_number('12,454.8-', '99G999D9S') → -12454.8

to_timestamp ( text, text ) → timestamp with time zone

Преобразует строку в метку времени согласно заданному формату. (См. также to_timestamp(double precision) в Таблице 32.)

to_timestamp('05 Dec 2000', 'DD Mon YYYY') → 2000-12-05 00:00:00-05

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

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

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

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

КодОписание
HHчас дня (01-12)
HH12час дня (01-12)
HH24час дня (00-23)
MIминута (00-59)
SSсекунда (00-59)
MSмиллисекунда (000-999)
USмикросекунда (000000-999999)
FF1десятая доля секунды (0-9)
FF2сотая доля секунды (00-99)
FF3миллисекунда (000-999)
FF4десятая доля миллисекунды (0000-9999)
FF5сотая доля миллисекунды (00000-99999)
FF6микросекунда (000000-999999)
SSSS, SSSSSсекунды после полуночи (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)
IDномер дня недели по ISO 8601, с понедельника (1) по воскресенье (7)
Wномер недели в месяце (1-5) (первая неделя начинается в первый день месяца)
WWномер недели в году (1-53) (первая неделя начинается в первый день года)
IWномер недели в недельном году по ISO 8601 (01-53; первый четверг года относится к неделе 1)
CCвек (2 цифры) (двадцать первый век начинается с 2001-01-01)
Jюлианская дата (целое число дней с 24 ноября 4714 г. до н.э. в полночь по местному времени; см. раздел Юлианские даты)
Qквартал
RMмесяц в верхнем регистре римскими цифрами (I-XII; I=январь)
rmмесяц в нижнем регистре римскими цифрами (i-xii; i=январь)
TZсокращенное наименование часового пояса в верхнем регистре (поддерживается только в to_char)
tzсокращенное наименование часового пояса в нижнем регистре (поддерживается только в to_char)
TZHчасы часового пояса
TZMминуты часового пояса
OFсмещение часового пояса от UTC (поддерживается только в to_char)

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

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

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

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

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

  • TM подавляет конечные пробелы независимо от указания FM.

  • Функции to_timestamp и to_date игнорируют регистр букв во входных данных; поэтому, например, для кодов MON, Mon и mon подойдут одни и те же строки. При использовании модификатора 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') полю TZH соответствует -10, но в to_timestamp('2000 -10', 'YYYY TZH') полю TZH соответствует 10.

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

    Совет
    Чтобы пропустить во входной строке произвольный текст, можно использовать в шаблоне буквы. Например, шаблоны to_timestamp('2000y6m1d', 'yyyytMMtDDt') и to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') пропускают буквы y, m и d.

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

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

  • В функциях to_timestamp and to_date отрицательные значения годов обрабатываются как обозначающие годы до н. э. Если одновременно написать отрицательный год и явно указать код BC (индикатор годов до н. э.), год будет относиться к н. э. Введение нулевого года воспринимается как 1 год до н. э.

  • В функциях to_timestamp и to_date преобразование YYYY имеет ограничение, когда обрабатывается год, состоящий из более чем 4 цифр. Следует написать после YYYY какой-либо нецифровой символ или подходящий код, иначе год всегда будет интерпретироваться как 4 цифры. Например, to_date('200001131', 'YYYYMMDD') (с годом 20000) будет интерпретироваться как год с 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 понятие «месяц» или «день месяца» не имеет смысла. В контексте григорианского года не имеет смысла неделя по ISO.

    Внимание!
    В то время как 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 выводит значение часа полностью, так что в значении interval результат может быть выше 23.

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

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

КодОписание
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() не предусмотрено явного положения для знака, то для него будет зарезервирован один столбец, и этот знак будет привязан к числу (будет находиться слева от него). Если слева от некоторых 9 находится S, знак тоже будет привязан к числу.

  • Знак, отформатированный с помощью кодов 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. В функции to_number код V аналогичным образом делит значения. Функции to_char и to_number не поддерживают использование V в сочетании с десятичной точкой (например, 99.9V99 не допускается).

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

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

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

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

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

Таблица 30. Примеры 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'

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

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

Кроме того, для типов даты/времени доступны обычные операторы сравнения, перечисленные в Таблице 1. Даты и метки времени (с часовым поясом или без него) можно сравнивать как угодно, тогда как время (с часовым поясом или без него) и интервалы можно сравнивать только со значениями того же типа. При сравнении метки времени без часового пояса и метки времени с часовым поясом предполагается, что первое значение задано в часовом поясе, установленном параметром конфигурации TimeZone, и оно меняется на UTC для сравнения со вторым значением (которое внутри уже представлено в UTC). Аналогично при сравнении даты с меткой времени предполагается, что значение даты представляет полночь в часовом поясе TimeZone.

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

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

Оператор

Описание

Пример(ы)

date + integer → date

Добавляет к дате указанное число дней

date '2001-09-28' + 7 → 2001-10-05

date + interval → timestamp

Добавляет к дате интервал

date '2001-09-28' + interval '1 hour' → 2001-09-28 01:00:00

date + time → timestamp

Добавляет к дате время

date '2001-09-28' + time '03:00' → 2001-09-28 03:00:00

interval + interval → interval

Складывает интервалы

interval '1 day' + interval '1 hour' → 1 day 01:00:00

timestamp + interval → timestamp

Добавляет к временной метке интервал

timestamp '2001-09-28 01:00' + interval '23 hours' → 2001-09-29 00:00:00

time + interval → time

Добавляет к времени интервал

time '01:00' + interval '3 hours' → 04:00:00

- interval → interval

Инвертирует интервал

- interval '23 hours' → -23:00:00

date - date → integer

Вычитает из одной даты другую, выдавая число прошедших дней

date '2001-10-01' - date '2001-09-28' → 3

date - integer → date

Вычитает из даты указанное число дней

date '2001-10-01' - 7 → 2001-09-24

date - interval → timestamp

Вычитает из даты интервал

date '2001-09-28' - interval '1 hour' → 2001-09-27 23:00:00

time - time → interval

Вычитает из одного времени другое

time '05:00' - time '03:00' → 02:00:00

time - interval → time

Вычитает из времени интервал

time '05:00' - interval '2 hours' → 03:00:00

timestamp - interval → timestamp

Вычитает из временной метки интервал

timestamp '2001-09-28 23:00' - interval '23 hours' → 2001-09-28 00:00:00

interval - interval → interval

Вычитает из одного интервала другой

interval '1 day' - interval '1 hour' → 1 day -01:00:00

timestamp - timestamp → interval

Вычитает из одной временной метки другую (преобразуя 24-часовые интервалы в дни подобно justify_hours())

timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' → 63 days 15:00:00

interval * double precision → interval

Умножает интервал на скалярное значение

interval '1 second' * 900 → 00:15:00

interval '1 day' * 21 → 21 days

interval '1 hour' * 3.5 → 03:30:00

interval / double precision → interval

Делит интервал на скалярное значение

interval '1 hour' / 1.5 → 00:40:00

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

Функция

Описание

Пример(ы)

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') → 62 years 6 mons 10 days

clock_timestamp ( ) → timestamp with time zone

Текущая дата и время (меняется во время выполнения операторов); см. подраздел Текущая дата/время

clock_timestamp() → 2019-12-23 14:39:53.662522-05

current_date → date

Текущая дата; см. подраздел Текущая дата/время

current_date → 2019-12-23

current_time → time with time zone

Текущее время суток; см. подраздел Текущая дата/время

current_time → 14:39:53.662522-05

current_time ( integer ) → time with time zone

Текущее время суток, с ограниченной точностью; см. подраздел Текущая дата/время

current_time(2) → 14:39:53.66-05

current_timestamp → timestamp with time zone

Текущая дата и время (начало текущей транзакции); см. подраздел Текущая дата/время

current_timestamp → 2019-12-23 14:39:53.662522-05

current_timestamp ( integer ) → timestamp with time zone

Текущая дата и время (начало текущей транзакции), с ограниченной точностью; см. подраздел Текущая дата/время

current_timestamp(0) → 2019-12-23 14:39:53-05

date_bin ( interval, timestamp, timestamp ) → timestamp

Укладывает входное значение в заданный интервал, установленный с указанным начальным моментом; см. подраздел date_bin

date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') → 2001-02-16 20:35:00

date_part ( text, timestamp ) → double precision

Выдает подполе временной метки (равнозначно extract); см. подраздел EXTRACT, date_part

date_part('hour', timestamp '2001-02-16 20:38:40') → 20

date_part ( text, interval ) → double precision

Выдает подполе интервала (равнозначно extract); см. подраздел EXTRACT, date_part

date_part('month', interval '2 years 3 months') → 3

date_trunc ( text, timestamp ) → timestamp

Усекает временную метку до указанной точности; см. подраздел date_trunc

date_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_trunc

date_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_trunc

date_trunc('hour', interval '2 days 3 hours 40 minutes') → 2 days 03:00:00

extract ( поле from timestamp ) → numeric

Выдает подполе временной метки; см. подраздел EXTRACT, date_part

extract(hour from timestamp '2001-02-16 20:38:40') → 20

extract ( поле from interval ) → numeric

Выдает подполе интервала; см. подраздел EXTRACT, date_part

extract(month from interval '2 years 3 months') → 3

isfinite ( date ) → boolean

Проверяет дату на конечность (не +/- бесконечность)

isfinite(date '2001-02-16') → true

isfinite ( timestamp ) → boolean

Проверяет временную метку на конечность (не +/- бесконечность)

isfinite(timestamp 'infinity') → false

isfinite ( interval ) → boolean

Проверяет интервал на конечность (в настоящее время всегда true)

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

localtime → time

Текущее время суток; см. подраздел Текущая дата/время

localtime → 14:39:53.662522

localtime ( integer ) → time

Текущее время суток, с ограниченной точностью; см. подраздел Текущая дата/время

localtime(0) → 14:39:53

localtimestamp → timestamp

Текущая дата и время (начало текущей транзакции); см. подраздел Текущая дата/время

localtimestamp → 2019-12-23 14:39:53.662522

localtimestamp ( integer ) → timestamp

Текущая дата и время (начало текущей транзакции), с ограниченной точностью; см. подраздел Текущая дата/время

localtimestamp(2) → 2019-12-23 14:39:53.66

make_date ( год int, месяц int, день int ) → date

Создает дату из полей года, месяца и дня (отрицательное значение года означает год до н. э.)

make_date(2013, 7, 15) → 2013-07-15

make_interval ( [ годы int [, месяцы int [, недели int [, дни int [, часы int [, минуты int [, секунды double precision ]]]]]]] ) → interval

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

make_interval(days => 10) → 10 days

make_time ( час int, минута int, секунда double precision ) → time

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

make_time(8, 15, 23.5) → 08:15:23.5

make_timestamp ( год int, месяц int, день int, час int, минута int, секунда double precision ) → timestamp

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

make_timestamp(2013, 7, 15, 8, 15, 23.5) → 2013-07-15 08:15:23.5

make_timestamptz ( год int, месяц int, день int, час int, минута int, секунда double precision [, часовой_пояс text ] ) → timestamp with time zone

Создает метку времени с часовым поясом из полей года, месяца, недели, дня, часа, минуты и секунды (отрицательное значение года означает год до н. э.). Если часовой_пояс не указан, используется текущий часовой пояс; в примерах предполагается, что часовой пояс сеанса — Europe/London (Европа/Лондон)

make_timestamptz(2013, 7, 15, 8, 15, 23.5) → 2013-07-15 08:15:23.5+01

make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New\_York') → 2013-07-15 13:15:23.5+01

now ( ) → timestamp with time zone

Текущая дата и время (начало текущей транзакции); см. подраздел Текущая дата/время

now() → 2019-12-23 14:39:53.662522-05

statement_timestamp ( ) → timestamp with time zone

Текущая дата и время (начало текущего оператора); см. подраздел Текущая дата/время

statement_timestamp() → 2019-12-23 14:39:53.662522-05

timeofday ( ) → text

Текущая дата и время (как clock_timestamp, но в виде текстовой строки); см. подраздел Текущая дата/время

timeofday() → Mon Dec 23 14:39:53.662522 2019 EST

transaction_timestamp ( ) → timestamp with time zone

Текущая дата и время (начало текущей транзакции); см. подраздел Текущая дата/время

transaction_timestamp() → 2019-12-23 14:39:53.662522-05

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:

(начало1, конец1) OVERLAPS (начало2, конец2)
(начало1, длительность1) OVERLAPS (начало2, длительность2)

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

SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Результат: true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Результат: false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Результат: false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
       (DATE '2001-10-30', DATE '2001-10-31');
Результат: true

При добавлении к значению timestamp with time zone значения interval (или при вычитании из него значения interval) компонент дней увеличивает (или уменьшает) дату timestamp with time zone на указанное количество суток, а время суток не меняется. При пересечении границы летнего времени (когда часовой пояс сеанса распознает летнее время) это означает, что interval '1 day' не обязательно равен interval '24 hours'. Например, в часовом поясе America/Denver (Америка/Денвер):

SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day';
Результат: 2005-04-03 12:00:00-06
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
Результат: 2005-04-03 13:00:00-06

Это происходит потому, что вследствие произошедшего 2005-04-03 02:00:00 в часовом поясе America/Denver перехода на летнее время был пропущен час.

Обратите внимание на возможную неоднозначность в поле 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');
Результат: 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;
Результат: 121.958333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
Результат: 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
Результат: 4 mons

EXTRACT, date_part

EXTRACT(поле FROM источник)

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

century

Век

SELECT EXTRACT(CENTURY FROM TIMESTAMP ’2000-12-16 12:21:13’);
Результат: 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 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’);
Результат: 16
SELECT EXTRACT(DAY FROM INTERVAL ’40 days 1 minute’);
Результат: 40

decade

Поле года, разделенное на 10

SELECT EXTRACT(DECADE FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 200

dow

День недели с воскресенья (0) по субботу (6)

SELECT EXTRACT(DOW FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 5

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

doy

День года (1-365/366)

SELECT EXTRACT(DOY FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 47

epoch

Для значений 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’);
Результат: 982384720.12
SELECT EXTRACT(EPOCH FROM INTERVAL ’5 days 3 hours’);
Результат: 442800

Значение эпохи можно преобразовать обратно в timestamp with time zone с помощью функции to_timestamp:

SELECT to_timestamp(982384720.12);
Результат: 2001-02-17 04:38:40.12+00

Имейте в виду, что применение to_timestamp к времени эпохи, извлеченному из значения date или timestamp, может выдать искаженный результат: по сути этот результат будет получен, исходя из предположения, что оригинальное значение было задано в часовом поясе UTC, а это может быть не так.

hour

Поле часа (0-23)

SELECT EXTRACT(HOUR FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 20

isodow

День недели с понедельника (1) по воскресенье (7)

SELECT EXTRACT(ISODOW FROM TIMESTAMP ’2001-02-18 20:38:40’);
Результат: 7

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

isoyear

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

SELECT EXTRACT(ISOYEAR FROM DATE ’2006-01-01’);
Результат: 2005
SELECT EXTRACT(ISOYEAR FROM DATE ’2006-01-02’);
Результат: 2006

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

julian

Юлианская дата, соответствующая дате или метке времени (неприменимо к интервалам). Метки времени, отличающиеся от полуночи по местному времени, приведут к дробным результатам. Дополнительную информацию см. в разделе Юлианские даты.

SELECT EXTRACT(JULIAN FROM DATE '2006-01-01');
Результат: 2453737
SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00');
Результат: 2453737.50000000000000000000

microseconds

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

SELECT EXTRACT(MICROSECONDS FROM TIME ’17:12:28.5’);
Результат: 28500000

millennium

Тысячелетие

SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 3

Годы в 20 века относятся ко второму тысячелетию. Третье тысячелетие началось 1 января 2001 года.

milliseconds

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

SELECT EXTRACT(MILLISECONDS FROM TIME ’17:12:28.5’);
Результат: 28500

minute

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

SELECT EXTRACT(MINUTE FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 38

month

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

SELECT EXTRACT(MONTH FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 2
SELECT EXTRACT(MONTH FROM INTERVAL ’2 years 3 months’);
Результат: 3
SELECT EXTRACT(MONTH FROM INTERVAL ’2 years 13 months’);
Результат: 1

quarter

Квартал года (1-4), к которому относится дата

SELECT EXTRACT(QUARTER FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 1

second

Поле секунд, включая дробные части

SELECT EXTRACT(SECOND FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 40
SELECT EXTRACT(SECOND FROM TIME ’17:12:28.5’);
Результат: 28.5

timezone

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

timezone_hour

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

timezone_minute

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

week

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

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

SELECT EXTRACT(WEEK FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 7

year

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

SELECT EXTRACT(YEAR FROM TIMESTAMP ’2001-02-16 20:38:40’);
Результат: 2001

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

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

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

date_part('поле', источник)

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

SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Результат: 16

SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Результат: 4

date_trunc

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

date_trunc(поле, источник [, часовой_пояс ])

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

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

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

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

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

Примеры (предполагается, что местный часовой пояс — America/New_York (Америка/Нью-Йорк)):

SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Результат: 2001-02-16 20:00:00

SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Результат: 2001-01-01 00:00:00

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
Результат: 2001-02-16 00:00:00-05

SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
Результат: 2001-02-16 08:00:00-05

SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
Результат: 3 days 02:00:00

date_bin

Функция date_bin «укладывает» входную метку времени в заданный интервал (шаг), установленный с указанным начальным моментом.

date_bin(шаг, источник, начальный_момент)

Здесь источник — это выражение значения типа timestamp или timestamp with time zone. (Значения типа date автоматически приводятся к типу timestamp.) Под шагом подразумевается выражение значения типа interval. Возвращаемое значение, также имеющее тип timestamp или timestamp with time zone, отмечает начало позиции, в которую помещается источник.

Примеры:

SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01');
Результат: 2020-02-11 15:30:00

SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30');
Результат: 2020-02-11 15:32:30

В случае целых единиц измерения (1 минута, 1 час и т. д.), она дает тот же результат, что и аналогичный вызов функции date_trunc, но разница в том, что date_bin может усечь дату до произвольного интервала.

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

AT TIME ZONE

Оператор AT TIME ZONE преобразует метку времени без часового пояса в метку времени с часовым поясом и обратно, а значения типа time with time zone пересчитывает для разных часовых поясов. В Таблице 33 показаны его варианты.

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

Оператор

Описание

Пример(ы)

timestamp without time zone AT TIME ZONE часовой_пояс → timestamp with time zone

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

timestamp '2001-02-16 20:38:40' at time zone 'America/Denver' → 2001-02-17 03:38:40+00

timestamp with time zone AT TIME ZONE часовой_пояс → timestamp without time zone

Преобразует заданную метку времени с часовым поясом в метку времени без часового пояса, соответствующую времени в указанном часовом поясе.

timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver' → 2001-02-16 18:38:40

time with time zone AT TIME ZONE часовой_пояс → time with time zone

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

time with time zone '05:34:17-05' at time zone 'UTC' → 10:34:17+00

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

Примеры (предполагается, что текущее значение параметра TimeZoneAmerica/ Los_Angeles (Америка/Лос-Анджелес)):

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
Результат: 2001-02-16 19:38:40-08

SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
Результат: 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';
Результат: 2001-02-16 05:38:40

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

Функция timezone (часовой_пояс, метка_времени) равнозначна совместимой с SQL конструкции метка_времени AT TIME ZONE часовой_пояс.

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

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

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(точность)
CURRENT_TIMESTAMP(точность)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(точность)
LOCALTIMESTAMP(точность)

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

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

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

SELECT CURRENT_TIME;
Результат: 14:39:53.662522-05

SELECT CURRENT_DATE;
Результат: 2001-12-23

SELECT CURRENT_TIMESTAMP;
Результат: 2001-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
Результат: 2001-12-23 14:39:53.66-05

SELECT LOCALTIMESTAMP;
Результат: 2001-12-23 14:39:53.662522

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

Примечание
В других СУБД эти значения могут меняться чаще.

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

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, а не значения timestamp with time zone. Функция now() представляет собой традиционный для QHB эквивалент функции transaction_timestamp().

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

SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP ’now’; -- но см. совет ниже

Совет
Не используйте третью форму при указании значения, которое будет вычисляться позднее, например, в предложении DEFAULT для столбца таблицы. Система преобразует now в значение timestamp сразу после анализа константы, поэтому когда потребуется такое значение по умолчанию, будет использовано время создания таблицы! Первые две формы не будут вычисляться, пока не понадобится значение по умолчанию, так как они являются вызовами функций. Таким образом, они выдадут желаемое поведение к моменту добавления строки в таблицу. (См. также подраздел Специальные значения)

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

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

pg_sleep ( double precision )
pg_sleep_for ( interval )
pg_sleep_until ( timestamp with time zone )

Функция pg_sleep переводит процесс текущего сеанса в спящий режим вплоть до истечения указанного числа секунд (можно указать дробное число). Вспомогательная функция pg_sleep_for позволяет задать длительность спящего режима в виде значения типа interval. Вспомогательная функция 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 или ее вариантов убедитесь, что ваш сеанс не содержит больше блокировок, чем это необходимо. В противном случае другим сеансам, возможно, придется ждать завершения вашего спящего режима, замедляя работу всей системы.

Функции поддержки перечислений

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

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

Таблица 34. Функции поддержки перечислений

Функция

Описание

Пример(ы)

enum_first ( anyenum ) → anyenum

Возвращает первое значение входных данных перечислимого типа.

enum_first(null::rainbow) → red

enum_last ( anyenum ) → anyenum

Возвращает последнее значение входных данных перечислимого типа.

enum_last(null::rainbow) → purple

enum_range ( anyenum ) → anyarray

Возвращает все значения входных данных перечислимого типа в упорядоченном массиве.

enum_range(null::rainbow) → {red,orange,yellow,​green,blue,purple}

enum_range ( anyenum, anyenum ) → anyarray

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

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 с двумя аргументами, эти функции игнорируют конкретное переданное им значение; их интересует только его объявленный тип данных. Может быть передан либо NULL, либо конкретное значение этого типа, при этом результат будет одинаковым. Как правило, эти функции применяются к столбцу таблицы или аргументу функции, а не к жестко закодированному имени типа, как показано в примерах.

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

Для геометрических типов point (точка), box (прямоугольник), lseg (отрезок), line (прямая), path (путь), polygon (многоугольник) и circle (окружность) существует большой набор встроенных вспомогательных функций и операторов, приведенных в Таблице 35, Таблице 36 и Таблице 37.

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

Оператор

Описание

Пример(ы)

геометрический_тип + point → геометрический_тип

Добавляет координаты второго аргумента типа point к координатам каждой точки первого аргумента, тем самым осуществляя перенос объекта. Доступен для типов point, box, path, circle.

box '(1,1),(0,0)' + point '(2,0)' → (3,1),(2,0)

path + path → path

Конкатенирует два открытых пути (возвращает NULL, если один из путей замкнут).

path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' → [(0,0),(1,1),(2,2),(3,3),(4,4)]

геометрический_тип - point → геометрический_тип

Вычитает координаты второго аргумента типа point из координат каждой точки первого аргумента, тем самым осуществляя перенос объекта. Доступен для типов point, box, path, circle.

box '(1,1),(0,0)' - point '(2,0)' → (-1,1),(-2,0)

геометрический_тип * point → геометрический_тип

Умножает каждую точку первого аргумента на второй аргумент типа point (воспринимая точки как комплексные числа, представленные действительной и мнимой частями, и проводя стандартное комплексное умножение). Если интерпретировать второй аргумент типа point как вектор, это будет равнозначно увеличению размера этого объекта и расстояния от начала координат при помощи длины этого вектора с поворотом объекта против часовой стрелки относительно начала координат на угол, равный углу между вектором и осью x. Доступно для типов point, box,[a] path, circle.

path '((0,0),(1,0),(1,1))' * point '(3.0,0)' → ((0,0),(3,0),(3,3))

path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45)) → ((0,0),​(0.7071067811865475,0.7071067811865475),​(0,1.414213562373095))

геометрический_тип / point → геометрический_тип

Делит каждую точку первого аргумента на второй аргумент типа point (воспринимая точки как комплексные числа, представленные действительной и мнимой частями, и проводя стандартное комплексное деление). Если интерпретировать второй аргумент типа point как вектор, это будет равнозначно уменьшению размера этого объекта и расстояния от начала координат при помощи длины этого вектора с поворотом объекта по часовой стрелки относительно начала координат на угол, равный углу между вектором и осью x. Доступно для типов point, box,[a] path, circle.

path '((0,0),(1,0),(1,1))' / point '(2.0,0)' → ((0,0),(0.5,0),(0.5,0.5))

path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45)) → ((0,0),​(0.7071067811865476,-0.7071067811865476),​(1.4142135623730951,0))

@-@ геометрический_тип → double precision

Вычисляет общую длину. Доступен для типов lseg, path.

@-@ path '[(0,0),(1,0),(1,1)]' → 2

@@ геометрический_тип → point

Вычисляет центральную точку. Доступен для типов box, lseg, polygon, circle.

@@ box '(2,2),(0,0)' → (1,1)

box # box → box

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

box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' → (1,1),(-1,-1)

геометрический_тип ## геометрический_тип → point

Вычисляет ближайшую к первому объекту точку на втором объекте. Доступен для этих пар типов: (point, box), (point, lseg), (point, line), (lseg, box), (lseg, lseg), (line, lseg).

point '(0,0)' ## lseg '[(2,0),(0,2)]' → (1,1)

геометрический_тип <-> геометрический_тип → double precision

Вычисляет расстояние между объектами. Доступен для всех геометрических типов, кроме polygon, для всех сочетаний типа point с другим геометрическим типом, а также для этих пар типов: (box, lseg), (lseg, line), (polygon, circle) (и для этих пар в обратном порядке).

circle '<(0,0),1>' <-> circle '<(5,0),1>' → 3

геометрический_тип @> геометрический_тип → boolean

Первый объект содержит второй? Доступен для этих пар типов: (box, point), (box, box), (path, point), (polygon, point), (polygon, polygon), (circle, point), (circle, circle).

circle '<(0,0),2>' @> point '(1,1)' → t

геометрический_тип <@ геометрический_тип → boolean

Первый объект содержится в (находится на) втором? Доступен для этих пар типов: (point, box), (point, lseg), (point, line), (point, path), (point, polygon), (point, circle), (box, box), (lseg, box), (lseg, line), (polygon, polygon), (circle, circle).

point '(1,1)' <@ circle '<(0,0),2>' → t

геометрический_тип && геометрический_тип → boolean

Эти объекты пересекаются? (Для результата true достаточно одной общей точки.) Доступен для типов box, polygon, circle.

box '(1,1),(0,0)' && box '(2,2),(0,0)' → t

геометрический_тип << геометрический_тип → boolean

Первый объект строго слева от второго? Доступен для типов point, box, polygon, circle.

circle '<(0,0),1>' << circle '<(5,0),1>' → t

геометрический_тип >> геометрический_тип → boolean

Первый объект строго справа от второго? Доступен для типов point, box, polygon, circle.

circle '<(5,0),1>' >> circle '<(0,0),1>' → t

геометрический_тип &< геометрический_тип → boolean

Первый объект не простирается правее второго? Доступен для типов box, polygon, circle.

box '(1,1),(0,0)' &< box '(2,2),(0,0)' → t

геометрический_тип &> геометрический_тип → boolean

Первый объект не простирается левее второго? Доступен для типов box, polygon, circle.

box '(3,3),(0,0)' &> box '(2,2),(0,0)' → t

геометрический_тип <<| геометрический_тип → boolean

Первый объект строго ниже второго? Доступен для типов point, box, polygon, circle.

box '(3,3),(0,0)' <<| box '(5,5),(3,4)' → t

геометрический_тип |>> геометрический_тип → boolean

Первый объект строго выше второго? Доступен для типов point, box, polygon, circle.

box '(5,5),(3,4)' |>> box '(3,3),(0,0)' → t

геометрический_тип &<| геометрический_тип → boolean

Первый объект не простирается выше второго? Доступен для типов box, polygon, circle.

box '(1,1),(0,0)' &<| box '(2,2),(0,0)' → t

геометрический_тип |&> геометрический_тип → boolean

Первый объект не простирается ниже второго? Доступен для типов box, polygon, circle.

box '(3,3),(0,0)' |&> box '(2,2),(0,0)' → t

box <^ box → boolean

Первый объект ниже второго (объекты могут соприкасаться краями)?

box '((1,1),(0,0))' <^ box '((2,2),(1,1))' → t

box >^ box → boolean

Первый объект выше второго (объекты могут соприкасаться краями)?

box '((2,2),(1,1))' >^ box '((1,1),(0,0))' → t

геометрический_тип ?# геометрический_тип → boolean

Эти объекты пересекаются? Доступен для этих пар типов: (box, box), (lseg, box), (lseg, lseg), (lseg, line), (line, box), (line, line), (path, path).

lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)' → t

?- line → boolean

?- lseg → boolean

Линия горизонтальна?

?- lseg '[(-1,0),(1,0)]' → t

point ?- point → boolean

Точки выровнены по горизонтали (то есть имеют одинаковую координату по y)?

point '(1,0)' ?- point '(0,0)' → t

?| line → boolean

?| lseg → boolean

Линия вертикальна?

?| lseg '[(-1,0),(1,0)]' → f

point ?| point → boolean

Точки выровнены по вертикали (то есть имеют одинаковую координату по x)?

point '(0,1)' ?| point '(0,0)' → t

line ?-| line → boolean

lseg ?-| lseg → boolean

Линии перпендикулярны?

lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' → t

line ?|| line → boolean

lseg ?|| lseg → boolean

Линии параллельны?

lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' → t

геометрический_тип ~= геометрический_тип → boolean

Эти объекты совпадают? Доступен для типов point, box, polygon, circle.

polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))' → t

[a] При «повороте» прямоугольника с помощью этих операторов перемещаются только его угловые точки: стороны этого прямоугольника по-прежнему считаются параллельными осям. Как следствие, в отличие от истинного поворота, при этой операции размер прямоугольника меняется.

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

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

Функция

Описание

Пример(ы)

area ( геометрический_тип ) → double precision

Вычисляет площадь. Доступна для типов box, path, circle. Входное значение типа path должно быть замкнутым, иначе возвращается NULL. Кроме того, если этот путь является самопересекающимся, результат может не иметь смысла.

area(box '(2,2),(0,0)') → 4

center ( геометрический_тип ) → point

Вычисляет центральную точку. Доступна для типов box, circle.

center(box '(1,2),(0,0)') → (0.5,1)

diagonal ( box ) → lseg

Извлекает диагональ прямоугольника в виде отрезка (аналогично lseg(box)).

diagonal(box '(1,2),(0,0)') → [(1,2),(0,0)]

diameter ( circle ) → double precision

Вычисляет диаметр окружности.

diameter(circle '<(0,0),2>') → 4

height ( box ) → double precision

Вычисляет вертикальный размер прямоугольника.

height(box '(1,2),(0,0)') → 2

isclosed ( path ) → boolean

Путь замкнутый?

isclosed(path '((0,0),(1,1),(2,0))') → t

isopen ( path ) → boolean

Путь открытый?

isopen(path '[(0,0),(1,1),(2,0)]') → t

length ( геометрический_тип ) → double precision

Вычисляет общую длину. Доступна для типов lseg, path.

length(path '((-1,0),(1,0))') → 4

npoints ( геометрический_тип ) → integer

Возвращает количество точек. Доступна для типов path, polygon.

npoints(path '[(0,0),(1,1),(2,0)]') → 3

pclose ( path ) → path

Преобразует путь в замкнутую форму.

pclose(path '[(0,0),(1,1),(2,0)]') → ((0,0),(1,1),(2,0))

popen ( path ) → path

Преобразует путь в открытую форму.

popen(path '((0,0),(1,1),(2,0))') → [(0,0),(1,1),(2,0)]

radius ( circle ) → double precision

Вычисляет радиус окружности.

radius(circle '<(0,0),2>') → 2

slope ( point, point ) → double precision

Вычисляет наклон линии, проведенной через две точки.

slope(point '(0,0)', point '(2,1)') → 0.5

width ( box ) → double precision

Вычисляет горизонтальный размер прямоугольника.

width(box '(1,2),(0,0)') → 1

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

Функция

Описание

Пример(ы)

box ( circle ) → box

Вычисляет прямоугольник, вписанный в окружность.

box(circle '<(0,0),2>') → (1.414213562373095,1.414213562373095),​(-1.414213562373095,-1.414213562373095)

box ( point ) → box

Преобразует точку в пустой прямоугольник.

box(point '(1,0)') → (1,0),(1,0)

box ( point, point ) → box

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

box(point '(0,1)', point '(1,0)') → (1,1),(0,0)

box ( polygon ) → box

Вычисляет окружающий прямоугольник для многоугольника.

box(polygon '((0,0),(1,1),(2,0))') → (2,1),(0,0)

bound_box ( box, box ) → box

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

bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') → (4,4),(0,0)

circle ( box ) → circle

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

circle(box '(1,1),(0,0)') → <(0.5,0.5),0.7071067811865476>

circle ( point, double precision ) → circle

Строит окружность по центру и радиусу.

circle(point '(0,0)', 2.0) → <(0,0),2>

circle ( polygon ) → circle

Преобразует многоугольник в окружность. Центром окружности является среднее арифметическое координат вершин многоугольника, а радиусом — среднее расстояние от вершин многоугольника до этого центра.

circle(polygon '((0,0),(1,3),(2,0))') → <(1,1),1.6094757082487299>

line ( point, point ) → line

Преобразует две точки в проходящую через них линию.

line(point '(-1,0)', point '(1,0)') → {0,-1,0}

lseg ( box ) → lseg

Извлекает диагональ прямоугольника в виде отрезка.

lseg(box '(1,0),(-1,0)') → [(1,0),(-1,0)]

lseg ( point, point ) → lseg

Строит отрезок по двум конечным точкам.

lseg(point '(-1,0)', point '(1,0)') → [(-1,0),(1,0)]

path ( polygon ) → path

Преобразует многоугольник в замкнутый путь с тем же списком точек.

path(polygon '((0,0),(1,1),(2,0))') → ((0,0),(1,1),(2,0))

point ( double precision, double precision ) → point

Строит точку по заданным координатам.

point(23.4, -44.5) → (23.4,-44.5)

point ( box ) → point

Вычисляет центр прямоугольника.

point(box '(1,0),(-1,0)') → (0,0)

point ( circle ) → point

Вычисляет центр окружности.

point(circle '<(0,0),2>') → (0,0)

point ( lseg ) → point

Вычисляет центр отрезка.

point(lseg '[(-1,0),(1,0)]') → (0,0)

point ( polygon ) → point

Вычисляет центр многоугольника (среднее арифметическое координат его вершин).

point(polygon '((0,0),(1,1),(2,0))') → (1,0.3333333333333333)

polygon ( box ) → polygon

Преобразует прямоугольник в многоугольник с 4 вершинами.

polygon(box '(1,1),(0,0)') → ((0,0),(0,1),(1,1),(1,0))

polygon ( circle ) → polygon

Преобразует окружность в многоугольник с 12 вершинами.

polygon(circle '<(0,0),2>') → ((-2,0),​(-1.7320508075688774,0.9999999999999999),​(-1.0000000000000002,1.7320508075688772),​(-1.2246063538223773e-16,2),​(0.9999999999999996,1.7320508075688774),​(1.732050807568877,1.0000000000000007),​(2,2.4492127076447545e-16),​(1.7320508075688776,-0.9999999999999994),​(1.0000000000000009,-1.7320508075688767),​(3.673819061467132e-16,-2),​(-0.9999999999999987,-1.732050807568878),​(-1.7320508075688767,-1.0000000000000009))

polygon ( integer, circle ) → polygon

Преобразует окружность в многоугольник с n вершинами.

polygon(4, circle '<(3,0),1>') → ((2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1))

polygon ( path ) → polygon

Преобразует замкнутый путь в многоугольник с тем же списком вершин.

polygon(path '((0,0),(1,1),(2,0))') → ((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.

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

Типы cidr и inet, предназначенные для сетевых IP-адресов, поддерживают обычные операторы сравнения, приведенные в Таблице 1, а также специальные операторы и функции, приведенные в Таблице 38 и Таблице 39.

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

Таблица 38. Операторы для IP-адресов

Оператор

Описание

Пример(ы)

inet << inet → boolean

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

inet '192.168.1.5' << inet '192.168.1/24' → t

inet '192.168.0.5' << inet '192.168.1/24' → f

inet '192.168.1/24' << inet '192.168.1/24' → f

inet <<= inet → boolean

Первая подсеть содержится во второй или равна ей?

inet '192.168.1/24' <<= inet '192.168.1/24' → t

inet >> inet → boolean

Первая подсеть строго содержит вторую?

inet '192.168.1/24' >> inet '192.168.1.5' → t

inet >>= inet → boolean

Первая подсеть содержит вторую или равна ей?

inet '192.168.1/24' >>= inet '192.168.1/24' → t

inet && inet → boolean

Одна из двух подсетей содержит другую или равна ей?

inet '192.168.1/24' && inet '192.168.1.80/28' → t

inet '192.168.1/24' && inet '192.168.2.0/28' → f

~ inet → inet

Вычисляет результат побитового НЕ.

~ inet '192.168.1.6' → 63.87.254.249

inet & inet → inet

Вычисляет результат побитового И.

inet '192.168.1.6' & inet '0.0.0.255' → 0.0.0.6

inet | inet → inet

Вычисляет результат побитового ИЛИ.

inet '192.168.1.6' | inet '0.0.0.255' → 192.168.1.255

inet + bigint → inet

Добавляет смещение к адресу.

inet '192.168.1.6' + 25 → 192.168.1.31

bigint + inet → inet

Добавляет смещение к адресу.

200 + inet '::ffff:fff0:1' → ::ffff:255.240.0.201

inet - bigint → inet

Вычитает смещение из адреса.

inet '192.168.1.43' - 36 → 192.168.1.7

inet - inet → bigint

Вычисляет разность двух адресов.

inet '192.168.1.43' - inet '192.168.1.19' → 24
inet '::1' - inet '::ffff:1' → -4294901760

Таблица 39. Функции для IP-адресов

Функция

Описание

Пример(ы)

abbrev ( inet ) → text

Создает сокращенный формат отображения адреса в виде текста. (Результат получается тот же, что и у функции вывода inet; «сокращенным» он является только в сравнении с результатом явного приведения к типу text, которое по историческим причинам никогда не будет убирать часть с сетевой маской.)

abbrev(inet '10.1.0.0/32') → 10.1.0.0

abbrev ( cidr ) → text

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

abbrev(cidr '10.1.0.0/16') → 10.1/16

broadcast ( inet ) → inet

Вычисляет широковещательный адрес для сети в заданном адресе.

broadcast(inet '192.168.1.5/24') → 192.168.1.255/24

family ( inet ) → integer

Возвращает семейство адреса: 4 для адресов IPv4, 6 для адресов IPv6.

family(inet '::1') → 6

host ( inet ) → text

Возвращает IP-адрес в виде текста, игнорируя сетевую маску.

host(inet '192.168.1.0/24') → 192.168.1.0

hostmask ( inet ) → inet

Вычисляет маску хоста для сети в заданном адресе.

hostmask(inet '192.168.23.20/30') → 0.0.0.3

inet_merge ( inet, inet ) → cidr

Вычисляет наименьшую сеть, содержащую обе заданные сети.

inet_merge(inet '192.168.1.5/24', inet '192.168.2.5/24') → 192.168.0.0/22

inet_same_family ( inet, inet ) → boolean

Проверяет, принадлежат ли адреса одному семейству IP.

inet_same_family(inet '192.168.1.5/24', inet '::1') → f

masklen ( inet ) → integer

Возвращает длину сетевой маски в битах.

masklen(inet '192.168.1.5/24') → 24

netmask ( inet ) → inet

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

netmask(inet '192.168.1.5/24') → 255.255.255.0

network ( inet ) → cidr

Возвращает сетевую часть адреса, обнуляя все биты справа от сетевой маски. (Это равнозначно приведению значения к типу cidr.)

network(inet '192.168.1.5/24') → 192.168.1.0/24

set_masklen ( inet, integer ) → inet

Задает длину сетевой маски для значения типа inet. Адресная часть при этом не меняется.

set_masklen(inet '192.168.1.5/24', 16) → 192.168.1.5/16

set_masklen ( cidr, integer ) → cidr

Задает длину сетевой маски для значения cidr. Биты адреса справа от новой сетевой маски при этом устанавливаются в ноль.

set_masklen(cidr '192.168.1.0/24', 16) → 192.168.0.0/16

text ( inet ) → text

Возвращает несокращенный IP-адрес и длину сетевой маски в виде текста. (Такой же результат получается при явном приведении к типу text.)

text(inet '192.168.1.5') → 192.168.1.5/32

Совет
Функции abbrev, host и text предназначены в основном для отображения IP-адресов в альтернативных форматах.

Типы для MAC-адресов, macaddr и macaddr8, поддерживают обычные операторы сравнения, , приведенные в Таблице 1, а также специальные функции, приведенные в Таблице 40. Кроме того, они поддерживают побитовые логические операторы ~, & и | (НЕ, И и ИЛИ), показанные выше для IP-адресов.

Таблица 40. Функции для MAC-адресов

Функция

Описание

Пример(ы)

trunc ( macaddr ) → macaddr

Устанавливает в ноль 3 последних байта адреса. Оставшийся префикс можно сопоставить с конкретным производителем (используя информацию, отсутствующую в QHB).

trunc(macaddr '12:34:56:78:90:ab') → 12:34:56:00:00:00

trunc ( macaddr8 ) → macaddr8

Устанавливает в ноль 5 последних байта адреса. Оставшийся префикс можно сопоставить с конкретным производителем (используя информацию, отсутствующую в QHB).

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 для включения в адрес IPv6.

macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') → 02:34:56:ff:fe:ab:cd:ef

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

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

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

Оператор

Описание

Пример(ы)

tsvector @@ tsquery → boolean

tsquery @@ tsvector → boolean

Аргумент типа tsvector соответствует аргументу типа tsquery? (Эти аргументы можно передавать в любом порядке.)

to_tsvector('fat cats ate rats') @@ to_tsquery('cat & rat') → t

text @@ tsquery → boolean

Текстовая строка, преобразованная после неявного вызова функции to_tsvector(), соответствует tsquery?

'fat cats ate rats' @@ to_tsquery('cat & rat') → t

tsvector @@@ tsquery → boolean

tsquery @@@ tsvector → boolean

Это устаревший синоним для @@.

to_tsvector('fat cats ate rats') @@@ to_tsquery('cat & rat') → t

tsvector || tsvector → tsvector

Конкатенирует два значения tsvector. Если в обоих аргументах содержатся позиции лексем, позиции второго аргумента корректируются соответствующим образом.

'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector → 'a':1 'b':2,5 'c':3 'd':4

tsquery && tsquery → tsquery

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

'fat | rat'::tsquery && 'cat'::tsquery → ( 'fat' | 'rat' ) & 'cat'

tsquery || tsquery → tsquery

Выполняет логическую операцию ИЛИ с двумя значениями tsquery, создавая запрос, который соответствует документам, соответствующим любому из входных запросов.

'fat | rat'::tsquery || 'cat'::tsquery → 'fat' | 'rat' | 'cat'

!! tsquery → tsquery

Выполняет логическую операцию НЕ со значением tsquery, создавая запрос, который соответствует документам, не соответствующим входному запросу.

!! 'cat'::tsquery → !'cat'

tsquery <-> tsquery → tsquery

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

to_tsquery('fat') <-> to_tsquery('rat') → 'fat' <-> 'rat'

tsquery @> tsquery → boolean

Первый аргумент типа tsquery содержит второй? (Здесь учитывается только факт нахождения всех лексем одного запроса в другом, а объединение операторов игнорируется.)

'cat'::tsquery @> 'cat & rat'::tsquery → f

tsquery <@ tsquery → boolean

Первый аргумент типа tsquery содержится во втором? (Здесь учитывается только факт нахождения всех лексем одного запроса в другом, а объединение операторов игнорируется.)

'cat'::tsquery <@ 'cat & rat'::tsquery → t

'cat'::tsquery <@ '!cat & rat'::tsquery → t

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

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

Функция

Описание

Пример(ы)

array_to_tsvector ( text[] ) → tsvector

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

array_to_tsvector('{fat,cat,rat}'::text[]) → 'cat' 'fat' 'rat'

get_current_ts_config ( ) → regconfig

Возвращает OID текущей конфигурации текстового поиска по умолчанию (заданной параметром default_text_search_config).

get_current_ts_config() → english

length ( tsvector ) → integer

Возвращает количество лексем в заданном tsvector.

length('fat:2,4 cat:3 rat:5A'::tsvector) → 3

numnode ( tsquery ) → integer

Возвращает количество лексем и операторов в заданном tsquery.

numnode('(fat & rat) | cat'::tsquery) → 5

plainto_tsquery ( [ конфигурация regconfig, ] запрос text ) → tsquery

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

plainto_tsquery('english', 'The Fat Rats') → 'fat' & 'rat'

phraseto_tsquery ( [ конфигурация regconfig, ] запрос text ) → tsquery

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

phraseto_tsquery('english', 'The Fat Rats') → 'fat' <-> 'rat'

phraseto_tsquery('english', 'The Cat and Rats') → 'cat' <2> 'rat'

websearch_to_tsquery ( [ конфигурация regconfig, ] запрос text ) → tsquery

Преобразует текст в tsquery, нормализуя слова согласно указанной или стандартной конфигурации. Последовательности слов в кавычках преобразуются в проверки фраз. Слово «or» воспринимается как формирующее оператор OR (ИЛИ), а символ минуса формирует оператор NOT (НЕ); другие пунктуационные знаки игнорируются. Это примерно соответствует поведению некоторых распространенных инструментов поиска интернете.

websearch_to_tsquery('english', '"fat rat" or cat dog') → 'fat' <-> 'rat' | 'cat' & 'dog'

querytree ( tsquery ) → text

Создает представление индексируемой части tsquery. Пустой результат или просто T означают, что запрос неиндексируемый.

querytree('foo & ! bar'::tsquery) → 'foo'

setweight ( вектор tsvector, вес "char" ) → tsvector

Присваивает заданный вес каждому элементу вектора.

setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A') → 'cat':3A 'fat':2A,4A 'rat':5A

setweight ( вектор tsvector, вес "char", лексемы text[] ) → tsvector

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

setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') → 'cat':3A 'fat':2,4 'rat':5A,6A

strip ( tsvector ) → tsvector

Убирает позиции и веса из значения tsvector.

strip('fat:2,4 cat:3 rat:5A'::tsvector) → 'cat' 'fat' 'rat'

to_tsquery ( [ конфигурация regconfig, ] запрос text ) → tsquery

Преобразует текст в tsquery, нормализуя слова согласно указанной или стандартной конфигурации. Слова должны соединяться допустимыми операторами tsquery.

to_tsquery('english', 'The & Fat & Rats') → 'fat' & 'rat'

to_tsvector ( [ конфигурация regconfig, ] документ text ) → tsvector

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

to_tsvector('english', 'The Fat Rats') → 'fat':2 'rat':3

to_tsvector ( [ конфигурация regconfig, ] документ json ) → tsvector

to_tsvector ( [ конфигурация regconfig, ] документ jsonb ) → tsvector

Преобразует все строковые значения в документе JSON в tsvector, нормализуя слова согласно указанной или стандартной конфигурации. Затем результаты конкатенируются в порядке следования в документе, формируя выходное значение. Информация о позициях слов генерируется таким образом, словно между каждой парой строковых значений находится одно стоп-слово. (Учтите, что в случае jsonb «порядок следования в документе» полей объекта JSON зависит от реализации; разница показана в примерах.)

to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) → 'dog':5 'fat':2 'rat':3

to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::jsonb) → 'dog':1 'fat':4 'rat':5

json_to_tsvector ( [ конфигурация regconfig, ] документ json, фильтр jsonb ) → tsvector

jsonb_to_tsvector ( [ конфигурация regconfig, ] документ jsonb, фильтр jsonb ) → tsvector

Выбирает в документе JSON все элементы, запрошенные фильтром и преобразует каждый в tsvector, нормализуя слова согласно указанной или стандартной конфигурации. Затем результаты конкатенируются в порядке следования в документе, формируя выходное значение. Информация о позициях слов генерируется таким образом, словно между каждой парой строковых значений находится одно стоп-слово. (Учтите, что в случае jsonb «порядок следования в документе» полей объекта JSON зависит от реализации.) Аргумент фильтр должен быть массивом jsonb, содержащим ноль и более следующих ключевых слов: "string" (включить все строковые значения), "numeric" (включить все числовые значения), "boolean" (включить все логические значения), "key" (включить все ключи) или "all" (включить всё вышеперечисленное). В особых случаях фильтр также может быть простым значением JSON, представляющим собой одно из этих ключевых слов.

json_to_tsvector('english', '{"a": "The Fat Rats", "b": 123}'::json, '["string", "numeric"]') → '123':5 'fat':2 'rat':3

json_to_tsvector('english', '{"cat": "The Fat Rats", "dog": 123}'::json, '"all"') → '123':9 'cat':1 'dog':7 'fat':4 'rat':5

ts_delete ( вектор tsvector, лексема text ) → tsvector

Удаляет все вхождения заданной лексемы из вектора.

ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') → 'cat':3 'rat':5A

ts_delete ( вектор tsvector, лексемы text[] ) → tsvector

Удаляет все вхождения лексем, перечисленных в списке лексемы, из вектора.

ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) → 'cat':3

ts_filter ( вектор tsvector, веса "char"[] ) → tsvector

Выбирает из вектора только элементы с заданными весами.

ts_filter('fat:2,4 cat:3b,7c rat:5A'::tsvector, '{a,b}') → 'cat':3B 'rat':5A

ts_headline ( [ конфигурация regconfig, ] документ text, запрос tsquery [, параметры text ] ) → text

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

cat ate the rat.

ts_headline ( [ json, запрос tsquery [, параметры text ] ) → text

ts_headline ( [ конфигурация regconfig, ] документ jsonb, запрос tsquery [, параметры text ] ) → text

Отображает в сокращенной форме соответствующие запросу вхождения, найденные в строковых значениях внутри документа JSON.

ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') → {"cat": "raining cats and dogs"}

ts_rank ( [ веса real[], ] вектор tsvector, запрос tsquery [, нормализация integer ] ) → real

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

ts_rank(to_tsvector('raining cats and dogs'), 'cat') → 0.06079271

ts_rank_cd ( [ веса real[], ] вектор tsvector, запрос tsquery [, нормализация integer ] ) → real

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

ts_rank_cd(to_tsvector('raining cats and dogs'), 'cat') → 0.1

ts_rewrite ( запрос tsquery, цель tsquery, подстановка tsquery ) → tsquery

Заменяет в запросе вхождения значения цель значением подстановка.

ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'foo|bar'::tsquery) → 'b' & ( 'foo' | 'bar' )

ts_rewrite ( запрос tsquery, выборка text ) → tsquery

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

SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') → 'b' & ( 'foo' | 'bar' )

tsquery_phrase ( запрос1 tsquery, запрос2 tsquery ) → tsquery

Конструирует фразовый запрос, который ищет вхождения, соответствующие запросу1 и запросу2, в идущих подряд лексемах (аналогично оператору <->).

tsquery_phrase(to_tsquery('fat'), to_tsquery('cat')) → 'fat' <-> 'cat'

tsquery_phrase ( запрос1 tsquery, запрос2 tsquery, расстояние integer ) → tsquery

Конструирует фразовый запрос, который ищет вхождения, соответствующие запросу1 и запросу2, на определенном, заданном в лексемах, расстоянии друг от друга.

tsquery_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}

unnest ( tsvector ) → setof record ( лексема text, позиции smallint[], веса text )

Разворачивает tsvector в набор строк, по одной на каждую лексему.

select * from unnest('cat:3 fat:2,4 rat:5A'::tsvector) →
     lexeme | positions | weights
    --------+-----------+---------
     cat    | {3}       | {D}
     fat    | {2,4}     | {D,D}
     rat    | {5}       | {A}

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

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

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

Функция

Описание

Пример(ы)

ts_debug ( [ конфигурация regconfig, ] документ text ) → setof record ( псевдоним text, описание text, фрагмент text, словари regdictionary[], словарь regdictionary, лексемы text[] )

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

ts_debug('english', 'The Brightest supernovaes') → (asciiword,"Word, all ASCII",The,{english_stem},english_stem,{}) ...

ts_lexize ( словарь regdictionary, фрагмент text ) → text[]

Возвращает массив заменяющих лексем, если входной фрагмент есть в словаре, пустой массив, если фрагмент есть в словаре, но является стоп-словом, или NULL, если такого слова нет.

ts_lexize('english_stem', 'stars') → {star}

ts_parse ( имя_анализатора text, документ text ) → setof record ( код_фрагмента integer, фрагмент text )

Извлекает фрагменты из документа, используя именованный анализатор.

ts_parse('default', 'foo - bar') → (1,foo) ...

ts_parse ( oid_анализатора oid, документ text ) → setof record ( код_фрагмента integer, фрагмент text )

Извлекает фрагменты из документа, используя анализатор с указанным OID.

ts_parse(3722, 'foo - bar') → (1,foo) ...

ts_token_type ( имя_анализатора text ) → setof record ( код_фрагмента integer, псевдоним text, описание text )

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

ts_token_type('default') → (1,asciiword,"Word, all ASCII") ...

ts_token_type ( oid_анализатора oid ) → setof record ( код_фрагмента integer, псевдоним text, описание text )

Возвращает таблицу, описывающую все типы фрагментов, которые может распознать анализатор с указанным OID.

ts_token_type(3722) → (1,asciiword,"Word, all ASCII") ...

ts_stat ( sql_запрос text [, веса text ] ) → setof record ( слово text, число_док integer, число_вхожд integer )

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

ts_stat('SELECT vector FROM apod') → (foo,10,15) ...

Функции генерирования UUID

В QHB имеется одна функция для генерирования UUID:

gen_random_uuid () → uuid

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

Модуль uuid-ossp предоставляет дополнительные функции, реализующие другие стандартные алгоритмы генерирования UUID.

Кроме того, QHB предоставляет для UUID приведенные в Таблице 1 простые операторы сравнения.

Функции XML

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

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

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

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

xmlcomment

xmlcomment ( text ) → xml

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

Пример:

SELECT xmlcomment('hello');

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

xmlconcat

xmlconcat ( xml [, ...] ) → xml

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

Пример:

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

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

Объявления XML, если они есть, объединяются следующим образом. Если все значения аргументов имеют объявление одной версии XML, эта версия используется в результате, иначе версия вообще не используется. Если у всех значений аргумента имеется объявление standalone со значением «yes», то это же значение используется в результате. Если у всех значений аргумента имеется объявление standalone и по крайней мере одно из них равно «no», тогда в результате используется это значение. Иначе у результата не будет объявления standalone. Если определено, что в результате должно быть объявление standalone, но нет объявления версии, будет выведена версия 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 имя [, XMLATTRIBUTES ( значение_атрибута [ AS имя_атрибута ] [, ...] ) ] [, содержимое [, ...]] ) → xml

Выражение xmlelement создает элемент XML с заданным именем, атрибутами и содержимым. Показанные в синтаксисе элементы имя и имя_атрибута представляют собой простые идентификаторы, а не значения. Элементы значение_атрибута и содержимое являются выражениями, которые могут выдавать любой тип данных QHB. Аргументы внутри XMLATTRIBUTES генерируют атрибуты элемента 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, экранируются путем замены нарушающих символов последовательностью _xHHHH_, где 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) будут представлены в кодировке base64 или в шестнадцатеричной кодировке, в зависимости от настройки параметра конфигурации xmlbinary. Как ожидается, конкретное поведение для отдельных типов данных будет развиваться, чтобы согласовать сопоставления QHB с сопоставлениями, указанными в стандарте SQL:2006 и новее, как описано в подразделе Сопоставления типов данных и значений между SQL и XML.

xmlforest

xmlforest ( содержимое [ AS имя ] [, ...] ) → xml

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

Примеры:

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 имя [, содержимое ] ) → xml

Выражение xmlpi создает инструкцию по обработке XML. Как и в выражении xmlelement, имя должно быть простым идентификатором, тогда как выражение содержимое может иметь любой тип данных. Это содержимое, если оно задано, не должно содержать последовательность символов ?>.

Пример:

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

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

xmlroot

xmlroot ( xml, VERSION {text|NO VALUE} [, STANDALONE {YES|NO|NO VALUE} ] ) → xml

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

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 ) → 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 → boolean

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

IS NOT DOCUMENT

xml IS NOT DOCUMENT → boolean

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

XMLEXISTS

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

Функция xmlexists вычисляет выражение XPath 1.0 (первый аргумент), используя в качестве элемента контекста переданное значение XML. Функция возвращает false, если в результате этого вычисления выдается пустой набор узлов, true, если выдается любое другое значение, или NULL, если любой аргумент равен NULL. Отличное от NULL значение, передаваемое в качестве элемента контекста, должно быть документом 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 (это рассматривается в подразделе Запросы ограничены XPath 1.0).

xml_is_well_formed

xml_is_well_formed ( text ) → boolean
xml_is_well_formed_document ( text ) → boolean
xml_is_well_formed_content ( text ) → boolean

Эти функции проверяют, представляет ли строка типа 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.

xpath

xpath ( xpath text, xml xml [, массив_пространств_имен text[] ] ) → xml[]

Функция xpath вычисляет выражение XPath 1.0 xpath (заданное в виде текста) для значения 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 text, xml xml [, массив_пространств_имен text[] ] ) → boolean

Функция 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 ( uri_пространства_имен AS имя_пространства_имен [, ...] ),]
    выражение_строки PASSING [BY {REF|VALUE}] выражение_документа [BY {REF|VALUE}]
    COLUMNS имя { тип [PATH выражение_столбца] [DEFAULT выражение_по_умолчанию] [NOT NULL | NULL]
                  | FOR ORDINALITY }
            [, ...]
) → setof record

Выражение xmltable создает таблицу на основе значения XML, фильтра XPath для извлечения строк и набора определений столбцов. Хотя синтаксически оно напоминает функцию, оно может присутствовать в запросе только в качестве таблицы в предложении FROM.

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

Обязательный аргумент выражение_строки — это выражение XPath 1.0 (заданное в виде значения типа text), которое вычисляется с использованием в качестве элемента контекста переданного значения XML, для получения набора узлов XML. Эти узлы — то, что xmltable превращает в выходные строки. Если выражение_документа равно NULL или выражение_строки создает пустой набор узлов или любое значение, отличное от набора узлов, строки выдаваться не будут.

Аргумент выражение_документа предоставляет элемент контекста для аргумента выражение_строки. Этим элементом должен быть синтаксически корректный документ XML; фрагменты/леса не принимаются. Предложения BY REF и BY VALUE принимаются, но игнорируются (это рассматривается в подразделе Непреднамеренные ограничения реализации).

В стандарте SQL функция xmltable вычисляет выражения на языке XML Query, но QHB допускает только выражение XPath 1.0 (это рассматривается в подразделе Запросы ограничены XPath 1.0).

Обязательное предложение COLUMNS задает столбцы, которые будут созданы в выходной таблице. Его формат показан выше в шаблоне синтаксиса. Для каждого столбца необходимо задать имя и тип данных (если только не указано FOR ORDINALITY, что подразумевает тип integer). Предложения, задающие путь, значение по умолчанию и допустимость значений NULL, являются необязательными.

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

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

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

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

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

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

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

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

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

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

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

Примеры:

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 и инструкций по обработке:

CREATE 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 ( table regclass, nulls boolean,
               tableforest boolean, targetns text ) → xml
query_to_xml ( query text, nulls boolean,
               tableforest boolean, targetns text ) → xml
cursor_to_xml ( cursor refcursor, count integer, nulls boolean,
                tableforest boolean, targetns text ) → xml

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

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

<имя_таблицы>
  <row>
    <имя_столбца1>данные</имя_столбца1>
    <имя_столбца2>данные</имя_столбца2>
  </row>

  <row>
    ...
  </row>

  ...
</имя_таблицы>

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

<имя_таблицы>
  <имя_столбца1>данные</имя_столбца1>
  <имя_столбца2>данные</имя_столбца2>
</имя_таблицы>

<имя_таблицы>
  ...
</имя_таблицы>

...

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

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

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

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

<имя_столбца xsi:nil="true"/>

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

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

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

table_to_xmlschema ( table regclass, nulls boolean,
                     tableforest boolean, targetns text ) → xml
query_to_xmlschema ( query text, nulls boolean,
                     tableforest boolean, targetns text ) → xml
cursor_to_xmlschema ( cursor refcursor, nulls boolean,
                      tableforest boolean, targetns text ) → xml

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

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

table_to_xml_and_xmlschema ( table regclass, nulls boolean,
                             tableforest boolean, targetns text ) → xml
query_to_xml_and_xmlschema ( query text, nulls boolean,
                             tableforest boolean, targetns text ) → xml

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

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

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

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

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

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

<имя_схемы>

отображение-таблицы1

отображение-таблицы2

...

</имя_схемы>

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

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

<имя_бд>

<имя_схемы1>
  ...
</имя_схемы1>

<имя_схемы2>
  ...
</имя_схемы2>

...

</имя_бд>

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

В качестве примера использования выходных данных, создаваемых этими функциями, на Примере 1 показана таблица стилей 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>

Расширенные XML функции

Расширенные XML функции в QHB это функции, представляющие дополнительные операции над данными, представленными в виде XML документов.

xml_append_child

xml_append_child ( XMLType_instance xml, XPath_string text, value_expr xml [, namespace_string text])

xml_append_child добавляет введенное пользователем значение к целевому XML в качестве дочернего элемента узла, указанного выражением XPath:

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, к которым должны быть присоединены один или несколько дочерних узлов. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.
  • value_expr указывает один или несколько узлов XML. Он должен разрешаться в строку.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_append_child(
  '<body>
    <wow id="1">
      <lol/>
    </wow>
    <wow id="2">
      <lol/>
    </wow>
   </body>'::xml,
  '/body/wow/lol'::text,
  '<New>Append</New>'::xml
  )
;

Результат:

<body>
  <wow id="1">
    <lol>
      <New>Append</New>
    </lol>
  </wow>
  <wow id="2">
    <lol>
      <New>Append</New>
    </lol>
  </wow>
</body>

xml_insert_before

xml_insert_before ( XMLType_instance xml, XPath_string text, value_expr xml [, namespace_string text] )

xml_insert_before вставляет введенное пользователем значение в целевой XML перед узлом, указанным выражением XPath. Эта функция похожа на xml_insert_after, но вставляет до, а не после целевого узла.

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, в которые необходимо вставить один или несколько дочерних узлов. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.
  • value_expr — это фрагмент XML, определяющий один или несколько вставляемых узлов и их положение в родительском узле. Он должен разрешаться в строку.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_insert_before(
  '<body><wow id="1"><lol/></wow><wow id="2"><lol/></wow></body>'::xml,
  '/body/wow[2]'::text,
  '<wow id="BEFORE New one">WOOOW</wow>'::xml
  )
;

Результат:

<body>
  <wow id="1">
    <lol/>
  </wow>
  <wow id="BEFORE New one">WOOOW</wow>
  <wow id="2">
    <lol/>
  </wow>
</body>

xml_insert_after

xml_insert_after ( XMLType_instance xml, XPath_string text, value_expr xml [, namespace_string text] )

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

  • XMLType_instance указывает целевой узел вставки.
  • XPath_string — это выражение XPath 1.0, которое находит в целевом узле ноль или более узлов любого типа, кроме узлов атрибутов. XML-данные вставляются сразу после каждого из этих узлов; то есть каждый указанный узел становится предшествующим одноуровневым узлом узла, указанного в value_expr.
  • value_expr — это XML-данные, которые необходимо вставить. Вы можете указать один или несколько узлов любого типа. Порядок узлов сохраняется после вставки.
  • Необязательная строка namespace_string — это пространство имен для целевого узла.

Пример:

select xml_insert_after(
  '<body>
    <wow id="1">
     <lol/>
    </wow>
    <wow id="2">
     <lol/>
    </wow>
  </body>'::xml,
  '/body/wow[2]'::text,
  '<wow id="BEFORE new one">WOOOW</wow>'::xml
  )
;

Результат:

<body>
  <wow id="1">
    <lol/>
  </wow>
  <wow id="2">
    <lol/>
  </wow>
  <wow id="BEFORE new one">WOOOW</wow>
</body>

xml_insert_child_after

xml_insert_child_after ( XMLType_instance xml, XPath_string text, XPathChild_string text, value_expr xml [, namespace_string text] )

xml_insert_child_after вставляет один или несколько узлов любого типа сразу после целевого узла, который не является узлом атрибута. Документ XML, который является целью вставки, может быть основан на схеме или не основан на схеме. :

  • XMLType_instance указывает целевой узел вставки.
  • XPath_string — это выражение XPath 1.0, которое находит в целевом узле ноль или более узлов любого типа, кроме узлов атрибутов. XML-данные вставляются в содержимое целевого узла, после узла задаваемого выражением XPathChild_string
  • XPathChild_string - это выражение XPath 1.0, которое находит в содержимом целевого узла ноль или более узлов после которых будет вставлено value_expr
  • value_expr — это XML-данные, которые необходимо вставить. Вы можете указать один или несколько узлов любого типа. Порядок узлов сохраняется после вставки.
  • Необязательная строка namespace_string — это пространство имен для целевого и дочернего узла.

Пример:

select xml_insert_child_after(
  '<books xmlns=\"http://example.com/\">\
            <shelf>\
                <book>Book A</book>\
                <book>Book B</book>\
            </shelf>\
            <shelf>\
                <book>Book C</book>\
                <book>Book D</book>\
            </shelf>\
        </books>'::xml,
  '/books/shelf'::text,
  'book[2]'::text,
  '<book>Third book in a shelf</book>'::xml,
  'xmlns="http://example.com/"'::text
  )
;

Результат:

<books xmlns="http://example.com/">
  <shelf>
    <book>Book A</book>
    <book>Book B</book>
    <book>Third book in a shelf</book>
  </shelf>
  <shelf>
    <book>Book C</book>
    <book>Book D</book>
    <book>Third book in a shelf</book>
  </shelf>
</books>

xml_update

xml_update(XMLType_instance,Update_pair[],[, namespace_string ])

xml_update принимает в качестве аргументов экземпляр XMLType и массив пар XPath-значение: value_expr и возвращает экземпляр XMLType с обновленными значениями для каждой пары. Если XPath_string является элементом XML, то соответствующее value_expr должно быть экземпляром XMLType. Если XPath_string является атрибутом или текстовым узлом, то value_expr может быть любым скалярным типом данных. Можно указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.

Типы данных цели каждой строки XPath_string и соответствующего ей value_expr должны совпадать. Необязательная строка namespace_string должна разрешаться в значение символьного типа, указывающее сопоставление по умолчанию или сопоставление пространства имен для префиксов, которые база данных QHB использует при оценке выражений XPath.

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

Эта функция материализует XML-документ в памяти и обновляет значение. Для использования в операторе UPDATE для модификации содержимого в столбце таблицы необходимо использовать результат функции в выражении UPDATE ... SET.

Пример:

select xml_update(
  '
    <body>
     <wow id="1">WOW1</wow>
     <wow id="2">WOW2</wow>
     <foo id="1">FOO1</foo>
     <foo id="2">FOO2</foo>
    </body>'::xml,
  '{"/body/wow[1]","<NewNode>I am new</NewNode>","/body/foo[2]","<NewNode>Another new node</NewNode>"}'   
  ) 

Результат:

<body>
  <NewNode>I am new</NewNode>
  <wow id="2">WOW2</wow>
  <foo id="1">FOO1</foo>
  <NewNode>Another new node</NewNode>
</body>

xml_delete

xml_delete ( XMLType_instance, XPath_string [, namespace_string ])

xml_delete удаляет узел или узлы, соответствующие выражению XPath в целевом XML.

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, которые необходимо удалить. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу. Любые дочерние узлы узлов, указанных в XPath_string, также удаляются.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_delete(
  '<body>
    <wow id="1">WOW1</wow>
    <wow id="2">WOW2</wow>
   </body>'::xml,
  '/body/wow[2]'::text   
  )
;

Результат:

<body>
  <wow id="1">WOW1</wow>
</body>

xml_extract_value

xml_ ( XMLType_instance, XPath_string [, namespace_string ])

xml_extract_value возвращает скалярное значение, соответствующие выражению XPath в целевом XML, если выражение XPath соответствует несколько узлов функция завершится с ошибкой.

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, для поиска. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_extract_value(
  '<books>\
            <shelf>\
                <book>Book A</book>\
                <book>Book B</book>\
            </shelf>\
            <shelf>\
                <book>Book C</book>\
                <book>Book D</book>\
                <book>Book D</book>\
            </shelf>\
        </books>"'::xml,
  '/books/shelf/book[3]'::text
  )
;

Результат:

Book D   

xml_extract

xml_ ( XMLType_instance, XPath_string [, namespace_string ])

xml_extract возвращает один или несколько узлов, соответствующих выражению XPath в целевом XML.

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, которые необходимо добавить в возвращаемый документ. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_extract(
  '<books>\
            <shelf>\
                <book>Book A</book>\
                <book>Book B</book>\
            </shelf>\
            <shelf>\
                <book>Book C</book>\
                <book>Book D</book>\
            </shelf>\
        </books>"'::xml,
  '/books/shelf/book'::text
  )
;

Результат:

<book>Book A</book>
<book>Book B</book>
<book>Book C</book>
<book>Book D</book>

xml_exists_node

xml_ ( XMLType_instance, XPath_string [, namespace_string ])

xml_exists_node проверяет существует ли узел или узлы, соответствующие выражению XPath в целевом XML, возвращает 1 если хотя бы один узел найден и 0 в другом случае.

  • XMLType_instance — это экземпляр XMLType.
  • XPath_string — это выражение Xpath, указывающее один или несколько узлов, которые необходимо удалить. Вы можете указать абсолютную строку XPath_string с начальной косой чертой или относительную строку XPath_string, опуская начальную косую черту. Если вы опускаете начальную косую черту, контекст относительного пути по умолчанию соответствует корневому узлу.
  • Необязательный параметр namespace_string предоставляет информацию о пространстве имен для XPath_string. Этот параметр должен иметь тип text.

Пример:

select xml_exists_node(
  '<books>\
            <shelf>\
                <book1>Book A</book1>\
                <book2>Book B</book2>\
            </shelf>\
            <shelf>\
                <book1>Book C</book1>\
                <book2>Book D</book2>\
                <book3>Book D</book3>\
            </shelf>\
        </books>"'::xml,
  '/books/shelf/book3'::text
  )
;

Результат:

1

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

В этом разделе описываются:

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

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

Чтобы узнать больше о стандарте SQL/JSON, обратитесь к стандарту ISO/IEC TR 19075-6. Подробную информацию о типах JSON, поддерживаемых в QHB, см. в разделе Типы JSON.

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

В Таблице 44 приведены операторы, доступные для использования с типами данных JSON (см. раздел Типы JSON). Кроме того, для типа jsonb (но не для json) доступны обычные операторы сравнения, приведенные в Таблице 1. Эти операторы сравнения следуют правилам упорядочивания для операций B-дерева, изложенным в подразделе Индексация jsonb.

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

Оператор

Описание

Пример(ы)

json -> integer → json

jsonb -> integer → jsonb

Извлекает n-й элемент массива JSON (элементы массива индексируются с нуля, но отрицательные числа считаются с конца).

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2 → {"c":"baz"}

'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> -3 → {"a":"foo"}

json -> text → json

jsonb -> text → jsonb

Извлекает поле объекта JSON по заданному ключу.

'{"a": {"b":"foo"}}'::json -> 'a' → {"b":"foo"}

json ->> integer → text

jsonb ->> integer → text

Извлекает n-й элемент массива JSON в виде значения типа text.

'[1,2,3]'::json ->> 2 → 3

json ->> text → text

jsonb ->> text → text

Извлекает поле объекта JSON по заданному ключу в виде значения типа text.

'{"a":1,"b":2}'::json ->> 'b' → 2

json #> text[] → json

jsonb #> text[] → jsonb

Извлекает дочерний объект JSON по заданному пути, где элементами пути могут быть ключи полей или индексы массивов.

'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}' → "bar"

json #>> text[] → text

jsonb #>> text[] → text

Извлекает дочерний объект JSON по заданному пути в виде значения типа text.

'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}' → bar

Примечание
Если структура входных данных JSON не соответствует запросу, например, если заданного ключа или элемента массива не существует, операторы извлечения поля/элемента/пути не выдают ошибку, а возвращают NULL.

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

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

Оператор

Описание

Пример(ы)

jsonb @> jsonb → boolean

В первое значение JSON вложено второе? (Подробную информацию о вложении см. в подразделе Проверка на вложение и существование в jsonb.)

'{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb → t

jsonb <@ jsonb → boolean

Первое значение JSON вложено во второе?

'{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb → t

jsonb ? text → boolean

Текстовая строка существует в значении JSON в качестве ключа верхнего уровня или элемента массива?

'{"a":1, "b":2}'::jsonb ? 'b' → t
'["a", "b", "c"]'::jsonb ? 'b' → t

jsonb ?| text[] → boolean

Какие-либо строки в текстовом массиве существуют в качестве ключей верхнего уровня или элементов массива?

'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] → t

jsonb ?& text[] → boolean

Все строки в текстовом массиве существуют в качестве ключей верхнего уровня или элементов массива?

'["a", "b", "c"]'::jsonb ?& array['a', 'b'] → t

jsonb || jsonb → jsonb

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

'["a", "b"]'::jsonb || '["a", "d"]'::jsonb → ["a", "b", "a", "d"]

'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb → {"a": "b", "c": "d"}

'[1, 2]'::jsonb || '3'::jsonb → [1, 2, 3]

'{"a": "b"}'::jsonb || '42'::jsonb → [{"a": "b"}, 42]

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

'[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) → [1, 2, [3, 4]]

jsonb - text → jsonb

Удаляет ключ (и его значение) из объекта JSON или соответствующие строковые значения из массива JSON.

'{"a": "b", "c": "d"}'::jsonb - 'a' → {"c": "d"}

'["a", "b", "c", "b"]'::jsonb - 'b' → ["a", "c"]

jsonb - text[] → jsonb

Удаляет все соответствующие ключи или элементы массива из левого операнда.

'{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] → {}

jsonb - integer → jsonb

Удаляет элемент массива с заданным индексом (отрицательные числа считаются с конца). Выдает ошибку, если значение JSON — не массив.

'["a", "b"]'::jsonb - 1 → ["a"]

jsonb #- text[] → jsonb

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

'["a", {"b":1}]'::jsonb #- '{1,b}' → ["a", {}]

jsonb @? jsonpath → boolean

Возвращает ли путь JSON какой-либо элемент для заданного значения JSON?

'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' → t

jsonb @@ jsonpath → boolean

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

'{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' → t

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

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

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

Функция

Описание

Пример(ы)

to_json ( anyelement ) → json

to_jsonb ( anyelement ) → jsonb

Преобразует любое значение SQL в json или jsonb. Массивы и составные объекты преобразуются рекурсивно в массивы и объекты (многомерные массивы становятся в JSON массивами массивов). В иных случаях, если задано приведение типа данных SQL к json, то для выполнения этого преобразования используется эта функция приведения;[b] для всех остальных выдается скалярное значение JSON. Значения всех скалярных типов, кроме числового, логического и NULL, будут представлены в виде текста, в который при необходимости будет добавлено экранирование символов для получения допустимого строкового значения JSON.

to_json('Fred said "Hi."'::text) → "Fred said \"Hi.\""

to_jsonb(row(42, 'Fred said "Hi."'::text)) → {"f1": 42, "f2": "Fred said \"Hi.\""}

array_to_json ( anyarray [, boolean ] ) → json

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

array_to_json('{{1,5},{99,100}}'::int[]) → [[1,5],[99,100]]

row_to_json ( record [, boolean ] ) → json

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

row_to_json(row(1,'foo')) → {"f1":1,"f2":"foo"}

json_build_array ( VARIADIC "any" ) → json

jsonb_build_array ( VARIADIC "any" ) → jsonb

Формирует массив JSON (возможно, неоднородный по типам) из переменного списка аргументов. Каждый аргумент преобразуется методом to_json или to_jsonb.

json_build_array(1, 2, 'foo', 4, 5) → [1, 2, "foo", 4, 5]

json_build_object ( VARIADIC "any" ) → json

jsonb_build_object ( VARIADIC "any" ) → jsonb

Формирует объект JSON из переменного списка аргументов. По соглашению, в списке аргументов по очереди перечисляются ключи и значения. Аргументы-ключи приводятся к текстовому типу; аргументы-значения преобразуются методом to_json или to_jsonb.

json_build_object('foo', 1, 2, row(3,'bar')) → {"foo" : 1, "2" : {"f1":3,"f2":"bar"}}

json_object ( text[] ) → json

jsonb_object ( text[] ) → jsonb

Формирует объект JSON из текстового массива. Этот массив должен иметь либо ровно одну размерность с четным числом членов (в этом случае они воспринимаются как чередующиеся пары ключ/значение), либо две размерности, и при этом каждый внутренний массив содержит ровно два элемента, которые воспринимаются как пара ключ/значение. Все значения преобразуются в строки JSON.

json_object('{a, 1, b, "def", c, 3.5}') → {"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 ( ключи text[], значения text[] ) → json

jsonb_object ( ключи text[], значения text[] ) → jsonb

Эта форма json_object принимает ключи и значения по парам из отдельных текстовых массивов. В остальном она идентична форме с одним аргументом.

json_object('{a,b}', '{1,2}') → {"a": "1", "b": "2"}

[b] Например, в расширении hstore определено приведение типа hstore к json, поэтому значения hstore, преобразованные посредством функций создания JSON, будут представлены в виде объектов JSON, а не примитивных строковых значений.

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

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

Функция

Описание

Пример(ы)

json_array_elements ( json ) → setof json

jsonb_array_elements ( jsonb ) → setof jsonb

Разворачивает массив JSON верхнего уровня в набор значений JSON.


    select * from json_array_elements('[1,true, [2,false]]') →
       value
     -----------
     1
     true
     [2,false]

json_array_elements_text ( json ) → setof text

jsonb_array_elements_text ( jsonb ) → setof text

Разворачивает массив JSON верхнего уровня в набор значений text.


    select * from json_array_elements_text('["foo", "bar"]') →
       value
    -----------
    foo
    bar

json_array_length ( json ) → integer

jsonb_array_length ( jsonb ) → integer

Возвращает количество элементов в массиве JSON верхнего уровня.

json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') → 5

json_each ( json ) → setof record ( ключ text, значение json )

jsonb_each ( jsonb ) → setof record ( ключ text, значение jsonb )

Разворачивает объект JSON верхнего уровня в набор пар ключ/значение (key/value).


    select * from json_each('{"a":"foo", "b":"bar"}') →
     key | value
    -----+-------
     a   | "foo"
     b   | "bar"

json_each_text ( json ) → setof record ( ключ text, значение text )

jsonb_each_text ( jsonb ) → setof record ( ключ text, значение text )

Разворачивает объект JSON верхнего уровня в набор пар ключ/значение (key/value). Возвращаемые значения будут иметь тип text.


    select * from json_each_text('{"a":"foo", "b":"bar"}') →
     key | value
    -----+-------
     a   | foo
     b   | bar

json_extract_path ( целевой_объект_json json, VARIADIC элементы_пути text[] ) → json

jsonb_extract_path ( целевой_объект_json jsonb, VARIADIC элементы_пути text[] ) → jsonb

Извлекает подобъект JSON по заданному пути. (Функционально это равнозначно действию оператора #>, но в некоторых случаях может быть удобнее записать путь в виде списка с переменным числом аргументов.)

json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') → "foo"

json_extract_path_text ( целевой_объект_json json, VARIADIC элементы_пути text[] ) → text

jsonb_extract_path_text ( целевой_объект_json jsonb, VARIADIC элементы_пути text[] ) → text

Извлекает подобъект JSON по заданному пути в виде значения text. (Функционально это равнозначно действию оператора #>>.)

json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') → foo

json_object_keys ( json ) → setof text

jsonb_object_keys ( jsonb ) → setof text

Возвращает набор ключей в объекте JSON верхнего уровня.


    select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') →
     json_object_keys
    ------------------
     f1
     f2

json_populate_record ( заполнение anyelement, целевой_объект_json json ) → anyelement

jsonb_populate_record ( заполнение anyelement, целевой_объект_json jsonb ) → anyelement

Разворачивает объект JSON верхнего уровня в строку, имеющую составной тип аргумента заполнение. Объект JSON сканируется на наличие полей, чьи имена соответствуют именам столбцов типа выходной строки, и их значения вставляются в эти столбцы вывода. (Поля, не соответствующие именам никаких выходных столбцов, игнорируются.) Как правило, значение заполнения просто равно NULL, что означает, что выходные столбцы не соответствующие полям объекта, будут заполнены значениями NULL. Однако если заполнение отлично от NULL, то для заполнения таких столбцов будут использованы содержащиеся в нем значения.

Для преобразования значения JSON в SQL-тип выходного столбца последовательно применяются следующие правила:

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

Хотя в следующем примере используется неизменное значение JSON, обычно выполняется обращение (с помощью LATERAL) к столбцу json или jsonb из другой таблицы, находящейся в предложении FROM того же запроса. Включение функции json_populate_record в предложение FROM — удачный прием, поскольку все извлекаемые столбцы доступны для использования без необходимости в повторных вызовах функции.


    create type subrowtype as (d int, e text); create type myrowtype as (a int, b text[],
    c subrowtype);
    select * from json_populate_record(null::myrowtype, '{"a": 1, "b": ["2", "a b"],
    "c": {"d": 4, "e": "a b c"}, "x": "foo"}') →
     a |   b       |      c
    ---+-----------+-------------
     1 | {2,"a b"} | (4,"a b c")

json_populate_recordset ( заполнение anyelement, целевой_объект_json json ) → setof anyelement

jsonb_populate_recordset ( заполнение anyelement, целевой_объект_json jsonb ) → setof anyelement

Разворачивает массив JSON верхнего уровня с объектами в набор строк, имеющих составной тип аргумента заполнение. Каждый элемент массива JSON обрабатывается так же, как описано выше для json[b]_populate_record.


    create type twoints as (a int, b int);
    select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,
    "b":4}]') →
     a | b
    ---+---
     1 | 2
     3 | 4

json_to_record ( json ) → record

jsonb_to_record ( jsonb ) → record

Разворачивает объект JSON верхнего уровня в строку, имеющую составной тип, определенный в предложении AS. (Как и со всеми функциями, возвращающими значение record, вызывающий запрос должен явно определить структуру записи в предложении AS.) Выходная запись заполняется значениями полей объекта JSON так же, как описано выше для json[b]_populate_record. Поскольку этой функции не передается значение записи, несоответствующие столбцы всегда заполняются значениями NULL.


    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 ) → setof record

jsonb_to_recordset ( jsonb ) → setof record

Разворачивает массив JSON верхнего уровня с объектами в набор строк, имеющих составной тип, определенный в предложении AS. (Как и со всеми функциями, возвращающими значение record, вызывающий запрос должен явно определить структуру записи в предложении AS.) Каждый элемент массива JSON обрабатывается так же, как описано выше для json[b]_populate_record.


    select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a
    int, b text) →
     a |  b
    ---+-----
     1 | foo
     2 |

jsonb_set ( цель jsonb, путь text[], новое_значение jsonb [, создать_если_отсутствует boolean ] ) → jsonb

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

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

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

jsonb_set_lax ( цель jsonb, путь text[], новое_значение jsonb [, создать_если_отсутствует boolean [, обращение_с_null text ]] ) → jsonb

Если новое_значение отлично от NULL, эта функция ведет себя идентично jsonb_set. В противном случае она действует согласно аргументу обращение_с_null, который может принимать значения 'raise_exception' (сгенерировать исключение), 'use_json_null' (использовать NULL в JSON), 'delete_key' (удалить ключ) или 'return_target' (вернуть цель). Значение по умолчанию — 'use_json_null'.

jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null) → [{"f1":null,"f2":null},2,null,3]

jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target') → [{"f1": 99, "f2": null}, 2]

jsonb_insert ( цель jsonb, путь text[], новое_значение jsonb [, вставить_после boolean ] ) → jsonb

Возвращает цель с вставленным в нее новым_значением. Если элемент, на который указывает путь, является элементом массива, новое_значение будет вставлено перед этим элементом, если параметр вставить_после равен false (это значение по умолчанию), или после него, если вставить_после равен true. Если элемент, на который указывает путь, является полем объекта, новое_значение будет вставлено, только если объект еще не содержит этот ключ. Все предыдущие звенья пути должны существовать, иначе цель будет возвращена без изменений. Как и с операторами, ориентированными на пути, отрицательные целые числа, находящиеся в пути, считают элементы с конца массивов JSON. Если последнее звено пути является индексом, выходящим за границы массива, новое значение добавляется в начало массива, когда индекс отрицательный, или в его конец, когда тот положительный.

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

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

json_strip_nulls ( json ) → json

jsonb_strip_nulls ( jsonb ) → jsonb

Рекурсивно удаляет из заданного значения JSON все поля объектов, имеющие значения NULL. Значения NULL, не относящиеся к полям объектов, не затрагиваются.

json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') → [{"f1":1},2,null,3]

jsonb_path_exists ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → boolean

Проверяет, возвращает ли путь JSON какой-либо элемент для заданного значения JSON. Если задается аргумент переменные, он должен быть объектом JSON, и его поля предоставляют именованные значения, подставляемые в выражение jsonpath. Если задается аргумент молча и он равен true, эта функция подавляет те же ошибки, что и операторы @? и @@.

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

jsonb_path_match ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → boolean

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

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

jsonb_path_query ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → setof jsonb

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


    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 ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → jsonb

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

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

jsonb_path_query_first ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → jsonb

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

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

jsonb_path_exists_tz ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → boolean

jsonb_path_match_tz ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → boolean

jsonb_path_query_tz ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → setof jsonb

jsonb_path_query_array_tz ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → jsonb

jsonb_path_query_first_tz ( цель jsonb, путь jsonpath [, переменные jsonb [, молча boolean ]] ) → jsonb

Данные функции действуют подобно их двойникам без суффикса _tz, за исключением того, что эти функции поддерживают сравнение значений даты/времени, которое требует преобразований с учетом часовых поясов. В следующем примере требуется интерпретация значения даты без указания времени 2015-08-02 в виде метки времени с часовым поясом, поэтому результат зависит от текущего значения параметра TimeZone. Из-за этой зависимости данные функции помечаются как стабильные, что означает, что их нельзя использовать в индексах. Их двойники являются постоянными, и поэтому могут применяться в индексах, но при запросе на подобные сравнения они будут выдавать ошибку.

jsonb_path_exists_tz('["2015-08-01 12:00:00 -05"]', '$[*] ? (@.datetime() < "2015-08-02".datetime())') → t

jsonb_pretty ( jsonb ) → text

Преобразует заданное значение JSON в структурированный текст с отступами.

jsonb_pretty('[{"f1":1,"f2":null}, 2]') →
    [
        {
            "f1": 1,
            "f2": null
        },
        2
    ]

json_typeof ( json ) → text

jsonb_typeof ( jsonb ) → text

Возвращает тип значения JSON на верхнем уровне в виде текстовой строки. Возможные типы: object, array, string, number, boolean и null. (Не следует путать результат null со значением NULL в SQL; см. примеры.)

json_typeof('-123.4') → number

json_typeof('null'::json) → null

json_typeof(NULL::json) IS NULL → t

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

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

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

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

Выражение пути состоит из последовательности элементов, допустимых для типа данных jsonpath. Обычно выражение пути вычисляется слева направо, но при желании изменить порядок операций можно воспользоваться скобками. Если вычисление прошло успешно, создается последовательность элементов 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
      }
    ]
  }
}

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

$.track.segments

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

$.track.segments[*].location

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

$.track.segments[0].location

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

$.track.segments.size()

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

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

? (условие)

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

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

Например, предположим, вы хотите получить все значения частоты сердцебиений, превышающие 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()

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

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

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

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

Строгий и нестрогий режимы

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

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

  • strict — строгий режим, в котором при возникновении структурной ошибки она выдается как есть.

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

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

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

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

lax $.track.segments.location

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

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

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

lax $.**.HR

Это происходит из-за того, что аксессор .**выбирает и массив segments, и каждый из его элементов, тогда как аксессор .HR в нестрогом режиме автоматически разворачивает массивы. Чтобы избежать неожиданных результатов, рекомендуется использовать аксессор .** только в строгом режиме. Следующий запрос выбирает каждое значение HR только один раз:

strict $.**.HR

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

В Таблице 48 показаны операторы и методы, доступные в jsonpath. Обратите внимание, что унарные операторы и методы можно применять к нескольким значениям, полученным на предыдущем этапе пути, тогда как бинарные операторы (сложение и т. п.) можно применять только к отдельным значениям.

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

Оператор/Метод

Описание

Пример(ы)

число + числочисло

Сложение

jsonb_path_query('[2]', '$[0] + 3') → 5

+ числочисло

Унарный плюс (нет операции); в отличие от сложения, он может выполнить проход по нескольким значениям

jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') → [2, 3, 4]

число - числочисло

Вычитание

jsonb_path_query('[2]', '7 - $[0]') → 5

- числочисло

Смена знака; в отличие от вычитания, он может выполнить проход по нескольким значениям

jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') → [-2, -3, -4]

число * числочисло

Умножение

jsonb_path_query('[4]', '2 * $[0]') → 8

число / числочисло

Деление

jsonb_path_query('[8.5]', '$[0] / 2') → 4.2500000000000000

число % числочисло

Остаток целочисленного деления (по модулю)

jsonb_path_query('[32]', '$[0] % 10') → 2

значение . type() → строка

Тип элемента JSON (см. json_typeof)

jsonb_path_query_array('[1, "2", {}]', '$[*].type()') → ["number", "string", "object"]

значение . size() → число

Размер элемента JSON (число элементов массива или 1, если это не массив)

jsonb_path_query('{"m": [11, 15]}', '$.m.size()') → 2

значение . double() → число

Приблизительное число с плавающей запятой, преобразованное из числа JSON или строки

jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') → 3.8

число . ceiling() → число

Ближайшее целое число, большее или равное заданному числу

jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') → 2

число . floor() → число

Ближайшее целое число, меньшее или равное заданному числу

jsonb_path_query('{"h": 1.7}', '$.h.floor()') → 1

число . abs() → число

Абсолютное значение (модуль) заданного числа

jsonb_path_query('{"z": -0.3}', '$.z.abs()') → 0.3

строка . datetime() → тип_даты_времени (см. примечание)

Значение даты/времени, преобразованное из строки

jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') → "2015-8-1"

строка . datetime(шаблон) → тип_даты_времени (see note)

Значение даты/времени, преобразованное из строки с помощью заданного шаблона to_timestamp

jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') → ["12:30:00", "18:40:00"]

объект . keyvalue() → массив

Пары ключ-значение объекта, представленные в виде массива объектов, содержащего три поля: "key" (ключ), "value" (значение) и "id"; "id" представляет собой уникальный идентификатор объекта, которому принадлежит данная пара ключ-значение

jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') → [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}]

Примечание
Результирующим типом методов datetime() и datetime(шаблон) может быть date, timetz, time, timestamptz или timestamp. Оба метода определяют свой результирующий тип динамически.

Метод datetime() последовательно пытается сопоставить свою входную строку с форматами ISO типов date, timetz, time, timestamptz и timestamp. На первом же подходящем формате он останавливается и выдает соответствующий тип данных.

Метод datetime(шаблон) определяет результирующий тип в соответствии с полями в предоставленной строке шаблона.

Методы datetime() и datetime(шаблон) применяют те же правила синтаксического анализа, что и функция SQL to_timestamp (см. раздел Функции форматирования типов данных), но с тремя исключениями. Во-первых, эти методы не позволяют использовать в шаблоне коды без соответствия. Во-вторых, в строке шаблона допускаются только следующие разделители: знак минуса, точка, косая черта (слэш), запятая, апостроф, точка с запятой, двоеточие и пробел. В-третьих, разделители в строке шаблона должны в точности соответствовать входной строке.

Если нужно сравнить разные типы даты/времени, применяется неявное приведение. Значение date можно привести к типу timestamp или timestamptz, timestamp — к типу timestamptz, а time — к типу timetz. Однако все эти преобразования, кроме первого, зависят от текущего значения TimeZone и поэтому могут выполняться только в функциях jsonpath, учитывающих часовой пояс.

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

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

Предикат/Значение

Описание

Пример(ы)

значение == значение → boolean

Сравнение равенства (этот и другие операторы сравнения работают со всеми скалярными значениями JSON)

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)') → [1, 1]

jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")') → ["a"]

значение != значение → boolean

значение <> значение → boolean

Сравнение неравенства

jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)') → [2, 3]

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <> "b")') → ["a", "c"]

значение < значение → boolean

Сравнение «меньше»

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ < 2)') → [1]

значение <= значение → boolean

Сравнение «меньше или равно»

jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <= "b")') → ["a", "b"]

значение > значение → boolean

Сравнение «больше»

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ > 2)') → [3]

значение >= значение → boolean

Сравнение «больше или равно»

jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ >= 2)') → [2, 3]

true → boolean

JSON-константа true

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)') → {"name": "Chris", "parent": true}

false → boolean

JSON-константа false

jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)') → {"name": "John", "parent": false}

null → значение

JSON-константа null (обратите внимание, что, в отличие от SQL, сравнение с null работает нормально)

jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') → "Mary"

логическое_значение && логическое_значение → boolean

Логическое И

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ > 1 && @ < 5)') → 3

логическое_значение || логическое_значение → boolean

Логическое ИЛИ

jsonb_path_query('[1, 3, 7]', '$[*] ? (@ < 1 || @ > 5)') → 7

! логическое_значение → boolean

Логическое НЕ

jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ < 5))') → 7

логическое_значение is unknown → boolean

Проверяет, является ли unknown логическим условием.

jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)') → "foo"

строка like_regex строка [ flag строка ] → boolean

Проверяет, соответствует ли первый операнд регулярному выражению, заданному во втором операнде, с необязательными модификациями, описываемыми строкой символов flag (см. подраздел Регулярные выражения SQL/JSON).

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') → ["abc", "abdacb"]

jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")') → ["abc", "aBdC", "abdacb"]

строка starts with строка → boolean

Проверяет, является ли второй операнд начальной подстрокой первого.

jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")') → "John Smith"

exists ( выражение_пути ) → boolean

Проверяет, соответствует ли выражение пути хотя бы одному элементу SQL/JSON. Возвращает unknown, если это выражение пути могло вызвать ошибку; это используется во втором примере, чтобы избежать ошибки «ключ не найден» в строгом режиме.

jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))') → [2, 4]

jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name') → []

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

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

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

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

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

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

$.* ? (@ like_regex "^\\d+$")

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

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

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

Функция

Описание

nextval ( regclass ) → bigint

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

setval ( regclass, bigint [, boolean ] ) → bigint

Устанавливает для объекта последовательности текущее значение и при необходимости флаг is_called. Форма с двумя параметрами устанавливает у последовательности заданное значение в поле last_value, а также устанавливает в поле is_called значение true, подразумевая, что при следующем вызове nextval последовательность продвинется к очередному значению, после чего вернет его. При этом currval также выдаст заданное значение. В форме с тремя параметрами в поле is_called можно установить true или false. У значения true будет тот же эффект, что и в форме с двумя параметрами. Если же присвоено значение false, то при первом вызове nextval после этого вернется именно заданное значение, а продвижение последовательности произойдет при следующем вызове nextval. Более того, в этом случае значение, выдаваемое currval, не изменится. Например:


    SELECT setval('myseq', 42);           При следующем вызове nextval вернется 43
    SELECT setval('myseq', 42, true);     То же самое
    SELECT setval('myseq', 42, false);    При следующем вызове nextval вернется 42

Результатом, возвращаемым setval, является просто значение ее второго аргумента.
Этой функции требуется право UPDATE для последовательности.

currval ( regclass ) → bigint

Возвращает значение, полученное при последнем вызове nextval для этой последовательности в текущем сеансе. (Если nextval никогда не вызывалась для этой последовательности в этом сеансе, будет выдана ошибка.) Поскольку возвращаемое значение ограничено рамками сеанса, данная функция выдает предсказуемый ответ, независимо от того, выполнялась ли потом nextval в других сеансах или нет.
Этой функции требуется право USAGE или UPDATE для последовательности.

lastval () → bigint

Возвращает значение, выданное при последнем вызове nextval в текущем сеансе. Эта функция идентична currval, за исключением того, что она не принимает в качестве аргумента имя последовательности, а обращается к той последовательности, к которой в последний раз в текущем сеансе применялась nextval. Если nextval в текущем сеансе еще не вызывалась, то при вызове lastval возникнет ошибка.
Этой функции требуется право USAGE или UPDATE для последней использованной последовательности.

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

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

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

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

Условные выражения

В этом разделе описываются SQL-совместимые условные выражения, доступные в QHB.

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

Примечание
Хотя COALESCE, GREATEST и LEAST синтаксически похожи на функции, они не являются обычными функциями и поэтому не могут использоваться с аргументами, в которых явно описан массив VARIADIC.

CASE

Выражение CASE в SQL является общим условным выражением, схожим с операторами if/else в других языках программирования:

CASE WHEN условие THEN результат
   [WHEN ...]
   [ELSE результат]
END

Предложения CASE можно использовать везде, где допускаются выражения. Каждое условие здесь — это выражение, возвращающее результат типа boolean. Если результат условия равен true, значением выражения CASE является результат, следующий за условием, а остальная часть выражения CASE не обрабатывается. Если результат условия не равен true, любые последующие предложения WHEN проверяются таким же образом. Если ни одно из условий WHEN не возвращает true, значением выражения CASE является результат предложения ELSE. Если предложение ELSE опущено и ни одно из условий не равно true, результат будет равен NULL.

Пример:

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

Типы данных всех выражений результатов должны быть преобразованы в один выходной тип.

Существует «простая» форма выражения CASE, которая представляет собой вариант общей формы, описанной выше:

CASE выражение
    WHEN значение THEN результат
  [WHEN ...]
  [ELSE результат]
END

Первое выражение вычисляется, а затем сравнивается с каждым из выражений значение в предложениях WHEN, пока не будет найдено равное ему. Если совпадений не найдено, возвращается результат предложения ELSE (или значение NULL). Эта форма похожа на оператор 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(значение [, ...])

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

SELECT COALESCE(description, short_description, '(none)') ...

Этот запрос возвращает description, если оно не равно NULL, либо short_description, если оно не равно NULL, либо (none), если они оба равны NULL.

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

Как и выражение CASE, COALESCE вычисляет только аргументы, которые необходимы для определения результата; то есть аргументы справа от первого отличного от NULL аргумента не вычисляются. Эта соответствующая стандарту SQL функция предоставляет возможности, схожие с таковыми NVL и IFNULL, использующихся в некоторых других СУБД.

NULLIF

NULLIF(значение1, значение2)

Функция NULLIF возвращает значение NULL, если значение1 равно значению2; в противном случае она возвращает значение1. Это можно использовать для выполнения операции, обратной той, что показана в приведенном выше примере COALESCE:

SELECT NULLIF(value, ’(none)’) ...

В этом примере если value равно (none), возвращается NULL, в противном случае возвращается значение value.

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

Результат имеет тот же тип, что и первый аргумент — но есть одна тонкость. Фактически возвращается первый аргумент подразумеваемого оператора =, и в некоторых случаях он преобразуется, чтобы соответствовать типу второго аргумента. К примеру, NULLIF(1, 2.2) выдает numeric, поскольку оператора integer = numeric не существует, есть лишь оператор numeric = numeric.

GREATEST и LEAST

GREATEST(значение [, ...])
LEAST(значение [, ...])

Функции GREATEST и LEAST выбирают наибольшее или наименьшее значение из списка с любым числом выражений. Все выражения должны быть преобразуемыми в общий тип данных, который и будет типом результата. Значения NULL в списке игнорируются. Результатом будет NULL, только если все выражения вычисляются как равные NULL.

Обратите внимание, что GREATEST и LEAST не входят в стандарт SQL, но относятся к распространенным расширениям. В некоторых другие базах данных они возвращают NULL, если любой из аргументов равен NULL, а не только когда все аргументы равны NULL.

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

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

Таблица 51. Операторы для массивов

Оператор

Описание

Пример(ы)

anyarray @> anyarray → boolean

Первый массив содержит второй, то есть каждый элемент, находящийся во втором массиве, равен какому-либо элементу первого? (Дубликаты обрабатываются на общих основаниях, поэтому массивы ARRAY[1] и ARRAY[1,1] считаются содержащими друг друга.)

ARRAY[1,4,3] @> ARRAY[3,1,3] → t

anyarray <@ anyarray → boolean

Первый массив содержится во втором?

ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6] → t

anyarray && anyarray → boolean

Массивы пересекаются, то есть имеют какие-либо общие элементы?

ARRAY[1,4,3] && ARRAY[2,1] → t

anycompatiblearray || anycompatiblearray → anycompatiblearray

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

ARRAY[1,2,3] || ARRAY[4,5,6,7] → {1,2,3,4,5,6,7}

ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]] → {{1,2,3},{4,5,6},{7,8,9.9}}

anycompatible || anycompatiblearray → anycompatiblearray

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

3 || ARRAY[4,5,6] → {3,4,5,6}

anycompatiblearray || anycompatible → anycompatiblearray

Конкатенирует элемент с концом массива (который должен быть пустым или одномерным).

ARRAY[4,5,6] || 7 → {4,5,6,7}

Более подробную информацию о поведении операторов для массивов см. в разделе Массивы. Более подробную информацию о том, какие операторы поддерживают операции с индексами, см. в разделе Типы индексов.

В Таблице 52 приведены функции, доступные для использования с типами массивами. Дополнительную информацию и примеры использования этих функций см. в разделе Массивы.

Таблица 52. Функции для массивов

Функция

Описание

Пример(ы)

array_append ( anycompatiblearray, anycompatible ) → anycompatiblearray

Добавляет элемент в конец массива (так же, как оператор anycompatiblearray || anycompatible).

array_append(ARRAY[1,2], 3) → {1,2,3}

array_cat ( anycompatiblearray, anycompatiblearray ) → anycompatiblearray

Конкатенирует два массива (так же, как оператор anycompatiblearray || anycompatiblearray).

array_cat(ARRAY[1,2,3], ARRAY[4,5]) → {1,2,3,4,5}

array_dims ( anyarray ) → text

Возвращает текстовое представление размерностей массива.

array_dims(ARRAY[[1,2,3], [4,5,6]]) → [1:2][1:3]

array_fill ( anyelement, integer[] [, integer[] ] ) → anyarray

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

array_fill(11, ARRAY[2,3]) → {{11,11,11},{11,11,11}}

array_fill(7, ARRAY[3], ARRAY[2]) → [2:4]={7,7,7}

array_length ( anyarray, integer ) → integer

Возвращает длину запрошенной размерности массива.

array_length(array[1,2,3], 1) → 3

array_lower ( anyarray, integer ) → integer

Возвращает нижнюю границу запрошенной размерности массива.

array_lower('[0:2]={1,2,3}'::integer[], 1) → 0

array_ndims ( anyarray ) → integer

Возвращает количество размерностей массива.

array_ndims(ARRAY[[1,2,3], [4,5,6]]) → 2

array_position ( anycompatiblearray, anycompatible [, integer ] ) → integer

Возвращает индекс первого вхождения второго аргумента в массиве или NULL, если таковой отсутствует. Если задан третий аргумент, поиск начинается с этого индекса. Массив должен быть одномерным. Сравнения производятся с применением семантики IS NOT DISTINCT FROM, что позволяет искать значения NULL.

array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'mon') → 2

array_positions ( anycompatiblearray, anycompatible ) → integer[]

Возвращает массив индексов всех вхождений второго аргумента в массиве, заданном в первом аргументе. Массив должен быть одномерным. Сравнения производятся с применением семантики IS NOT DISTINCT FROM, что позволяет искать значения NULL. NULL возвращается, только массив равен NULL; если заданное значение отсутствует в массиве, возвращается пустой массив.

array_positions(ARRAY['A','A','B','A'], 'A') → {1,2,4}

array_prepend ( anycompatible, anycompatiblearray ) → anycompatiblearray

Добавляет элемент в начало массива (так же, как оператор anycompatible || anycompatiblearray).

array_prepend(1, ARRAY[2,3]) → {1,2,3}

array_remove ( anycompatiblearray, anycompatible ) → anycompatiblearray

Удаляет из массива все элементы, равные заданному значению. Массив должен быть одномерным. Сравнения производятся с применением семантики IS NOT DISTINCT FROM, что позволяет удалять значения NULL.

array_remove(ARRAY[1,2,3,2], 2) → {1,3}

array_replace ( anycompatiblearray, anycompatible, anycompatible ) → anycompatiblearray

Заменяет каждый элемент массива, равный второму аргументу, значением третьего аргумента.

array_replace(ARRAY[1,2,5,4], 5, 3) → {1,2,3,4}

array_to_string ( массив anyarray, разделитель text [, нулевая_строка text ] ) → text

Преобразует каждый элемент массива в текстовое представление и конкатенирует те из них, что разделены строкой разделитель. Если задана нулевая_строка и она отлична от NULL, то эта строка представляет содержащиеся в массиве записи NULL; в противном случае такие записи опускаются.

array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') → 1,2,3,*,5

array_upper ( anyarray, integer ) → integer

Возвращает верхнюю границу запрошенной размерности массива.

array_upper(ARRAY[1,8,3,7], 1) → 4

cardinality ( anyarray ) → integer

Возвращает общее количество элементов в массиве или 0, если это пустой массив.

cardinality(ARRAY[[1,2],[3,4]]) → 4

trim_array ( массив anyarray, n integer ) → anyarray

Усекает массив, удаляя последние n элементов. Если массив многомерный, усекается только первая размерность.

trim_array(ARRAY[1,2,3,4,5,6], 2) → {1,2,3,4}

unnest ( anyarray ) → setof anyelement

Разворачивает массив в набор строк. Элементы массива прочитываются в порядке хранения.


    unnest(ARRAY[1,2]) →
         1
         2


    unnest(ARRAY[['foo','bar'],['baz','quux']]) →
         foo
         bar
         baz
         quux

unnest ( anyarray, anyarray [, ... ] ) → setof anyelement, anyelement [, ... ]

Разворачивает несколько массивов (возможно, разных типов данных) в набор строк. Если у массивов неодинаковая длина, то более короткие заполняются значениями NULL. Эта форма допускается только в предложении FROM; см. подраздел Табличные функции.


    select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) →
         a |  b
        ---+-----
         1 | foo
         2 | bar
           | baz

Описание работающей с массивами функции array_agg см. в разделе Агрегатные функции.

Диапазонные/мультидиапазонные функции и операторы

Описание диапазонных типов данных см. в разделе Диапазонные типы.

В Таблице 53 приведены специальные операторы, доступные для диапазонных типов. В Таблице 54 приведены специальные операторы, доступные для мультидиапазонных типов. Помимо них для диапазонных и мультидиапазонных типов доступны обычные операторы сравнения, перечисленные в Таблице 1. Операторы сравнения сначала сравнивают нижние границы диапазонов, и только если они равны, сравнивают верхние границы. Мультидиапазонные операторы сравнивают каждый диапазон, пока не найдут неравный. Такие операции обычно не приводят к полезному в целом упорядочиванию, но зато позволяют строить по диапазонам уникальные индексы.

Таблица 53. Диапазонные операторы

Оператор

Описание

Пример(ы)

anyrange @> anyrange → boolean

Первый диапазон содержит второй?

int4range(2,4) @> int4range(2,3) → t

anyrange @> anyelement → boolean

Диапазон содержит этот элемент?

'[2011-01-01,2011-03-01)'::tsrange @> '2011-01-10'::timestamp → t

anyrange <@ anyrange → boolean

Первый диапазон содержится во втором?

int4range(2,4) <@ int4range(1,7) → t

anyelement <@ anyrange → boolean

Элемент содержится в этом диапазоне?

42 <@ int4range(1,7) → f

anyrange && anyrange → boolean

Диапазоны пересекаются, то есть имеют какие-либо общие элементы?

3 || ARRAY[4,5,6] → {3,4,5,6}

anyrange << anyrange → boolean

Первый диапазон находится строго слева от второго?

int8range(1,10) << int8range(100,110) → t

anyrange >> anyrange → boolean

Первый диапазон находится строго справа от второго?

int8range(50,60) >> int8range(20,30) → t

anyrange &< anyrange → boolean

Первый диапазон не простирается правее второго?

int8range(1,20) &< int8range(18,20) → t

anyrange &> anyrange → boolean

Первый диапазон не простирается левее второго?

int8range(7,20) &> int8range(5,10) → t

anyrange -|- anyrange → boolean

Диапазоны граничат друг с другом?

numrange(1.1,2.2) -|- numrange(2.2,3.3) → t

anyrange + anyrange → anyrange

Вычисляет объединение диапазонов. Диапазоны должны пересекаться или граничить друг с другом, чтобы их объединение было одним диапазоном (но см. range_merge()).

numrange(5,15) + numrange(10,20) → [5,20)

anyrange * anyrange → anyrange

Вычисляет пересечение диапазонов.

int8range(5,15) * int8range(10,20) → [10,15)

anyrange - anyrange → anyrange

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

int8range(5,15) - int8range(10,20) → [5,10)

Таблица 54. Мультидиапазонные операторы

Оператор

Описание

Пример(ы)

anymultirange @> anymultirange → boolean

Первый мультидиапазон содержит второй?

'{[2,4)}'::int4multirange @> '{[2,3)}'::int4multirange → t

anymultirange @> anyrange → boolean

Мультидиапазон содержит этот диапазон?

'{[2,4)}'::int4multirange @> int4range(2,3) → t

anymultirange @> anyelement → boolean

Мультидиапазон содержит этот элемент?

'{[2011-01-01,2011-03-01)}'::tsmultirange @> '2011-01-10'::timestamp → t

anyrange @> anymultirange → boolean

Диапазон содержит этот мультидиапазон?

'[2,4)'::int4range @> '{[2,3)}'::int4multirange → t

anymultirange <@ anymultirange → boolean

Первый мультидиапазон содержится во втором?

'{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange → t

anymultirange <@ anyrange → boolean

Мультидиапазон содержится в этом диапазоне?

'{[2,4)}'::int4multirange <@ int4range(1,7) → t

anyrange <@ anymultirange → boolean

Диапазон содержится в этом мультидиапазоне?

int4range(2,4) <@ '{[1,7)}'::int4multirange → t

anyelement <@ anymultirange → boolean

Элемент содержится в этом мультидиапазоне?

42 <@ '{[1,7)}'::int4multirange → t

anymultirange && anymultirange → boolean

Мультидиапазоны пересекаются, то есть имеют какие-либо общие элементы?

'{[3,7)}'::int8multirange && '{[4,12)}'::int8multirange → t

anymultirange && anyrange → boolean

Мультидиапазон пересекает этот диапазон?

'{[3,7)}'::int8multirange && int8range(4,12) → t

anyrange && anymultirange → boolean

Диапазон пересекает этот мультидиапазон?

int8range(3,7) && '{[4,12)}'::int8multirange → t

anymultirange << anymultirange → boolean

Первый мультидиапазон находится строго слева от второго?

'{[1,10)}'::int8multirange << '{[100,110)}'::int8multirange → t

anymultirange << anyrange → boolean

Мультидиапазон находится строго слева от этого диапазона?

'{[1,10)}'::int8multirange << int8range(100,110) → t

anyrange << anymultirange → boolean

Диапазон находится строго слева от этого мультидиапазона?

int8range(1,10) << '{[100,110)}'::int8multirange → t

anymultirange >> anymultirange → boolean

Первый мультидиапазон находится строго справа от второго?

'{[50,60)}'::int8multirange >> '{[20,30)}'::int8multirange → t

anymultirange >> anyrange → boolean

Мультидиапазон находится строго справа от этого диапазона?

'{[50,60)}'::int8multirange >> int8range(20,30) → t

anyrange >> anymultirange → boolean

Диапазон находится строго справа от этого мультидиапазона?

int8range(50,60) >> '{[20,30)}'::int8multirange → t

anymultirange &< anymultirange → boolean

Первый мультидиапазон не простирается правее второго?

'{[1,20)}'::int8multirange &< '{[18,20)}'::int8multirange → t

anymultirange &< anyrange → boolean

Мультидиапазон не простирается правее этого диапазона?

'{[1,20)}'::int8multirange &< int8range(18,20) → t

anyrange &< anymultirange → boolean

Диапазон не простирается правее этого мультидиапазона?

int8range(1,20) &< '{[18,20)}'::int8multirange → t

anymultirange &> anymultirange → boolean

Первый мультидиапазон не простирается левее второго?

'{[7,20)}'::int8multirange &> '{[5,10)}'::int8multirange → t

anymultirange &> anyrange → boolean

Мультидиапазон не простирается левее этого диапазона?

'{[7,20)}'::int8multirange &> int8range(5,10) → t

anyrange &> anymultirange → boolean

Диапазон не простирается левее этого мультидиапазона?

int8range(7,20) &> '{[5,10)}'::int8multirange → t

anymultirange -|- anymultirange → boolean

Мультидиапазоны граничат друг с другом?

'{[1.1,2.2)}'::nummultirange -|- '{[2.2,3.3)}'::nummultirange → t

anymultirange -|- anyrange → boolean

Мультидиапазон граничит с этим диапазоном?

'{[1.1,2.2)}'::nummultirange -|- numrange(2.2,3.3) → t/code>

anyrange -|- anymultirange → boolean

Диапазон граничит с этим мультидиапазоном?

numrange(1.1,2.2) -|- '{[2.2,3.3)}'::nummultirange → t

anymultirange + anymultirange → anymultirange

Вычисляет объединение мультидиапазонов. Мультидиапазонам необязательно пересекаться или граничить друг с другом.

'{[5,10)}'::nummultirange + '{[15,20)}'::nummultirange → {[5,10), [15,20)}

anymultirange * anymultirange → anymultirange

Вычисляет пересечение мультидиапазонов.

'{[5,15)}'::int8multirange * '{[10,20)}'::int8multirange → {[10,15)}

anymultirange - anymultirange → anymultirange

Вычисляет разность мультидиапазонов.

'{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange → {[5,10), [15,20)}

Операторы слева/справа/граничит всегда возвращают false, когда один из диапазонов или мультидиапазонов пуст; то есть считается, что пустой диапазон находится не перед и не после какого-либо другого диапазона.

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

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

В Таблице 55 приведены функции, доступные для диапазонных типов. В Таблице 56 приведены функции для мультидиапазонных типов.

Таблица 55. Диапазонные функции

Функция

Описание

Пример(ы)

lower ( anyrange ) → anyelement

Извлекает нижнюю границу диапазона (NULL, если диапазон пуст или его нижняя граница бесконечна).

lower(numrange(1.1,2.2)) → 1.1

upper ( anyrange ) → anyelement

Извлекает верхнюю границу диапазона (NULL, если диапазон пуст или его верхняя граница бесконечна).

upper(numrange(1.1,2.2)) → 2.2

isempty ( anyrange ) → boolean

Диапазон пустой?

isempty(numrange(1.1,2.2)) → f

lower_inc ( anyrange ) → boolean

Нижняя граница диапазона включена в него?

lower_inc(numrange(1.1,2.2)) → t

upper_inc ( anyrange ) → boolean

Верхняя граница диапазона включена в него?

upper_inc(numrange(1.1,2.2)) → f

lower_inf ( anyrange ) → boolean

Нижняя граница диапазона бесконечна?

lower_inf('(,)'::daterange) → t

upper_inf ( anyrange ) → boolean

Верхняя граница диапазона бесконечна?

upper_inf('(,)'::daterange) → t

range_merge ( anyrange, anyrange ) → anyrange

Вычисляет наименьший диапазон, включающий оба заданных диапазона.

range_merge('[1,2)'::int4range, '[3,4)'::int4range) → [1,4)

Таблица 56. Мультидиапазонные функции

Функция

Описание

Пример(ы)

lower ( anymultirange ) → anyelement

Извлекает нижнюю границу мультидиапазона (NULL, если мультидиапазон пуст или его нижняя граница бесконечна).

lower('{[1.1,2.2)}'::nummultirange) → 1.1

upper ( anymultirange ) → anyelement

Извлекает верхнюю границу мультидиапазона (NULL, если мультидиапазон пуст или его верхняя граница бесконечна).

upper('{[1.1,2.2)}'::nummultirange) → 2.2

isempty ( anymultirange ) → boolean

Мультидиапазон пустой?

isempty('{[1.1,2.2)}'::nummultirange) → f

lower_inc ( anymultirange ) → boolean

Нижняя граница мультидиапазона включена в него?

lower_inc('{[1.1,2.2)}'::nummultirange) → t

upper_inc ( anymultirange ) → boolean

Верхняя граница мультидиапазона включена в него?

upper_inc('{[1.1,2.2)}'::nummultirange) → f

lower_inf ( anymultirange ) → boolean

Нижняя граница мультидиапазона бесконечна?

lower_inf('{(,)}'::datemultirange) → t

upper_inf ( anymultirange ) → boolean

Верхняя граница мультидиапазона бесконечна?

upper_inf('{(,)}'::datemultirange) → t

range_merge ( anymultirange ) → anyrange

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

range_merge('{[1,2), [3,4)}'::int4multirange) → [1,4)

multirange ( anyrange ) → anymultirange

Возвращает мультидиапазон, содержащий только заданный диапазон.

multirange('[1,2)'::int4range) → {[1,2)}

unnest ( anymultirange ) → setof anyrange

Разворачивает мультидиапазон в набор диапазонов. Диапазоны прочитываются в порядке хранения (по возрастанию)


    unnest('{[1,2), [3,4)}'::int4multirange) →
         [1,2)
         [3,4)

Функции lower_inc, upper_inc, lower_inf и upper_inf возвращают false, если диапазон или мультидиапазон пуст.

Агрегатные функции

Агрегатные функции вычисляют единственный результат из набора входных значений. Встроенные агрегатные функции общего назначения перечислены в Таблице 57, а статистические агрегаты — в Таблице 58. Встроенные внутригрупповые упорядочивающие агрегатные функции перечислены в Таблице 59, а встроенные внутригрупповые гипотезирующие — в Таблице 60. Операции группировки, тесно связанные с агрегатными функциями, перечислены в Таблице 61. Особые рекомендации по синтаксису для агрегатных функций приведены в подразделе Агрегатные выражения. Дополнительную вводную информацию см. в разделе введения в язык SQL Агрегатные функции.

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

Таблица 57. Агрегатные функции общего назначения

Функция
Частичный режим

Описание

array_agg ( anynonarray ) → anyarray

Нет

Собирает всех входные значения, включая NULL, в массив.

array_agg ( anyarray ) → anyarray

Нет

Конкатенирует все входные массивы в массив с размерностью больше на один. (Входные массивы должны иметь одинаковую размерность и не могут быть пустыми или равны NULL.)

avg ( smallint ) → numeric

avg ( integer ) → numeric

avg ( bigint ) → numeric

avg ( numeric ) → numeric

avg ( real ) → double precision

avg ( double precision ) → double precision

avg ( interval ) → interval

Да

Вычисляет среднее арифметическое все входных значений, отличных от NULL.

bit_and ( smallint ) → smallint

bit_and ( integer ) → integer

bit_and ( bigint ) → bigint

bit_and ( bit ) → bit

Да

Вычисляет побитовое И для всех входных значений, отличных от NULL.

bit_or ( smallint ) → smallint

bit_or ( integer ) → integer

bit_or ( bigint ) → bigint

bit_or ( bit ) → bit

Да

Вычисляет побитовое ИЛИ для всех входных значений, отличных от NULL.

bit_xor ( smallint ) → smallint

bit_xor ( integer ) → integer

bit_xor ( bigint ) → bigint

bit_xor ( bit ) → bit

Да

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

bool_and ( boolean ) → boolean

Да

Возвращает true, если все отличные от NULL входные значения равны true, в противном случае — false.

bool_or ( boolean ) → boolean

Да

Возвращает true, если какое-либо отличное от NULL входное значение равно true, в противном случае — false.

count ( * ) → bigint

Да

Вычисляет количество входных строк.

count ( "any" ) → bigint

Да

Вычисляет количество входных строк, в которых входное значение отлично от NULL.

every ( boolean ) → boolean

Да

Это соответствующий стандарту SQL аналог bool_and.

json_agg ( anyelement ) → json

jsonb_agg ( anyelement ) → jsonb

Нет

Собирает все входные значения, включая NULL, в массив JSON. Значения преобразуются в JSON методом to_json или to_jsonb.

json_object_agg ( ключ "any", значение "any" ) → json

jsonb_object_agg ( ключ "any", значение "any" ) → jsonb

Нет

Собирает все пары ключ/значение в объект JSON. Аргументы-ключи приводятся к текстовому типу; аргументы-значения преобразуются методом to_json или to_jsonb. Значения могут быть NULL, но ключи — нет.

max ( см. описание ) → тот же тип, что и на входе

Да

Вычисляет максимальное из входных значений, отличных от NULL. Доступна для всех числовых, строковых, перечислимых типов и типов даты/времени, а также для типов inet, interval, money, oid, pg_lsn, tid и массивов любого из этих типов.

min ( см. описание ) → тот же тип, что и на входе

Да

Вычисляет минимальное из входных значений, отличных от NULL. Доступна для всех числовых, строковых, перечислимых типов и типов даты/времени, а также для типов inet, interval, money, oid, pg_lsn, tid и массивов любого из этих типов.

range_agg ( значение anyrange ) → anymultirange

Нет

Вычисляет объединение входных значений, отличных от NULL.

range_intersect_agg ( значение anyrange ) → anymultirange

Нет

Вычисляет пересечение входных значений, отличных от NULL.

string_agg ( значение text, разделитель text ) → text

string_agg ( значение bytea, разделитель bytea ) → bytea

Нет

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

sum ( smallint ) → bigint

sum ( integer ) → bigint

sum ( bigint ) → numeric

sum ( numeric ) → numeric

sum ( real ) → real

sum ( double precision ) → double precision

sum ( interval ) → interval

sum ( money ) → money

Да

Вычисляет сумму входных значений, отличных от NULL.

xmlagg ( xml ) → xml

Нет

Конкатенирует отличные от NULL входные значения XML (см. подраздел xmlagg).

Следует отметить, что, за исключением count, эти функции возвращают значение NULL, когда не выбрана ни одна строка. В частности, в отсутствие строк sum возвращает это значение вместо нуля (как можно было бы ожидать), а 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;

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

Примечание
Логические агрегаты bool_and и bool_or аналогичны описанным в стандарте SQL агрегатам every и any или some. QHB поддерживает every, но не any или some, поскольку в стандартном синтаксисе присутствует неоднозначность:

SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;

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

Примечание
Пользователи, привыкшие работать с другими СУБД SQL, могут быть разочарованы производительностью агрегата count, когда он применяется к целой таблице. Подобный запрос:

SELECT count(*) FROM sometable;

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

В Таблице 58 приведены агрегатные функции, обычно используемые в статистическом анализе. (Они отделены просто для того, чтобы избежать загромождения списка более часто используемых агрегатных функций). Функции, показанные как принимающие числовой_тип, доступны для типов smallint, integer, bigint, numeric, real и double precision. Когда в описании упоминается N, это означает количество входных строк, для которых все входные выражения отличны от NULL. Во всех случаях, когда вычисление не имеет смысла, например, когда N равно нулю, возвращается NULL.

Таблица 58. Агрегатные функции для статистики

Функция
Частичный режим

Описание

corr ( Y double precision, X double precision ) → double precision

Да

Вычисляет коэффициент корреляции.

covar_pop ( Y double precision, X double precision ) → double precision

Да

Вычисляет ковариацию совокупности.

covar_samp ( Y double precision, X double precision ) → double precision

Да

Вычисляет выборочную ковариацию.

regr_avgx ( Y double precision, X double precision ) → double precision

Да

Вычисляет среднее для независимой переменной, sum(X)/N.

regr_avgy ( Y double precision, X double precision ) → double precision

Да

Вычисляет среднее для зависимой переменной, sum(Y)/N.

regr_count ( Y double precision, X double precision ) → bigint

Да

Вычисляет число строк, в которых оба входных выражения отличны от NULL.

regr_intercept ( Y double precision, X double precision ) → double precision

Да

Вычисляет пересечение с осью y линейного уравнения, решенного подбором по методу наименьших квадратов по парам (X, Y).

regr_r2 ( Y double precision, X double precision ) → double precision

Да

Вычисляет квадрат коэффициента корреляции.

regr_slope ( Y double precision, X double precision ) → double precision

Да

Вычисляет наклон линейного уравнения, решенного подбором по методу наименьших квадратов по парам (X, Y).

regr_sxx ( Y double precision, X double precision ) → double precision

Да

Вычисляет «сумму квадратов» независимой переменной, sum(X^2) - sum(X)^2/N.

regr_sxy ( Y double precision, X double precision ) → double precision

Да

Вычисляет «сумму произведений» независимой и зависимой переменных, sum(X*Y) - sum(X) * sum(Y)/N.

regr_syy ( Y double precision, X double precision ) → double precision

Да

Вычисляет «сумму квадратов» зависимой переменной, sum(Y^2) - sum(Y)^2/N.

stddev ( числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Это исторический псевдоним stddev_samp.

числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Вычисляет стандартное отклонение по совокупности входных значений.

stddev_samp ( числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Вычисляет стандартное отклонение по выборке входных значений.

variance ( числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Это исторический псевдоним var_samp.

var_pop ( числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Вычисляет дисперсию совокупности входных значений (квадрат стандартного отклонения по совокупности).

var_samp ( числовой_тип ) → double precision для real или double precision, иначе numeric

Да

Вычисляет дисперсию выборки входных значений (квадрат стандартного отклонения по выборке).

В Таблице 59 приведены некоторые агрегатные функции, использующие синтаксис упорядочивающих агрегатов. Эти функции иногда называют функциями «обратного распределения». Их агрегированные входные данные добавляются указанием ORDER BY, а кроме того они могут принимать непосредственный аргумент, который не агрегируется, но вычисляется только один раз. Все эти функции игнорируют значения NULL в агрегируемых входных данных. Для функций, принимающих параметр fraction, его значение должно быть между 0 и 1; в противном случае возникнет ошибка. Однако если fraction имеет значение NULL, то и результат будет NULL.

Таблица 59. Упорядочивающие функции

Функция
Частичный режим

Описание

mode () WITHIN GROUP ( ORDER BY anyelement ) → anyelement

Нет

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

percentile_cont ( дробь double precision ) WITHIN GROUP ( ORDER BY double precision ) → double precision

percentile_cont ( дробь double precision ) WITHIN GROUP ( ORDER BY interval ) → interval

Нет

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

percentile_cont ( дроби double precision[] ) WITHIN GROUP ( ORDER BY double precision ) → double precision[]

percentile_cont ( дроби double precision[] ) WITHIN GROUP ( ORDER BY interval ) → interval[]

Нет

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

percentile_disc ( дробь double precision ) WITHIN GROUP ( ORDER BY anyelement ) → anyelement

Нет

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

percentile_disc ( дроби double precision[] ) WITHIN GROUP ( ORDER BY anyelement ) → anyarray

Нет

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

Все «гипотезирующие» агрегаты, перечисленные в Таблице 60, связаны с одноименными оконными функциями, определенными в разделе Оконные функции. Во всех случаях результат этих агрегатов представляет собой значение, которое связанная оконная функция вернула бы для «гипотетической» строки, сформированной из аргументов, если бы такая строка была добавлена в упорядоченную группу строк, представленную отсортированными_аргументами. Для каждой из этих функций список непосредственных аргументов, заданный в параметре аргументы, должен соответствовать числу и типу агрегируемых аргументов, заданных в параметре отсортированные_аргументы. В отличие от большинства встроенных агрегатов, эти агрегаты не являются строгими, то есть они не опускают входные строки, содержащие NULL. Значения NULL сортируются согласно правилу, заданному в предложении ORDER BY.

Таблица 60. Гипотезирующие агрегатные функции

Функция
Частичный режим

Описание

rank ( аргументы ) WITHIN GROUP ( ORDER BY отсортированные_аргументы ) → bigint

Нет

Вычисляет ранг гипотетической строки с пропусками, то есть номер первой строки в одноранговой с ней группе.

dense_rank ( аргументы ) WITHIN GROUP ( ORDER BY отсортированные_аргументы ) → bigint

Нет

Вычисляет ранг гипотетической строки без пропусков; в сущности, эта функция считает одноранговые группы.

percent_rank ( аргументы ) WITHIN GROUP ( ORDER BY отсортированные_аргументы ) → double precision

Нет

Вычисляет относительный ранг гипотетической строки, то есть (rank - 1) / (общее число строк - 1). Таким образом, это значение лежит в диапазоне от 0 до 1, включая границы.

cume_dist ( аргументы ) WITHIN GROUP ( ORDER BY отсортированные_аргументы ) → double precision

Нет

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

Таблица 61. Операции группировки

Функция

Описание

GROUPING ( выражение(я)_group_by ) → integer

Возвращает битовую маску, показывающую, какие выражения GROUP BY не включены в текущий группирующий набор. Биты присваиваются самому правому аргументу, соответствующему младшему значащему биту; каждый бит равен 0, если соответствующее выражение включено в критерий группировки группирующего набора, генерирующего текущую результирующую строку, и 1, если оно туда не включено.

Операции группировки, приведенные в Таблице 61, применяются совместно с группирующими наборами (см. подраздел GROUPING SETS, CUBE и ROLLUP) для различения результирующих строк. Аргументы функции GROUPING на самом деле не вычисляются, но они должны в точности соответствовать выражениям, заданным в предложении GROUP BY на их уровне запроса. Например:

=> 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)

Здесь значение grouping, равное 0 в первых четырех строках, показывает, что эти строки были сгруппированы обычным образом, по обоим группирующим столбцам. Значение 1 показывает, что столбец model не был группирующим в двух предпоследних строках, а значение 3 показывает, что в последней строке не были группирующими ни make, ни model (то есть агрегирование проводилось по всем входным строкам).

Оконные функции

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

Встроенные оконные функции перечислены в Таблице 62. Обратите внимание, что эти функции должны вызываться с использованием синтаксиса оконных функций, то есть необходимо предложение OVER.

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

Таблица 62. Универсальные оконные функции

Функция

Описание

row_number () → bigint

Возвращает номер текущей строки в ее партиции, считая с 1.

rank () → bigint

Возвращает ранг текущей строки с пропусками, то есть row_number первой строки в одноранговой с ней группе.

dense_rank () → bigint

Возвращает ранг текущей строки без пропусков; в сущности, эта функция считает одноранговые группы.

percent_rank () → double precision

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

cume_dist () → double precision

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

ntile ( число_участков_памяти integer ) → integer

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

lag ( значение anycompatible [, сдвиг integer [, значение_по_умолчанию anycompatible ]] ) → anycompatible

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

lead ( значение anycompatible [, сдвиг integer [, значение_по_умолчанию anycompatible ]] ) → anycompatible

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

first_value ( значение anyelement ) → anyelement

Возвращает значение, вычисленное для первой строки в рамке окна.

last_value ( значение anyelement ) → anyelement

Возвращает значение, вычисленное для последней строки в рамке окна.

nth_value ( значение anyelement, n integer ) → anyelement

Возвращает значение, вычисленное для n-й строки в рамке окна (считая с 1); возвращает NULL, если такой строки нет.

Все функции, перечисленные в Таблице 62, зависят от порядка сортировки, заданного в предложении 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. Для получения других результатов можно использовать другие спецификации рамок.

Примечание
В стандарте SQL определены параметры RESPECT NULLS или IGNORE NULLS для функций lead, lag, first_value, last_value и nth_value. В QHB это не реализовано: поведение этих функций всегда соответствует описанному в стандарте как поведение по умолчанию, а именно, с параметром RESPECT NULLS. Аналогичным образом для функции nth_value не реализованы стандартные параметры FROM FIRST или FROM LAST: поддерживается только поведение по умолчанию — с параметром FROM FIRST. (Результата как у параметра FROM LAST можно добиться, изменив порядок ORDER BY на обратный.)

Выражения подзапроса

В этом разделе описываются 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 для машиночитаемой версии.
qhb_commit_id()textВозвращает текущий номер зафиксированной транзакции.

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, для получения задержки репликации.

Подробнее о правильном использовании этих функций см. в разделе Непрерывное архивирование и восстановление на момент времени (PITR).

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

Функции, показанные в таблице 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 () или связанных функций дает им во