PostgreSQLLa base de données la plus sophistiquée au monde.

Version anglaise

69. Déclaration du catalogue système et contenu initial

PostgreSQL™ utilise de nombreux catalogues systèmes différents pour garder la trace de l'existence et les propriétés des objets des bases de données, tels que les tables et les fonctions. Il n'y a aucune différence physique entre un catalogue système et une table utilisateur standard, mais le code C des processus clients connait la structure et les propriétés de chaque catalogue, et peut les manipuler directement à un bas niveau. Ainsi, par exemple, il est déconseillé de tenter de modifier la structure d'un catalogue à la volée ; cela casserait de nombreuses suppositions inscrites dans le code C sur comment les lignes du catalogues sont arrangées. Mais les structures des catalogues peuvent changer entre plusieurs versions majeures.

Les structures des catalogues sont déclarées dans des en-têtes de fichiers C spécialement formatées dans le répertoire src/include/catalog/ du code source. En particulier, il y a pour chaque catalogue un fichier d'en-tête nommé d'après le catalogue (par exemple, pg_class.h pour pg_class), qui définit l'ensemble des colonnes que le catalogue a, ainsi que certaines autres propriétés basique telles que son OID. D'autres fichiers cruciaux définissant la structure du catalogue incluent indexing.h, qui définit les index présents sur tous les catalogues systèmes, et toasting.h, qui définit les tables TOAST pour les catalogues qui en ont besoin.

Beaucoup des catalogues ont des données initiales qui doivent être chargées à l'intérieur durant la phase de « bootstrap » d'initdb, pour amener le système à un point où il est capable d'exécuter des ordres SQL. (Par exemple, pg_class.h doit contenir une entrée pour lui-même, ainsi qu'autant d'entrées pour chacun des autres catalogues système et index.) Ces données initiales sont conservées dans un format éditable dans des fichiers de données qui sont également stockés dans le répertoire src/include/catalog/. Par exemple, pg_proc.dat décrit toutes les lignes initiales qui doivent être insérées dans le catalogue pg_proc.

Pour créer les fichiers de catalogue et y charger ces données initiales, un processus client fonctionnant en mode bootstrap lit un fichier BKI (Backend Interface) contenant les commandes et les données initiales. Le fichier postgres.bki utilisé dans ce mode est préparé à partir des en-têtes et fichiers de données susmentionnés, en même temps que la création d'une distribution PostgreSQL™, par un script Perl nommé genbki.pl. Bien qu'il soit spécifique à une version précise de PostgreSQL™, postgres.bki ne dépend pas de la plateforme et est installé dans le sous répertoire share de l'arborescence installée.

genbki.pl produit également des fichiers d'en-tête dérivés pour chaque catalogue, par exemple pg_class_d.h pour le catalogue pg_class. Ce fichier contient des définitions de macro automatiquement générées, et peut contenir d'autres macros, déclarations d'énumérations, etc qui peuvent être utiles pour du code C client qui lit un catalogue en particulier.

La plupart des développeurs de PostgreSQL n'ont pas besoin de se préoccuper directement du fichier BKI, mais presque toutes les fonctionnalités non triviales ajoutées dans les processus clients nécessiteront de modifier les fichiers d'en-tête de catalogue et/ou les fichiers de données initiales. Le reste de ce chapitre donne des informations sur ce sujet, et par soucis de complétude décrit le format de fichier BKI.

69.1. Règles de déclaration de catalogue système

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_catalogname. 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 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 a des OID (ce qui est le cas par défaut).

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 positioner 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. Mais veuillez noter que les contraintes NOT NULL ne sont vérifiées que dans l'exécuteur, pas quand des lignes sont générées par n'importe quel code C. Il est donc nécessaire de prendre des précautions quand des lignes de catalogue sont créées ou mises à jour.

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.