一、引入
-- 创建一个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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




