69.2. 系统目录初始数据

每个具有任何手动创建的初始数据(有些则没有)的目录都有一个对应的.dat文件,该文件以可编辑的格式包含其初始数据。

69 .2.1. 资料 Files 格式

每个.dat文件都包含 Perl 数据结构 Literals,这些 Literals 被简单地评估为生成内存中的数据结构,该数据结构由一组哈希引用组成,每个目录行一个。 pg_database.dat的摘录略作修改后,将演示其主要功能:

[

# A comment could appear here.
{ oid => '1', oid_symbol => 'TemplateDbOid',
  descr => 'database\'s default template',
  datname => 'template1', datdba => 'PGUID', encoding => 'ENCODING',
  datcollate => 'LC_COLLATE', datctype => 'LC_CTYPE', datistemplate => 't',
  datallowconn => 't', datconnlimit => '-1', datlastsysoid => '0',
  datfrozenxid => '0', datminmxid => '1', dattablespace => '1663',
  datacl => '_null_' },

]

注意事项:

建议在提交目录数据补丁之前运行reformat_dat_file.pl。为了方便起见,您只需更改为src/include/catalog/并运行make reformat-dat-files即可。

69 .2.2. OID 分配

通过写入oid => nnnn元数据字段,可以为出现在初始数据中的目录行提供手动分配的 OID。此外,如果分配了 OID,则可以通过写入oid_symbol => name元数据字段来创建该 OID 的 C 宏。

如果在其他预加载的行中有对它们的 OID 引用,则预加载的目录行必须具有预分配的 OID。如果必须从 C 代码中引用行的 OID,则还需要预分配的 OID。如果两种情况都不适用,则可以省略oid元数据字段,在这种情况下,引导程序代码会自动分配一个 OID,或者在没有 OID 的目录中将其保留为零。实际上,我们通常为给定目录中的所有预加载行或不为所有预加载行预分配 OID,即使实际上只有部分交叉引用也是如此。

用 C 代码写任何 OID 的实际数值被认为是非常糟糕的形式。始终使用宏代替。直接引用pg_proc OID 很常见,以至于有一种特殊的机制可以自动创建必要的宏。参见src/backend/utils/Gen_fmgrtab.pl。类似地-但由于历史原因,操作方式有所不同-存在一种自动方法来为pg_type OID 创建宏。因此,在这两个目录中不需要oid_symbol条目。同样,系统会自动设置pg_class OID 的系统目录和索引的宏。对于所有其他系统目录,您必须通过oid_symbol条目手动指定所需的任何宏。

要为新的预加载行找到可用的 OID,请运行脚本src/include/catalog/unused_oids。它打印未使用的 OID 的范围(例如,输出行“ 45-900”表示尚未分配 OID 45 至 900)。当前,OID 1-9999 保留用于手动分配。 unused_oids脚本仅浏览目录标题和.dat文件,以查看未出现的文件。您也可以使用duplicate_oids脚本检查错误。 (genbki.pl还将在编译时检测到重复的 OID.)

在引导运行开始时,OID 计数器从 10000 开始。如果目录行在需要 OID 的表中,但是oid字段未预先分配 OID,则它将收到 10000 或更高的 OID。

69 .2.3. OID 参考查询

从一个初始目录行到另一个初始目录行的交叉引用可以通过仅写入参考行的预分配 OID 来编写。但这容易出错并且难以理解,因此对于频繁引用的目录,genbki.pl提供了代替编写符号引用的机制。当前,这可以用于访问方法,函数,运算符,操作类,操作族和类型的引用。规则如下:

genbki.pl在运行时解析所有符号引用,并将简单的数字 OID 放入发出的 BKI 文件中。因此,不需要引导后端处理符号引用。

69 .2.4. 用于编辑数据文件的食谱

以下是有关更新目录数据文件时执行常见任务的最简单方法的一些建议。

将默认的新列添加到目录: 使用BKI_DEFAULT(value)Comments 将该列添加到头文件中。只需通过在需要非默认值的现有行中添加字段来调整数据文件。

向没有一列的现有列添加默认值: 向头文件添加BKI_DEFAULT注解,然后运行make reformat-dat-files删除现在冗余的字段条目。

删除一列,不管它是否具有默认值: 从标题中删除该列,然后运行make reformat-dat-files删除现在无用的字段条目。

更改或删除现有的默认值: 您不能简单地更改头文件,因为这将导致当前数据被错误地解释。首先运行make expand-dat-files重写具有显式插入的所有默认值的数据文件,然后更改或删除BKI_DEFAULT注解,然后运行make reformat-dat-files再次删除多余的字段。

即席批量编辑: reformat_dat_file.pl可用于执行多种批量更改。查找其块 Comments,该 Comments 显示可以在其中插入一次性代码的位置。在下面的示例中,我们将把pg_proc中的两个布尔字段合并为一个 char 字段:

+    /* see PROKIND_ categories below */
+    char        prokind BKI_DEFAULT(f);
-           # At this point we have the full row in memory as a hash
-           # and can do any operations we want. As written, it only
-           # removes default values, but this script can be adapted to
-           # do one-off bulk-editing.
+           # One-off change to migrate to prokind
+           # Default has already been filled in by now, so change to other
+           # values as appropriate
+           if ($values{proisagg} eq 't')
+           {
+               $values{prokind} = 'a';
+           }
+           elsif ($values{proiswindow} eq 't')
+           {
+               $values{prokind} = 'w';
+           }
$ cd src/include/catalog
$ perl  rewrite_dat_with_prokind.pl  pg_proc.dat

此时,pg_proc.dat具有所有三列prokindproisaggproiswindow,尽管它们只会出现在具有非默认值的行中。

-    /* is it an aggregate? */
-    bool        proisagg BKI_DEFAULT(f);
-
-    /* is it a window function? */
-    bool        proiswindow BKI_DEFAULT(f);

有关用于批量编辑的脚本的更多示例,请参阅此消息所附的convert_oid2name.plremove_pg_type_oid_symbols.pl

上一章 首页 下一章