52 static void _soundex(
const char *instr,
char *outstr);
62 letter = toupper((
unsigned char) letter);
64 if (letter >=
'A' && letter <=
'Z')
72 #define MAX_METAPHONE_STRLEN 255
100 #undef USE_TRADITIONAL_METAPHONE
107 static void _metaphone(
char *
word,
int max_phonemes,
char **phoned_word);
115 1, 16, 4, 16, 9, 2, 4, 16, 9, 2, 0, 2, 2, 2, 1, 4, 0, 2, 4, 4, 1, 0, 0, 0, 8, 0
122 if (isalpha((
unsigned char)
c))
124 c = toupper((
unsigned char)
c);
126 if (
c >=
'A' &&
c <=
'Z')
132 #define isvowel(c) (getcode(c) & 1)
135 #define NOCHANGE(c) (getcode(c) & 2)
138 #define AFFECTH(c) (getcode(c) & 4)
141 #define MAKESOFT(c) (getcode(c) & 8)
144 #define NOGHTOF(c) (getcode(c) & 16)
168 ins_c, del_c, sub_c,
false));
260 size_t str_i_len = strlen(str_i);
265 if (!(str_i_len > 0))
270 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
271 errmsg(
"argument exceeds the maximum length of %d bytes",
277 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
278 errmsg(
"output exceeds the maximum length of %d bytes",
283 (
errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING),
284 errmsg(
"output cannot be empty string")));
301 #define Next_Letter (toupper((unsigned char) word[w_idx+1]))
303 #define Curr_Letter (toupper((unsigned char) word[w_idx]))
305 #define Look_Back_Letter(n) \
306 (w_idx >= (n) ? toupper((unsigned char) word[w_idx-(n)]) : '\0')
308 #define Prev_Letter (Look_Back_Letter(1))
310 #define After_Next_Letter \
311 (Next_Letter != '\0' ? toupper((unsigned char) word[w_idx+2]) : '\0')
312 #define Look_Ahead_Letter(n) toupper((unsigned char) Lookahead(word+w_idx, n))
320 char letter_ahead =
'\0';
333 #define Phonize(c) do {(*phoned_word)[p_idx++] = c;} while (0)
335 #define End_Phoned_Word do {(*phoned_word)[p_idx] = '\0';} while (0)
337 #define Phone_Len (p_idx)
340 #define Isbreak(c) (!isalpha((unsigned char) (c)))
358 if (!(max_phonemes > 0))
360 elog(
ERROR,
"metaphone: Requested output length must be > 0");
363 if ((
word == NULL) || !(strlen(
word) > 0))
365 elog(
ERROR,
"metaphone: Input string length must be > 0");
368 if (max_phonemes == 0)
370 *phoned_word =
palloc(
sizeof(
char) * strlen(
word) + 1);
374 *phoned_word =
palloc(
sizeof(
char) * max_phonemes + 1);
379 for (; !isalpha((
unsigned char) (
Curr_Letter)); w_idx++)
459 (max_phonemes == 0 ||
Phone_Len < max_phonemes);
466 unsigned short int skip_letter = 0;
517 #ifndef USE_TRADITIONAL_METAPHONE
630 #ifndef USE_TRADITIONAL_METAPHONE
671 if (max_phonemes == 0 ||
Phone_Len < max_phonemes)
697 w_idx += skip_letter;
731 while (*instr && !isalpha((
unsigned char) *instr))
742 *outstr++ = (char) toupper((
unsigned char) *instr++);
747 if (isalpha((
unsigned char) *instr) &&
788 if (sndx1[
i] == sndx2[
i])
Datum idx(PG_FUNCTION_ARGS)
#define TextDatumGetCString(d)
#define Assert(condition)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_TEXT_PP(n)
#define PG_GETARG_DATUM(n)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
Datum metaphone(PG_FUNCTION_ARGS)
static void _metaphone(char *word, int max_phonemes, char **phoned_word)
#define After_Next_Letter
Datum levenshtein_less_equal_with_costs(PG_FUNCTION_ARGS)
#define Look_Back_Letter(n)
static const char *const soundex_table
Datum soundex(PG_FUNCTION_ARGS)
static char soundex_code(char letter)
static const char _codes[26]
Datum levenshtein_with_costs(PG_FUNCTION_ARGS)
static void _soundex(const char *instr, char *outstr)
static int getcode(char c)
Datum difference(PG_FUNCTION_ARGS)
#define MAX_METAPHONE_STRLEN
static char Lookahead(char *word, int how_far)
Datum levenshtein_less_equal(PG_FUNCTION_ARGS)
#define Look_Ahead_Letter(n)
PG_FUNCTION_INFO_V1(levenshtein_with_costs)
Datum levenshtein(PG_FUNCTION_ARGS)
int varstr_levenshtein(const char *source, int slen, const char *target, int tlen, int ins_c, int del_c, int sub_c, bool trusted)
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
#define VARSIZE_ANY_EXHDR(PTR)
char * text_to_cstring(const text *t)
text * cstring_to_text(const char *s)
int varstr_levenshtein_less_equal(const char *source, int slen, const char *target, int tlen, int ins_c, int del_c, int sub_c, int max_d, bool trusted)