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表裏的默認值
也就是說,增長列以後缺失默認值的值不會再發生改變。若是你在增長列時未指定默認值,那麼這個列的值永遠不
會自動填充。