Documentation PostgreSQL 8.3.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 :
IndexBuildResult * ambuild (Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo);
Construire un nouvel index. La relation de l'index a été créée physiquement mais elle est vide. Elle doit être remplie avec toute donnée fixe nécessaire à la méthode d'accès, ainsi que les entrées pour toutes les lignes existant déjà dans la table. Habituellement, la fonction ambuild appelle IndexBuildHeapScan() pour parcourir la table à la recherche des lignes qui existent déjà et calculer les clés à insérer dans l'index. La fonction doit renvoyer une structure allouée par palloc contenant les statistiques du nouvel index.
bool aminsert (Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_tid, Relation heapRelation, bool check_uniqueness);
Insérer une nouvelle ligne dans un index existant. Les tableaux values et isnull donnent les valeurs de 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 peut aussi valoir true. Dans ce cas la méthode d'accès doit vérifier qu'il n'y a pas de ligne en conflit ; c'est la seule situation où le paramètre heapRelation est nécessaire dans la méthode d'accès. Voir Section 50.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 n'indique pas une erreur, car il est utilisé dans divers cas, dont la méthode d'indexage qui refuse d'indexer une valeur NULL.)
IndexBulkDeleteResult * ambulkdelete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state);
Supprimer un(des) tuple(s) de l'index. Il s'agit d'une opération de « suppression massive » à implanter par le parcours complet de l'index et la vérification de chaque entrée pour déterminer si elle doit être supprimée. La fonction callback en argument doit être appelée, sous la forme callback(TID, callback_state) returns bool, pour déterminer si une entrée d'index particulière, identifiée par son TID, est à supprimer. Cette fonction Doit renvoyer NULL ou une structure issue d'un palloc qui contient des statistiques sur les effets de l'opération de suppression. La fonction peut retourner NULL si aucune information ne doit être envoyée à amvacuumcleanup.
En cas de limitation de maintenance_work_mem, la suppression de nombreux tuples impose d'appeler ambulkdelete à plusieurs reprises. L'argument stats est le résultat du dernier appel pour cet index (il est NULL au premier appel dans une opération VACUUM). Ceci permet à l'AM d'accumuler des statistiques sur l'opération dans son intégralité. Typiquement, ambulkdelete modifie et renvoie la même structure si le stats fourni n'est pas NULL.
IndexBulkDeleteResult * amvacuumcleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats);
Nettoyage après une opération VACUUM (zéro à plusieurs appels à ambulkdelete). La fonction n'a pas d'autre but que de retourner des statistiques concernant les index, mais elle peut réaliser un nettoyage en masse (réclamer les pages d'index vides, par exemple). stats est le retour de l'appel à ambulkdelete, ou NULL si ambulkdelete n'a pas été appelée car aucune ligne n'avait besoin d'être supprimée. Si le résultat n'est pas NULL, il s'agit d'une structure allouée par palloc. Les statistiques qu'elle contient sont utilisées pour mettre à jour pg_class, et sont rapportées par VACUUM si VERBOSE est indiqué. La fonction peut retourner NULL si l'index n'a pas été modifié lors de l'opération de VACUUM mais, dans le cas contraire, il faut retourner des statistiques correctes.
void amcostestimate (PlannerInfo *root, IndexOptInfo *index, List *indexQuals, RelOptInfo *outer_rel, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation);
Estimer les coûts d'un parcours d'index. Cette fonction est décrite complètement dans Section 50.6, « Fonctions d'estimation des coûts d'index », ci-dessous.
bytea * amoptions (ArrayType *reloptions, bool validate);
Analyser et valider le tableau reloptions pour un index. Cette fonction n'est appelée que lorsqu'il existe un tableau reloptions non NULL pour l'index. reloptions est un tableau de type text contenant des entrées de la forme nom=valeur. La fonction construit une valeur de type bytea à copier dans le champ rd_options de l'entrée relcache de l'index. Les données contenues dans la valeur bytea sont définies par la méthode d'accès, mais les méthodes d'accès standard utilisent actuellement toutes la structure StdRdOptions. Lorsque validate est true, la fonction remonte un message d'erreur clair si une option n'est pas reconnue ou a des valeurs invalides ; quand validate est false, les entrées invalides sont ignorées silencieusement. (validate est faux lors du chargement d'options déjà stockées dans pg_catalog ; une entrée invalide ne peut être trouvée que 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é.) Pour obtenir le comportement par défaut, il suffit de retourner NULL.
Le but d'un index est de supporter les parcours de lignes qui correspondent à une condition WHERE indexable, souvent appelée qualificateur (qualifier) ou clé de parcours (scan key). La sémantique du parcours d'index est décrite plus complètement dans Section 50.3, « Parcours d'index », ci-dessous. Les fonctions liées au parcours qu'une méthode d'accès à l'index doit fournir sont :
IndexScanDesc ambeginscan (Relation indexRelation, int nkeys, ScanKey key);
Débuter 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 allouée par palloc. Pour des raisons de codage, la méthode d'accès à l'index doit créer cette structure en appelant RelationGetIndexScan(). Dans la plupart des cas, ambeginscan se contente de réaliser l'appel ; les parties intéressantes de début de parcours d'index sont dans amrescan.
boolean amgettuple (IndexScanDesc scan, ScanDirection direction);
Récupérer la prochaine ligne d'un parcours donné, dans la direction donnée (vers l'avant ou l'arrière de l'index). Renvoie TRUE si une ligne a été obtenue, FALSE s'il ne reste aucune ligne. Dans le cas TRUE, le TID de la ligne est stocké dans la structure scan. « success » signifie uniquement que l'index contient une entrée qui correspond aux clés de parcours, pas que la ligne existe toujours dans la pile ou qu'elle peut réussir le test d'instantané de l'appelant.
boolean amgetmulti (IndexScanDesc scan, ItemPointer tids, int32 max_tids, int32 *returned_tids);
Récupérer plusieurs lignes d'un parcours donné. Renvoie TRUE si le parcours peut continuer, FALSE s'il ne subsiste plus aucune ligne. tids pointe sur un tableau fournit par l'appelant de max_tids enregistrements ItemPointerData, remplit, à l'appel, des TID des lignes correspondantes. *returned_tids est initialisé au nombre de TID réellement renvoyés. Il peut y en avoir moins que max_tids, voire zéro, même si la valeur de retour vaut TRUE. (Cette provision 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 ; l'utilisation de amgetmulti est soumise à d'autres restrictions, comme expliqué dans Section 50.3, « Parcours d'index ».
void amrescan (IndexScanDesc scan, ScanKey key);
Recommencer le parcours donné, si possible avec de nouvelles clés de parcours (pour continuer à utiliser les anciennes clés, passer NULL pour key). Il n'est pas possible de changer le nombre de clés. En pratique, la fonctionnalité de relance est utilisée quand une nouvelle ligne externe est sélectionnée par une jointure imbriquée en boucle, ce qui impose une nouvelle valeur de comparaison de clés, mais la structure de la clé de parcours reste inchangée. Cette fonction est aussi appelée par RelationGetIndexScan(). Elle est de ce fait à la fois utilisée pour initialiser un parcours d'index et pour le re-parcourir.
void amendscan (IndexScanDesc scan);
Terminer un parcours et libérer les ressources. La structure scan elle-même ne doit pas être libérée, mais tout verrou pris en interne par la méthode d'accès doit être libéré.
void ammarkpos (IndexScanDesc scan);
Marquer la position courante du parcours. La méthode d'accès ne mémorise qu'une seule position par parcours.
void amrestrpos (IndexScanDesc scan);
Restaurer 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 affiche le bon nombre d'arguments, mais les déclare tous du type internal (la plupart des arguments ont des types qui ne sont pas connus en SQL, et il n'est pas souhaitable que les utilisateurs appelent les fonctions directement). Le type de retour est déclaré void, internal ou boolean suivant le cas. La seule exception est amoptions, qui doit être correctement déclarée prenant text[] et bool et retournant bytea. Cette protection autorise le code client à exécuter amoptions pour tester la validité des paramètres.