timescaledb实现探究一(hook)

void
_planner_init(void)
{
	prev_planner_hook = planner_hook;
	planner_hook = timescaledb_planner;
	prev_set_rel_pathlist_hook = set_rel_pathlist_hook;
	set_rel_pathlist_hook = timescaledb_set_rel_pathlist;

	prev_get_relation_info_hook = get_relation_info_hook;
	get_relation_info_hook = timescaledb_get_relation_info_hook;
	prev_create_upper_paths_hook = create_upper_paths_hook;
	create_upper_paths_hook = timescale_create_upper_paths_hook;
}

_PG_init ---> _planner_init

_planner_init里设置了4个hook函数,取代posgresql原有的部分逻辑

这些hook都是postresql里的全局变量(函数指针),如果被赋值,则使用该hook指向的函数。

1. planner_hook: 生成计划数时hit

    timescaledb_planner取代standard_planner

PlannedStmt *
planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
{
	PlannedStmt *result;

	if (planner_hook)
		result = (*planner_hook) (parse, cursorOptions, boundParams);
	else
		result = standard_planner(parse, cursorOptions, boundParams);
	return result;
}

实际上,ttimescaledb_planner内部实现也是先执行 standard_planner, 得到plan, 再按照自己逻辑对plan做处理的。

2. set_rel_pathlist_hook:  构造访问路径时hit

    timescaledb_set_rel_pathlist 在原来构造路径的基础上做一次编辑修改

	/*
	 * Allow a plugin to editorialize on the set of Paths for this base
	 * relation.  It could add new paths (such as CustomPaths) by calling
	 * add_path(), or delete or modify paths added by the core code.
	 */
	if (set_rel_pathlist_hook)
		(*set_rel_pathlist_hook) (root, rel, rti, rte);

3. get_relation_info_hook: 获取表对象信息时hit

timescaledb_get_relation_info_hook 编辑修改获取的表对象信息(大小,索引等)

	/*
	 * Allow a plugin to editorialize on the info we obtained from the
	 * catalogs.  Actions might include altering the assumed relation size,
	 * removing an index, or adding a hypothetical index to the indexlist.
	 */
	if (get_relation_info_hook)
		(*get_relation_info_hook) (root, relationObjectId, inhparent, rel);

4. create_upper_paths_hook: 创建一些路径(分组聚合,窗口,排序等)时hit

timescale_create_upper_paths_hook 编辑修改这些路径

In grouping_planner function
	/* Let extensions possibly add some more paths */
	if (create_upper_paths_hook)
		(*create_upper_paths_hook) (root, UPPERREL_FINAL,
									current_rel, final_rel);

In create_grouping_paths function
	/* Let extensions possibly add some more paths */
	if (create_upper_paths_hook)
		(*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,
									input_rel, grouped_rel);

In create_window_paths function
	/* Let extensions possibly add some more paths */
	if (create_upper_paths_hook)
		(*create_upper_paths_hook) (root, UPPERREL_WINDOW,
									input_rel, window_rel);

In create_distinct_paths function
	/* Let extensions possibly add some more paths */
	if (create_upper_paths_hook)
		(*create_upper_paths_hook) (root, UPPERREL_DISTINCT,
									input_rel, distinct_rel);

In create_ordered_paths function
	/* Let extensions possibly add some more paths */
	if (create_upper_paths_hook)
		(*create_upper_paths_hook) (root, UPPERREL_ORDERED,
									input_rel, ordered_rel);

猜你喜欢

转载自blog.csdn.net/jacicson1987/article/details/83015961