PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 16.4 » Internes » Index BRIN » Extensibilité

71.3. Extensibilité #

L'interface BRIN possède un niveau élevé d'abstraction, qui nécessite l'implémentation de la méthode d'accès rien que pour l'implémentation de la sémantique des types de données accédées. La couche BRIN s'occupera par contre elle-même de la concurrence, l'accès et la recherche dans la structure de l'index.

Tout ce qu'il faut pour faire fonctionner la méthode d'accès BRIN est d'implémenter quelques méthodes utilisateurs, déterminant pour l'index les genre de valeurs stockées dans le résumé et la manière dont elles interagissent avec les nœuds du parcours. En bref, BRIN combine l'extensibilité avec la généralité, la réutilisation du code et une interface claire.

Il y a quatre méthodes qu'un opérateur de classe pour BRIN doit fournir :

BrinOpcInfo *opcInfo(Oid type_oid)

Retourne les informations internes au sujet du résumé de données de la colonne indexée. Cette valeur doit pointer vers une structure BrinOpcInfo (allouée avec la fonction palloc), qui a cette définition :

typedef struct BrinOpcInfo
{
    /* Nombre de colonnes stockées dans une colonne indexée de cette classe d'opérateur */
    uint16      oi_nstored;

    /* Pointeur opaque pour l'utilisation privée de la classe d'opérateur */
    void       *oi_opaque;

    /* Type des entrées cachées de la colonne stockées */
    TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
} BrinOpcInfo;
       

BrinOpcInfo.oi_opaque peut être utilisé par les routines d'opérateur de classe pour transmettre des informations entre les procédures de support pendant le parcours de l'index.

bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey *keys, int nkeys)

Retourne si toutes les entrées ScanKey sont cohérentes avec les valeurs indexées données pour cet intervalle. Le nombre d'attributs à utiliser est passé en tant que partie de la clé de parcours. De multiples clés de parcours pour un même attribut peuvent être passées en une fois ; le nombre d'entrées est déterminé par le paramètre nkeys.

bool consistent(BrinDesc *bdesc, BrinValues *column, ScanKey key)

Retourne la clé de parcours si elle est cohérente avec les valeurs indexées données pour cet intervalle. Le nombre attribué à utiliser est passé en tant que partie de la clé de parcours. Cette version est une variante pour compatibilité descendante plus ancienne de la fonction de cohérence.

bool addValue(BrinDesc *bdesc, BrinValues *column, Datum newval, bool isnull)

Renvoie à une ligne indexée et une valeur indexée, modifie les attributs indiqués de cette ligne, de manière à ce que le cumul représente la nouvelle valeur. Si une modification a été apportée à la ligne, la valeur true est retournée.

bool unionTuples(BrinDesc *bdesc, BrinValues *a, BrinValues *b)

Consolidation de deux lignes d'index. Ceci en prenant deux lignes d'index et en modifiant l'attribut indiqué de la première des deux, de manière à ce qu'elle représente les deux lignes. La seconde ligne n'est pas modifiée.

Une classe d'opérateur pour BRIN peut indiquer en option la méthode suivante :

void options(local_relopts *relopts)

Définit un ensemble de paramètres visibles aux utilisateurs qui contrôlent le comportement d'une classe d'opérateur.

La fonction options se voit donné un pointeur vers une structure local_relopts qui doit être remplie avec un ensemble d'options spécifiques à la classe d'opérateur. Les options peuvent être accédées à partir des autres fonctions de support en utilisant les macros PG_HAS_OPCLASS_OPTIONS() et PG_GET_OPCLASS_OPTIONS().

Étant donné que l'extraction des clés des valeurs indexées et la représentation de la clé dans BRIN sont flexibles, elles peuvent dépendre de paramètres spécifiés par l'utilisateur.

La distribution du noyau inclut du support pour les quatre types de classe d'opérateur : minmax, minmax-multi, inclusion et bloom. Les définitions de classes d'opérateur qui les utilisent sont envoyées en types de données basiques appropriées. Des classes d'opérateurs appropriées peuvent être définies par l'utilisateur pour d'autres types de données utilisant des définitions équivalentes, et ceci sans avoir besoin d'écrire du code source. La déclaration des entrées appropriées dans le catalogue est suffisante. Notez que les hypothèses sur les sémantiques de stratégie d'opérateurs sont embarquées dans les fonctions de support du code source.

