MySQL UDF in C
rappit 23.04.2012 - 10:27 2394 4
rappit
Bloody Newbie
|
Hallo, ich versuche ein UDF für MySQL zu schreiben und mein C-Wissen ist leider etwas eingerostet typedef char** stringArray;
stringArray MallocStringArray(size_t SizeOfOneString, size_t StringCount)
{
char** t=malloc(StringCount*sizeof(char*));
size_t i;
for(i=0;i<StringCount;++i)
t[i]=malloc(SizeOfOneString);
return t;
}
void FreeStringArray(stringArray StringArray, size_t StringCount)
{
size_t i;
for(i=0;i<StringCount;++i)
free(StringArray[i]);
free(StringArray);
}
void levenshtein_w_deinit(UDF_INIT *initid) {
if (initid->ptr != NULL) {
free(initid->ptr);
}
}
my_bool levenshtein_w_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if ((args->arg_count != 3) ||
(args->arg_type[0] != STRING_RESULT || args->arg_type[1] != STRING_RESULT || args->arg_type[2] != INT_RESULT)) {
strcpy(message, "Function requires 3 arguments, (string, string, int)");
return 1;
}
initid->max_length = LEVENSHTEIN_MAX;
initid->maybe_null = 0; //doesn't return null
fprintf(stderr, "\n\nSTART FUNCTION\n\n");
fflush(stderr);
return 0;
}
longlong levenshtein_w(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
if (args->args[0] == NULL || args->args[1] == NULL || args->args[2] == NULL)
return 0;
int lv_distance = *(int *) args->args[2];
char* suchbegriff=malloc(250);
char* keywords=malloc(250);
suchbegriff = args->args[0];
keywords = args->args[1];
//Log for Testing
fprintf(stderr, "Uebergabe: %s (%p) \n", args->args[1], args->args[1]);
fflush(stderr);
stringArray strings;
strings=MallocStringArray(250,30);
// Suchbegriff spliten und in string Array speichern
// ....
return 1;
}
Laut Doku sollt bei einem Aufruf einer UDF folgendes passiert init(); levenshtein_w(); deinint(); Wenn ich jetzt folgendes aufrufe SELECT levenshtein_w( 'kommunikationsexpertin', suchstring_levenshtein, 2 ) FROM `stellengesuch_suchstring2` LIMIT 4 Schaut die Aufruffolge allerdings so aus init(); levenshtein_w(); levenshtein_w(); levenshtein_w(); levenshtein_w(); deinint(); Wie oben ersichtlich im Code logge ich den Übergabeparamter weg. Log: Uebergabe: mitarbeiterinsexpertinbsleiteresuch (0xaf7b530) Uebergabe: verkaufsleiter vertriebsleiteresuch (0xaf14280) Uebergabe: kommunikationsexpertinbsleiteresuch (0xaf14280) Wie man sieht bleibt bei jedem Auruf der alte String erhalten :O Wenn der neue String also kürzer als der alte ist steht der alte zum Teil auch noch im Speicher.... Wie kann das sein? Danke, lg
Bearbeitet von rappit am 23.04.2012, 10:31
|
mat
AdministratorLegends never die
|
Das ist in jedem Fall komisch: char* suchbegriff=malloc(250);
char* keywords=malloc(250);
suchbegriff = args->args[0];
keywords = args->args[1];
Du machst ein malloc und dann überschreibst du den Pointer sofort wieder.
|
rappit
Bloody Newbie
|
Das ist in jedem Fall komisch:
char* suchbegriff=malloc(250);
char* keywords=malloc(250);
suchbegriff = args->args[0];
keywords = args->args[1];
Du machst ein malloc und dann überschreibst du den Pointer sofort wieder. Hmm das dürfte wohl noch vom Testen sein. Aber sogar wenn ich direkt args->arges[1] in das Log schreib tritt der Fehler auf.
|
mat
AdministratorLegends never die
|
So wie es aussieht, macht er dir einfach kein '\0' am Schluss des Strings. In der Dokumentation gibt es einen lengths-Parameter im Argument-Array: unsigned long *lengths
For the initialization function, the lengths array indicates the maximum string length for each argument. You should not change these. For each invocation of the main function, lengths contains the actual lengths of any string arguments that are passed for the row currently being processed. For arguments of types INT_RESULT or REAL_RESULT, lengths still contains the maximum length of the argument (as for the initialization function). Wenn das Argument also ein String ist, dann wirst du diesen selber herausholen müssen. Am besten wahrscheinlich gleich kopieren. Würde es so machen: char szBuffer[LEVENSHTEIN_MAX];
*szBuffer = 0;
strncat(args->args[0],szBuffer,args->lengths[0]);
|
rappit
Bloody Newbie
|
Danke, danke, danke - das wars! char suchbegriff[250];
*suchbegriff = 0;
char keywords[1000];
*keywords = 0;
strncat(suchbegriff,args->args[0],(args->lengths[0] > 250) ? 250 : args->lengths[0]);
strncat(keywords,args->args[1],(args->lengths[1] > 1000) ? 1000 : args->lengths[1]);
So funktionierts. Hab die args-Länge mitgeloggt und da sieht man schön dass dort die String-Länge passt. Vielen Dank nochmal!
|