2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5

60.1. 创建自定义扫描路径 #

自定义扫描提供程序通常会通过设置以下钩子来为基表添加路径,该钩子会在核心代码生成完所有可能的访问路径后调用(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_pathadd_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,则扫描节点只会生成被扫描关系的 Var;如果设置了该标志,则扫描节点必须能够评估这些 Var 上的标量表达式。)可选的 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 的最佳路径,则规划器将使用该子句集将其转换为计划。

60.1.1. 自定义扫描路径回调 #

Plan *(*PlanCustomPath) (PlannerInfo *root,
                         RelOptInfo *rel,
                         CustomPath *best_path,
                         List *tlist,
                         List *clauses,
                         List *custom_plans);

将自定义路径转换为最终计划。返回值通常是一个 CustomScan 对象,回调必须分配并初始化该对象。有关更多详细信息,请参阅 第 60.2 节

List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
                                          List *custom_private,
                                          RelOptInfo *child_rel);

在将由给定子关系 child_rel 的最顶层父项参数化的路径转换为由该子关系参数化时,会调用此回调。该回调用于重新参数化任何路径或转换保存在 CustomPath 的给定 custom_private 成员中的任何表达式节点。回调可以根据需要使用 reparameterize_path_by_childadjust_appendrel_attrsadjust_appendrel_attrs_multilevel

提交更正

如果您在文档中看到任何不正确、与您对特定功能的实际使用不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。