我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PostgreSQL源码学习--插入数据#6

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PostgreSQL源码学习--插入数据#6

PostgreSQL源码学习--插入数据#6

本节介绍ExecModifyTable函数。

相关数据结构

typedef struct ModifyTableState
{
	PlanState	ps;				
	CmdType		operation;		
	bool		canSetTag;		
	bool		mt_done;		
	PlanState **mt_plans;		
	int			mt_nplans;		
	int			mt_whichplan;	
	TupleTableSlot **mt_scans;	
	ResultRelInfo *resultRelInfo;	
	ResultRelInfo *rootResultRelInfo;	
	List	  **mt_arowmarks;	
	EPQState	mt_epqstate;	
	bool		fireBSTriggers; 
	List	   *mt_excludedtlist;	

	
	TupleTableSlot *mt_root_tuple_slot;

	
	struct PartitionTupleRouting *mt_partition_tuple_routing;

	
	struct TransitionCaptureState *mt_transition_capture;

	
	struct TransitionCaptureState *mt_oc_transition_capture;

	
	TupleConversionMap **mt_per_subplan_tupconv_maps;
} ModifyTableState;

ExecModifyTable函数

static TupleTableSlot *
ExecModifyTable(PlanState *pstate);

CHECK_FOR_INTERRUPTS();


if (estate->es_epq_active != NULL)
	elog(ERROR, "ModifyTable should not be called during EvalPlanQual");


if (node->mt_done)
	return NULL;


if (node->fireBSTriggers)
{
	fireBSTriggers(node);
	node->fireBSTriggers = false;
}


resultRelInfo = node->resultRelInfo + node->mt_whichplan;
subplanstate = node->mt_plans[node->mt_whichplan];
junkfilter = resultRelInfo->ri_junkFilter;


saved_resultRelInfo = estate->es_result_relation_info;
estate->es_result_relation_info = resultRelInfo;


for (;;)
{
	
	ResetPerTupleExprContext(estate);
	
	
	if (pstate->ps_ExprContext)
		ResetExprContext(pstate->ps_ExprContext);
	
	
	planSlot = ExecProcNode(subplanstate);
	
	if (TupIsNull(planSlot))
	{
		
		node->mt_whichplan++;
		if (node->mt_whichplan < node->mt_nplans)
		{
			resultRelInfo++;
			subplanstate = node->mt_plans[node->mt_whichplan];
			junkfilter = resultRelInfo->ri_junkFilter;
			estate->es_result_relation_info = resultRelInfo;
			
			EvalPlanQualSetPlan(&node->mt_epqstate, subplanstate->plan,
							node->mt_arowmarks[node->mt_whichplan]);
			
			if (node->mt_transition_capture != NULL)
			{
				node->mt_transition_capture->tcs_map =
					tupconv_map_for_subplan(node, node->mt_whichplan);
			}
			if (node->mt_oc_transition_capture != NULL)
			{
				node->mt_oc_transition_capture->tcs_map =
					tupconv_map_for_subplan(node, node->mt_whichplan);
			}
			continue;
		}
		else
			break;
	}
	
	
	if (resultRelInfo->ri_usesFdwDirectModify)
	{
		Assert(resultRelInfo->ri_projectReturning);

		slot = ExecProcessReturning(resultRelInfo, NULL, planSlot);

		estate->es_result_relation_info = saved_resultRelInfo;
		return slot;
	}
	
	
	EvalPlanQualSetSlot(&node->mt_epqstate, planSlot);
	slot = planSlot;
	
	tupleid = NULL;
	oldtuple = NULL;
	
	if (junkfilter != NULL)
	{
		
		if (operation == CMD_UPDATE || operation == CMD_DELETE)
		{
			relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind;
			if (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW)
			{
				datum = ExecGetJunkAttribute(slot,
								 junkfilter->jf_junkAttNo,
								 &isNull);
				
				if (isNull)
					elog(ERROR, "ctid is NULL");

				tupleid = (ItemPointer) DatumGetPointer(datum);
				tuple_ctid = *tupleid;	
				tupleid = &tuple_ctid;
			}
			
			
			else if (AttributeNumberIsValid(junkfilter->jf_junkAttNo))
			{
				datum = ExecGetJunkAttribute(slot,
								 junkfilter->jf_junkAttNo,
								 &isNull);
				
				if (isNull)
					elog(ERROR, "wholerow is NULL");

				oldtupdata.t_data = DatumGetHeapTupleHeader(datum);
				oldtupdata.t_len =
					HeapTupleHeaderGetDatumLength(oldtupdata.t_data);
				ItemPointerSetInvalid(&(oldtupdata.t_self));
				
				oldtupdata.t_tableOid =
					(relkind == RELKIND_VIEW) ? InvalidOid :
					RelationGetRelid(resultRelInfo->ri_RelationDesc);

				oldtuple = &oldtupdata;
			}
			else
				Assert(relkind == RELKIND_FOREIGN_TABLE);
		}
		
		
		if (operation != CMD_DELETE)
			slot = ExecFilterJunk(junkfilter, slot);
	}
	
	
	switch (operation)
	{
		case CMD_INSERT:
			
			if (proute)
				slot = ExecPrepareTupleRouting(node, estate, proute,
									   resultRelInfo, slot);
			slot = ExecInsert(node, slot, planSlot,
						  estate, node->canSetTag);
			
			if (proute)
				estate->es_result_relation_info = resultRelInfo;
			break;
		case CMD_UPDATE:
			slot = ExecUpdate(node, tupleid, oldtuple, slot, planSlot,
							  &node->mt_epqstate, estate, node->canSetTag);
			break;
		case CMD_DELETE:
			slot = ExecDelete(node, tupleid, oldtuple, planSlot,
							  &node->mt_epqstate, estate,
							  true, node->canSetTag,
							  false  , NULL, NULL);
			break;
		default:
			elog(ERROR, "unknown operation");
			break;
	}
	
	
	if (slot)
	{
		estate->es_result_relation_info = saved_resultRelInfo;
		return slot;
	}
}


	estate->es_result_relation_info = saved_resultRelInfo;


