- 专栏内容:postgresql内核源码分析
- 个人主页:我的主页
- 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
目录
前言
本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。
概述
当我们在客户端查询时,除了表中的数据之外,还有一个状态信息,看到的也是以tuple的形式展示出来,其实这此数据是临时组成tuple格式,而不是存储在表中的数据。
下面我们就来看下,这类型数据是如何拼装成tuple格式的,需要那些步骤。
步骤分解
- 需要一个接收者
DestReceiver *dest;
dest = CreateDestReceiver(DestRemoteSimple);
- tuple描述符,来记录tuple信息
TupleDesc tupdesc;
/* need a tuple descriptor representing four columns */
tupdesc = CreateTemplateTupleDesc(4);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "systemid",
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "timeline",
INT4OID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "xlogpos",
TEXTOID, -1, 0);
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "dbname",
TEXTOID, -1, 0);
这里是一个有4列的tuple,然后定义每列的表头和类型,对应的参数分别为:
attributeNumber, 列的序号,从1开始
attributeName, 列名称,也就是表头显示
oidtypeid,列的类型ID,对应pg_type中的oid
typmod, 对应于pg_attribute中的atttypmod,记录了在表创建时提供的类型相关数据(例如一个varchar列的最大长度)。它会被传递给类型相关的输入函数和长度强制函数。对于那些不需要atttypmod的类型,这个值通常总是为-1。
attdim,如果该列是一个数组类型,这里就是其维度数;否则为0。
- 输出状态,将接收者和tuple描述符关联起来
TupOutputState *tstate;
/* prepare for projection of tuples */
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
通过定义的一组通用操作TTSOpsVirtual,将两者联系起来。
- 开始准备数据
Datum values[4];
bool nulls[4];
/* column 1: system identifier */
values[0] = CStringGetTextDatum(sysid);
/* column 2: timeline */
values[1] = Int32GetDatum(ThisTimeLineID);
/* column 3: wal location */
values[2] = CStringGetTextDatum(xloc);
/* column 4: database name, or NULL if none */
if (dbname)
values[3] = CStringGetTextDatum(dbname);
else
nulls[3] = true;
此处需要定义两个数组,一个是存储数据,另一个是无数据时的null有效;
- 发送数据
先将数据填加到发送slot中;
/* insert data */
memcpy(slot->tts_values, values, natts * sizeof(Datum));
memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
修改slot的标志
slot->tts_flags &= ~TTS_FLAG_EMPTY;
slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
调用接收者的发送接口进行处理
/* send the tuple to the receiver */
(void) tstate->dest->receiveSlot(slot, tstate->dest);
- 结束发送
主要作用是清理现场,一是关闭当前接收者;二是释放过程中申请的内存资源
slot->tts_ops->clear(slot);
tstate->dest->rShutdown(tstate->dest);
最后再获后释放内存空间。
结尾
作者邮箱:[email protected]
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!