【PG内核】pg11秒级新增非空默认字段的实现方法

pg11新特性,可以瞬间向一个表中添加非空默认字段。

今天研究了一下这个特性的内核实现方式,写个博客简单记录一下。

 

结论奉上

pg在从硬盘或者内存获取到一条数据记录后(以下称tuple),会使用

heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc,Datum *values, bool *isnull)

函数把这个tuple根据其所在表的表结构(tupleDesc)进行"肢解",肢解结果放到values数组里。

也就是说values数组里的每一个元素对应着一个字段的值。isnull也是一个数组,这个数组记录着

对应的字段是否有值。

 

在pg11中heap_deform_tuple()函数增加了一段代码

for (; attnum < tdesc_natts; attnum++)
		values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]);

用于对values为空但是有缺失默认值的字段追加赋值。

(只对增加列时就制定了默认值的字段有效,先增加列后指定默认值的无效)

这样增加字段的之前tuple的数据没有任何改动的情况下,就可以查询出默认值。

 

系统表的改变

postgres=# \d pg_attribute
              Table "pg_catalog.pg_attribute"
    Column     |   Type    | Collation | Nullable | Default 
---------------+-----------+-----------+----------+---------
 attrelid      | oid       |           | not null | 
 attname       | name      |           | not null | 
 atttypid      | oid       |           | not null | 
 attstattarget | integer   |           | not null | 
 attlen        | smallint  |           | not null | 
 attnum        | smallint  |           | not null | 
 attndims      | integer   |           | not null | 
 attcacheoff   | integer   |           | not null | 
 atttypmod     | integer   |           | not null | 
 attbyval      | boolean   |           | not null | 
 attstorage    | "char"    |           | not null | 
 attalign      | "char"    |           | not null | 
 attnotnull    | boolean   |           | not null | 
 atthasdef     | boolean   |           | not null | 
 atthasmissing | boolean   |           | not null | 
 attidentity   | "char"    |           | not null | 
 attisdropped  | boolean   |           | not null | 
 attislocal    | boolean   |           | not null | 
 attinhcount   | integer   |           | not null | 
 attcollation  | oid       |           | not null | 
 attacl        | aclitem[] |           |          | 
 attoptions    | text[]    |           |          | 
 attfdwoptions | text[]    |           |          | 
 attmissingval | anyarray  |           |          | 
Indexes:
    "pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname)
    "pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum)

postgres=# 

系统表pg_attribute中增加了atthasmissing和attmissingval字段。

atthasmissing:这个字段是否有缺失默认值

attmissingval:缺失默认值,getmissingattr()函数获取的值的来源就是这里。

增加一个有默认值的字段时这个字段的atthasmissing设置为true,attmissingval设置为默认值。

注意:当修改某个字段的默认值时,只会修改pg_attrdef系统表里的默认值,不会修改pg_attribute表里的默认值

也就是说,增加列之后缺失默认值的值不会再发生改变。如果你在增加列时未指定默认值,那么这个列的值永远不

会自动填充。

 

 

 

 

转载于:https://my.oschina.net/lcc1990/blog/3003889

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值