2010-07-17 9 views
5

Estoy tratando de escribir una función personalizada definida por el usuario para mysql así que tomé la función str_ucwords desde http://www.mysqludf.org/index.php como un ejemplo para construir la mía.propercase mysql udf

my_bool str_ucwords_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 
{ 
    /* make sure user has provided exactly one string argument */ 
    if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT || args->args[0] == NULL) 
    { 
     strcpy(message,"str_ucwords requires one string argument"); 
     return 1; 
    } 

    /* str_ucwords() will not be returning null */ 
    initid->maybe_null=0; 

    return 0; 
} 

char *str_ucwords(UDF_INIT *initid, UDF_ARGS *args, 
    char *result, unsigned long *res_length, 
    char *null_value, char *error) 
{ 
    int i; 
    int new_word = 0; 

    // copy the argument string into result 
    strncpy(result, args->args[0], args->lengths[0]); 

    *res_length = args->lengths[0]; 

    // capitalize the first character of each word in the string 
    for (i = 0; i < *res_length; i++) 
    { 
     if (my_isalpha(&my_charset_latin1, result[i])) 
     { 
      if (!new_word) 
      { 
       new_word = 1; 
       result[i] = my_toupper(&my_charset_latin1, result[i]); 
      } 
     } 
     else 
     { 
      new_word = 0; 
     } 
    } 

    return result; 
} 

Esto funciona bien si trato select str_ucwords("test string"); pero si trato de seleccionar unos campos de una base de datos como select str_ucwords(name) from name; no consigo nada volvió.

¿Cómo cambio esta función para que pueda extraer datos de los campos en la base de datos?

Ya he intentado eliminar args->arg_type[0] != STRING_RESULT de la función init.

Respuesta

2

El problema no es el tipo del argumento, es que es NULL cuando se llama a str_ucwords_init (desde que se llama al str_ucwords_init antes de recuperar las filas). Para obtener str_ucwords para trabajar con campos, debe admitir valores NULL estableciendo initid->maybe_null en 1 en la función _init, y estableciendo *null_value en 1 (y result en NULO, aunque eso puede no ser necesario) en str_ucwords cuando el argumento real es nulo .

my_bool str_ucwords_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { 
    unsigned long res_length; 

    /* make sure user has provided exactly one argument */ 
    if (args->arg_count != 1) { 
     snprintf(message, MYSQL_ERRMSG_SIZE, "wrong number of arguments: str_ucwords requires one string argument, got %d arguments", args->arg_count); 
     return 1; 
    } 
    /* make sure user has provided a string argument */ 
    if (args->arg_type[0] != STRING_RESULT) { 
     snprintf(message, MYSQL_ERRMSG_SIZE, "str_ucwords requires one string argument (expected type %d, got type %d)", STRING_RESULT, args->arg_type[0]); 
     return 1; 
    } 

    res_length = args->lengths[0]; 

    if (SIZE_MAX < res_length) { 
     snprintf(message, MYSQL_ERRMSG_SIZE, "res_length (%lu) cannot be greater than SIZE_MAX (%zu)", res_length, (size_t) (SIZE_MAX)); 
     return 1; 
    } 

    initid->ptr = NULL; 

    if (res_length > 255) { 
     char *tmp = (char *) malloc((size_t) res_length); /* This is a safe cast because res_length <= SIZE_MAX. */ 
     if (tmp == NULL) { 
      snprintf(message, MYSQL_ERRMSG_SIZE, "malloc() failed to allocate %zu bytes of memory", (size_t) res_length); 
      return 1; 
     } 
     initid->ptr = tmp; 
    } 

    initid->maybe_null = 1; 
    initid->max_length = res_length; 
    return 0; 
} 

char *str_ucwords(UDF_INIT *initid, UDF_ARGS *args, 
      char *result, unsigned long *res_length, 
      char *null_value, char *error) 
{ 
    int i; 
    int new_word = 1; 

    if (args->args[0] == NULL) { 
     result = NULL; 
     *res_length = 0; 
     *null_value = 1; 
    } else { 
     if (initid->ptr != NULL) { 
      result = initid->ptr; 
     } 

     // copy the argument string into result 
     memcpy(result, args->args[0], args->lengths[0]); 
     *res_length = args->lengths[0]; 

     // capitalize the first character of each word in the string 
     for (i = 0; i < *res_length; i++) { 
      if (my_isalpha(&my_charset_latin1, result[i])) { 
       if (new_word) { 
        new_word = 0; 
        result[i] = my_toupper(&my_charset_latin1, result[i]); 
       } else { 
        result[i] = my_tolower(&my_charset_latin1, result[i]); 
       } 
      } else { 
       new_word = 1; 
      } 
     } 
    } 
    return result; 
} 

Las versiones posteriores de lib_mysqludf_str deben apoyar los valores NULL en las funciones sin alteración, lo que significa que también deben trabajar con las columnas de la tabla.

Cuestiones relacionadas