Re: OPERATOR CLASS

From: Dmitry E(dot) Oboukhov <unera(at)debian(dot)org>
To: Nikita Glukhov <n(dot)gluhov(at)postgrespro(dot)ru>
Cc: "pgsql-ru-general(at)lists(dot)postgresql(dot)org" <pgsql-ru-general(at)lists(dot)postgresql(dot)org>
Subject: Re: OPERATOR CLASS
Date: 2019-04-11 12:40:39
Message-ID: 7716931554986439@iva6-628714d786b2.qloud-c.yandex.net
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-ru-general

<div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">11.04.2019, 13:32, "Nikita Glukhov" &lt;n(dot)gluhov(at)postgrespro(dot)ru&gt;:</div><blockquote xmlns="http://www.w3.org/1999/xhtml" type="cite"><div bgcolor="#FFFFFF"><p>On 11.04.2019 5:40, Dmitry E. Oboukhov wrote:</p><blockquote type="cite" cite="mid:2084391554950401(at)myt2-cd7fa496c4f7(dot)qloud-c(dot)yandex(dot)net"><div>11.04.2019, 01:58, "Nikita Glukhov" <a rel="noopener noreferrer" href="mailto:n(dot)gluhov(at)postgrespro(dot)ru">&lt;n(dot)gluhov(at)postgrespro(dot)ru&gt;</a>:</div> <blockquote type="cite"><div bgcolor="#FFFFFF"> FUNCTION 1 btint4cmp, <br /> FUNCTION 2 gin_extract_jsonb_path, <br /> FUNCTION 3 gin_extract_jsonb_query_path, <br /> FUNCTION 4 gin_consistent_jsonb_path,<br /> FUNCTION 6 gin_triconsistent_jsonb_path,<br />STORAGE integer;</div></blockquote><div> </div><div>А вот по этим функциям где-то можно почитать разъяснения?</div></blockquote><p>В официальной документации вроде бы все достаточно подробно описано:<br /><br /><a rel="noopener noreferrer" href="https://www.postgresql.org/docs/11/gin-extensibility.html">https://www.postgresql.org/docs/11/gin-extensibility.html</a> (на английском)<br /><a rel="noopener noreferrer" href="https://postgrespro.ru/docs/postgresql/11/gin-extensibility">https://postgrespro.ru/docs/postgresql/11/gin-extensibility</a> (на русском)</p></div></blockquote><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">интересно - можно ли писать эти функции на SQL (plpgsql)?</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">если смотреть на функцию gin_triconsistent_jsonb, например, то</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">Тип данных результата  | "char"<br />Типы данных аргументов | internal, smallint, jsonb, integer, internal, internal, internal</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">если посмотреть на неё со стороны документации, то</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"><span><code>bool consistent(bool check[], StrategyNumber n, Datum query, int32 nkeys, Pointer extra_data[], bool *recheck, Datum queryKeys[], bool nullFlags[])</code></span></div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">я хочу (хотел, пока Ваш ответ не прочитал) написать скетч индекса на plpgsql. пусть он медленно работает в области сплита данных на индексируемые массивы итп, но если он заработает - появится смысл сесть это и на C написать.</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><blockquote xmlns="http://www.w3.org/1999/xhtml" type="cite"><div bgcolor="#FFFFFF"><p> </p><blockquote type="cite" cite="mid:2084391554950401(at)myt2-cd7fa496c4f7(dot)qloud-c(dot)yandex(dot)net"><div>и вот еще вопрос. Некоторые из этих функций принимают internal в виде аргументов, соответственно вызвать их и посмотреть их поведение прямо из SELECT - непонятно как.</div><div> </div><div>соответственно непонятно - как полностью с нуля написать свой OPERATOR CLASS не используя программирование на C (допустим хотим сделать скетч на SQL, возможно ли это сделать?)</div></blockquote><p><br />Да, все GIN-функции, за исключением первой compare(), можно написать сейчас только на C, и вызывать их из SQL нельзя. Но можно попробовать сделать один раз специальный обобщенный OPERATOR CLASS, в котором из функциий 2-6, написанных на C, будут вызываться другие функции с соответствующими номерами (например, 12-16), в которых уже будут использоваться только SQL-типы. Но полностью перенести всю функциональность C-функций на уровень SQL будет не так просто, потому что многие функции могут возвращать несколько значений сразу, а внутри Postgres, по-моему, нет такого удобного способа вызова для функций с OUT-параметрами, который есть для обычных функций. Например,<br /><br />  Datum *extractQuery(Datum query, int32 *nkeys, StrategyNumber n, bool **pmatch, Pointer **extra_data, bool **nullFlags, int32 *searchMode)</p></div></blockquote><div xmlns="http://www.w3.org/1999/xhtml">спасибо, помедитирую над этим всем.</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">я сишечную реализацию не смотрел вовсе, думал со стороны SQL до скетча добраться можно.</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><blockquote xmlns="http://www.w3.org/1999/xhtml" type="cite"><div bgcolor="#FFFFFF"><p>возвращает массив извлеченных элементов, а также необязательные массив флагов pmatch, массив произвольных С-указателй extra_data, массив null-флагов nullFlags, и режим поиска searchMode. Если оставить только обязательный массив элементов, то сигнатрура SQL-функции extract_query будет совсем простой:<br /> <br />   extract_query (query anyelement, strategy int2) RETURNS storage_type[]</p><p>но я не уверен, что с anyelement не возникнет каких-либо проблем.<br /> </p><p>И еще хочу на всякий случай напомнить, что у нас есть еще расширение JsQuery (<a rel="noopener noreferrer" href="https://github.com/postgrespro/jsquery">https://github.com/postgrespro/jsquery</a><a href="https://github.com/postgrespro/jsquery) которое содержит опклассы, позволяющие выполнять по GIN-индексам более широкий ряд jsonb-запросов (например, range-запросов, которые реализованы с использования partialMatch). Возможно даже, что JsQuery решит Вашу задачу. Сейчас мы работает в JsQuery на поддержкой jsonpath, который выйдет в PostgreSQL12, а в будущем планируем даже перенести эти JsQuery-опклассы в ядро.">), которое содержит опклассы, позволяющие выполнять по GIN-индексам более широкий ряд jsonb-запросов (например, range-запросов, которые реализованы с использования partialMatch). Возможно даже, что JsQuery решит Вашу задачу. Сейчас мы работает в JsQuery на поддержкой jsonpath, который выйдет в PostgreSQL12, а в будущем планируем даже перенести эти JsQuery-опклассы в ядро.</a></p></div></blockquote><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">цитата оттуда:</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml"><blockquote><div><div><div><span><code>int compare(Datum a, Datum b)</code></span></div><div><p>Сравнивает два ключа (не индексированные объекты!) и возвращает целое меньше нуля, ноль или целое больше нуля, показывающее, что первый ключ меньше, равен или больше второго. Ключи NULL никогда не передаются этой функции.</p></div></div></div><p>Если же класс операторов не определяет метод <code>compare</code>, GIN попытается найти класс операторов B-дерева по умолчанию для типа данных ключа индекса и воспользоваться его функцией сравнения. Если класс операторов GIN предназначен только для одного типа данных, рекомендуется задавать функцию сравнения в этом классе операторов, так как поиск класса операторов B-дерева занимает несколько циклов. Однако для полиморфных классов операторов GIN (например, <code>array_ops</code>) задать одну функцию сравнения обычно не представляется возможным.</p></blockquote></div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">для полиморфных типов (например массивы) a и b - это ключи возвращённые <span><code>extractValue или это массивы ключей извлечённые из записей? (я еще не разобрался с API низкого уровня, сорри если </code></span>вопрос глупый: пытаюсь понять как индекс работает).</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">то есть extractValue вернул например:</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">1. для записи 1 - массив "a", "b", "c"</div><div xmlns="http://www.w3.org/1999/xhtml">2. для записи 2 - массив "c", "d", "e"</div><div xmlns="http://www.w3.org/1999/xhtml">3. для записи 3 - массив "x", "y", "z"</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">потом пользователь ищет</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">"ary" @&gt; [ "c" ]</div><div xmlns="http://www.w3.org/1999/xhtml"> </div><div xmlns="http://www.w3.org/1999/xhtml">compare что с чем сравнивает при этом? я хочу своей функцией compare иметь возможность поднять или опустить ввверх-низ списка записи в зависимости от своих критериев.</div>

Attachment Content-Type Size
unknown_filename text/html 11.5 KB

In response to

Responses

Browse pgsql-ru-general by date

  From Date Subject
Next Message Nikita Glukhov 2019-04-11 14:56:03 Re: OPERATOR CLASS
Previous Message Nikita Glukhov 2019-04-11 10:31:43 Re: OPERATOR CLASS