当前位置: 首页 > news >正文

pg空值管理

文章目录

  • 环境
  • 文档用途
  • 详细信息

环境

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

文档用途

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

详细信息

1.元组头部结构及其主要字段解释说明


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

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)); }
http://www.jsqmd.com/news/1094104/

相关文章:

  • 深入解析无列名SQL注入:原理、实战与防御
  • Pi Agent 对接实现:消息解析、重试与取消
  • QuantConnect Lean算法交易引擎:从零开始构建专业量化交易系统的完整指南
  • 私教服务 | 他不加班,项目延期了,我该怎么办?
  • 一套 Spec-First 的 AI 编程工作流
  • 基于HAL库的STM32笔记——GPIO
  • 作为Python开发者值得关注的五个第三方库
  • ITSM系统里的工单分类:为什么分类越细,IT服务台反而越难用?
  • AI教材写作新突破!借助AI工具快速编写教材,低查重率不是梦
  • 进阶调节作用分析 | 多个自变量、二分类因变量、有序因变量及面板数据都能做
  • 自动售货机和传统便利店的区别,哪个更有优势?~YH
  • 聚龙汇刘睿 以信任为基石 打造投资社群新生态
  • PHP代码审计实战:preg_match正则绕过与无字母数字WebShell构造
  • 告别付费:Android原生TTS引擎的离线语音合成实战
  • 联想拯救者BIOS隐藏功能解锁:5分钟释放你的笔记本全部性能
  • 2026实测12款论文降AI率软件,效果最好的竟然是它!
  • Agent Runtime 范式革命:从混沌执行到确定性系统
  • 深入解析JavaScript原型链污染:原理、危害与防御实战
  • 2026年为什么越来越多家庭开始重视家庭系统建设?
  • agent 学习
  • AI期刊论文写作工具哪个好?2026年主流工具横向测评
  • 艺起玩一夏 | 暑期用小艺做攻略、听讲解、修美图,轻松玩转沉浸式研学
  • Java毕业设计-基于 SpringBoot 的戏曲文化科普与分享平台设计 传统文化视域下戏曲传播管理系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • 主流办公APP对比,图文会议总结功能谁更实用
  • 2026一线大厂Java面试八股文整理(附答案)| 建议收藏
  • ByteArrayInputStream和DataInputStream的源码分析和使用方法详细分析前言)UTF-8 编码规则
  • 621万vs697万!2026年结婚人数预测你信哪个?
  • 世界模型的PopLang底座:当物理AI遇上ibbot智体机灵,每台手机都能成为“认知推演沙盘”
  • Python列表去重的20种实现方式
  • 2026年门店SaaS系统开发服务商测评推荐:适配本地生活服务的优质方案解析