IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

54.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
void
ambuildempty (Relation indexRelation);

Construire un index vide et l'inscrire dans le fichier d'initialisation (INIT_FORKNUM) de la relation. Cette méthode est seulement appelée pour les tables non tracées. L'index vide inscrit dans le fichier d'initialisation sera copié sur le fichier de la relation à chaque redémarrage du serveur.

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 54.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.

bool
amcanreturn (Relation indexRelation);

Vérifie si l'index supporte les parcours d'index seul en renvoyant les valeurs indexées de la colonne pour une entrée d'index sous la forme d'un IndexTuple. Renvoie TRUE si c'est le cas, et FALSE sinon. Si la méthode d'accès de l'index ne peut jamais supporter les parcours d'index seul (un index est hash, qui stocke seulement les valeurs du hachage, et pas la donnée originale), il suffit de configurer le champ amcanreturn à zéro dans pg_am.

void
amcostestimate (PlannerInfo *root,
                IndexPath *path,
                double loop_count,
                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 54.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 54.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,
             int norderbys);

Prépare un parcours d'index. Les paramètres nkeys et norderbys indiquent le nombre de qualificateurs et d'opérateurs de tri qui seront utilisés dans le parcours. Cela pourrait se révéler utile pour l'allocation d'espace. Notez que les valeurs actuelles des clés de parcours ne sont pas encore fournies. Le résultat doit être une structure allouée avec la fonction palloc. Pour des raisons d'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 et, peut-être, d'aquérir des verrous ; les parties intéressantes de début de parcours d'index sont dans amrescan.

void
amrescan (IndexScanDesc scan,
          ScanKey keys,
          int nkeys,
          ScanKey orderbys,
          int norderbys);

Démarre ou relance un parcours d'index, possiblement avec des nouvelles clés d'index. (Pour relancer en utilisant des clés déjà passées, NULL est passé pour keys et/ou orderbys.) Notez qu'il n'est pas autorisé que le nombre de clés ou d'opérateurs de tri soit plus grande que celui passé à la fonction ambeginscan. En pratique, la fonctionnalité de relancement est utilisée quand une nouvelle ligne externe est sélectionnée par une jointure de boucle imbriquée, et donc une nouvelle valeur de comparaison de clé est requise, mais la structure de clé de parcours reste la même.

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.

Si l'index supporte les parcours d'index seul (c'est-à-dire que amcanreturn renvoit TRUE), alors, en cas de succès, la méthode d'accès doit aussi vérifier scan->xs_want_itup, et si ce dernier est TRUE, elle doit renvoyer les données indexées originales pour l'entrée d'index, sous la forme d'un pointeur d'IndexTuple stocké dans scan->xs_itup, avec un descripteur de lignes dans scan->xs_itupdesc. (La gestion de la donnée référencée par le pointeur est de la responsabilité de la méthode d'accès. Les données doivent rester bonnes au moins jusqu'au prochain appel à amgettuple, amrescan ou amendscan pour le parcours.)

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 54.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
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.