# 71.1. System Catalog Declaration Rules
The key part of a catalog header file is a C structure definition describing the layout of each row of the catalog. This begins with aCATALOG
macro, which so far as the C compiler is concerned is just shorthand fortypedef struct FormData_*
catalogname*
. Each field in the struct gives rise to a catalog column. Fields can be annotated using the BKI property macros described ingenbki.h
, for example to define a default value for a field or mark it as nullable or not nullable. TheCATALOG
line can also be annotated, with some other BKI property macros described ingenbki.h
, to define other properties of the catalog as a whole, such as whether it is a shared relation.
The system catalog cache code (and most catalog-munging code in general) assumes that the fixed-length portions of all system catalog tuples are in fact present, because it maps this C struct declaration onto them. Thus, all variable-length fields and nullable fields must be placed at the end, and they cannot be accessed as struct fields. For example, if you tried to setpg_type
.typrelid
to be NULL, it would fail when some piece of code tried to referencetypetup->typrelid
(or worse,typetup->typelem
, because that followstyprelid
)。这将导致随机错误甚至分段违规。
作为对此类错误的部分防护,不应该使可变长度或可为空的字段对 C 编译器直接可见。这是通过将它们包装在#ifdef CATALOG_VARLEN
...#万一
(在哪里CATALOG_VARLEN
是一个从未定义的符号)。这可以防止 C 代码粗心地尝试访问可能不存在或可能位于其他偏移量的字段。作为防止创建错误行的独立防护措施,我们要求将所有不应为空的列标记为pg_attribute
.引导代码将自动将目录列标记为非空
如果它们是固定宽度并且前面没有任何可为空或可变宽度的列。如果此规则不充分,您可以通过使用强制正确标记BKI_FORCE_NOT_NULL
和BKI_FORCE_NULL
根据需要进行注释。
前端代码不应包含任何pg_xxx.h
目录头文件,因为这些文件可能包含不会在后端之外编译的 C 代码。(通常,这是因为这些文件还包含函数的声明src/后端/目录/
文件。)相反,前端代码可能包含相应的生成pg_xxx_d.h
标头,将包含 OID#定义
s 和任何其他可能在客户端使用的数据。如果您希望目录标题中的宏或其他代码对前端代码可见,请编写#ifdef EXPOSE_TO_CLIENT_CODE
...#万一
围绕该部分进行指导genbki.pl
将该部分复制到pg_xxx_d.h
标题。
一些目录是如此基础,以至于它们甚至无法由 BKI 创建创造
用于大多数目录的命令,因为该命令需要将信息写入这些目录以描述新目录。这些被称为引导程序目录,并且定义一个需要很多额外的工作:您必须在预加载的内容中手动为它们准备适当的条目pg_class
和pg_type
,并且这些条目将需要更新以用于目录结构的后续更改。(引导目录也需要在pg_attribute
, 但幸运的是genbki.pl
现在可以处理这些琐事。)尽可能避免使新目录成为引导目录。