在线精品99_中国九九盗摄偷拍偷看_91免费版在线观看_91.app_91高清视频在线_99热最新网站

PostgreSQL中create

129次阅读
没有评论

共计 7874 个字符,预计需要花费 20 分钟才能阅读完成。

这篇文章主要讲解了“PostgreSQL 中 create_sort_plan 函数实现逻辑是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着丸趣 TV 小编的思路慢慢深入,一起来研究和学习“PostgreSQL 中 create_sort_plan 函数实现逻辑是什么”吧!

一、数据结构

Plan
所有计划节点通过将 Plan 结构作为第一个字段从 Plan 结构“派生”。这确保了在将节点转换为计划节点时,一切都能正常工作。(在执行器中以通用方式传递时,节点指针经常被转换为 Plan *)

/* ----------------
 * Plan node
 *
 * All plan nodes  derive  from the Plan structure by having the
 * Plan structure as the first field. This ensures that everything works
 * when nodes are cast to Plan s. (node pointers are frequently cast to Plan*
 * when passed around generically in the executor)
 *  所有计划节点通过将 Plan 结构作为第一个字段从 Plan 结构“派生”。 *  这确保了在将节点转换为计划节点时,一切都能正常工作。 * (在执行器中以通用方式传递时,节点指针经常被转换为 Plan *)
 *
 * We never actually instantiate any Plan nodes; this is just the common
 * abstract superclass for all Plan-type nodes.
 *  从未实例化任何 Plan 节点; 这只是所有 Plan-type 节点的通用抽象超类。 * ----------------
 */
typedef struct Plan
 NodeTag type;// 节点类型
 /*
 *  成本估算信息;estimated execution costs for plan (see costsize.c for more info)
 */
 Cost startup_cost; /*  启动成本;cost expended before fetching any tuples */
 Cost total_cost; /*  总成本;total cost (assuming all tuples fetched) */
 /*
 *  优化器估算信息;planner s estimate of result size of this plan step
 */
 double plan_rows; /*  行数;number of rows plan is expected to emit */
 int plan_width; /*  平均行大小 (Byte 为单位);average row width in bytes */
 /*
 *  并行执行相关的信息;information needed for parallel query
 */
 bool parallel_aware; /*  是否参与并行执行逻辑?engage parallel-aware logic? */
 bool parallel_safe; /*  是否并行安全;OK to use as part of parallel plan? */
 /*
 * Plan 类型节点通用的信息.Common structural data for all Plan types.
 */
 int plan_node_id; /* unique across entire final plan tree */
 List *targetlist; /* target list to be computed at this node */
 List *qual; /* implicitly-ANDed qual conditions */
 struct Plan *lefttree; /* input plan tree(s) */
 struct Plan *righttree;
 List *initPlan; /* Init Plan nodes (un-correlated expr
 * subselects) */
 /*
 * Information for management of parameter-change-driven rescanning
 * parameter-change-driven 重扫描的管理信息.
 * 
 * extParam includes the paramIDs of all external PARAM_EXEC params
 * affecting this plan node or its children. setParam params from the
 * node s initPlans are not included, but their extParams are.
 *
 * allParam includes all the extParam paramIDs, plus the IDs of local
 * params that affect the node (i.e., the setParams of its initplans).
 * These are _all_ the PARAM_EXEC params that affect this node.
 */
 Bitmapset *extParam;
 Bitmapset *allParam;
} Plan;

二、源码解读

create_plan- create_plan_recurse- create_projection_plan 函数创建计划树, 执行投影操作并通过递归的方式为子访问路径生成执行计划。create_sort_plan 函数创建 Sort 计划节点。

//---------------------------------------------------------------- create_projection_plan
 * create_projection_plan
 *
 * Create a plan tree to do a projection step and (recursively) plans
 * for its subpaths. We may need a Result node for the projection,
 * but sometimes we can just let the subplan do the work.
 *  创建计划树, 执行投影操作并通过递归的方式为子访问路径生成执行计划.
 *  一般来说需要一个 Result 节点用于投影操作, 但有时候可以让子计划执行此项任务.
 */
