La fonction du gestionnaire TSM renvoie une structure
   TsmRoutine allouée avec palloc contenant des pointeurs
   vers les fonctions de support décrites ci-dessous. La plupart des
   fonctions sont obligatoires, mais certaines sont optionnelles, et
   leurs pointeurs peuvent être NULL.
  
void
SampleScanGetSampleSize (PlannerInfo *root,
                         RelOptInfo *baserel,
                         List *paramexprs,
                         BlockNumber *pages,
                         double *tuples);
   
   Cette fonction est appelée durant la planification. Elle doit
   estimer le nombre de pages de la relation qui seront lues
   lors d'un simple parcours, et le nombre de lignes qui seront
   sélectionnées lors du parcours. (Par exemple, cela pourrait
   être déterminé en estimant la fraction échantillonnée,
   puis en multipliant baserel->pages
   et baserel->tuples par ce chiffre,
   après s'être assuré d'avoir arrondi ces chiffres à des
   valeurs entières.) La liste paramexprs
   contient les expressions qui sont les paramètres de la clause
   TABLESAMPLE. Il est recommandé d'utiliser
   la fonction estimate_expression_value pour
   essayer de réduire ces expressions à des constantes, si leurs
   valeurs sont nécessaires pour les besoins de l'estimation ; mais la
   fonction doit renvoyer les estimations des tailles même si elles
   ne peuvent être réduites, et elle ne devrait pas échouer même
   si les valeurs apparaissent invalides (rappelez-vous qu'il s'agit
   uniquement d'une estimation de valeurs futures à l'exécution). Les
   paramètres pages et tuples
   sont les valeurs de sortie.
  
void
InitSampleScan (SampleScanState *node,
                int eflags);
   
   Initialise pour l'exécution d'un nœud du plan SampleScan.
   La fonction est appelée au démarrage de l'exécuteur.  Elle
   devrait effectuer toutes les initialisations nécessaires
   avant que le traitement ne puisse commencer. Le nœud
   SampleScanState a déjà été
   créé, mais son champ tsm_state
   est NULL. La fonction peut allouer via palloc les
   données internes d'état nécessaires à la fonction
   d'échantillonnage, et enregistrer un pointeur dans
   node->tsm_state. Des informations à
   propos de la table à parcourir sont accessibles via d'autres
   champs du nœud SampleScanState
   (mais veuillez noter que le descripteur du parcours
   node->ss.ss_currentScanDesc n'est pas
   encore positionné à ce stade). eflags
   contient un ensemble de bits décrivant le mode opératoire de
   l'exécuteur pour ce nœud du plan.
  
   Lorsque (eflags & EXEC_FLAG_EXPLAIN_ONLY) est
   true, le parcours ne sera pas encore effectué. Dans ce cas, cette
   fonction devrait effectuer uniquement le minimum requis pour mettre dans
   un état valide le nœud pour la commande EXPLAIN
   et la fonction EndSampleScan.
  
   Cette fonction est optionnelle (positionnez alors le pointeur sur
   NULL), auquel cas la fonction BeginSampleScan
   doit effectuer toutes les initialisations nécessaires à la méthode
   d'échantillonnage.
  
