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

51.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);

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,
          IndexUniqueCheck checkUnique);

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 checkUnique indique le type de vérification unique à réaliser. Cela varie si la contrainte unique est déferrable ou non ; voir Section 51.5, « Vérification de l'unicité de l'index » pour les détails. Habituellement, la méthode d'accès a seulement besoin du paramètre heapRelation lors de la vérification de l'unicité (car après, elle doit regarder la table pour vérifier la visibilité de la ligne).

La valeur résultat, de type booléen, de la fonction est significative seulement quand checkUnique vaut UNIQUE_CHECK_PARTIAL. Dans ce cas, un résultat TRUE signifie que la nouvelle entrée est reconnue comme unique alors que FALSE indique qu'elle pourrait ne pas être unique (et une vérification d'unicité déferrée doit être planifiée). Dans les autres cas, un résultat FALSE constant est recommendé.

Certains index pourraient ne pas indexer toutes les lignes. Si la ligne ne doit pas être indexée, aminsert devrait terminer sans rien faire.

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.

À partir de PostgreSQL™ 8.4, amvacuumcleanup sera aussi appelé à la fin d'une opération ANALYZE operation. Dans ce cas, stats vaut toujours NULL et toute valeur de retour sera ignorée. Ce cas peut être distingué en vérifiant info->analyze_only. Il est recommandé que la méthode d'accès ne fasse rien en dehors du nettoyage après insertion pour ce type d'appel, et cel aseulement dans un processus de travail autovacuum.

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 51.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. La plupart des méthodes d'accès standard utilisent 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 51.3, « Parcours d'index », ci-dessous. Une méthode d'accès à l'index peut supporter les parcours d'accès standards (« plain »), les parcours d'index « bitmap » ou les deux. Les fonctions liées au parcours qu'une méthode d'accès à l'index doit ou devrait 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. En cas de succès, amgettuple doit aussi configuré scan->xs_recheck à TRUE ou FALSE. FALSE signifie qu'il est certain que l'entrée de l'index correspond aux clés de parcours. TRUE signifie que ce n'est pas certain et que les conditions représentées par les clés de parcours doivent être de nouveau vérifiées sur la ligne de la table après l'avoir récupéré. Cette différence permet de supporter les opérateurs d'index « à perte ». Notez que la nouvelle vérification s'étendra seulement aux conditions de parcours ; un prédicat partiel d'index n'est jamais vérifié par les appelants à amgettuple.

La fonction amgettuple a seulement besoin d'exister si la méthode d'accès supporte les parcours d'index standards. Si ce n'est pas le cas, le champ amgettuple de la ligne de pg_am doit valoir zéro.

int64
amgetbitmap (IndexScanDesc scan,
             TIDBitmap *tbm);

Récupère toutes les lignes du parcours sélectionné et les ajoute au TIDBitmap fournit par l'appelant (c'est-à-dire un OU de l'ensemble des identifiants de ligne dans l'ensemble où se trouve déjà le bitmap). Le nombre de lignes récupérées est renvoyé (cela peut n'être qu'une estimation car certaines méthodes d'accès ne détectent pas les duplicats). Lors de l'insertion d'identifiants de ligne dans le bitmap, amgetbitmap peut indiquer que la vérification des conditions du parcours est requis pour des identifiants précis de transactions. C'est identique au paramètre de sortie xs_recheck de amgettuple. Note : dans l'implantation actuelle, le support de cette fonctionnalité peut beaucoup ressembler au support du stockage à perte du bitmap lui-même, et du coup les appelants vérifient les conditions du parcours et le prédicat de l'index partiel (si disponible) pour les lignes vérifiables à nouveau. Cela pourrait ne pas toujours être vrai. amgetbitmap et amgettuple ne peuvent pas être utilisés dans le même parcours d'index ; il existe d'autres restrictions lors de l'utilisation de amgetbitmap, comme expliquées dans Section 51.3, « Parcours d'index ».

La fonction amgetbitmap doit seulement exister si la méthode d'accès supporte les parcours d'index « bitmap ». Dans le cas contraire, le champ amgetbitmap de la ligne correspondante dans pg_am doit être à zéro.

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.