Создание пользовательских путей сканирования
Пользовательский провайдер сканирования обычно добавляет пути для базового отношения, устанавливая с ледующий хук, который вызывается после того, как основной код сгенерировал все возможные пути доступа для отношения (за исключением путей Gather, которые создаются после этого вызова, чтобы они могли использовать частичные пути, добавленные хуком):
typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *rel,
Index rti,
RangeTblEntry *rte);
extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
Хотя эта функция может использоваться для изучения, изменения или удаления путей, сгенерированных основной системой, пользовательский провайдер сканирования обычно ограничивается созданием объектов CustomPath
и добавлением их в rel
с помощью add_path
. Пользовательский провайдер сканирования отвечает за инициализацию объекта CustomPath
, который объявляется следующим образом:
typedef struct CustomPath
{
Path path;
uint32 flags;
List *custom_paths;
List *custom_private;
const CustomPathMethods *methods;
} CustomPath;
Поле path
должен быть инициализирован как любой другой путь, включая оценку количества строк, начальную и полную стоимость, а также порядок сортировки, предоставляемый этим путем. flags
- битовая маска, которая указывает, может ли поставщик сканирования поддерживать определенные дополнительные возможности. flags
должен включать CUSTOMPATH_SUPPORT_BACKWARD_SCAN
, если пользовательский путь может поддерживать сканирование назад, CUSTOMPATH_SUPPORT_MARK_RESTORE
, если он может поддерживать маркировку и восстановление, и CUSTOMPATH_SUPPORT_PROJECTION
, если он может выполнять проекции. (Если флаг CUSTOMPATH_SUPPORT_PROJECTION
не установлен, узел сканирования будет запрашиваться только для получения варов сканируемого отношения; если же этот флаг установлен, узел сканирования должен уметь оценивать скалярные выражения над этими варами). Необязательный custom_paths
- это список узлов Path
, используемых этим узлом custom-path; они будут преобразованы планировщиком в узлы Plan
. custom_private
может использоваться для хранения приватных данных пользовательского пути. Частные данные должны храниться в форме, которая может быть обработана nodeToString
, так что отладочные процедуры, которые пытаются вывести пользовательский путь, будут работать так, как задумано. методы должны указывать на объект (обычно статически выделенный), реализующий необходимые методы пользовательского пути, которые более подробно описаны ниже.
Провайдер нестандартного сканирования может также реализовать пути соединений. Как и для базовых отношений, такой путь должен выдавать тот же результат, который обычно выдается соединением, которое он заменяет. Для этого провайдер соединения должен установить следующий хук, а затем в функции хука создать путь(и) CustomPath
для отношения соединения.
typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *joinrel,
RelOptInfo *outerrel,
RelOptInfo *innerrel,
JoinType jointype,
JoinPathExtraData *extra);
extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
Этот хук будет вызываться многократно для одного и того же отношения join
, с различными комбинациями внутренних и внешних отношений; ответственность хука заключается в минимизации дублирования работы.
Пользовательские обратные вызовы пути сканирования
Plan *(*PlanCustomPath) (PlannerInfo *root,
RelOptInfo *rel,
CustomPath *best_path,
List *tlist,
List *clauses,
List *custom_plans);
Преобразование пользовательского пути в готовый план. Возвращаемое значение обычно представляет собой объект CustomScan
, который обратный вызов должен выделить и инициализировать. Более подробную информацию см. в разделе «Создание пользовательских планов сканирования».
List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
List *custom_private,
RelOptInfo *child_rel);
Этот обратный вызов вызывается при преобразовании пути, параметризованного самым верхним родителем данного дочернего отношения child_rel
, в путь, параметризованный дочерним отношением. Этот обратный вызов используется для перепараметризации любых путей или трансляции любых узлов выражений, сохраненных в данном члене custom_private
CustomPath
. Обратный вызов может использовать reparameterize_path_by_child
, adjust_appendrel_attrs
или adjust_appendrel_attrs_multilevel
, если это необходимо.