void
BeginSampleScan (SampleScanState *node,
                 Datum *params,
                 int nparams,
                 uint32 seed);
   
   Débute l'exécution d'un parcours d'échantillonnage.  Cette
   fonction est appelée juste avant la première tentative de
   récupération d'une ligne, et peut être appelée à nouveau si le
   parcours a besoin d'être relancé. Des informations sur la table à
   parcourir sont accessibles via les champs de la structure du nœud
   SampleScanState (mais notez que le descripteur
   du parcours node->ss.ss_currentScanDesc n'est pas
   encore positionné à ce stade). Le tableau params,
   de longueur nparams, contient les valeurs des
   paramètres indiqués dans la clause TABLESAMPLE. Ces
   paramètres seront en nombre et de types spécifiés par la méthode
   d'échantillonnage dans la liste parameterTypes, et
   ont été vérifiés comme n'étant pas null. seed>
   contient une graine à usage de la méthode d'échantillonnage pour
   générer des nombres aléatoires ; il s'agit d'un hash dérivé
   de la valeur de la clause REPEATABLE si fournie,
   ou du résultat de la fonction random() dans le cas
   contraire.
  
   Cette fonction peut ajuster les champs
   node->use_bulkread
   et node->use_pagemode. Si
   node->use_bulkread est true, ce qui est le cas
   par défaut, le parcours utilisera une stratégie d'accès aux tampons
   mémoires qui encourage le recyclage des tampons après usage. Il peut être
   raisonnable de mettre cette valeur à false
   si le parcours doit visiter seulement une petite fraction des pages
   de la table. Si node->use_pagemode est
   true, ce qui est la valeur par défaut, le parcours
   effectuera une vérification de la visibilité avec un unique passage
   pour l'ensemble des lignes composant chaque page visitée. Il peut
   être raisonnable de mettre cette valeur à false
   si le parcours doit sélectionner seulement une petite fraction des lignes de
   chaque page visitée. Ceci aura pour conséquence un nombre moindre
   de vérifications de visibilité effectuées, mais chacune sera plus
   coûteuse car elle demandera plus de verrouillages.
  
   Si la méthode d'échantillonnage est marquée comme
   repeatable_across_scans, elle doit être capable de
   sélectionner le même ensemble de lignes lors d'un parcours relancé
   à nouveau comme elle l'a fait à l'origine, c'est-à-dire qu'un
   nouvel appel à la fonction BeginSampleScan doit
   engendrer la sélection des mêmes lignes que précédemment (dans la
   mesure où les paramètres de la clause TABLESAMPLE
   et la graine ne changent pas).
  
BlockNumber NextSampleBlock (SampleScanState *node, BlockNumber nblocks);
   Renvoie le numéro du bloc de la page suivante à parcourir, ou
   InvalidBlockNumber si il n'y a plus de pages
   à parcourir.
  
Cette fonction peut être omise (mettez le pointeur à la valeur NULL), auquel cas le code du serveur effectuera un parcours séquentiel de l'ensemble de la relation. Un tel parcours peut utiliser un parcours synchronisé, aussi la méthode d'échantillonnage ne peut pas supposer que les pages de la relation sont visitées dans le même ordre à chaque parcours.
OffsetNumber
NextSampleTuple (SampleScanState *node,
                 BlockNumber blockno,
                 OffsetNumber maxoffset);
   
   Renvoie le décalage de la ligne suivante à echantillonner sur la
   page spécifiée, ou InvalidOffsetNumber si il
   n'y a plus de lignes à échantillonner. maxoffset
   est le décalage le plus grand utilisé sur la page.
  
    Il n'est pas explicitement indiqué à la fonction
    NextSampleTuple les décalages dans l'intervalle
    1 .. maxoffset qui contiennent des lignes valides. Ce
    n'est normalement pas un problème dans la mesure où le code du serveur
    ignore les requêtes pour échantillonner des lignes manquantes ou non
    visibles ; ceci ne devrait pas entraîner de biais dans l'échantillon.
    Cependant, si nécessaire, la fonction peut utiliser
    node->donetuples pour examiner le nombre de lignes
    renvoyées valides et visibles.
   
    La fonction NextSampleTuple ne doit
    pas assumer que blockno
    est le même numéro de page que celui renvoyé par le plus récent
    appel à la fonction NextSampleBlock. Le
    numéro a été renvoyé par un précédent appel à la fonction
    NextSampleBlock, mais le code du serveur
    est autorisé à appeler NextSampleBlock
    en amont du parcours des pages, pour rendre possible la
    récupération en avance. Il est acceptable d'assumer qu'une fois le
    parcours d'une page débuté, les appels successifs à la fonction
    NextSampleTuple se réfèrent tous à la
    même page jusqu'à ce que InvalidOffsetNumber
    soit retourné.
   
void EndSampleScan (SampleScanState *node);
Termine le parcours et libère les ressources. Il n'est normalement pas important de libérer la mémoire allouée via palloc, mais toutes les ressources visibles à l'extérieur doivent être nettoyées. Cette fonction peut être omise (positionnez le pointeur sur la valeur NULL) dans la plupart des cas où de telles ressources n'existent pas.