Handling varying-length opaque-type arguments

For UDR arguments that are varying-length opaque types, the routine manager puts the data into an mi_bitvarying varying-length structure. It then passes a pointer to this mi_bitvarying structure as the MI_DATUM structure for the UDR argument. Your UDR must extract the actual opaque-type data from the data portion of the mi_bitvarying varying-length structure.

For more information about how to access varying-length structures, see A varying-length structure.

Suppose that you want to create a user-defined function named image_id() that accepts a varying-length opaque type named image (which is defined in Internal representation for the image opaque data type) and returns its integer image identifier (img_id). The following CREATE FUNCTION statement registers the image_id() function in the database:
CREATE FUNCTION image_id(arg1 image)
RETURNS INTEGER
EXTERNAL NAME '/usr/udrs/image/image.so'
LANGUAGE C;
Because image is a varying-length data type, the following declaration of image_id() specifies an mi_bitvarying pointer as the parameter data type even though the function is registered to accept a value of type image:
/* Valid C UDR declaration for varying-length opaque-type
 * parameter
 */
mi_integer image_id(image)
   mi_bitvarying *image;
The following declaration of image_id() is invalid because it specifies an image pointer as the parameter data type:
/* INVALID declaration for varying-length opaque-type
 * parameter
 */
mi_integer image_id(image)
   image_t *image;

The image_id() function in the preceding declaration would not execute correctly because it interprets its argument as the internal structure for image (image_t) when the routine manager actually sends this argument as an mi_bitvarying value.

The following code fragment shows the implementation of the image_id() function.
#include <mi.h>
#include <ctype.h>
#include <image.h>

mi_integer image_id(image)
   mi_bitvarying *image;
{
   image_t *image_ptr;

   /* Obtain pointer to image_t structure, contained
    * within the data portion of the mi_bitvarying 
    * structure.
    */
   image_ptr = (image_t *)mi_get_vardata((mi_lvarchar *)image);

   return (image_ptr->img_id);
}
Tip: A C UDR that returns varying-length opaque-type data must return a pointer to an mi_bitvarying structure. For more information, see Return opaque-type values.