摘要:
接前面,在 PortalStart 中调用了 ExecutorStart,ExecutorStart 会调用 InitPlan:/* ---------------------------------------------------------------- * InitPlan * * Initializes the query plan: open files, allocate storage * and start up the rule manager * -----------------------------------------... 阅读全文
摘要:
接前面,继续观察 PortalStart,其中有: /* * Create QueryDesc in portal's context; for the moment, set * the destination to DestNone. */ queryDesc = CreateQueryDesc((PlannedStmt *) linitial(portal->stmts), ... 阅读全文
摘要:
回到上一个层面,继续看 PortalStart的处理:voidPortalStart(Portal portal, ParamListInfo params, int eflags, bool use_active_snapshot){ ... PG_TRY(); { ... /* * Determine the portal execution strategy */ portal->strategy = ChoosePortalStrategy(portal->stmts); ... 阅读全文
摘要:
接前面,继续分析:PortalStrategyChoosePortalStrategy(List *stmts){ int nSetTag; ListCell *lc; /* * PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the * single-statement case, since there are no rewrite rules that can add * auxiliary queries to a SELECT or a util... 阅读全文
摘要:
接前面,继续分析 ChoosePortalStrategy:/* * ChoosePortalStrategy * Select portal execution strategy given the intended statement list. * * The list elements can be Querys, PlannedStmts, or utility statements. * That's more general than portals need, but plancache.c uses this too. * * See the comments ... 阅读全文
摘要:
simple_exec_query函数中,有如下一句:plantree_list = pg_plan_queries(querytree_list, 0, NULL);那么,plantree_list 里面,到底有什么,让我来给它大卸八块:plantree_list 是List *类型(指向List 的指针):typedef struct List{ NodeTag type; /* T_List, T_IntList, or T_OidList */ int length; ListCell *head; ... 阅读全文
摘要:
接前面,仔细看这个 :这 add_base_rels_to_query 是个递归调用嘛。想像一下: select * from tst01 where id in (select sid from tst02) or id in (select sid from tst03) 之类的,此函数将层层深入,构造一个二叉树式样的语法树。voidadd_base_rels_to_query(PlannerInfo *root, Node *jtnode){ if (jtnode == NULL) return; if (IsA(jtnode, RangeTblRef)) ... 阅读全文
摘要:
接前面,再次上溯一个层次,看代码(planmain.c :query_planner):voidquery_planner(PlannerInfo *root, List *tlist, double tuple_fraction, double limit_tuples, Path **cheapest_path, Path **sorted_path, double *num_groups){ ... /* * Make a flattened version of the rangetable... 阅读全文
摘要:
再次梳理 build_simple_rel 的执行内容:/* * build_simple_rel * Construct a new RelOptInfo for a base relation or 'other' relation. */RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind){ RelOptInfo *rel; RangeTblEntry *rte; /* Rel should not exist already */ Assert... 阅读全文
摘要:
接前面,回到get_relation_info(plancat.c)函数 上:relation 是由 heap_open 函数调用后获得的。voidget_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel){ Index varno = rel->relid; Relation relation; bool hasindex; List *indexinfos = NI... 阅读全文