Example: Creating a row type

Suppose you have the row type that the following SQL statement creates:
CREATE ROW TYPE rowtype_t
(
 id INTEGER,
 name CHAR(20)
);

Server only

The following code shows how to use the mi_row_create() function to create a new row type of type rowtype_t:
/*
 * Create a row structure for the 'rowtype_t' row type
 */

   MI_CONNECTION *conn;
   MI_ROW_DESC *rowdesc;
   MI_ROW *row;
   MI_DATUM *values;
   mi_boolean *nulls;
   mi_integer num_cols;

/* Allocate a row descriptor for the 'rowtype_t' row type */
rowdesc = mi_row_desc_create(
         mi_typestring_to_id(conn, "rowtype_t"));

/* Assume number of columns is known */
num_cols = 2;

/* Allocate the 'col_values' and 'col_nulls' arrays */
values = mi_alloc(num_cols *sizeof(MI_DATUM));
nulls = mi_alloc(num_cols *sizeof(mi_boolean));

/* Populate the 'col_values' and 'col_nulls' arrays */

   /* Initialize value for field 1: 'id' */
   values[0] = 1;
   nulls[0] = MI_FALSE;
   
   /* Initialize value for field 2: 'name' */
   values[1] = mi_string_to_lvarchar("Dexter");
   nulls[1] = MI_FALSE;

/* Create row structure for 'name_t' */
row = mi_row_create(conn, rowdesc, values, nulls);
When this code completes, the row variable points to a row structure that contains the following field values.
Field name Field value
fname "Dexter"
middle "M"
lname "Haven"

Client only

If the preceding code fragment were part of a client LIBMI application, it would require changes to the way the values are addressed in the values array. For example, the INTEGER value would require the following cast to create a copy of the column value:
mi_integer col_val;
...
/* Initialize value for field 1: 'id' */
col_val = 1;
values[0] = &col_val;
nulls[0] = MI_FALSE;

This different kind of addressing is required because in client LIBMI applications, mi_row_create() passes values for all data types by reference. Therefore, the contents of the MI_DATUM structure is always a pointer to the actual value, never the value itself.