PostgreSQL在何处处理 sql查询之二十八
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; ListCell *tail; } List; struct ListCell { union { void *ptr_value; int int_value; Oid oid_value; } data; ListCell *next; };
由于 ListCell中有一个union 类型,这就比较麻烦了。所以还是先看看在Portal里如何处理的:
static void exec_simple_query(const char *query_string) { ... foreach(parsetree_item, parsetree_list) { ... plantree_list = pg_plan_queries(querytree_list, 0, NULL); ... PortalDefineQuery(portal, NULL, query_string, commandTag, plantree_list, NULL); ... PortalStart(portal, NULL, 0, snapshot_set); ... } ... }
先看看 PortalDefineQuery 函数是如何使用 plantree_list 的:
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, const char *commandTag, List *stmts, CachedPlan *cplan) { AssertArg(PortalIsValid(portal)); AssertState(portal->status == PORTAL_NEW); AssertArg(sourceText != NULL); AssertArg(commandTag != NULL || stmts == NIL); portal->prepStmtName = prepStmtName; portal->sourceText = sourceText; portal->commandTag = commandTag; portal->stmts = stmts; portal->cplan = cplan; portal->status = PORTAL_DEFINED; }
就是把plan_tree 赋值给 portal->stmts 了。
再看 PortalStart 是如何处理的:ChoosePortalStrategy 要用到 portal->stmts。
void PortalStart(Portal portal, ParamListInfo params, int eflags, bool use_active_snapshot) { ... PG_TRY(); { ActivePortal = portal; CurrentResourceOwner = portal->resowner; PortalContext = PortalGetHeapMemory(portal); oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); /* Must remember portal param list, if any */ portal->portalParams = params; /* * Determine the portal execution strategy */ portal->strategy = ChoosePortalStrategy(portal->stmts); /* * Fire her up according to the strategy */ switch (portal->strategy) { ... } } PG_CATCH(); { /* Uncaught error while executing portal: mark it dead */ MarkPortalFailed(portal); /* Restore global vars and propagate error */ ActivePortal = saveActivePortal; CurrentResourceOwner = saveResourceOwner; PortalContext = savePortalContext; PG_RE_THROW(); } PG_END_TRY(); MemoryContextSwitchTo(oldContext); ActivePortal = saveActivePortal; CurrentResourceOwner = saveResourceOwner; PortalContext = savePortalContext; portal->status = PORTAL_READY; }