La partie cruciale d'un fichier d'en-tête de catalogue est une définition de
structure C décrivant l'agencement de chaque ligne dans le catalogue. Cela
commence avec une macro CATALOG
, qui, pour autant que le
compilateur C est concerné, est juste un raccourci pour typedef
struct FormData_
.
Chaque champ dans cette structure donne naissance à une colonne de catalogue.
Les champs peuvent être annotés en utilisant les macros de propriété BKI
décrites dans catalogname
genbki.h
, par exemple pour définir une
valeur par défaut pour un champ pour le marquer comme potentiellement NULL ou
non. La ligne CATALOG
peut également être annotée,
avec d'autres macros de propriété décrites dans genbki.h
,
pour définir d'autres propriétés du catalogue dans son ensemble, par exemple
s'il s'agit d'une relation partagée.
Le code de cache du catalogue système (et la plupart du code concernant le
catalogue en général) part du principe que la partie de taille fixe de toutes
les lignes de tous les catalogues système sont vraiment présentes, car il
associe cette déclaration de structure C sur elles. Ainsi, tous les champs
de longueur variable et tous les champs potentiellement NULL doivent être
placés à la fin, et ils ne peuvent pas être accédés comme des champs de
structure. Par exemple, si vous essayez de positionner
pg_type
.typrelid
à
NULL, cela échouerait quand certaines parties du code essaient de référencer
typetup->typrelid
(ou pire,
typetup->typelem
, car cela suit
typrelid
). Cela aurait pour conséquence des
erreurs aléatoires ou même des erreurs de segmentation.
Comme protection contre ce type d'erreurs, les champs de longueur variable
ou potentiellement NULL ne devraient pas être fait directement visibles
pour le compilateur C. Cela se fait en les entourant de
#ifdef CATALOG_VARLEN
... #endif
(où
CATALOG_VARLEN
est un symbole qui n'est jamais défini).
Cela empêche le code C d'imprudemment essayer d'accéder à des champs qui
pourraient ne pas être là ou pourraient être à des décalage différents.
Comme protection contre la création de lignes incorrectes, nous exigeons
que toutes les colonnes qui devraient être non NULL soient marquées comme
telles dans pg_attribute
. Le code de « bootstrap »
marquera automatiquement les colonnes comme NOT NULL
si
elles sont de taille fixe et ne sont précédées d'aucune colonne potentiellement NULL.
Quand cette règle ne convient pas, vous pouvez forcer un marquage correct en
utilisant les annotations BKI_FORCE_NOT_NULL
et
BKI_FORCE_NULL
selon les besoins.
Le code client ne devrait pas inclure de fichier d'en-tête de catalogue
pg_xxx.h
, car ces fichiers peuvent contenir du code C
qui ne compilerait pas en dehors des processus clients. (Typiquement, cela
arrive car ces fichiers contiennent également des déclarations pour des
fonctions dans des fichiers de src/backend/catalog/
.)
À la place, le client peut inclure les en-têtes correspondantes
pg_xxx_d.h
générées, qui contiendront les OID définis
par des #define
et toute autre donnée qui peut être utile
pour le code client. Si vous voulez que des macros ou d'autre code soient
visibles par le code client, écrivez #ifdef
EXPOSE_TO_CLIENT_CODE
... #endif
autour de cette
section pour demander à genbki.pl
de copier cette
section dans l'en-tête pg_xxx_d.h
.
Une petite partie des catalogues est tellement fondamentale qu'ils ne peuvent
même pas être créés par la commande BKI
create
qui est utilisée pour la plupart des catalogues,
car cette commande a besoin d'écrire des informations dans ces catalogues
pour décrire les nouveaux catalogues. Ceux-ci sont appelés les catalogues
bootstrap, et en définir un nécessite beaucoup de
travail supplémentaire : vous devez manuellement préparer les entrées
appropriées pour eux dans le contenu pré-chargé de
pg_class
et pg_type
, et ces
entrées auront besoin d'être modifiées pour les futures changements de la
structure du catalogue. (Les catalogues « bootstrap » nécessitent également des
entrées pré-chargées dans pg_attribute
, mais
heureusement, genbki.pl
gère maintenant cette corvée.)
Évitez de faire des nouveaux catalogues comme catalogue « bootstrap » si cela est
possible.