static Plan *
create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags)
 Plan *plan;
 Plan *subplan;
 List *tlist;
 bool needs_result_node = false;
 /*
 * Convert our subpath to a Plan and determine whether we need a Result
 * node.
 *  转换 subpath 为 Plan, 并确定是否需要 Result 节点.
 *
 * In most cases where we don t need to project, creation_projection_path
 * will have set dummypp, but not always. First, some createplan.c
 * routines change the tlists of their nodes. (An example is that
 * create_merge_append_plan might add resjunk sort columns to a
 * MergeAppend.) Second, create_projection_path has no way of knowing
 * what path node will be placed on top of the projection path and
 * therefore can t predict whether it will require an exact tlist. For
 * both of these reasons, we have to recheck here.
 *  在大多数情况下,我们不需要投影运算,creation_projection_path 将设置 dummypp 标志,但并不总是如此。
 *  首先, 一些 createplan.c 中的函数更改其节点的 tlist。
 * (例如,create_merge_append_plan 可能会向 MergeAppend 添加 resjunk sort 列)。
 *  其次,create_projection_path 无法知道将在投影路径顶部放置哪些路径节点,因此无法预测它是否需要一个确切的 tlist。
 *  由于这两个原因,我们不得不在这里重新检查。
 */
 if (use_physical_tlist(root,  best_path- path, flags))
 {
 /*
 * Our caller doesn t really care what tlist we return, so we don t
 * actually need to project. However, we may still need to ensure
 * proper sortgroupref labels, if the caller cares about those.
 *  如果我们的调用者并不关心返回的结果 tlist,所以实际上不需要投影运算。
 *  然而,如果调用者关心 sortgroupref 标签,可能仍然需要确保正确的 sortgroupref 数据。
 */
 subplan = create_plan_recurse(root, best_path- subpath, 0);
 tlist = subplan- targetlist;
 if (flags   CP_LABEL_TLIST)
 apply_pathtarget_labeling_to_tlist(tlist,
 best_path- path.pathtarget);
 }
 else if (is_projection_capable_path(best_path- subpath))
 {
 /*
 * Our caller requires that we return the exact tlist, but no separate
 * result node is needed because the subpath is projection-capable.
 * Tell create_plan_recurse that we re going to ignore the tlist it
 * produces.
 *  调用者要求返回精确的 tlist,但是不需要单独的 Result 节点,因为子路径支持投影。
 *  调用 create_plan_recurse 时忽略它生成的 tlist。
 */
 subplan = create_plan_recurse(root, best_path- subpath,
 CP_IGNORE_TLIST);
 tlist = build_path_tlist(root,  best_path- path);
 }
 else
 {
 /*
 * It looks like we need a result node, unless by good fortune the
 * requested tlist is exactly the one the child wants to produce.
 *  看起来需要一个 Result 节点,除非幸运的是,请求的 tlist 正是子节点想要生成的。
 */
 subplan = create_plan_recurse(root, best_path- subpath, 0);
 tlist = build_path_tlist(root,  best_path- path);
 needs_result_node = !tlist_same_exprs(tlist, subplan- targetlist);
 }
 /*
 * If we make a different decision about whether to include a Result node
 * than create_projection_path did, we ll have made slightly wrong cost
 * estimates; but label the plan with the cost estimates we actually used,
 * not  corrected  ones. (XXX this could be cleaned up if we moved more
 * of the sortcolumn setup logic into Path creation, but that would add
 * expense to creating Paths we might end up not using.)
 *  如果我们对是否包含一个 Result 节点做出与 create_projection_path 不同的决定,
 *  我们就会做出略微错误的成本估算;
 *  但是在这个计划上标上我们实际使用的成本估算,而不是“修正的”成本估算。
 * (如果我们将更多的 sortcolumn 设置逻辑移到路径创建中,这个问题就可以解决了,
 *  但是这会增加创建路径的成本,而最终可能不会使用这些路径。)
 */
 if (!needs_result_node)
 {
 /* Don t need a separate Result, just assign tlist to subplan */
 // 不需要单独的 Result 节点, 把 tlist 赋值给 subplan
 plan = subplan;
 plan- targetlist = tlist;
 /* Label plan with the estimated costs we actually used */
 // 标记估算成本
 plan- startup_cost = best_path- path.startup_cost;
 plan- total_cost = best_path- path.total_cost;
 plan- plan_rows = best_path- path.rows;
 plan- plan_width = best_path- path.pathtarget- width;
 plan- parallel_safe = best_path- path.parallel_safe;
 /* ... but don t change subplan s parallel_aware flag */
 }
 else
 {
 /* We need a Result node */
 // 需要 Result 节点
 plan = (Plan *) make_result(tlist, NULL, subplan);
 copy_generic_path_info(plan, (Path *) best_path);
 }
 return plan;
