本文只是講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 */
歡迎關注個人公衆號,文章同步發佈。