PostgreSQL系統表及其TOAST是如何定義的

本文只是講PG怎樣定義系統表,而不是修改系統表甚至是定義本身的系統表。html

PG系統表,好比:pg_class、pg_attribute、pg_type 等等
這幾個表相互關聯,後二者要在pg_class記錄本身的表定義,而pg_class又須要在後二者記錄本身的字段和類型,看起來是個死扣。sql

關於它們怎麼定義,有興趣能夠閱讀:
System Catalog Declarations and Initial Contents
比之前的文檔更加細緻和明確,dat文件的定義方式也比之前更清晰。bootstrap

一、系統表數據結構定義,打開 pg_class.hbash

CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO
{
  NameData  relname;    /* class name */
  Oid      relnamespace;  /* OID of namespace containing this class */
  Oid      reltype;    /* OID of entry in pg_type for table's
                 * implicit row type */
  Oid      reloftype;    /* OID of entry in pg_type for underlying
                 * composite type */
...

pg_class 表結構數據結構

flying=# \d pg_class
                     Table "pg_catalog.pg_class"
       Column        |     Type     | Collation | Nullable | Default
---------------------+--------------+-----------+----------+---------
 relname             | name         |           | not null |
 relnamespace        | oid          |           | not null |
 reltype             | oid          |           | not null |
 reloftype           | oid          |           | not null |
...

是否是一一對應,事實上建表腳本就是由這裏抽取生成,因此它們才如此一致。post

二、src/backend/catalog/genbki.pl腳本this

這個Perl腳本負責抽取定義並生成postgres.bki,有興趣能夠結合上邊的文檔理解它。spa

BKI腳本由一個單獨的語法引擎支持,不是咱們常說的SQL,它在bootstrap下,有興趣能夠本身看,之後有機會再講。postgresql

三、代碼code

咱們這裏只是看看PG怎麼作,並非修改,每一個定義都有其相應代碼,它們在commands和catalog下。

後邊我會單獨寫一篇如何新增本身的系統字段。

四、TOAST表

像text類型的字段須要toast存儲,系統表的OID都是預置而且不容許修改,因此它們的TOAST一樣須要預設。

來看 src/include/catalog/toasting.h,以 pg_proc爲例:

DECLARE_TOAST(pg_proc, 2836, 2837);

這個preprocessor是這樣定義的:

#define DECLARE_TOAST(name,toastoid,indexoid) extern int no_such_variable

看起來毫無心義對吧,其實它並非真的給PG代碼用,而是genbki,看過代碼就知道怎麼回事。

五、索引

系統表也是須要索引的,定義在 src/include/catalog/indexing.h,仍是以 pg_proc爲例:

DECLARE_UNIQUE_INDEX(pg_proc_oid_index, 2690, on pg_proc using btree(oid oid_ops));
#define ProcedureOidIndexId  2690
DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index, 2691, on pg_proc using btree(proname name_ops, proargtypes oidvector_ops, pronamespace oid_ops));
#define ProcedureNameArgsNspIndexId  2691

它有兩個索引,上邊的定義包括:名字、OID、am、字段。

這些預處理符一樣不是給C代碼準備的,只有genbki用得上。

六、初始數據

它們定義在同名的dat文件裏,好比 pg_proc.dat。

七、字段可選值

這個並不算表定義,但也是放在一塊兒的,好比pg_proc的provolatile只容許:

#define PROVOLATILE_IMMUTABLE	'i' /* never changes for given input */
#define PROVOLATILE_STABLE		's' /* does not change within a scan */
#define PROVOLATILE_VOLATILE	'v' /* can change even within a scan */

歡迎關注個人公衆號,文章同步發佈。

相關文章
相關標籤/搜索