fireASTriggers(node);

node->mt_done = true;

return NULL;

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PostgreSQL源码学习--插入数据#6

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

PostgreSQL源码学习--插入数据#6

本节介绍ExecModifyTable函数。相关数据结构typedef struct ModifyTableState{PlanStateps;CmdTypeoperation;/* INSERT
PostgreSQL源码学习--插入数据#6
2020-08-14

PostgreSQL源码学习--插入数据#4,5

本节介绍table_tuple_insert和ExecInsert函数。相关数据结构//src/include/utils/rel.htypedef struct RelationData{TupleDescrd_att;/* tupl
PostgreSQL源码学习--插入数据#4,5
2016-01-11

PostgreSQL源码学习--插入数据#2

本节介绍heap_insert函数的代码流程本节前置toast机制:https://www.postgresql.org/docs/12/storage-toast.html可见性映射表:https://www.postgresql.org/docs/12/s
PostgreSQL源码学习--插入数据#2
2020-02-11

PostgreSQL源码学习--插入数据#3

本节介绍heapam_tuple_insert函数的代码流程相关数据结构结构体中有些成员可能目前难以理解,暂时先列出来,先把当前用到的成员能搞明白就可以。// src/include/executor/tuptable.htypedef struct Tupl
PostgreSQL源码学习--插入数据#3
2014-10-19

PostgreSQL源码学习(2)插入数据#0

插入数据主要的实现在bufpage.c中,主要的函数是PageAddItemExtended。查看调用栈:#0 PageAddItemExtended (page=0x7fddcac3cd00 "", item=0x141f540 "34701",
PostgreSQL源码学习(2)插入数据#0
2019-10-17

PostgreSQL源码学习(3)插入数据#1

相关数据结构//src/interfaces/ecpg/preproc/type.htypedef int Buffer;HeapTupleData的结构已在前面
PostgreSQL源码学习(3)插入数据#1
2015-01-16

PostgreSQL源码学习--更新数据#3

本节介绍ExecUpdate函数。ExecUpdate函数static TupleTableSlot *ExecUpdate(ModifyTableState *mtstate, ItemPointer tupleid, HeapTuple oldtu
PostgreSQL源码学习--更新数据#3
2016-11-30

PostgreSQL源码学习--删除数据#0

以一条delete from test where a = 123;的SQL语句为例,跟踪删除数据的代码逻辑。(PG版本为12.2)删除数据主要的函数是heap_delete。查看调用栈:#0 heap_delete (relation=0x7f67ac24
PostgreSQL源码学习--删除数据#0
2015-03-25

PostgreSQL源码学习--更新数据#1,2

本节介绍heapam_tuple_update和table_tuple_update函数。heapam_tuple_update函数//src/backend/access/heap/heapam_handler.cstatic TM_Resultheapam
PostgreSQL源码学习--更新数据#1,2
2018-03-29

PostgreSQL源码学习--更新数据#0

以一条update test set b = "bcd" where a = 123;的SQL语句为例,跟踪更新数据的代码逻辑。(PG版本为12.2)删除数据主要的函数是heap_update。查看调用栈:#0 heap_update (relation=0
PostgreSQL源码学习--更新数据#0
2017-05-20

PostgreSQL源码学习--删除数据#1,2

本节介绍heapam_tuple_delete和table_tuple_delete函数。heapam_tuple_delete函数//src/backend/access/heap/heapam_handler.cstatic TM_Resultheapam
PostgreSQL源码学习--删除数据#1,2
2020-08-27

PostgreSQL源码学习--删除数据#3

本节介绍ExecDelete函数。从表中删除时,tupleid标识要删除的元组,oldtuple为空;从视图中删除时,oldtuple传递给INSTEAD OF触发器标识要删除的内容,tupleid无效;从外部表中删除时,tupleid无效,fdw使用plan
PostgreSQL源码学习--删除数据#3
2020-01-09

redis源码学习02:跳跃表插入结点

本文是本人在学习redis源码时的笔记,本文主要是对跳跃表插入结点代码的中文注释,如有错误欢迎指正。 有关跳跃表的原理可以上网搜材料,有很多。 首先看下redis源码里有关跳跃表的相关结构体: typedef struct zskiplistNode { /
redis源码学习02:跳跃表插入结点
2015-07-29

编程热搜

目录