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

49.2. Fonctions de la méthode d'accès aux index

Les fonctions de construction et de maintenance d'index que doit fournir une méthode d'accès aux index sont :

IndexBuildResult *
ambuild (Relation heapRelation,
         Relation indexRelation,
         IndexInfo *indexInfo);

Construit un nouvel index. La relation de l'index a été créée physiquement mais elle est vide. Elle doit être remplie avec les données fixes dont a besoin la méthode d'accès, ainsi que les entrées pour toutes les lignes existant déjà dans la table. D'habitude, la fonction ambuild appellera IndexBuildHeapScan() pour parcourir la table avec les lignes qui existent déjà et pour calculer les clés qui doivent être insérées dans l'index. La fonction doit renvoyer une structure allouée par palloc contenant les statistiques sur le nouvel index.

bool
aminsert (Relation indexRelation,
          Datum *values,
          bool *isnull,
          ItemPointer heap_tid,
          Relation heapRelation,
          bool check_uniqueness);

Insère une nouvelle ligne dans un index existant. Les tableaux values et isnull donnent les valeurs clés à indexer. heap_tid est le TID à indexer. Si la méthode d'accès supporte les index uniques (son drapeau pg_am.amcanunique vaut true), alors check_uniqueness pourrait aussi valoir true, auquel cas la méthode d'accès doit vérifier qu'il n'y a pas de lignes en conflit ; c'est la seule situation dans laquelle la méthode d'accès a habituellement besoin du paramètre heapRelation. Voir Section 49.5, « Vérification de l'unicité de l'index » pour les détails. Le résultat vaut TRUE si une entrée de l'index a été insérée, FALSE sinon (un résultat FALSE l'indique par forcément une erreur mais est utilisé dans les cas comme un index AM refusant d'indexer une valeur NULL).

IndexBulkDeleteResult *
ambulkdelete (IndexVacuumInfo *info,
              IndexBulkDeleteResult *stats,
              IndexBulkDeleteCallback callback,
              void *callback_state);

Supprime le(s) ligne(s) de l'index. C'est une opération de « suppression en flot » qui a pour but d'être implémentée par le parcours complet de l'index et par la vérification de chaque entrée pour vérifier si elle doit être supprimée. La fonction callback passée doit être appelée, dans le style callback(TID, callback_state) renvoie bool, pour déterminer si une entrée d'index particulière, identifiée par son TID référencé, est à supprimer. Doit renvoyer soit NULL soit une structure issue d'un palloc et contenant des statistiques sur les effets de l'opération de suppression. Il est bien de renvoyer NULL s'il n'est pas nécessaire de renvoyer des informations à amvacuumcleanup.

À cause d'un maintenance_work_mem limité, ambulkdelete pourrait nécessiter d'être appelé plus d'une fois lorsque plusieurs lignes sont supprimées. L'argument stats est le résultat du dernier appel pour cet index (il est NULL pour le premier appel à l'intérieur d'une opération VACUUM). Ceci permet à l'AM d'accumuler les statistiques sur une même opération. Typiquement, ambulkdelete modifiera et renverra la même structure si le stats fourni n'est pas NULL.

IndexBulkDeleteResult *
amvacuumcleanup (IndexVacuumInfo *info,
                 IndexBulkDeleteResult *stats);

