pg空值管理

本文详细介绍了瀚高数据库在Linux环境下,特别是RedHatEnterpriseLinux7版本中,元组头部结构、nullbitmap的使用以及如何通过infomask判断属性是否为空的方法,包括att_isnull函数的实现和infomask_show函数的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

瀚高数据库
目录
环境
文档用途
详细信息

环境

系统平台:Linux x86-64 Red Hat Enterprise Linux 7
版本:14,13,12

文档用途

从元组底层的角度看属性为空的判定

详细信息

1.元组头部结构及其主要字段解释说明
image.png
在这里插入图片描述

2.伪代码

HeapTupleHeader tup = tuple->t_data;                    // 某个表当中某个元组的元组头部指针

bits8	     *bp = tup->t_bits;                      // ptr to null bitmap in one tuple

int	     tdesc_natts = ((Relation)rel)->rd_att->natts;    // 从RelationData中的TupleDescData获取元组的属性数量

int         natts = ((tup)->t_infomask2 & HEAP_NATTS_MASK) // 在该元组的元组头部中,根据infomask2计算该元组的属性数目 HEAP_NATTS_MASK = 0x7ff, 11位

natts = Min(natts, tdesc_natts);                      // 新元组数目可能比预期的要多,为了避免越界访问,选小

bool hasnulls = tup->infomask & HEAP_HASNULL;



for (attnum = 0; attnum < natts; attnum++)

{

  Form_pg_attribute thisatt = &((Relation)rel)->rd_att->attrs[i]; //对每个属性获取pg_attribute的描述



  if (hasnulls && att_isnull(attnum, bp))// 在该元组的t_bits当中判断该属性对应的属性值是否为空

 {

      ...... 

  }

}

att_isnull实现:

/*

 * Check a tuple's null bitmap to determine whether the attribute is null.

 * Note that a 0 in the null bitmap indicates a null, while 1 indicates

 * non-null.

 */

static inline bool att_isnull(int ATT, const bits8 *BITS)

{

	return !(BITS[ATT >> 3] & (1 << (ATT & 0x07)));

}

att_isnull解释:

t_bits[…]的每一个元素是一个字节的数,bits8==uint8

ATT >> 3: 元组属性编号从0开始编号,8位一组,正好对应一个t_bits[]当中的一个元素

1<<(ATT&Ox7): 8位一组,从0开始编号, 1<<ATT&(111)b计算的这这一组中的位置。

3.TEST
image.png

infomask_show函数实现:

#include "postgres.h"

#include "fmgr.h"

#include "utils/varlena.h"

#include "utils/builtins.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(infomask_show);





//#define HEAP_HASNULL 0x0001 /* has null attribute(s) */

//#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */

//#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */

//#define HEAP_HASOID_OLD 0x0008 /* has an object-id field */

//#define HEAP_XMAX_KEYSHR_LOCK 0x0010 /* xmax is a key-shared locker */

//#define HEAP_COMBOCID 0x0020 /* t_cid is a combo CID */

//#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */

//#define HEAP_XMAX_LOCK_ONLY 0x0080 /* xmax, if valid, is only a locker */



 /* xmax is a shared locker */

//#define HEAP_XMAX_SHR_LOCK (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)



//#define HEAP_LOCK_MASK (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \

HEAP_XMAX_KEYSHR_LOCK)

//#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */

//#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */

//#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)

//#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */

//#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */

//#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId */

//#define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */

//#define HEAP_MOVED_OFF 0x4000 /* moved to another place by pre-9.0 * VACUUM FULL; kept for binary * * upgrade support */

//#define HEAP_MOVED_IN 0x8000 /* moved from another place by pre-9.0* VACUUM FULL; kept for binary* * upgrade support */

char buf[1024];

char *macro_vector[] = {"HEAP_HASNULL","HEAP_HASVARWIDTH","HEAP_HASEXTERNAL","HEAP_HASOID_OLD","HEAP_XMAX_KEYSHR_LOCK","HEAP_COMBOCID",

"HEAP_XMAX_EXCL_LOCK","HEAP_XMAX_LOCK_ONLY","HEAP_XMIN_COMMITTED","HEAP_XMIN_INVALID","HEAP_XMIN_FROZEN","HEAP_XMAX_COMMITTED","HEAP_XMAX_INVALID","HEAP_XMAX_IS_MULTI",

"HEAP_UPDATED","HEAP_MOVED_OFF","HEAP_MOVED_IN"};

Datum infomask_show(PG_FUNCTION_ARGS)

{

  unsigned short infomask_bits = PG_GETARG_UINT16(0);

  //PG_RETURN_UINT16(infomask_bits);

  int i = 0;

  char *start = buf;

  while (i < 16)

  {

    if (infomask_bits & (1 << i))

{

     if( i > 0 )

{  

    int len = strlen(buf);

strcpy(buf+len, " | ");

        len = strlen(buf);

start = buf + len;

}

strcpy(start,macro_vector[i]);

}

    i++;

  }

  

  PG_RETURN_TEXT_P(cstring_to_text(buf));

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值