pg.ddx.io  pgsql-ru-general@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Nikita Glukhov <n.gluhov@postgrespro.ru>
To: Dmitry E. Oboukhov <unera@debian.org>
Cc: pgsql-ru-general@lists.postgresql.org
Subject: Re: OPERATOR CLASS
Date: Thu, 11 Apr 2019 01:58:09 +0300
Message-ID: <e74bf466-c22b-ab29-be29-fa960aeb84d0@postgrespro.ru> (raw)
In-Reply-To: <10196171554829471@iva7-6548a8037c6d.qloud-c.yandex.net>
References: <10196171554829471@iva7-6548a8037c6d.qloud-c.yandex.net>

 > Есть вопросы по сабжу.

 > 1. Можно ли как-то их просматривать в консоли (команды \d* не нашел).

У нас есть патч для psql, который реализует требуемые команды для показа 
информации об опклассах.
(см. тред "Psql patch to show access methods info" 
https://www.postgresql.org/message-id/flat/1529675324.14193.5.camel%40postgrespro.ru)
Но он, к сожалению, уже не войдет в PostgreSQL 12.

Пример вывода этих команд для интересующего Вас jsonb_path_ops:

\dAo+ gin jsonb_path_ops
                         List operators of family related to access method
  AM  | Opfamily Schema | Opfamily Name  |       Operator       | Strategy | Purpose | Sort family
-----+-----------------+----------------+----------------------+----------+---------+-------------
  gin | pg_catalog      | jsonb_path_ops | @> (jsonb, jsonb)    |        7 | search  |
  gin | pg_catalog      | jsonb_path_ops | @? (jsonb, jsonpath) |       15 | search  |
  gin | pg_catalog      | jsonb_path_ops | @@ (jsonb, jsonpath) |       16 | search  |


\dAp+ gin jsonb_path_ops
                               List of operator family procedures
  AM  | Family schema |  Family name   | Left  | Right | Number |          Proc name
-----+---------------+----------------+-------+-------+--------+------------------------------
  gin | pg_catalog    | jsonb_path_ops | jsonb | jsonb |      1 | btint4cmp
  gin | pg_catalog    | jsonb_path_ops | jsonb | jsonb |      2 | gin_extract_jsonb_path
  gin | pg_catalog    | jsonb_path_ops | jsonb | jsonb |      3 | gin_extract_jsonb_query_path
  gin | pg_catalog    | jsonb_path_ops | jsonb | jsonb |      4 | gin_consistent_jsonb_path
  gin | pg_catalog    | jsonb_path_ops | jsonb | jsonb |      6 | gin_triconsistent_jsonb_path
(5 rows)

\dAc gin jsonb*
              Operator classes for index AM "gin"
  Input type | Storage type |    Operator class    | Default?
------------+--------------+----------------------+----------
  jsonb      | text         | jsonb_ops            | yes
  jsonb      | integer      | jsonb_path_ops       | no

Если есть какие-то пожелания, каким хотелось бы видеть вывод этих 
команд, мы рады будем их выслушать (а сообщение в том треде о полезности 
этих команд от пользователя-разработчика опклассов, думаю, очень поможет 
их продвижению в PostgreSQL 13).

 > Если нет - в каких-то внутренних схемах?

pg_opclass, pg_opfamily, pg_amop, pg_amproc:

SELECT
   amopstrategy AS "Strategy",
   amoppurpose AS "Purpose",
   oprname AS "Operator",
   amoplefttype::regtype AS "Left type",
   amoprighttype::regtype AS "Right type"
FROM
   pg_amop amop,
   pg_opfamily opf,
   pg_operator opr
WHERE
   opfname = 'jsonb_path_ops' AND
   amopfamily = opf.oid AND
   amopopr = opr.oid;

  Strategy | Purpose | Operator | Left type | Right type
----------+---------+----------+-----------+------------
         7 | s       | @>       | jsonb     | jsonb
        15 | s       | @?       | jsonb     | jsonpath
        16 | s       | @@       | jsonb     | jsonpath
(3 rows)


SELECT
   amprocnum AS "Number",
   amproc::regproc AS "Function",
   amproclefttype::regtype AS "Left type",
   amprocrighttype::regtype AS "Right type"
FROM
   pg_amproc,
   pg_opfamily
WHERE
   opfname = 'jsonb_path_ops' AND
   amprocfamily = pg_opfamily.oid;

  Number |           Function           | Left type | Right type
--------+------------------------------+-----------+------------
       1 | btint4cmp                    | jsonb     | jsonb
       2 | gin_extract_jsonb_path       | jsonb     | jsonb
       3 | gin_extract_jsonb_query_path | jsonb     | jsonb
       4 | gin_consistent_jsonb_path    | jsonb     | jsonb
       6 | gin_triconsistent_jsonb_path | jsonb     | jsonb
(5 rows)


 > 2. Можно ли как-то определить свой класс операторов по методу "такой 
же как оператор класс с таким-то именем, но оператор сравнения у него 
вот такой?"
 > 3. Если п.2 нельзя, то можно ли вынуть из сабжа ссылки на его 
функции/операторы как-то?

Создать новый опкласс на основе имеющегося, переопределяя только лишь 
некоторые его операторы или функции, к сожалению, невозможно.
Но, используя CREATE OPERATOR CLASS, действительно можно выполнить эту 
задачу, вручную добавив в него все переиспользумые операторы и функции, 
помимо своего оператора сравнения. Как получить ссылки на 
функции/операторы — описано выше.

 > Все вопросы про SQL, а не C


 > PS: что хочу
 > хочу GIN индекс по jsonb со своим оператором сортировки.
 > Насколько я понимаю для того что мне хочется нужно проделать следующее:
 >  1. Создать свой класс аналогичный jsonb_path_ops у которого будет 
всё так же как у предка, но моя функция FUNCTION 1 mycompare(jsonb, jsonb)
 >  2. Построить индекс по полю jsonb указав этот opclass
 >  3. PROFIT

Если переиспользовать jsonb_path_ops, то функция сравнения должна быть 
не для jsonb, а для int4 — того типа, что используется для хранения 
внутри (pg_opclass.opckeytype, "Storage type" в \dAc). Функцию 
mycompare(jsonb, jsonb) вместе со своим оператором сравнения имеет смысл 
использовать в опклассе для btree, а не для gin.

jsonb_path_ops хранит int4-хеши вида "hash (key1, key2, ..., keyN, 
value)", где "key1, key2, ..., keyN" — это путь к полю объекта или 
элемента массива "value", состоящий из названий ключей (массивы не 
учитываются в путях).