Nettoie après une opération VACUUM (zéro ou plus d'appels à ambulkdelete). Ceci n'a rien à voir avec autre chose que le renvoi des statistiques des index, mais il peut réaliser un nettoyage en masse, comme réclamer les pages d'index vides. stats est ce que renvoie l'appel à ambulkdelete, ou NULL si ambulkdelete n'a pas été appelé car aucune ligne n'avait besoin d'être supprimée. Si le résultat n'est pas NULL, il est une structure allouée avec palloc. Les statistiques qu'elle contient seront utilisées pour mettre à jour pg_class, et seront rapportées par VACUUM si VERBOSE est indiqué. Il est bien de renvoyer NULL si l'index n'a pas changé du tout lors de l'opération de VACUUM mais, sinon, des statistiques correctes devront être renvoyées.

void
amcostestimate (PlannerInfo *root,
                IndexOptInfo *index,
                List *indexQuals,
                RelOptInfo *outer_rel,
                Cost *indexStartupCost,
                Cost *indexTotalCost,
                Selectivity *indexSelectivity,
                double *indexCorrelation);

Estime les coûts d'un parcours d'index. Cette fonction est décrite complètement dans Section 49.6, « Fonctions d'estimation des coûts d'index », ci-dessous.

bytea *
amoptions (ArrayType *reloptions,
           bool validate);

Analyse et valide le tableau reloptions pour un index. C'est appelé seulement quand un tableau reloptions non NULL existe pour l'index. reloptions est un tableau de type text contenant des entrées de la forme nom=valeur. La fonction devrait construire une valeur de type bytea qui sera copiée dans le champ rd_options de l'entrée relcache de l'index. Les données contenues dans la valeur bytea dépendent de la méthode d'accès mais les méthodes d'accès standards utilisent actuellement tous la structure StdRdOptions. Quand validate est true, la fonction devrait rapporter un message d'erreur convenable si aucune des option n'est pas reconnue ou a des valeurs invalides ; quand validate est false, les entrées invalides devraient être ignorées silencieusement. (validate est faux lors du chargement des options déjà stockées dans pg_catalog ; une entrée invalide pourrait seulement être trouvée si la méthode d'accès a modifié ses règles pour les options et, dans ce cas, ignorer les entrées obsolètes est approprié.) Il est aussi bon de renvoyer NULL si le comportement par défaut est voulu.

Bien sûr, Le but d'un index est de supporter les parcours de lignes correspondant à une condition WHERE indexable, souvent appelée un qualifieur ou une clé de parcours. La sémantique du parcours d'index est décrite plus complètement dans Section 49.3, « Parcours d'index », ci-dessous. Les fonctions relatives au parcours qu'une méthode d'accès à l'index doit fournir sont :

IndexScanDesc
ambeginscan (Relation indexRelation,
             int nkeys,
             ScanKey key);

Débute un nouveau parcours. Le tableau key (de longueur nkeys) décrit les clés de parcours pour le parcours de l'index. Le résultat doit être une structure issue de palloc. Pour les raisons de l'implémentation, la méthode d'accès à l'index doit créer cette structure en appelant RelationGetIndexScan(). Dans la plupart des cas, ambeginscan fait peu en dehors de cet appel ; les parties intéressantes de début du parcours d'index sont dans amrescan.

boolean
amgettuple (IndexScanDesc scan,
            ScanDirection direction);

Récupère la prochaine ligne dans le parcours donné, se déplaçant dans bonne direction (en avant ou en arrière dans l'index). Renvoie TRUE si une ligne a été obtenue, FALSE s'il ne reste aucune ligne correspondante. Dans le cas TRUE, le TID de la ligne est stocké dans la structure scan. Notez que « success » signifie seulement que l'index contient une entrée correspondant aux clés de parcours, pas que la ligne existe toujours dans l'en-tête ou réussira le test de l'appelant.

boolean
amgetmulti (IndexScanDesc scan,
            ItemPointer tids,
            int32 max_tids,
            int32 *returned_tids);

Récupère plusieurs lignes dans le parcours donné. Renvoie TRUE si le parcours devait continuer, FALSE si aucune ligne correspondante ne reste. tids pointe vers un tableau de max_tids fourni par l'appelant. ItemPointerData enregistre, ce que l'appel remplit avec les TID des lignes correspondantes. *returned_tids est initialisé au nombre de TID réellement renvoyé. Ceci peut être moins que max_tids, voire même zéro, même si la valeur de retour vaut TRUE (ceci permet à la méthode d'accès de choisir les points d'arrêt les plus efficaces dans son parcours, par exemple les limites de la page d'index). amgetmulti et amgettuple ne peuvent pas être utilisés dans le même parcours d'index ; il y a aussi d'autres restrictions lors de l'utilisation de amgetmulti, comme expliqué dans Section 49.3, « Parcours d'index ».

void
amrescan (IndexScanDesc scan,
          ScanKey key);

Recommence le parcours donné, si possible avec de nouvelles clés de parcours (pour continuer à utiliser les anciennes clés, NULL est passé pour key). Notez qu'il n'est pas possible de changer le nombre de clés. En pratique, la fonctionnalité de relancement est utilisée quand une nouvelle ligne externe est sélectionné par une jointure imbriquée en boucle et, du coup, la valeur de la comparaison d'une nouvelle clé est nécessaire mais la structure de la clé de parcours reste identique. Cette fonction est aussi appelée par RelationGetIndexScan(), donc c'est utilisé pour une configuration initiale d'un parcours d'index ainsi que pour parcourir de nouveau.

void
amendscan (IndexScanDesc scan);

Termine un parcours et libère les ressources. La structure scan elle-même ne devrait pas être libérée, mais aucun verrou pris en interne par la méthode d'accès doit être libéré.

void
ammarkpos (IndexScanDesc scan);

Marque la position courante du parcours. La méthode d'accès a seulement besoin de supporter le rappel d'une position de parcours par parcours.

void
amrestrpos (IndexScanDesc scan);

Restaure le parcours à sa plus récente position marquée.

Par convention, l'entrée pg_proc de toute fonction de méthode d'accès aux index devrait afficher le bon nombre d'arguments, mais les déclarer comme étant du type internal (car la plupart des arguments ont des types qui ne sont pas connus en SQL, et nous ne voulons pas que les utilisateurs appelent les fonctions directement). Le type renvoyé est déclaré comme void, internal ou boolean suivant le cas. La seule exception est amoptions, qui devrait être correctement déclarée comme prenant text[] et bool et renvoyer bytea. Cette provision autorise le code du client à exécuter amoptions pour tester la validité des paramètres.