Chaque catalogue qui a des données initiales créées manuellement (certains
n'en ont pas) a un fichier .dat
correspondant qui contient
ses données initiales dans un format éditable.
Chaque fichier .dat
contient des structures de données
Perl littérales qui sont simplement évaluées pour produire une structure
de données en mémoire qui consiste en un tableau de références de hash, un
par ligne de catalogue. Un extrait de pg_database.dat
légèrement modifié va vous décrire les fonctionnalités principales :
[ # 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_' }, ]
Les points à noter :
La structure générale du fichier est : crochet ouvrant, un ensemble ou plus d'accolades qui chacune représentent une ligne de catalogue, crochet fermant. Il faut mettre une virgule après chaque accolade fermante.
Au sein de chaque ligne de catalogue, écrivez des paires de
clé
=>
valeur
séparées par des virgules. Les
clé
s autorisées sont les noms des colonnes du
catalogue, ainsi que les clés de métadonnées oid
,
oid_symbol
et descr
.
(L'utilisation de oid
et oid_symbol
est décrite dans Section 70.2.2
ci-dessous. descr
fournit une chaîne de texte de
description pour l'objet, qui sera insérée dans
pg_description
ou
pg_shdescription
selon le cas.)
Bien que les clés de métadonnées soient facultatives, les colonnes
définies pour le catalogue doivent toutes être fournies, sauf pour le cas
où le fichier .h
du catalogue définit une valeur par
défaut pour la colonne.
Toutes les valeurs doivent être entourées de guillemets simples. Il faut
échapper les guillemets simples utilisés au sein d'une valeur avec un
antislash. Les antislash qui doivent être utilisés comme une donnée
peuvent être doublés, mais cela n'est pas nécessaire ; cela correspond aux
règles Perl pour les littéraux entourés d'un guillemet simple. Veuillez
noter que les antislash apparaissant comme données seront traités comme
des échappements par le scanner du bootstrap, d'après les mêmes règles que
pour les échappements de chaînes de texte constantes (voir
Section 4.1.2.2) ; par exemple
\t
est converti en un caractère tabulation. Si vous
voulez un antislash dans la valeur finale, il vous faudra en écrire
quatre : Perl en retire deux, laissant \\
pour le
scanner boostrap.
Les valeurs null sont représentées par _null_
.
(Veuillez noter qu'il n'y a aucun moyen de créer une valeur qui est
simplement cette chaîne de texte.)
Les commentaires sont précédés d'un #
, et doivent etre
sur leur propre ligne.
Afin d'aider la lisibilité, les valeurs des champs qui sont des OID d'autres entrées de catalogue peuvent être représentées par des noms plutôt que des OIDs numériques. Cela est décrit dans Section 70.2.3 ci-dessous.
Puisque les hash sont des structures de données non triées, l'ordre des
champs et des lignes ne sont pas sémantiquement significatifs. Cependant,
pour maintenir un aspect cohérent, nous définissions quelques règles qui
sont appliquées par le script de formatage
reformat_dat_file.pl
:
Au sein de chaque paire d'accolades, les champs de métadonnées
oid
, oid_symbol
,
et descr
(si présent) apparaissent en premier, dans
cet ordre, puis les champs propres au catalogue apparaissent dans leur
ordre défini.
Des retours à la ligne sont insérés entre les champs selon le besoin pour limiter la longueur de ligne à 80 caractères, si cela est possible. Un retour à la ligne est également inséré entre les champs de métadonnées et les champs normaux.
Si le fichier de catalogue .h
spécifie une valeur
par défaut pour la colonne, et qu'une entrée de donnée a la même
valeur, reformat_dat_file.pl
omettra cette valeur
du fichier de données. Cela conserve la représentation de données
compacte.
reformat_dat_file.pl
conserve les lignes vides
et les commentaires en l'état.
Il est recommandé d'exécuter reformat_dat_file.pl
avant de soumettre des patchs pour les données de catalogue. Par
commodité, vous pouvez simplement effectuer des changements dans
src/include/catalog/
et exécuter
make reformat-dat-files
.
Si vous voulez ajouter une nouvelle méthode pour diminuer la taille de
de la représentation des données, vous devez l'implémenter dans
reformat_dat_file.pl
et également apprendre à
Catalog::ParseData()
comment remettre les données
dans leur représentation complète.
Il est possible de donner un OID manuellement assigné à une ligne de
catalogue apparaissant dans les données initiales en écrivant un champ de
métadonnées oid =>
.
De plus, si un OID est assigné, une macro C pour cet OID peut être créée
en écrivant un champ de métadonnée nnnn
oid_symbol
=>
.
nom
Les lignes de catalogues préchargées doivent avoir des OID pré-assignés s'il
y a des références d'OID pointant vers elles dans d'autres lignes
pré-chargées. Un OID pré-assigné est également nécessaire si l'OID de la
ligne doit être référencé depuis le code C. Si aucun de ces cas ne
s'applique, le champ de métadonnée oid
peut être omis,
auquel cas le code de bootstrap assignera un OID automatiquement, ou le
laissera à zéro dans un catalogue qui n'a pas d'OID. En pratique, nous
pré-assignons généralement des OID pour soit toutes soit aucune des lignes
d'un catalogue donné, même si seulement une partie des lignes sont vraiment
référencées dans d'autres catalogues.
Écrire la vraie valeur numérique d'un OID dans le code C est considéré comme
une très mauvaise pratique ; il faut toujours utiliser une macro à la place.
Des références directes à des OID de pg_proc
sont
suffisamment communes pour qu'il y ait un mécanisme spécial afin de créer
les macros nécessaires automatiquement ; voir
src/backend/utils/Gen_fmgrtab.pl
. De même
-- mais, pour raisons historiques, fait d'une autre manière --
il y a une méthode automatique pour créer les macros pour les OID de
pg_type
. Les entrées de
oid_symbol
ne sont donc pas forcément dans ces deux
catalogues. De la même manière, les macros pour les OID de catalogue
système et index pg_class
sont positionnés
automatiquement. Pour tous les autres catalogues systèmes, vous devez
spécifier manuellement toute macro dont vous avez besoin avec les entrées
oid_symbol
.
Pour trouver un OID disponible pour une nouvelle ligne préchargée, exécutez
le script src/include/catalog/unused_oids
. Il affiche
l'intervalle inclusif d'OIDs inutilisés (par exemple, la ligne en sortie
« 45-900 » signifie que les OIDs 45 jusqu'à 900 n'ont pas encore
été alloués). Pour le moment, les OIDs 1-9999 sont réservés pour des
assignements manuels ; le script unused_oids
regarde
simplement dans les en-têtes de catalogue et les fichiers
.dat
pour voir lesquels n'apparaissent pas. Vous
pouvez également utiliser le script duplicate_oids
pour
trouver des erreurs. (genbki.pl
détectera également
les OID en doublon au moment de la compilation.)
Le compteur d'OID démarre à 10000 au début d'une exécution de bootstrap.
Si une ligne de catalogue est dans une table qui nécessite des OID, mais
qu'aucun OID n'a été préassigné par un champ oid
, alors
il recevra un OID de 10000 ou plus.
Les références inter-catalogue d'une ligne de catalogue initiale vers une
autre peut être écrite en écrivant simplement l'OID préassigné de la ligne
référencée. Mais cela serait source d'erreur et difficile à comprendre,
ainsi pour les catalogues référencés fréquemment,
genbki.pl
fournit un mécanisme pour écrire à la place
des références symboliques. Pour le moment, c'est possible pour les
références vers des méthodes d'accès, fonctions, opérateurs, classes
d'opérateur, familles d'opérateur et types. Les règles sont :
L'utilisation de références symboliques est activée pour une colonne
en particulier en attachant
BKI_LOOKUP(
à la définition de la colonne, où lookuprule
)lookuprule
est pg_am
, pg_proc
,
pg_operator
, pg_opclass
,
pg_opfamily
, ou pg_type
.
BKI_LOOKUP
peut être attaché aux colonnes de type
Oid
, regproc
, oidvector
,
ou Oid[]
; dans les deux derniers cas, cela implique
d'effectuer une recherche pour chaque élément du tableau.
Dans une telle colonne, toutes les entrées doivent utiliser le format
symbolique sauf quand on écrit 0
pour InvalidOid. (Si
la colonne est déclarée regproc
, vous pouvez facultativement
écrire -
à la place de 0
.)
genbki.pl
vous avertira sur des noms non reconnus.
Les méthodes d'accès sont uniquement représentées par leur noms, tous
les types. Les noms de types doivent correspondre aux
typname
des entrées de
pg_type
correspondantes ; vous ne pouvez utiliser
aucun alias tel que integer
pour
int4
.
Une fonction peut être représentée par son
proname
, s'il est unique parmi les entrées
de pg_proc.dat
(cela fonctionne comme les entrées
regproc). Sinon, écrivez-les sous la forme
proname(argtypename,argtypename,...)
, comme
pour regprocedure. Les noms de type des arguments doivent être écrits
exactement comme ils le sont dans les champs
proargtypes
des entrées de
pg_proc.dat
. N'insérez aucun espace.
Les oérateurs sont représentés par
oprname(lefttype,righttype)
,
en écrivant les noms de type exactement comme ils apparaissent dans les
oprleft
et oprright
des entrées de
pg_operator.dat
.
(Écrivez 0
pour les opérandes omises d'un opérateur
unaire.)
Les noms des classes et familles d'opérateur ne sont uniques qu'au sein
d'une méthode d'accès, elles sont donc représentées avec
nom_methode_acces
/
nom_objet
.
Il n'est prévu de qualification par le schéma pour aucun de ces cas ; tous les objects créés durant le bootstrap sont prévus pour être dans le schéma pg_catalog.
genbki.pl
résout toutes les références symboliques
pendant son exécution, et incrit de simples OID numériques dans les
fichiers BKI émis. Le processus client de bootstrap n'a donc pas besoin
de gérer les références symboliques.
Voici quelques suggestions pour les moyens les plus simples d'effectuer des tâches communes lors de la mise à jour de fichiers de données du catalogue.
Ajouter une nouvelle colonne avec valeur par défaut à un
catalogue :
Ajoutez la colonne au fichier d'en-tête avec une annotation
BKI_DEFAULT(
Le fichier de données ne doit être ajusté en ajoutant le champ dans les
lignes existantes que quand il est nécessaire d'avoir autre chose que la
valeur par défaut.
valeur
)
Ajouter une valeur par défaut à une colonne existant qui n'en a
pas :
Ajoutez une annotation BKI_DEFAULT
au fichier d'en-tête,
puis exécutez make reformat-dat-files
pour supprimer les
entrées de champ qui sont maintenant redondantes.
Ajouter une colonne, qu'elle ait une valeur par défaut ou
non :
Supprimez la colonne de l'en-tête, puis exécutez make
reformat-dat-files
pour supprimer les entrées de champ maintenant
inutiles.
Changer ou supprimer une valeur par défaut existante :
Vous ne pouvez pas simplement changer le fichier d'en-tête, puisque cela
aurait pour conséquence une mauvaise interprétation des données actuelles.
Tout d'abord, exécutez make expand-dat-files
pour
réécrire les fichiers de données avec toutes les valeurs par défaut
insérées explicitement, puis modifiez ou supprimer l'annotation
BKI_DEFAULT
, puis exécutez make
reformat-dat-files
pour supprimer à nouveau les champs superflus.
Édition en masse ad hoc :
reformat_dat_file.pl
peut être modifié pour effectuer
différents types de changements en masse. Cherchez les commentaires de
blocs montrant où du code unique peut être inséré. Dans l'exemple suivant,
nous allons consolider deux champs booléans de
pg_proc
en un champ de type char :
Ajout de la nouvelle colonne, avec une valeur par défaut, à
pg_proc.h
:
+ /* see PROKIND_ categories below */ + char prokind BKI_DEFAULT(f);
Création d'un nouveau script basé sur
reformat_dat_file.pl
pour insérer les valeurs
appropriées à la volée :
- # 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'; + }
Lancement du nouveau script :
$ cd src/include/catalog $ perl rewrite_dat_with_prokind.pl pg_proc.dat
À cette étape, pg_proc.dat
a la totalité des trois
colonnes, prokind
,
proisagg
et proiswindow
, bien qu'elles n'apparaîtront
que dans les lignes où elles ont des valeurs qui ne sont pas la valeur
par défaut.
Suppression de l'ancienne colonne de pg_proc.h
:
- /* is it an aggregate? */ - bool proisagg BKI_DEFAULT(f); - - /* is it a window function? */ - bool proiswindow BKI_DEFAULT(f);
Finalement, exécution de make reformat-dat-files
pour supprimer les anciennes entrées inutiles de
pg_proc.dat
.
Pour plus d'exemples de scripts utilisés pour l'édition en masse, voir
convert_oid2name.pl
et remove_pg_type_oid_symbols.pl
joints au message
suivant :
https://www.postgresql.org/message-id/CAJVSVGVX8gXnPm+Xa=DxR7kFYprcQ1tNcCT5D0O3ShfnM6jehA@mail.gmail.com