jsonb_ops же хранит text'овые строки вида "Tvalue", где "T" это префикс 
типа (key, string, number, boolean, null), а "value" это 
название/значение поля объекта или значение элемента массива в тестовом 
виде.

Поэтому для нового gin-опкласса, возможно, имеет смысл взять за основу 
jsonb_ops, а не на jsonb_path_ops. Но вообще, хотелось бы поподробнее 
узнать об этом новом операторе сравнения, тогда мы сможем лучше Вам помочь.


Вот на всякий случай пример создания копии jsonb_path_ops.

CREATE OPERATOR CLASS my_jsonb_path_ops
   FOR TYPE jsonb USING gin AS
   OPERATOR 7  @>,
   OPERATOR 15 @? (jsonb, jsonpath),
   OPERATOR 16 @@ (jsonb, jsonpath),
   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;

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

view thread (6+ messages)  latest in thread

Message-ID: <e74bf466-c22b-ab29-be29-fa960aeb84d0@postgrespro.ru>
Permalink:  ../e74bf466-c22b-ab29-be29-fa960aeb84d0@postgrespro.ru/
Also on:    postgresql.org/message-id/e74bf466-c22b-ab29-be29-fa960aeb84d0@postgrespro.ru

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-ru-general@postgresql.org
  Cc: n.gluhov@postgrespro.ru, unera@debian.org, pgsql-ru-general@lists.postgresql.org
  Subject: Re: OPERATOR CLASS
  In-Reply-To: <e74bf466-c22b-ab29-be29-fa960aeb84d0@postgrespro.ru>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox