60.3. Ejecución de escaneos personalizados #

60.3.1. Callbacks de ejecución de escaneo personalizado

Cuando se ejecuta un CustomScan, su estado de ejecución se representa mediante un CustomScanState, que se declara de la siguiente manera:

typedef struct CustomScanState
{
    ScanState ss;
    uint32    flags;
    const CustomExecMethods *methods;
} CustomScanState;

ss se inicializa como para cualquier otro estado de escaneo, excepto que si el escaneo es para una unión en lugar de una relación base, ss.ss_currentRelation se deja NULL. flags es una máscara de bits con el mismo significado que en CustomPath y CustomScan. methods debe apuntar a un objeto (generalmente asignado estáticamente) que implemente los métodos de estado de escaneo personalizados requeridos, que se detallan más adelante. Típicamente, un CustomScanState, que no necesita admitir copyObject, será en realidad una estructura más grande que incorpora el anterior como su primer miembro.

60.3.1. Callbacks de ejecución de escaneo personalizado #

void (*BeginCustomScan) (CustomScanState *node,
                         EState *estate,
                         int eflags);

Completa la inicialización del CustomScanState suministrado. Los campos estándar han sido inicializados por ExecInitCustomScan, pero cualquier campo privado debe inicializarse aquí.

TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);

Obtiene la siguiente tupla de escaneo. Si queda alguna tupla, debe llenar ps_ResultTupleSlot con la siguiente tupla en la dirección de escaneo actual, y luego devolver el slot de la tupla. De lo contrario, debe devolver NULL o un slot vacío.

void (*EndCustomScan) (CustomScanState *node);

Limpia cualquier dato privado asociado con el CustomScanState. Este método es requerido, pero no necesita hacer nada si no hay datos asociados o si se limpiarán automáticamente.

void (*ReScanCustomScan) (CustomScanState *node);

Rebobina el escaneo actual al principio y se prepara para volver a escanear la relación.

void (*MarkPosCustomScan) (CustomScanState *node);

Guarda la posición de escaneo actual para que posteriormente pueda ser restaurada por el callback RestrPosCustomScan. Este callback es opcional y solo debe suministrarse si el flag CUSTOMPATH_SUPPORT_MARK_RESTORE está establecido.

void (*RestrPosCustomScan) (CustomScanState *node);

Restaura la posición de escaneo anterior guardada por el callback MarkPosCustomScan. Este callback es opcional y solo debe suministrarse si el flag CUSTOMPATH_SUPPORT_MARK_RESTORE está establecido.

Size (*EstimateDSMCustomScan) (CustomScanState *node,
                               ParallelContext *pcxt);

Estima la cantidad de memoria compartida dinámica que se requerirá para la operación paralela. Esta puede ser mayor que la cantidad que realmente se usará, pero no debe ser menor. El valor de retorno se expresa en bytes. Este callback es opcional y solo debe suministrarse si este proveedor de escaneo personalizado admite la operación en paralelo.

void (*InitializeDSMCustomScan) (CustomScanState *node,
                                 ParallelContext *pcxt,
                                 void *coordinate);

Inicializa la memoria compartida dinámica que se requerirá para la operación paralela. coordinate apunta a un área de memoria compartida de tamaño igual al valor de retorno de EstimateDSMCustomScan. Este callback es opcional y solo debe suministrarse si este proveedor de escaneo personalizado admite la operación en paralelo.

void (*ReInitializeDSMCustomScan) (CustomScanState *node,
                                   ParallelContext *pcxt,
                                   void *coordinate);

Vuelve a inicializar la memoria compartida dinámica requerida para la operación paralela cuando el nodo de plan de escaneo personalizado está a punto de volver a escanearse. Este callback es opcional y solo debe suministrarse si este proveedor de escaneo personalizado admite la operación en paralelo. La práctica recomendada es que este callback restablezca únicamente el estado compartido, mientras que el callback ReScanCustomScan restablece únicamente el estado local. Actualmente, este callback se llamará antes de ReScanCustomScan, pero es mejor no confiar en ese orden.

void (*InitializeWorkerCustomScan) (CustomScanState *node,
                                    shm_toc *toc,
                                    void *coordinate);

Inicializa el estado local de un trabajador en paralelo basado en el estado compartido configurado por el líder durante InitializeDSMCustomScan. Este callback es opcional y solo debe suministrarse si este proveedor de escaneo personalizado admite la operación en paralelo.

void (*ShutdownCustomScan) (CustomScanState *node);

Libera recursos cuando se anticipa que el nodo no se ejecutará hasta su finalización. Esto no se llama en todos los casos; a veces, EndCustomScan puede llamarse sin que esta función se haya llamado primero. Dado que el segmento DSM utilizado por la consulta paralela se destruye justo después de que se invoque este callback, los proveedores de escaneo personalizados que deseen realizar alguna acción antes de que desaparezca el segmento DSM deben implementar este método.

void (*ExplainCustomScan) (CustomScanState *node,
                           List *ancestors,
                           ExplainState *es);

Muestra información adicional para el EXPLAIN de un nodo de plan de escaneo personalizado. Este callback es opcional. Los datos comunes almacenados en el ScanState, como la lista de destino y la relación de escaneo, se mostrarán incluso sin este callback, pero el callback permite mostrar un estado privado adicional.