The my_byte_length scalar UDF example computes the size of a column by streaming the data in piece by piece, then returns the size of the column in bytes.
#include "extfnapiv4.h" #include <stdlib.h> #include <string.h> #include <math.h> #include <assert.h> // A simple function that returns the size of a cell value in bytes // // CREATE FUNCTION my_byte_length(IN arg1 LONG BINARY) // RETURNS UNSIGNED INT // DETERMINISTIC // IGNORE NULL VALUES // EXTERNAL NAME 'my_byte_length@libudfex' #if defined __cplusplus extern "C" { #endif static void my_byte_length_evaluate(a_v3_extfn_scalar_context *cntxt, void *arg_handle) { if (cntxt == NULL || arg_handle == NULL) { return; } an_extfn_value arg; an_extfn_value outval; a_sql_uint64 total_len; // Get first argument a_sql_uint32 fetchedLength = 0; (void) cntxt->get_value( arg_handle, 1, &arg ); if (arg.data == NULL) { return; } fetchedLength += arg.piece_len; // saving total length as it loses scope inside get_piece total_len = arg.len.total_len; while (fetchedLength < total_len) { (void) cntxt->get_piece( arg_handle, 1, &arg, fetchedLength ); fetchedLength += arg.piece_len; } //if this fails, the function did not get the full data from the cell assert(fetchedLength == total_len); outval.type = DT_UNSINT; outval.piece_len = 4; outval.data = &fetchedLength; cntxt->set_value(arg_handle, &outval, 0); } static a_v3_extfn_scalar my_byte_length_descriptor = { 0, 0, &my_byte_length_evaluate, 0, // Reserved - initialize to NULL 0, // Reserved - initialize to NULL 0, // Reserved - initialize to NULL 0, // Reserved - initialize to NULL 0, // Reserved - initialize to NULL NULL // _for_server_internal_use }; a_v3_extfn_scalar *my_byte_length() { return &my_byte_length_descriptor; } #if defined __cplusplus } #endif