A custom scan provider will typically add paths for a base relation by setting the following hook, which is called after the core code has generated all the access paths it can for the relation (except for Gather paths, which are made after this call so that they can use partial paths added by the hook):
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;
Although this hook function can be used to examine, modify, or remove
paths generated by the core system, a custom scan provider will typically
confine itself to generating CustomPath
objects and adding
them to rel
using add_path
. The custom scan
provider is responsible for initializing the CustomPath
object, which is declared like this:
typedef struct CustomPath { Path path; uint32 flags; List *custom_paths; List *custom_private; const CustomPathMethods *methods; } CustomPath;
path
must be initialized as for any other path, including
the row-count estimate, start and total cost, and sort ordering provided
by this path. flags
is a bit mask, which
specifies whether the scan provider can support certain optional
capabilities. flags
should include
CUSTOMPATH_SUPPORT_BACKWARD_SCAN
if the custom path can support
a backward scan, CUSTOMPATH_SUPPORT_MARK_RESTORE
if it
can support mark and restore,
and CUSTOMPATH_SUPPORT_PROJECTION
if it can perform
projections. (If CUSTOMPATH_SUPPORT_PROJECTION
is not
set, the scan node will only be asked to produce Vars of the scanned
relation; while if that flag is set, the scan node must be able to
evaluate scalar expressions over these Vars.)
An optional custom_paths
is a list of Path
nodes used by this custom-path node; these will be transformed into
Plan
nodes by planner.
custom_private
can be used to store the custom path's
private data. Private data should be stored in a form that can be handled
by nodeToString
, so that debugging routines that attempt to
print the custom path will work as designed. methods
must
point to a (usually statically allocated) object implementing the required
custom path methods, which are further detailed below.
A custom scan provider can also provide join paths. Just as for base
relations, such a path must produce the same output as would normally be
produced by the join it replaces. To do this, the join provider should
set the following hook, and then within the hook function,
create CustomPath
path(s) for the join relation.
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;
This hook will be invoked repeatedly for the same join relation, with different combinations of inner and outer relations; it is the responsibility of the hook to minimize duplicated work.
Plan *(*PlanCustomPath) (PlannerInfo *root, RelOptInfo *rel, CustomPath *best_path, List *tlist, List *clauses, List *custom_plans);
Convert a custom path to a finished plan. The return value will generally
be a CustomScan
object, which the callback must allocate and
initialize. See Section 63.2 for more details.
List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root, List *custom_private, RelOptInfo *child_rel);
This callback is called while converting a path parameterized by the
top-most parent of the given child relation child_rel
to be parameterized by the child relation. The callback is used to
reparameterize any paths or translate any expression nodes saved in the
given custom_private
member of a
CustomPath
. The callback may use
reparameterize_path_by_child
,
adjust_appendrel_attrs
or
adjust_appendrel_attrs_multilevel
as required.