看看portal生成完毕后,干了什么(PortalDefineQuery):
1 /* 2 * Create unnamed portal to run the query or queries in. If there 3 * already is one, silently drop it. 4 */ 5 portal = CreatePortal("", true, true); 6 /* Don't display the portal in pg_cursors */ 7 portal->visible = false; 8 9 /*10 * We don't have to copy anything into the portal, because everything11 * we are passing here is in MessageContext, which will outlive the12 * portal anyway.13 */14 PortalDefineQuery(portal,15 NULL,16 query_string,17 commandTag,18 plantree_list,19 NULL);
再来看PortalDefineQuery的定义:
1 /* 2 * PortalDefineQuery 3 * A simple subroutine to establish a portal's query. 4 * 5 * Notes: as of PG 8.4, caller MUST supply a sourceText string; it is not 6 * allowed anymore to pass NULL. (If you really don't have source text, 7 * you can pass a constant string, perhaps "(query not available)".) 8 * 9 * commandTag shall be NULL if and only if the original query string10 * (before rewriting) was an empty string. Also, the passed commandTag must11 * be a pointer to a constant string, since it is not copied.12 *13 * If cplan is provided, then it is a cached plan containing the stmts, and14 * the caller must have done GetCachedPlan(), causing a refcount increment.15 * The refcount will be released when the portal is destroyed.16 *17 * If cplan is NULL, then it is the caller's responsibility to ensure that18 * the passed plan trees have adequate lifetime. Typically this is done by19 * copying them into the portal's heap context.20 *21 * The caller is also responsible for ensuring that the passed prepStmtName22 * (if not NULL) and sourceText have adequate lifetime.23 *24 * NB: this function mustn't do much beyond storing the passed values; in25 * particular don't do anything that risks elog(ERROR). If that were to26 * happen here before storing the cplan reference, we'd leak the plancache27 * refcount that the caller is trying to hand off to us.28 */29 void30 PortalDefineQuery(Portal portal,31 const char *prepStmtName,32 const char *sourceText,33 const char *commandTag,34 List *stmts,35 CachedPlan *cplan)36 {37 AssertArg(PortalIsValid(portal));38 AssertState(portal->status == PORTAL_NEW);39 40 AssertArg(sourceText != NULL);41 AssertArg(commandTag != NULL || stmts == NIL);42 43 portal->prepStmtName = prepStmtName;44 portal->sourceText = sourceText;45 portal->commandTag = commandTag;46 portal->stmts = stmts;47 portal->cplan = cplan;48 portal->status = PORTAL_DEFINED;49 }
根据参数调用的情况:
*prepStmtName是NULL,sourceText是 query_string,commandTag传递了。
Lits *stmts 是 exec_simple_query中生成的 plantree_list,CachedPlan *cplan 是空值。在我使用 select * from tab01 这种语句的时候,commandTag是 SELECT。