GraphKnowledge

graph-lakehouse

Creating New UDX Library Source Files

This topic provides information on creating new extension source files in C++ environments. You can add new extensions by creating a C++ source library file that define the operations performed by one or more UDX functions, aggregates, or services. Within the same source library file, you can create new extensions of different types (UDF, UDA, or UDS), which differ based on the number and shape of UDX input arguments and returned results.

Documentation on UDX development in JVM environments is in progress and not available at this time.

Creating New Extension Source Files in C++

  1. Create or edit a C++ .cpp source file to define new UDX function, aggregate, or service implementation details.

  2. At the top of the .cpp file, add the following line to include the UDX header file, udx_api.hpp.The header file is in the <install_path>/include directory and defines the UDX classes, class data members and methods, utility functions, macros, and other declarations available for your use in implementing Graph Lakehouse UDX function, aggregate, or service functionality:

    #include "udx_api.hpp"

  3. Graph Lakehouse's API entities are defined in the udx2 namespace. Add the following line to the file to use the udx2 namespace:

    using namespace udx2;

  4. Next, for a single extension, specify the interface for the type of UDX you want to the implement: a function, aggregate, or service. Then, use methods provided for the specified extension type to process input and output parameters for the extension.

    For example, to add a user-defined function (UDF) extension (which maps a single row of input values to a single row of output values), add the Function declaration to instantiate a named object of the Function class type. Then, add the apply() method statement that Graph Lakehouse calls to invoke the UDF.

    struct function_name : Function { void apply(const Row& a, Row& r); };

    In this example, function_name is the short name that you want to use for the function. In the apply() method, argument a is the input to the UDF and argument r is the output the UDF returns. Both arguments are of type Row; argument a is a constant reference, and argument r is a non-constant reference. In the apply() function, include the appropriate get and set routines to define the Row type and read or fetch the input values for argument a and return the values for argument r.

    The following table lists the get and set routines available for Graph Lakehouse extensions. Use the Read Cell and/or Read Cell with Default get routines for argument a. The Read Cell with Default routines are used to return a default value if the cell is not defined (empty). Use the Write Cell set routines for argument r:

    Read Cell (arg a) Read Cell with Default (arg a) Write Cell (arg r)
    defined(size_t) N/A undefined(size_t)
    getBoolean(size_t) getBoolean(size_t, bool) setBoolean(size_t, bool)
    getByte(size_t) getByte(size_t, uint8_t) setByte(size_t, byte)
    getShort(size_t) getShort(size_t, short) setShort(size_t, short)
    getInt(size_t) getInt(size_t, int) setInt(size_t, int)
    getLong(size_t) getLong(size_t, long) setLong(size_t, long)
    getFloat(size_t) getFloat(size_t, float) setFloat(size_t, float)
    getDouble(size_t) getDouble(size_t, double) setDouble(size_t, double)
    getDate(size_t) getDate(size_t, Date) setDate(size_t, Date)
    getTime(size_t) getTime(size_t, Time) setTime(size_t, Time)
    getDateTime(size_t) getDateTime(size_t, DateTime) setDateTime(size_t, DateTime)
    getDuration(size_t) getDuration(size_t, Duration) setDuration(size_t, Duration)
    getString(size_t) getString(size_t, String) setString(size_t, String)
    getLString(size_t) getLString(size_t, LString) setLString(size_t, LString)
    getUDT(size_t) getUDT(size_t, UDT) setUDT(size_t, UDT)
    getURI(size_t) getURI(size_t, URI) setURI(size_t, URI)
    getTag(size_t) getTag(size_t, String) N/A
    getType(size_t) N/A N/A
    N/A N/A clear()
    getBlob(size_t) getBlob(size_t, Blob) setBlob(size_t, Blob)

    These routines may also be used in an extension's programming logic that implements the operation of a particular extension.

  5. Implement the programming logic that provides the functionality of the specific extension, function, aggregate, or service. For example, as shown in the following code snippet for a concat UDF extension, the apply() function concatenates two strings and returns the concatenated string:

    struct concat : Function { void apply(const Row& a, Row& r) { r.setString(0, string(a.getString(0)) + string(a.getString(1))); } };

  6. If you want to implement error handling, you can include the following azg_throw macro, which is similar to the printf() function in C. Create and specify the full URI for the function as a string, and include the message to display when an error occurs.

    azg_throw("function_URI", "error_message");

    The function_URI argument is a prefix that you define, followed by the function name. The URI must be globally unique. Altair recommends that you use a format such as http://mycompany.com/grouping/etc#function_name. For example:

    azg_throw("http://cambridgesemantics.com/udx/function#concat", "Error message – code %d", m_code);

    You register the function URI after you complete implementation for all extension definitions in the library file and then register the entire extension library for all the extensions in the same source file. (See Registering a UDX in an Extension Library.)

  7. Include statements to instantiate extensions by specifying the following extern "C" extension factory function for each extension defined within the same extension library source file:

    extern "C" ExtensionFactory* udx_functionName() { return new FactoryFor<functionName>(); }

    Where functionName is the short name of the function, not the full URI. For example:

    extern "C" ExtensionFactory* udx_concat() { return new FactoryFor(); }

Once you've finished implementing the operation of all extensions within an extension library file, you register the extensions. For instructions on how to do that, see Registering a UDX in an Extension Library.

For more information on creating specific user-defined extension types in C++, see UDX Examples.

Source: https://docs.sw.siemens.com/documentation/external/PL20260518131381558/en-US/html/udx-create.htm · retrieved 2026-08-23