摘要:
接前面,继续观察 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... 阅读全文