Postgres - статьи

         

Интерфейсные функции


Для упрощения описания в объявлениях функций используется псевдосинтаксис, реальные определения должны соответствовать . В последующей секции рассматривается пример реализации R-tree.

GISTENTRY * compress( GISTENTRY * in )
GISTENTRY * decompress( GISTENTRY * in )

Эти функции отвечают за компрессию/декомпрессию ключей. Если функция меняет значение ключа (key), то:

она должна возвращать заново palloc'оченное значение как структуры, так и ключа( если ключ передавался по ссылке, pass-by-reference).

  • скопировать в новую структуру значения rel, page, offset, leafkey.
  • правильно установить bytes.
  • не менять старую структуру (in), и не делать pfree ни in, ни in->key
  • При вызове compress in->leafkey=TRUE, если значение в key взято из таблицы, а не из индекса. В этом случае, если эта функция нетривиальна, даже если не меняется ключ, надо обязательно определить in->bytes и установить in->leafkey=FALSE.

    Всем остальным интерфейсным функциям ключи передаются только после обработки ключа функции decompress.

  • bool equal( Datum a, Datum b)

    Возвращает TRUE только в случае a==b.

  • float * penalty( GISTENTRY *origentry, GISTENTRY *newentry, float *result)

    Вычисляет меру увеличения origentry->key при его объединении с newentry->key. Вычисленное значение должна поместить в *result и вернуть указатель на него.

    Если эта функция не помечена как isstrict, то key может быть NULL. В противном случае, функция не вызывается и считается, что мера увеличения равно 0, если хотя бы один из параметров имеет значение NULL.

  • Datum union(GistEntryVector *entryvec, int *size)

    Выполняет объединение (union) ключей. Возвращает объединенный ключ (не GISTENTRY!). В *size помещает размер результирующего ключа в байтах. Структура GistEntryVector:

    typedef struct { int32 n; /* количество элементов в поле vector*/ GISTENTRY vector[1]; } GistEntryVector;



    Массив никогда не содержит NULL элементов.

  • bool consistent( GISTENTRY *entry, Datum query, StrategyNumber strategy )

    Проверяет ключ (entry->key) на соответствие запросу (query) с помощью операции с номером strategy и возвращает TRUE в случае соответствия, или FALSE в противном.


    Если ключ находится на внутренней странице дерева, функция должна возвращать TRUE, если entry->key МОЖЕТ соответствовать query и FALSE, если entry->key ТОЧНО не соответствует query.

    Если ключ находится на концевой странице (leaf page), то поведение определяется параметром RECHECK для конкретной операции (см. CREATE OPERATOR CLASS). Если задан параметр RECHECK, то это означает, что индекс является неточным ("lossy"), т.е. результат поиска требуется проверить на соответствие запросу (поведение consistent аналогично поведению на внутренних страницах в этом случае), в противном случае требуется вернуть ТОЧНЫЙ ответ.

    Макрос GIST_LEAF(entry) возвращает TRUE, если ключ находится на leaf странице.

    Узнать, какие операции какой strategy соответствуют можно с помощью следующего SQL( на примере box_ops, подробнее смотри раздел ):

    select pg_amop.amopstrategy, pg_operator.oprname, pg_amop.amopreqcheck from pg_type, pg_operator, pg_opclass, pg_am, pg_amop where pg_type.typname = 'box' and pg_am.amname = 'gist' and pg_opclass.opcname = 'box_ops' and pg_am.oid=pg_opclass.opcamid and pg_opclass.oid = pg_amop.amopclaid and pg_opclass.opcintype = pg_type.oid and pg_amop.amopopr = pg_operator.oid;

    Соответственно, при внесении нового opclass и/или операций надо позаботиться об обновлении системных таблиц.

  • GIST_SPLITVEC * split(GistEntryVector *entryvec, GIST_SPLITVEC *v)

    Разделяет массив ключей entryvec на два. Массив entryvec не может содержать NULL значения.

    Структура GIST_SPLITVEC: typedef struct GIST_SPLITVEC { OffsetNumber *spl_left; /* array of entries that go left */ int spl_nleft; /* size of this array */ Datum spl_ldatum; /* Union of keys in spl_left */ OffsetNumber *spl_right; /* array of entries that go right */ int spl_nright; /* size of the array */ Datum spl_rdatum; /* Union of keys in spl_right */ ... } GIST_SPLITVEC;

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

    v->spl_left и v->spl_right должны аллоцироваться(palloc) самостоятельно, при возврате они должны содержать номера элементов массива entryvec. При этом, один номер НЕ может содержаться в spl_left и spl_right одновременно.

    Внимание:



    • Значения в массиве entryvec начинаются с 1, а не с 0


    • Функция обязана определить spl_ldatum и spl_rdatum - объединяющие ключи, соответственно, для левого и правого массива.



    • Содержание раздела







      Forekc.ru
      Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий