MI_DATUM in a C UDR (Server)
- For most data types, the MI_DATUM structure contains a
pointer to the data type.
The actual value of most data types is too large to fit within an MI_DATUM structure. For such data types, the DataBlade® API passes the value using the pass-by-reference mechanism. Use the contents of the MI_DATUM structure as a pointer to access the actual value.
- For a few small data types, the MI_DATUM structure contains
the actual data value.
Types of values that fit in an MI_DATUM structure (Passed by value) shows the few data types whose value can always fit in an MI_DATUM structure. For these data types, the DataBlade® API passes the value using the pass-by-value mechanism. Use the contents of the MI_DATUM structure as the actual data value.
DataBlade® API data types | Length | SQL data types |
---|---|---|
Data types that can hold four-byte integers, including mi_integer and mi_unsigned_integer | 4 | The SQL INTEGER data type |
mi_date | 4 | The SQL DATE data type |
Data types that can hold two-byte integers, including mi_smallint and mi_unsigned_smallint | 2 | The SQL SMALLINT data type |
Data types that can hold a one-byte character, including mi_char1 and mi_unsigned_char1 | 1 | The SQL CHAR(1) data type (Multicharacter values must be passed by reference.) |
mi_boolean | 1 | The SQL BOOLEAN data type |
mi_pointer | size of (void *) | The SQL POINTER data type |
C data structure for the internal format of an opaque data type when the structure size can fit into an MI_DATUM structure | Depends on the size of the C data structure | An opaque data type whose CREATE OPAQUE TYPE statement specifies the PASSEDBYVALUE modifier |
mi_integer my_func(arg1, arg2)
mi_integer arg1; /* passed by value */
mi_integer *arg2; /* passed by reference */
Values of data types with sizes smaller than or equal to the size of void * can be passed by value because they can fit into an MI_DATUM structure. A value smaller than the size of MI_DATUM is cast promoted to the MI_DATUM size with whatever byte position is appropriate for the computer architecture. When you obtain a smaller passed-by-value value from an MI_DATUM structure, you need to reverse the cast promotion to ensure that your value is correct.
datum = (void *((char) bool))
In the preceding cast promotion, datum is an MI_DATUM structure and bool is an mi_boolean value.
mi_boolean bool_val;
MI_DATUM datum;
...
bool_val = (char) datum;
To avoid the cast promotion situation, it is recommended that you declare small pass-by-value SQL types as mi_integer.
my_type_id = mi_fp_argtype(my_fparam, 1);
my_type_desc = mi_type_typedesc(conn, my_type_id);
if ( mi_type_byvalue(my_type_desc) == MI_TRUE )
{
/* Argument is passed by value: extract one-, two-, or
* four-byte item from argument
*/
}
else
{
/* Argument is passed by reference: it contains a pointer
* to the actual value
*/
}
However, a UDR that hardcodes a type identifier in a switch or if statement to determine actions can handle only built-in data types. It cannot handle all possible user-defined types because not all of them have unique, type-specific identifiers.