//---------------------------------------------------------------- create_sort_plan
 /*
 * create_sort_plan
 *
 * Create a Sort plan for  best_path  and (recursively) plans
 * for its subpaths.
 *  创建 Sort 计划节点
 */
 static Sort *
 create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)
 {
 Sort *plan;
 Plan *subplan;
 
 /*
 * We don t want any excess columns in the sorted tuples, so request a
 * smaller tlist. Otherwise, since Sort doesn t project, tlist
 * requirements pass through.
 *  我们不希望在排序元组中有任何多余的列,所以希望得到一个更小的 tlist。
 *  否则,由于 Sort 不执行投影运算,tlist 就会通过完整的保留传递。
 */
 subplan = create_plan_recurse(root, best_path- subpath,
 flags | CP_SMALL_TLIST);
 
 /*
 * make_sort_from_pathkeys() indirectly calls find_ec_member_for_tle(),
 * which will ignore any child EC members that don t belong to the given
 * relids. Thus, if this sort path is based on a child relation, we must
 * pass its relids.
 * make_sort_from_pathkeys() 间接调用 find_ec_member_for_tle(),它将忽略不属于给定 relid 的任何子 EC 成员。
 *  因此,如果这个排序路径是基于子关系的,我们必须传递它的 relids。
 */
 plan = make_sort_from_pathkeys(subplan, best_path- path.pathkeys,
 IS_OTHER_REL(best_path- subpath- parent) ?
 best_path- path.parent- relids : NULL);
 
 copy_generic_path_info(plan- plan, (Path *) best_path);
 
 return plan;
 }

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-20发表,共计7874字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)
主站蜘蛛池模板: 91视频久久 | 亚洲午夜精品久久久久久人妖 | 欧美日韩国产高清一区二区三区 | 老色鬼福利视频在线观看 | 久久综合色区 | 日韩一级在线观看 | 久久综合久久伊人 | 久久人妻内射无码一区三区 | 女人被狂躁60分钟视频 | 欧美老妇疯狂xxxxbbbb | 国产午夜精品av一区二区 | 精品国产福利在线观看一区 | 香蕉久久人人爽人人爽人人片av | 在线另类 | 国产女女精品视频久热视频 | 欧美狠狠入鲁的视频极速 | 刺激性视频黄页 | 欧洲精品成人免费视频在线观看 | 国产成人精品久久二区二区 | 日韩精品无码人妻一区二区三区 | 国产成人影院 | 国产精品一区二区久久精品 | 欧美日韩免费播放一区二区 | 美女一区二区三区 | 草久热| 久久精品国产99国产精品 | 中文字幕被公侵犯的漂亮人妻 | 久久精品综合一区二区三区 | 色在线看 | 九九九色视频在线观看免费 | 亚洲图欧美日韩色综合图 | 亚洲国产成人久久77 | 国产综合视频在线 | 日韩精品视频一区二区三区 | 在线免费视频a | 99视频精品在线 | 天天色天天干天天射 | 国产精品视频久久久久久 | 四虎影院最新网站 | 最新中文字幕视频 | 国产精品成人av在线观看春天 |