Les classes d'opérateurs qui implémentent des sémantiques complètement différentes sont utilisables. Les implémentations fournies par les quatre principales fonctions de support présentées ci-dessous sont écrites. Notez que la compatibilité ascendante entre les versions majeures n'est pas garantie : par exemple, les fonctions de support additionnelles peuvent être requises dans des versions ultérieures.

Pour écrire une classe d'opérateur pour un type de données qui implémente un résultat complétement ordonné, il est possible d'utiliser les fonctions de support "minmax" avec les opérateurs correspondant tel que décrit dans Tableau 71.2. Tous les membres de classe d'opérateurs (fonctions et opérateurs) sont obligatoires.

Tableau 71.2. Fonctions et numéros de support pour les classes d'opérateur Minmax

Membre de classe d'opérateurObjet
Fonction de support 1Fonction interne brin_minmax_opcinfo()
Fonction de support 2Fonction interne brin_minmax_add_value()
Fonction de support 3Fonction interne brin_minmax_consistent()
Fonction de support 4Fonction interne brin_minmax_union()
Stratégie d'opérateur 1Opérateur strictement inférieur
Stratégie d'opérateur 2Opérateur inférieur
Stratégie d'opérateur 3Opérateur d'égalité
Stratégie d'opérateur 4Opérateur supérieur
Stratégie d'opérateur 5Opérateur strictement supérieur

Pour écrire un opérateur de classe pour un type de données complexe, qui aurait des valeurs incluses dans un autre type, il est possible d'utiliser la fonction de support d'inclusion avec l'opérateur correspondant, tel que décrit dans Tableau 71.3. Cela nécessite uniquement une simple fonction d'addition, qui peut être écrite dans n'importe quel langage. Des fonctions supplémentaires peuvent être définies pour obtenir des fonctionnalités additionnelles. Tous les opérateurs sont optionnels. Certains opérateurs requièrent d'autres opérateurs, affichés en tant que dépendances de la table.

Tableau 71.3. Fonctions et numéros de support pour les classes d'opérateur d'inclusion

Membre de classe d'opérateurObjetDépendance
Fonction de support 1Fonction interne brin_inclusion_opcinfo() 
Fonction de support 2Fonction interne brin_inclusion_add_value() 
Fonction de support 3Fonction interne brin_inclusion_consistent() 
Fonction de support 4Fonction interne brin_inclusion_union() 
Fonction de support 11Fonction de fusion de deux élements 
Fonction de support 12Fonction optionnelle de vérification si les deux éléments peuvent être fusionnés  
Fonction de support 13Fonction optionnelle de vérification si un élément est contenu dans un autre 
Fonction de support 14Fonction optionnelle de vérification si un élement est vide 
Stratégie d'opérateur 1Opérateur A-gauche-de Stratégie d'opérateur 4
Stratégie d'opérateur 2Opérateur Ne-s-etend-pas-à-la-droite-deStratégie d'opérateur 5
Stratégie d'opérateur 3Opérateur chevauchement 
Stratégie d'opérateur 4Opérateur Ne-s-etend-pas-à-la-gauche-deStratégie d'opérateur 1
Stratégie d'opérateur 5Opérateur A-droite-deStratégie d'opérateur 2
Stratégie d'opérateur 6, 18Opérateur Equivalent-ou-identique-àStratégie d'opérateur 7
Stratégie d'opérateur 7, 16, 24, 25Opérateur Contient-ou-identique-à 
Stratégie d'opérateur 8, 26, 27Opérateur Contient-ou-identique-àStratégie d'opérateur 3
Stratégie d'opérateur 9Opérateur Ne-s-étend-pas-plus-loinStratégie d'opérateur 11
Stratégie d'opérateur 10Opérateur Est-le-suivantStratégie d'opérateur 12
Stratégie d'opérateur 11Opérateur Est-le-précédentStratégie d'opérateur 9
Stratégie d'opérateur 12Opérateur Ne-s-étend-pas-plus-loinStratégie d'opérateur 10
Stratégie d'opérateur 20Opérateur Strictement-inférieur-àStratégie d'opérateur 5
Stratégie d'opérateur 21Opérateur Inférieur-àStratégie d'opérateur 5
Stratégie d'opérateur 22Opérateur Strictement-supérieur-àStratégie d'opérateur 1
Stratégie d'opérateur 23Opérateur supérieur-àStratégie d'opérateur 1

Les numéros 1 à 10 des fonctions support sont reservés pour les fonctions internes BRIN, de ce fait le niveau des fonctions SQL commence à 11. La fonction de support 11 est la principale fonction utilisée pour construire l'index. Elle doit accepter deux arguments, avec le même type de données que la la classe d'opérateur, et renvoyer l'union des deux. La classe d'opérateur inclusion peut stocker des valeurs unies de types différents si elles sont définies avec le paramètre STORAGE La valeur renvoyée par la fonction union doit correspondre au type de données STORAGE

