Re: OPERATOR CLASS - Mailing list pgsql-ru-general

From Nikita Glukhov
Subject Re: OPERATOR CLASS
Date
Msg-id 3b78bd3f-f051-3ff0-97db-e2f4f9a7ab54@postgrespro.ru
Whole thread Raw
In response to Re: OPERATOR CLASS  (Nikita Glukhov <n.gluhov@postgrespro.ru>)
List pgsql-ru-general

On 11.04.2019 5:40, Dmitry E. Oboukhov wrote:

11.04.2019, 01:58, "Nikita Glukhov" <n.gluhov@postgrespro.ru>:
 
 FUNCTION 1 btint4cmp, 
 FUNCTION 2 gin_extract_jsonb_path, 
 FUNCTION 3 gin_extract_jsonb_query_path, 
 FUNCTION 4 gin_consistent_jsonb_path,
 FUNCTION 6 gin_triconsistent_jsonb_path,
STORAGE integer;
 
А вот по этим функциям где-то можно почитать разъяснения?

В официальной документации вроде бы все достаточно подробно описано:

https://www.postgresql.org/docs/11/gin-extensibility.html (на английском)
https://postgrespro.ru/docs/postgresql/11/gin-extensibility (на русском)

 
насколько я понимаю функция 1 - сравнивает именно то, что возвращает функция 2
функция 3 нужна за тем же зачем и функция 2, но она работает над запросом
 
то есть если у нас
 
WHERE json_field @> json_query
 
то реально получается следующее
 
json_field пропускается через функцию 2 при индексировании
json_query - пропускается через функцию 3 при самом запросе
функция 1 используется для сравнения двух элементов между собой

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

 а вот функции 4 и 6 - они для чего используются?

В документации про это написано, но если будут вопросы, отвечу на них.

Вот файл, в котором находится реализация этих функций для jsonb:
https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/jsonb_gin.c

и вот еще вопрос. Некоторые из этих функций принимают internal в виде аргументов, соответственно вызвать их и посмотреть их поведение прямо из SELECT - непонятно как.
 
соответственно непонятно - как полностью с нуля написать свой OPERATOR CLASS не используя программирование на C (допустим хотим сделать скетч на SQL, возможно ли это сделать?)


Да, все GIN-функции, за исключением первой compare(), можно написать сейчас только на C, и вызывать их из SQL нельзя. Но можно попробовать сделать один раз специальный обобщенный OPERATOR CLASS, в котором из функциий 2-6, написанных на C, будут вызываться другие функции с соответствующими номерами (например, 12-16), в которых уже будут использоваться только SQL-типы. Но полностью перенести всю функциональность C-функций на уровень SQL будет не так просто, потому что многие функции могут возвращать несколько значений сразу, а внутри Postgres, по-моему, нет такого удобного способа вызова для функций с OUT-параметрами, который есть для обычных функций. Например,

  Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)

возвращает массив извлеченных элементов, а также необязательные массив флагов pmatch, массив произвольных С-указателй extra_data, массив null-флагов nullFlags, и режим поиска searchMode. Если оставить только обязательный массив элементов, то сигнатрура SQL-функции extract_query будет совсем простой:
 
   extract_query (query anyelement, strategy int2) RETURNS storage_type[]

но я не уверен, что с anyelement не возникнет каких-либо проблем.

И еще хочу на всякий случай напомнить, что у нас есть еще расширение JsQuery (https://github.com/postgrespro/jsquery), которое содержит опклассы, позволяющие выполнять по GIN-индексам более широкий ряд jsonb-запросов (например, range-запросов, которые реализованы с использования partialMatch). Возможно даже, что JsQuery решит Вашу задачу. Сейчас мы работает в JsQuery на поддержкой jsonpath, который выйдет в PostgreSQL12, а в будущем планируем даже перенести эти JsQuery-опклассы в ядро.

--
Nikita Glukhov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

pgsql-ru-general by date:

Previous
From: Nikita Glukhov
Date:
Subject: Re: OPERATOR CLASS
Next
From: Nikita Glukhov
Date:
Subject: Re: OPERATOR CLASS