Skip to content

Commit 18d99bc

Browse files
committed
Update soundex to new fmgr interface and fix algorithm
1 parent baa3a09 commit 18d99bc

File tree

4 files changed

+98
-57
lines changed

4 files changed

+98
-57
lines changed

contrib/soundex/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#
2-
# $Header: /cvsroot/pgsql/contrib/soundex/Attic/Makefile,v 1.7 2000/07/09 13:13:33 petere Exp $
2+
# $Header: /cvsroot/pgsql/contrib/soundex/Attic/Makefile,v 1.8 2000/10/04 19:25:34 petere Exp $
33
#
44

55
subdir = contrib/soundex
66
top_builddir = ../..
7-
include ../../src/Makefile.global
7+
include $(top_builddir)/src/Makefile.global
88

99
NAME := soundex
1010
SONAME := $(NAME)$(DLSUFFIX)
@@ -14,7 +14,7 @@ CFLAGS += -I. $(CFLAGS_SL)
1414
all: $(SONAME) $(NAME).sql
1515

1616
$(NAME).sql: $(NAME).sql.in
17-
sed -e 's:MODULE_PATHNAME:$(datadir)/contrib/$(SONAME):g' < $< > $@
17+
sed 's,@MODULE_FILENAME@,$(libdir)/contrib/$(SONAME),g' $< >$@
1818

1919
install: all installdirs
2020
$(INSTALL_SHLIB) $(SONAME) $(libdir)/contrib
@@ -28,7 +28,7 @@ uninstall:
2828
rm -f $(libdir)/contrib/$(SONAME) $(datadir)/contrib/$(NAME).sql $(docdir)/contrib/README.$(NAME)
2929

3030
clean distclean maintainer-clean:
31-
rm -f $(SONAME) $(NAME).sql
31+
rm -f $(SONAME) $(NAME).o $(NAME).sql
3232

3333
depend dep:
3434
$(CC) -MM -MG $(CFLAGS) *.c > depend

contrib/soundex/README.soundex

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
This directory contains a module that implements the "Soundex" code as
2+
a PostgreSQL user-defined function. The Soundex system is a method of
3+
matching similar sounding names (or any words) to the same code. It
4+
was initially used by the United States Census in 1880, 1900, and
5+
1910, but it has little use beyond English names (or the English
6+
pronunciation of names), and it is not a linguistic tool.
7+
8+
To install it, first configure the main source tree, then run make;
9+
make install in this directory. Finally, load the function definition
10+
with psql:
11+
12+
psql -f PREFIX/share/contrib/soundex.sql
13+
14+
The following are some usage examples:
115

216
SELECT text_soundex('hello world!');
317

@@ -50,4 +64,3 @@ WHERE text_sx_eq(nm,'john')\g
5064
SELECT *
5165
from s
5266
where s.nm #= 'john';
53-

contrib/soundex/soundex.c

Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,79 @@
1-
/*****************************************************************************/
2-
/* soundex.c */
3-
/*****************************************************************************/
4-
1+
/* $Header: /cvsroot/pgsql/contrib/soundex/Attic/soundex.c,v 1.7 2000/10/04 19:25:34 petere Exp $ */
2+
#include "postgres.h"
3+
#include "fmgr.h"
4+
#include "utils/builtins.h"
55
#include <ctype.h>
66
#include <string.h>
77
#include <stdio.h>
88

9-
#include "postgres.h" /* for char16, etc. */
109

11-
#include "utils/palloc.h" /* for palloc */
10+
Datum
11+
text_soundex(PG_FUNCTION_ARGS);
1212

13-
/* prototypes for soundex functions */
14-
text *text_soundex(text *t);
15-
char *soundex(char *instr, char *outstr);
13+
static void
14+
soundex(const char *instr, char *outstr);
1615

