【PG內核】pg11秒級新增非空默認字段的實現方法

pg11新特性,能夠瞬間向一個表中添加非空默認字段。sql

今天研究了一下這個特性的內核實現方式,寫個博客簡單記錄一下。數組

 

結論奉上ide

pg在從硬盤或者內存獲取到一條數據記錄後(如下稱tuple),會使用函數

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

函數把這個tuple根據其所在表的表結構(tupleDesc)進行"肢解",肢解結果放到values數組裏。code

也就是說values數組裏的每個元素對應着一個字段的值。isnull也是一個數組,這個數組記錄着orm

對應的字段是否有值。內存

 

在pg11中heap_deform_tuple()函數增長了一段代碼get

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表裏的默認值

也就是說,增長列以後缺失默認值的值不會再發生改變。若是你在增長列時未指定默認值,那麼這個列的值永遠不

會自動填充。

相關文章
相關標籤/搜索