自定义扫描提供器通常通过设置以下钩子来为基本关系添加路径,该钩子在核心代码为关系生成所有可用的访问路径之后被调用(除了 Gather 和 Gather Merge 路径,它们在此调用之后生成,以便它们可以使用钩子添加的部分路径)
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 对象,并使用 add_path 将它们添加到 rel,或者如果它们是部分路径,则使用 add_partial_path。自定义扫描提供器负责初始化 CustomPath 对象,该对象声明如下
typedef struct CustomPath
{
Path path;
uint32 flags;
List *custom_paths;
List *custom_restrictinfo;
List *custom_private;
const CustomPathMethods *methods;
} CustomPath;
path 必须像任何其他路径一样初始化,包括行数估计、开始和总成本,以及此路径提供的排序。 flags 是一个位掩码,指定扫描提供器是否支持某些可选功能。如果自定义路径可以支持向后扫描,则 flags 应包括 CUSTOMPATH_SUPPORT_BACKWARD_SCAN,如果它可以支持标记和恢复,则包括 CUSTOMPATH_SUPPORT_MARK_RESTORE,如果它可以执行投影,则包括 CUSTOMPATH_SUPPORT_PROJECTION。(如果未设置 CUSTOMPATH_SUPPORT_PROJECTION,则只会要求扫描节点生成扫描关系的 Vars;而如果设置了该标志,则扫描节点必须能够评估这些 Vars 上的标量表达式。)可选的 custom_paths 是此自定义路径节点使用的 Path 节点列表;这些将由规划器转换为 Plan 节点。如下所述,也可以为连接关系创建自定义路径。在这种情况下,custom_restrictinfo 应用于存储应用于自定义路径替换的连接的连接子句集。否则它应为 NIL。 custom_private 可用于存储自定义路径的私有数据。私有数据应以可以由 nodeToString 处理的形式存储,以便尝试打印自定义路径的调试例程按设计工作。 methods 必须指向实现所需自定义路径方法(在下面进一步详细介绍)的(通常是静态分配的)对象。
自定义扫描提供器还可以提供连接路径。就像基本关系一样,这样的路径必须生成与它替换的连接通常产生的相同输出。为此,连接提供器应设置以下钩子,然后在钩子函数中,为连接关系创建 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;
对于同一个连接关系,此钩子会使用内部和外部关系的不同组合重复调用;钩子有责任尽量减少重复工作。
另请注意,应用于连接的连接子句集(作为 extra->restrictlist 传递)根据内部和外部关系的组合而有所不同。为 joinrel 生成的 CustomPath 路径必须包含它使用的连接子句集,如果规划器将其选为 joinrel 的最佳路径,则规划器将使用这些子句将 CustomPath 路径转换为计划。
Plan *(*PlanCustomPath) (PlannerInfo *root,
RelOptInfo *rel,
CustomPath *best_path,
List *tlist,
List *clauses,
List *custom_plans);
将自定义路径转换为已完成的计划。返回值通常是一个 CustomScan 对象,回调必须分配并初始化该对象。有关更多详细信息,请参见 第 59.2 节。
List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
List *custom_private,
RelOptInfo *child_rel);
在将由给定子关系 child_rel 的最顶层父级参数化的路径转换为由子关系参数化时,会调用此回调。回调用于重新参数化在 CustomPath 的给定 custom_private 成员中保存的任何路径或转换任何表达式节点。回调可以根据需要使用 reparameterize_path_by_child、adjust_appendrel_attrs 或 adjust_appendrel_attrs_multilevel。
如果您在文档中看到任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。