Les numéros 12 et 14 des fonctions de support sont fournies pour supporter les irrégularités des types de données internes. La fonction 12 est utilisée pour supporter les adresses réseaux de différentes familles qui ne sont pas fusionnables. La fonction 14 est utilisée pour supporter les intervalles vides. La fonction 13 est une fonction optionnelle mais recommandée. Elle permet à une nouvelle valeur d'être vérifiée avant d'être passée à la fonction d'union. Puisque BRIN peut raccourcir certaines opérations lorsque l'union n'est pas modifiée, utiliser cette fonction peut améliorer les performances de l'index.

Pour écrire une classe d'opérateur pour un type de données qui implémente seulement l'opérateur égalité et supporte le hachage, il est possible d'utiliser les procédures d'appui bloom aux côtés des opérateurs correspondants, comme montré dans Tableau 71.4. Tout membre de classe d'opérateur (procédures et opérateurs) sont obligatoires.

Tableau 71.4. Procédures et numéros de support pour les classes d'opérateur Bloom

Membre de la classe d'opérateurObjet
Procédure support 1Fonction interne brin_bloom_opcinfo()
Procédure support 2Fonction interne brin_bloom_add_value()
Procédure support 3Fonction interne brin_bloom_consistent()
Procédure support 4Fonction interne brin_bloom_union()
Fonction de support 5fonction interne brin_bloom_options()
Procédure support 11Fonction pour calculer le hachage d'un élément
Stratégie d'opérateur 1Opérateur égal-à

Les procédures support numéros 1-10 sont réservées pour les fonctions internes BRIN, ainsi les fonctions au niveau SQL débutent avec le numéro 11. La fonction support numéro 11 est la principale fonction requise pour construire un index. Elle doit accepter un argument avec le même type de données que la classe d'opérateur et retourner un hachage de la valeur.

La classe d'opérateur minmax-multi est aussi prévue pour les types de données implémentant un ensemble totalement ordonné, et peut être vue comme une simple extension de la classe d'opérateur minmax. Tandis que la classe d'opérateur minmax résume les valeurs pour chaque intervalle de bloc dans un intervalle unique et contigu, minmax-multi permet de résumer dans de multiples intervalles plus petits pour améliorer la gestion des valeurs aberrantes. Il est possible d'utiliser les procédures support minmax-multi aux côtés des opérateurs correspondant, comme indiqué dans Tableau 71.5. Tous les membres de classe d'opérateur (procédures et opérateurs) sont obligatoires.

Tableau 71.5. Procédure et numéros de support pour les classes d'opérateur minmax-multi

Membre de classe d'opérateurObjet
Procédure support 1Fonction interne brin_minmax_multi_opcinfo()
Procédure support 2Fonction interne brin_minmax_multi_add_value()
Procédure support 3Fonction interne brin_minmax_multi_consistent()
Procédure support 4Fonction interne brin_minmax_multi_union()
Fonction de support 5Fonction interne brin_minmax_multi_options()
Procédure support 11Fonction de calcul de distance entre deux valeurs (longueur d'un intervalle)
Stratégie d'opérateur 1Opérateur inférieur-à
Stratégie d'opérateur 2Opérateur inférieur-ou-égal-à
Stratégie d'opérateur 3Opérateur égal-à
Stratégie d'opérateur 4Opérateur supérieur-ou-égal-à
Stratégie d'opérateur 5Opérateur supérieur-à

Les classes d'opérateur minmax et inclusion supportent les opérateurs utilisables sur des types de données croisés, même si cela complexifie la gestion des dépendances. La classe d'opérateur minmax a besoin d'un ensemble complet d'opérateurs pour être définie avec deux arguments qui auraient le même type de données. Cela permet aux types de données additionnels d'être supportés en définissant un ensemble d'opérateurs supplémentaires. Les opérateurs de la classe d'opérateur inclusion sont dépendants d'autres stratégies d'opérateur tel que décrit dans le Tableau 71.3, ou des mêmes stratégie d'opérateur qu'eux-même. Cela nécessite que l'opérateur dépendant soit défini avec le type de données STORAGE pour l'argument du côté gauche, et que l'autre type de données supportée se trouve du côté droit de l'opérateur de support. Vous pouvez consulter float4_minmax_ops comme exemple pour minmax et box_inclusion_ops comme exemple pour inclusion.