Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hEMAk-0007s3-1N for pgsql-ru-general@arkaria.postgresql.org; Wed, 10 Apr 2019 22:58:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hEMAi-00065p-Pn for pgsql-ru-general@arkaria.postgresql.org; Wed, 10 Apr 2019 22:58:24 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hEMAi-00065h-7i for pgsql-ru-general@lists.postgresql.org; Wed, 10 Apr 2019 22:58:24 +0000 Received: from cyclops.postgrespro.ru ([93.174.131.138] helo=mail.postgrespro.ru) by makus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hEMAe-0007gT-2e for pgsql-ru-general@lists.postgresql.org; Wed, 10 Apr 2019 22:58:23 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id BF9D721C3FCF; Thu, 11 Apr 2019 01:58:17 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=x tagged_above=-99 required=4 WHITELISTED tests=[] autolearn=unavailable Received: from [10.100.236.29] (unknown [195.82.154.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id 86AB521C3FCC; Thu, 11 Apr 2019 01:58:17 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1554937097; bh=DkC4OVctvtIKF5hW6wz4FmnmmTl3IwPs7cpe6hvl7dc=; h=To:From:Subject:In-Reply-To:References:Cc:Date; b=Y2bMJsnWffISQEjYfSLpFyZAtufDYF1Bsqr3lzB41GX6ydeaxfMRSmJiN28NAHffq d7Zkj/nNG2PW3/ZvU4YudxoQhG8Oi+zHlSWFTNAX8q3TcxgUbgnMNAmsbWyzPRW/iW EodWj5AuI+NuqeXkjgODCDYj5POcSe78WbYE6+KA= To: "Dmitry E. Oboukhov" From: Nikita Glukhov Subject: Re: OPERATOR CLASS Organization: Postgres Professional In-Reply-To: <10196171554829471@iva7-6548a8037c6d.qloud-c.yandex.net> References: <10196171554829471@iva7-6548a8037c6d.qloud-c.yandex.net> Cc: pgsql-ru-general@lists.postgresql.org Message-ID: Date: Thu, 11 Apr 2019 01:58:09 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="------------C8E45070A248B5E76E700D77" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------C8E45070A248B5E76E700D77 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit > Есть вопросы по сабжу. > 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 --------------C8E45070A248B5E76E700D77 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit

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

> 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
--------------C8E45070A248B5E76E700D77--