31.19. Alternative row processor

As the standard usage, rows are stored into PQresult until full resultset is received. Then such completely-filled PQresult is passed to user. This behaviour can be changed by registering alternative row processor function, that will see each row data as soon as it is received from network. It has the option of processing the data immediately, or storing it into custom container.

Note - as row processor sees rows as they arrive, it cannot know whether the SQL statement actually finishes successfully on server or not. So some care must be taken to get proper transactionality.

PQsetRowProcessor

Sets a callback function to process each row.

void PQsetRowProcessor(PGconn *conn, PQrowProcessor func, void *param);

conn

The connection object to set the row processor function.

func

Storage handler function to set. NULL means to use the default processor.

param

A pointer to contextual parameter passed to func.

PQrowProcessor

The type for the row processor callback function.

int (*PQrowProcessor)(PGresult *res, void *param, PGrowValue *columns);

typedef struct
{
    int         len;            /* length in bytes of the value, -1 if NULL */
    char       *value;          /* actual value, without null termination */
} PGrowValue;

The columns array will have PQnfields() elements, each one pointing to column value in network buffer. The len field will contain number of bytes in value. If the field value is NULL then len will be -1 and value will point to position where the value would have been in buffer. This allows estimating row size by pointer arithmetic.

This function must process or copy row values away from network buffer before it returns, as next row might overwrite them.

This function must return 1 for success, and 0 for failure. On failure this function should set the error message with PGsetRowProcessorErrMsg if the cause is other than out of memory. When non-blocking API is in use, it can also return 2 for early exit from PQisBusy function. The supplied res and columns values will stay valid so row can be processed outside of callback. Caller is resposible for tracking whether the PQisBusy returned early from callback or for other reasons. Usually this should happen via setting cached values to NULL before calling PQisBusy.

The function is allowed to exit via exception (setjmp/longjmp). The connection and row are guaranteed to be in valid state. The connection can later be closed via PQfinish. Processing can also be continued without closing the connection, call getResult on syncronous mode, PQisBusy on asynchronous connection. Then processing will continue with new row, previous row that got exception will be skipped.

res

A pointer to the PGresult object.

param

Extra parameter that was given to PQsetRowProcessor.

columns

Column values of the row to process. Column values are located in network buffer, the processor must copy them out from there.

Column values are not null-terminated, so processor cannot use C string functions on them directly.

PQsetRowProcessorErrMsg

Set the message for the error occurred in PQrowProcessor. If this message is not set, the caller assumes the error to be out of memory.

void PQsetRowProcessorErrMsg(PGresult *res, char *msg)

res

A pointer to the PGresult object passed to PQrowProcessor.

msg

Error message. This will be copied internally so there is no need to care of the scope.

If res already has a message previously set, it will be overwritten. Set NULL to cancel the the custom message.