Handling character arguments

When the routine manager receives text data for a C UDR, it puts this text data into an mi_lvarchar varying-length structure. It then passes a pointer to this mi_lvarchar structure as the MI_DATUM structure for the UDR argument. Therefore, a C UDR must have its text parameter declared as a pointer to an mi_lvarchar structure when the parameter accepts data from the following SQL character data types:
  • CHAR
  • IDSSECURITYLABEL
  • LVARCHAR
  • NCHAR
  • NVARCHAR
  • VARCHAR

Use of the SQL TEXT data type in a C UDR is not supported.

For more information about the NCHAR and NVARCHAR data types, see the Informix® GLS User's Guide.

Important: These SQL data types cannot be represented as null-terminated strings. A C UDR never receives a null-terminated string as an argument. Do not code a C UDR to receive null-terminated strings as arguments. For more information about how to access mi_lvarchar, see Varying-length data type structures.
For example, suppose you want to define a user-defined function named initial_cap() that accepts a VARCHAR string, ensures that the string begins with an uppercase letter, and ensures that the rest of the string consists of lowercase letters. This UDR would be useful in the following query to retrieve a customers last name:
SELECT customer_num
FROM customer
WHERE initial_cap(lname) = "Sadler";

In the preceding query, use of the initial_cap() function means that you do not have to ensure that the customer last names (in the lname column) were entered with an initial uppercase letter. The preceding query would locate the customer number for either Sadler or sadler.

The following CREATE FUNCTION statement registers the initial_cap() function in the database:
CREATE FUNCTION initial_cap(str VARCHAR(50))
RETURNS VARCHAR(50)
EXTERNAL NAME '/usr/udrs/text/checkcaps.so'
LANGUAGE C;
The following declaration of initial_cap() specifies an mi_lvarchar pointer as the parameter data type even though the function is registered to accept a VARCHAR column value:
/* Valid C UDR declaration for string parameter */
mi_lvarchar *initial_cap(str)
   mi_lvarchar *str;
The following declaration of initial_cap() is invalid because it specifies an mi_string pointer as the parameter data type:
/* INVALID declaration for string parameter */
mi_string *initial_cap(string)
   mi_string *string;

The initial_cap() function in the preceding declaration would not execute correctly because it interprets its argument as an mi_string value when the routine manager actually sends this argument as an mi_lvarchar value.

The following code fragment shows the implementation of the initial_cap() function.
Figure 1: Handling character data in a UDR
#include <mi.h>
#include <ctype.h>

mi_lvarchar *initial_cap(str)
   mi_lvarchar *str;
{
   char *var_ptr, one_char;
   mi_lvarchar *lvarch_out;
   mi_integer i, var_len;

   /* Create copy of input data */
   lvarch_out = mi_var_copy(str);

   /* Obtain data pointer for varying-length data */
   var_ptr = mi_get_vardata(lvarch_out);

   /* Obtain data length */
   var_len = mi_get_varlen(lvarch_out);

   /* Check string for proper letter case */
   for ( i=0; i < var_len; i++ )
      {  
      one_char = var_ptr[i];

      if ( i == 0 ) 
         /* Change lowercase first letter to uppercase */
         {
         if ( islower(one_char) ) /* is lowercase */
            var_ptr[i] = toupper(one_char);
         }
      else 
         /* Change uppercase other letters to lowercase */
         if ( isupper(one_char) ) /* is uppercase */
            var_ptr[i] = tolower(one_char);
      }  

   return (lvarch_out);
}
Tip: A C UDR that returns data for one of the SQL character data types must return a pointer to an mi_lvarchar. The initial_cap() function returns a varying-length structure to hold the initial-capital string. For more information, see Return character values.