自定义扫描提供程序通常会通过设置以下钩子来为基本关系添加路径,该钩子在核心代码生成所有可以为关系生成的访问路径后调用(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
或(如果它们是部分路径)add_partial_path
将它们添加到 rel
中。自定义扫描提供程序负责初始化 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
路径必须包含其使用的连接子句集,规划器将使用该子句集将 CustomPath
路径转换为计划,如果规划器将其选为 joinrel
的最佳路径。
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
,具体取决于需要。
如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步澄清的内容,请使用此表单报告文档问题。