PostgreSQL源码学习–调度器#13

PostgreSQL源码学习–调度器#13本节介绍PortalRunMulti函数。 PortalRunMulti函数 static void PortalRunMulti(Portal portal, bool isTopLevel, b…

PostgreSQL源码学习--调度器#13

本节介绍PortalRunMulti函数。

PortalRunMulti函数

static void
PortalRunMulti(Portal portal,
		   bool isTopLevel, bool setHoldSnapshot,
		   DestReceiver *dest, DestReceiver *altdest,
		   char *completionTag);

代码100分

代码100分//src/backend/tcop/pquery.c

/* 若目标是DestRemoteExecute,则设置为DestNone */
if (dest->mydest == DestRemoteExecute)
	dest = None_Receiver;
if (altdest->mydest == DestRemoteExecute)
	altdest = None_Receiver;

/* 依次处理每个计划 */
foreach(stmtlist_item, portal->stmts)
{
	PlannedStmt *pstmt = lfirst_node(PlannedStmt, stmtlist_item);
	
	/* 检查取消信号 */
	CHECK_FOR_INTERRUPTS();
	
	/* 若是DML语句 */
	if (pstmt->utilityStmt == NULL)
	{
		/* 动态追踪中当一个查询的规划被开始时触发的探针 */
		TRACE_POSTGRESQL_QUERY_EXECUTE_START();
		
		/* 若有需要,在这里重置执行器计时 */
		if (log_executor_stats)
			ResetUsage();
		
		/* 第一次创建一个新快照,后续更新快照副本的计数就可以 */
		if (!active_snapshot_set)
		{
			Snapshot	snapshot = GetTransactionSnapshot();
			
			/* 有需要时,注册快照并保存在portal中 */
			if (setHoldSnapshot)
			{
				snapshot = RegisterSnapshot(snapshot);
				portal->holdSnapshot = snapshot;
			}
			
			/* 不可以让一个holdSnapshot同时也是一个activeSnapshot,因此这里会拷贝一次 */
			PushCopiedSnapshot(snapshot);
			active_snapshot_set = true;
		}
		UpdateActiveSnapshotCommandId();
		
		/* 处理DML的query语句(上节讲过) */
		if (pstmt->canSetTag)
		{
			/* 语句会设置completionTag */
			ProcessQuery(pstmt,
					 portal->sourceText,
					 portal->portalParams,
					 portal->queryEnv,
					 dest, completionTag);
		}
		else
		{
			/* 语句是rewrite阶段增加的,不会设置completionTag */
			ProcessQuery(pstmt,
					 portal->sourceText,
					 portal->portalParams,
					 portal->queryEnv,
					 altdest, NULL);
		}
		
		/* 若有需要,在这里完成执行器计时并输出 */
		if (log_executor_stats)
			ShowUsage("EXECUTOR STATISTICS");

		/* 动态追踪中当一个查询的规划结束时触发的探针 */
		TRACE_POSTGRESQL_QUERY_EXECUTE_DONE();
	}
	/* DDL语句 */
	else
	{
		if (pstmt->canSetTag)
		{
			Assert(!active_snapshot_set);
			/* 语句会设置completionTag */
			PortalRunUtility(portal, pstmt, isTopLevel, false,
							 dest, completionTag);
		}
		else
		{
			Assert(IsA(pstmt->utilityStmt, NotifyStmt));
			/* 语句是rewrite阶段增加的,不会设置completionTag */
			PortalRunUtility(portal, pstmt, isTopLevel, false,
							 altdest, NULL);
		}
	}
	
	/* 在查询之间增加命令计数器 */
	if (lnext(stmtlist_item) != NULL)
		CommandCounterIncrement();
	
	/* 清理辅助用的内存上下文 */
	Assert(portal->portalContext == CurrentMemoryContext);

	MemoryContextDeleteChildren(portal->portalContext);
}

/* 如果刚刚push了快照,现在将其pop */
if (active_snapshot_set)
	PopActiveSnapshot();

/* 若没有设置completionTag,使用默认值 */
if (completionTag && completionTag[0] == "")
{
	if (portal->commandTag)
		strcpy(completionTag, portal->commandTag);
	if (strcmp(completionTag, "SELECT") == 0)
		sprintf(completionTag, "SELECT 0 0");
	else if (strcmp(completionTag, "INSERT") == 0)
		strcpy(completionTag, "INSERT 0 0");
	else if (strcmp(completionTag, "UPDATE") == 0)
		strcpy(completionTag, "UPDATE 0");
	else if (strcmp(completionTag, "DELETE") == 0)
		strcpy(completionTag, "DELETE 0");
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7861.html

(0)
上一篇 2023-03-12
下一篇 2023-03-12

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注