72.1. Правила объявления системного каталога#

72.1. Правила объявления системного каталога

72.1. Правила объявления системного каталога

Ключевая часть заголовочного файла каталога - это определение структуры на языке C, описывающей структуру каждой строки каталога. Она начинается с макроса CATALOG, который, по мнению компилятора C, является сокращением для typedef struct FormData_catalogname. Каждое поле в структуре соответствует колонке каталога. Поля могут быть аннотированы с использованием макросов свойств BKI, описанных в файле genbki.h, например, для определения значения по умолчанию для поля или отметки его как допускающего значение NULL или не допускающего его. Строка CATALOG также может быть аннотирована с использованием других макросов свойств BKI, описанных в файле genbki.h, для определения других свойств каталога в целом, таких как является ли он общим отношением.

Код кеша системного каталога (и большая часть кода манипулирования каталогами в общем) предполагает, что фиксированная часть всех кортежей системного каталога фактически присутствует, потому что он отображает это объявление структуры C на них. Таким образом, все переменные поля и поля с возможным значением NULL должны быть размещены в конце, и к ним нельзя обращаться как к полям структуры. Например, если вы попытаетесь установить pg_type.typrelid в значение NULL, это приведет к ошибке, когда какой-то код попытается обратиться к typetup->typrelid (или, что еще хуже, typetup->typelem, потому что это следует за typrelid). Это может привести к случайным ошибкам или даже нарушениям сегментации.

Для частичной защиты от этого типа ошибок переменные переменной длины или с возможным значением NULL не должны быть напрямую видимыми для компилятора C. Это достигается обертыванием их в #ifdef CATALOG_VARLEN ... #endif (где CATALOG_VARLEN - это символ, который никогда не определен). Это предотвращает небрежный доступ к полям C-кода, которые могут отсутствовать или находиться на другом смещении. В качестве независимой защиты от создания некорректных строк мы требуем, чтобы все столбцы, которые должны быть ненулевыми, были отмечены такими в pg_attribute. Код загрузки автоматически помечает каталожные столбцы как NOT NULL, если они имеют фиксированную ширину и не предшествуют ни одному столбцу с возможным значением NULL или переменной шириной. Если эта правило недостаточно, вы можете принудительно указать правильную маркировку, используя аннотации BKI_FORCE_NOT_NULL и BKI_FORCE_NULL по мере необходимости.

Frontend code should not include any pg_xxx.h catalog header file, as these files may contain C code that won't compile outside the backend. (Typically, that happens because these files also contain declarations for functions in src/backend/catalog/ files). Instead, frontend code may include the corresponding generated pg_xxx_d.h header, which will contain OID #defines and any other data that might be of use on the client side. If you want macros or other code in a catalog header to be visible to frontend code, write #ifdef EXPOSE_TO_CLIENT_CODE ... #endif around that section to instruct genbki.pl to copy that section to the pg_xxx_d.h header.

Некоторые из каталогов настолько фундаментальны, что их нельзя создать даже с помощью команды BKI create, которая используется для большинства каталогов, потому что эта команда должна записывать информацию в эти каталоги, чтобы описать новый каталог. Эти каталоги называются bootstrap каталогами, и их определение требует дополнительной работы: вам нужно вручную подготовить соответствующие записи для них в предварительно загруженных содержимых pg_class и pg_type, и эти записи будут нуждаться в обновлении при последующих изменениях структуры каталога. (Bootstrap каталоги также требуют предварительно загруженных записей в pg_attribute, но, к счастью, сейчас этим занимается genbki.pl). Постарайтесь избегать создания новых каталогов в качестве bootstrap каталогов, если это возможно.