Un parcours personnalisé est représenté dans un arbre de plans finalisé en utilisant la structure suivante :
typedef struct CustomScan { Scan scan; uint32 flags; List *custom_plans; List *custom_exprs; List *custom_private; List *custom_scan_tlist; Bitmapset *custom_relids; const CustomScanMethods *methods; } CustomScan;
scan
doit être initialisé
comme pour tous les autres parcours, y compris le coût
estimé, les listes cibles, les qualifications, et ainsi de
suite. flags
est un masque de bits avec la
même signification que dans CustomPath
.
custom_plans
peut
être utilisé pour stocker des nœuds enfants de type
Plan
. custom_exprs
devrait être utilisé pour stocker des arbres d'expressions
qui devront être corrigés par setrefs.c
et subselect.c
, tandis que
custom_private
devrait être
utilisé pour stocker d'autres données privées qui sont
seulement utilisées par le module de parcours personnalisé
lui-même. custom_scan_tlist
peut être
à NIL lors du parcours d'une relation de base, indiquant que le
parcours personnalisé renvoie des lignes parcourues qui correspondent
au type des lignes de la relation de base. Dans le cas contraire,
il s'agit d'une liste de cibles décrivant les lignes actuellement
parcourues. custom_scan_tlist
devrait être
fourni pour les jointures, et peut être fourni pour les parcours
dont le module de parcours personnalisé peut calculer certaines
expressions non variables. custom_relids
est positionné par le code du serveur sur l'ensemble des relations
(index de l'ensemble des tables) que ce nœud de parcours gère ; sauf
lorsque ce parcours remplace une jointure, il aura alors un seul
membre. methods
doit pointer sur un objet
(généralement alloué statiquement) implémentant les méthodes
requises d'un parcours personnalisé, lesquelles sont détaillées
ci-dessous.
Lorsqu'un CustomScan
parcourt une simple
relation, scan.scanrelid
doit être l'index
dans l'ensemble des tables de la table à parcourir. Lorsqu'il
remplace une jointure, scan.scanrelid
devrait être à zéro.
Les arbres de plan doivent pouvoir être dupliqués en utilisant
la fonction copyObject
, aussi les données
stockées dans les champs « custom » doivent consister
en des nœuds que cette fonction peut gérer. De plus, les
modules de parcours personnalisés ne peuvent pas substituer une
structure plus large qui incorporerait une structure de type
CustomScan
, comme il est possible
pour les structures CustomPath
ou
CustomScanState
.
Node *(*CreateCustomScanState) (CustomScan *cscan);
Alloue une structure CustomScanState
pour ce CustomScan
. L'allocation actuelle
sera souvent plus grande que requis pour une structure ordinaire
CustomScanState
car beaucoup de modules
voudront incorporer celui-ci comme le premier champ d'une structure
plus large. La valeur renvoyée doit avoir la marque du nœud et le
champ methods
positionnés correctement, les
autres champs devraient être laissés à zéro à ce stade ; après que
la fonction ExecInitCustomScan
ait effectué une
initialisation basique, la fonction BeginCustomScan
sera appelée pour permettre au module de parcours personnalisé
d'effectuer ce qu'il a besoin de faire.