/* wrapper for Levenshtein string comparison */ void levenshtein_wrapper(sqlite3_context *ctx, int n_values, sqlite3_value **value) { // check for NULL values, return NULL if any of the input strings is NULL if(sqlite3_value_type(value[0]) == SQLITE_NULL || sqlite3_value_type(value[1]) == SQLITE_NULL) { sqlite3_result_null(ctx); return; } const unsigned char *str1 = sqlite3_value_text(value[0]); const unsigned char *str2 = sqlite3_value_text(value[1]); #ifdef DEBUG Rprintf("String 1: %s\n", str1); Rprintf("String 2: %s\n", str2); #endif double result; int editDistance; editDistance = levenshtein_internal(str1, str2, 1, 1, 1); /* Only the string metric based on the edit distance is used in this package, therefore transform right here */ result = 1.0 - (double) editDistance / (double) max(strlen(str1), strlen(str2)); #ifdef DEBUG Rprintf("Ergebnis des Stringvergleichs: %f\n", result); #endif sqlite3_result_double(ctx, result); }
Datum levenshtein(PG_FUNCTION_ARGS) { text *src = PG_GETARG_TEXT_PP(0); text *dst = PG_GETARG_TEXT_PP(1); PG_RETURN_INT32(levenshtein_internal(src, dst, 1, 1, 1)); }
Datum levenshtein_with_costs(PG_FUNCTION_ARGS) { text *src = PG_GETARG_TEXT_PP(0); text *dst = PG_GETARG_TEXT_PP(1); int ins_c = PG_GETARG_INT32(2); int del_c = PG_GETARG_INT32(3); int sub_c = PG_GETARG_INT32(4); PG_RETURN_INT32(levenshtein_internal(src, dst, ins_c, del_c, sub_c)); }