# UDA User-defined Functions

A structure of type `mco_uda_userdef_funcs_t` is required in the call to `mco_uda_register_udf()`. It is defined as follows in `mcouda.h`:

        typedef struct mco_uda_userdef_funcs_t_ {
            mco_uda_compare_userdef_f         fcomp;
            mco_uda_compare_extkey_userdef_f  fcomp_ext;
            mco_uda_hash_userdef_f            fhash;
            mco_uda_hash_extkey_userdef_f     fhash_ext;
            } mco_uda_userdef_funcs_t, *mco_uda_userdef_funcs_h;

The UDA user-defined functions are required for user-defined indexes called from UDA functions. They have the following prototypes defined in `mcouda.h`:

        typedef int2 (*mco_uda_compare_userdef_f)(mco_uda_object_handle_p obj1, unsigned short index1,
                mco_uda_object_handle_p obj2, unsigned short index2, void *user_context);

        typedef int2 (*mco_uda_compare_extkey_userdef_f)(mco_uda_object_handle_p obj, unsigned short index,
                mco_uda_value_t *keys, uint2 keys_count, void *user_context);

        typedef uint4 (*mco_uda_hash_userdef_f)(mco_uda_object_handle_p obj, unsigned short index, void *user_context);

        typedef uint4 (*mco_uda_hash_extkey_userdef_f)(mco_uda_value_t *keys, uint2 keys_count, void *user_context);

Note that the compare functions should return <0, =, or >0 depending on whether the object value is less than, equal to or greater than the external key value. Following are examples of UDA user-defined function implementations:

    /* User-defined compare & hash functions */
    int2 cmp_obj_obj(mco_uda_object_handle_p obj1, unsigned short index1,
        mco_uda_object_handle_p obj2, unsigned short index2, void *param_)
    {
        mco_uda_value_t val1, val2;
        char buf1[20], buf2[20];
        userdef_param_t *param = (userdef_param_t *) param_; /* Get context */

        /* Get first object's value */
        val1.type = MCO_DD_STRING;
        val1.v.p.size = sizeof(buf1);
        val1.v.p.p.c = buf1;
        mco_uda_get(obj1, param->fld_no, index1, &val1);
        /* Get second object's value */
        val2.type = MCO_DD_STRING;
        val2.v.p.size = sizeof(buf2);
        val2.v.p.p.c = buf2;
        mco_uda_get(obj2, param->fld_no, index2, &val2);

        /* Compare values */
        return STR_CMP(buf1, buf2);
    }

    int2 cmp_obj_ext(mco_uda_object_handle_p obj, unsigned short index,
        mco_uda_value_t *keys, uint2 keys_count, void *param_)
    {
        mco_uda_value_t val;
        char buf[20];
        userdef_param_t *param = (userdef_param_t *) param_;

        /* Get object's value */
        val.type = MCO_DD_STRING;
        val.v.p.size = sizeof(buf);
        val.v.p.p.c = buf;
        mco_uda_get(obj, param->fld_no, index, &val);

        /* Compare object's value and external key */
        return STR_CMP(buf, keys[0].v.p.p.c);
    }

    uint4 hash_obj(mco_uda_object_handle_p obj, unsigned short index, void *param_)
    {
        mco_uda_value_t val;
        char buf[20];
        userdef_param_t *param = (userdef_param_t *) param_;

        /* Get object's value */
        val.type = MCO_DD_STRING;
        val.v.p.size = sizeof(buf);
        val.v.p.p.c = buf;
        mco_uda_get(obj, param->fld_no, index, &val);

        /* Hash value */
        return strlen(buf);
    }

    uint4 hash_ext(mco_uda_value_t *keys, uint2 keys_count, void *param)
    {
        /* Hash external key */
        return strlen(keys[0].v.p.p.c);
    }

Related Topics