Documentation PostgreSQL 8.1.23 > Internes > Définition de l'interface des méthodes d'accès aux index > Fonctions de la méthode d'accès aux index | |
Définition de l'interface des méthodes d'accès aux index | Parcours d'index |
Les fonctions de construction et de maintenance d'index que doit fournir une méthode d'accès aux index sont :
void 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.
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 48.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 (Relation indexRelation, 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 pourrait ê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.
IndexBulkDeleteResult * amvacuumcleanup (Relation indexRelation, IndexVacuumCleanupInfo *info, IndexBulkDeleteResult *stats);
Nettoie après une opération VACUUM (un ou plusieurs appels à ambulkdelete). Une méthode d'accès à l'index n'a pas besoin de fournir cette fonction (si oui, l'entrée dans pg_am doit valoir zéro). Si elle est fournie, elle est typiquement utilisée pour un nettoyage en masse comme pour réclamer des pages d'index vides. info fournit quelques arguments supplémentaires comme un niveau de message pour des rapports statistiques, et stats est tout ce que le dernier appel à ambulkdelete a pu renvoyer. amvacuumcleanup pourrait remplacer ou modifier cette structure avant de la renvoyer. Si le résultat est non NULL, il doit s'agir d'une structure issue d'un palloc. Les statistiques qu'elle contient seront rapportées par VACUUM si VERBOSE est donné.
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 48.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 48.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.
void amcostestimate (PlannerInfo *root, IndexOptInfo *index, List *indexQuals, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation);
Estime le coût d'un parcours d'index. Cette fonction est décrite complètement dans Section 48.6, « Fonctions d'estimation des coûts d'index », ci-dessous.
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.