暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

gpdb7源码中如何快速获取Tuple数据

原创 Yongtao 2023-04-18
469

一、引入

-- 创建一个heap表 CREATE TABLE t_heap(c1 int, c2 text); -- 创建一个AO表 CREATE TABLE t_ao(c1 int, c2 text) with(appendonly=true); -- 向heap表插入和查询 insert into t_heap values(1, 'a'); select * from t_heap; select c1 from t_heap; select c2 from t_heap; -- 向AO表插入和查询 insert into t_ao values(1, 'a'); select * from t_ao; select c1 from t_ao; select c2 from t_ao;

如上,SQL应用层获取某个表的某一行(某个HeapTuple)用一句SELECT即可。但是在代码内部则需要指针(Datum)来快速定位。本文简单介绍两种Tuple和代码层面快速获取Tuple信息的方法。

代码源自:postgres 12.12 和 greenplum 7

二、HeapTuple和MemTuple两个结构体

2.1 HeapTuple

HeapTuple是Heap表存储每行数据的基本单元,该结构体包括(1)长度,(2)自指针,(3)对应表OID以及(4)实际数据。

typedef struct HeapTupleData { uint32 t_len; /* length of *t_data */ ItemPointerData t_self; /* SelfItemPointer */ Oid t_tableOid; /* table the tuple came from */ #define FIELDNO_HEAPTUPLEDATA_DATA 3 HeapTupleHeader t_data; /* -> tuple header and data */ } HeapTupleData; typedef HeapTupleData *HeapTuple;
2.2 MemTuple

MemTuple是AO表存储每行数据的基本单元,就两个变量,内容极其少,还需要依赖其它。

typedef struct MemTupleData { uint32 PRIVATE_mt_len; unsigned char PRIVATE_mt_bits[1]; /* varlen */ } MemTupleData; typedef MemTupleData *MemTuple; typedef struct MemTupleBinding { TupleDesc tupdesc; int column_align; int null_bitmap_extra_size; /* extra bytes required by null bitmap */ MemTupleBindingCols bind; /* 2 bytes offsets */ MemTupleBindingCols large_bind; /* large tup, 4 bytes offsets */ } MemTupleBinding;

事实上,greenplum的AO表的MemTuple还需要依赖MemTupleBinding才能解析每行数据(每个Tuple)。

三、heap_getattr()函数和memtuple_getattr()函数

3.1 源码中如何heap表中快速获得实际数据
/* 输入HeapTuple和TupleDesc,attum表示这个Tuple的第几列 */ static inline Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull) // 实际使用 /* print all columns individually */ for (natt = 0; natt < tupdesc->natts; natt++) { Datum origval; /* possibly toasted Datum */ /* get Datum from tuple */ origval = heap_getattr(tuple, natt + 1, tupdesc, &isnull); }
3.1 源码中如何AO表中快速获得实际数据
/* 输入HeapTuple和MemTupleBinding,MemTupleBinding里头有TupleDesc和其它信息,attum表示这个Tuple的第几列 */ Datum memtuple_getattr(MemTuple mtup, MemTupleBinding *pbind, int attnum, bool *isnull) // 实际使用 for(i=0; i<pbind->tupdesc->natts; ++i) { MemTupleAttrBinding *attrbind = &(colbind->bindings[i]); if(attrbind->flag == MTB_ByRef) { bool isnull; Datum d = memtuple_getattr(mtup, pbind, i+1, &isnull); } }

事实上基本不这么用,在gpdb7的代码里只在以下函数用过一次。

bool MemTupleHasExternal(MemTuple mtup, MemTupleBinding *pbind)

因为Heap表的基本单元是HeapTuple,而AO表的基本单元不是MemTuple,而是Varblock。
AO表目前我还不够理解,等深入挖掘后再来改这篇文章。

如有疏漏,恳请赐教。

最后修改时间:2023-04-19 14:19:31
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论