17-
text *
18-
text_soundex(text *t)
19-
{
20-
text *new_t;
16+
#define SOUNDEX_LEN 4
2117

22-
char outstr[6 + 1]; /* max length of soundex is 6 */
23-
char *instr;
2418

25-
/* make a null-terminated string */
26-
instr = palloc(VARSIZE(t) + 1);
27-
memcpy(instr, VARDATA(t), VARSIZE(t) - VARHDRSZ);
28-
instr[VARSIZE(t) - VARHDRSZ] = (char) 0;
19+
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
20+
#define _textout(str) DatumGetPointer(DirectFunctionCall1(textout, PointerGetDatum(str)))
2921

30-
/* load soundex into outstr */
31-
soundex(instr, outstr);
3222

33-
/* Now the outstr contains the soundex of instr */
34-
/* copy outstr to new_t */
35-
new_t = (text *) palloc(strlen(outstr) + VARHDRSZ);
36-
memset(new_t, 0, strlen(outstr) + 1);
37-
VARSIZE(new_t) = strlen(outstr) + VARHDRSZ;
38-
memcpy((void *) VARDATA(new_t),
39-
(void *) outstr,
40-
strlen(outstr));
23+
#ifndef SOUNDEX_TEST
24+
/*
25+
* SQL function: text_soundex(text) returns text
26+
*/
27+
Datum
28+
text_soundex(PG_FUNCTION_ARGS)
29+
{
30+
char outstr[SOUNDEX_LEN + 1];
31+
char *arg;
32+
33+
arg = _textout(PG_GETARG_TEXT_P(0));
4134

42-
/* free instr */
43-
pfree(instr);
35+
soundex(arg, outstr);
4436

45-
return (new_t);
37+
PG_RETURN_TEXT_P(_textin(outstr));
4638
}
39+
#endif /* not SOUNDEX_TEST */
40+
41+
42+
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
43+
static const char *soundex_table = "01230120022455012623010202";
44+
#define soundex_code(letter) soundex_table[toupper(letter) - 'A']
45+
4746

48-
char *
49-
soundex(char *instr, char *outstr)
47+
static void
48+
soundex(const char *instr, char *outstr)
5049
{
51-
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
52-
char *table = "01230120022455012623010202";
53-
int count = 0;
50+
int count;
5451

52+
AssertArg(instr);
53+
AssertArg(outstr);
54+
55+
outstr[SOUNDEX_LEN] = '\0';
56+
57+
/* Skip leading non-alphabetic characters */
5558
while (!isalpha(instr[0]) && instr[0])
5659
++instr;
5760

61+
/* No string left */
5862
if (!instr[0])
59-
{ /* Hey! Where'd the string go? */
60-
outstr[0] = (char) 0;
61-
return outstr;
62-
}
63-
64-
if (toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H')
6563
{
66-
instr[0] = 'F';
67-
instr[1] = 'A';
64+
outstr[0] = (char) 0;
65+
return;
6866
}
6967

68+
/* Take the first letter as is */
7069
*outstr++ = (char) toupper(*instr++);
7170

72-
while (*instr && count < 5)
71+
count = 1;
72+
while (*instr && count < SOUNDEX_LEN)
7373
{
74-
if (isalpha(*instr) && *instr != *(instr - 1))
74+
if (isalpha(*instr) && soundex_code(*instr) != soundex_code(*(instr - 1)))
7575
{
76-
*outstr = table[toupper(instr[0]) - 'A'];
76+
*outstr = soundex_code(instr[0]);
7777
if (*outstr != '0')
7878
{
7979
++outstr;
@@ -83,6 +83,33 @@ soundex(char *instr, char *outstr)
8383
++instr;
8484
}
8585

86-
*outstr = '\0';
87-
return (outstr);
86+
/* Fill with 0's */
87+
while (count < SOUNDEX_LEN)
88+
{
89+
*outstr = '0';
90+
++outstr;
91+
++count;
92+
}
93+
}
94+
95+
96+
97+
#ifdef SOUNDEX_TEST
98+
int
99+
main (int argc, char *argv[])
100+
{
101+
if (argc < 2)
102+
{
103+
fprintf(stderr, "usage: %s string\n", argv[0]);
104+
return 1;
105+
}
106+
else
107+
{
108+
char output[SOUNDEX_LEN + 1];
109+
110+
soundex(argv[1], output);
111+
printf("soundex(%s) = %s\n", argv[1], output);
112+
return 0;
113+
}
88114
}
115+
#endif /* SOUNDEX_TEST */

contrib/soundex/soundex.sql.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
21
CREATE FUNCTION text_soundex(text) RETURNS text
3-
AS 'MODULE_PATHNAME' LANGUAGE 'c';
2+
AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'newC';
43

4+
CREATE FUNCTION soundex(text) RETURNS text
5+
AS '@MODULE_FILENAME@', 'text_soundex' LANGUAGE 'newC';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy