Fix oversight in previous error-reporting patch; mustn't pfree path string
[PostgreSQL.git] / src / backend / tsearch / dict_ispell.c
blob45c83174581cb638b27588a275295cc5a8f0d444
1 /*-------------------------------------------------------------------------
3 * dict_ispell.c
4 * Ispell dictionary interface
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
9 * IDENTIFICATION
10 * $PostgreSQL$
12 *-------------------------------------------------------------------------
14 #include "postgres.h"
16 #include "commands/defrem.h"
17 #include "tsearch/dicts/spell.h"
18 #include "tsearch/ts_locale.h"
19 #include "tsearch/ts_public.h"
20 #include "tsearch/ts_utils.h"
21 #include "utils/builtins.h"
22 #include "utils/memutils.h"
25 typedef struct
27 StopList stoplist;
28 IspellDict obj;
29 } DictISpell;
31 Datum
32 dispell_init(PG_FUNCTION_ARGS)
34 List *dictoptions = (List *) PG_GETARG_POINTER(0);
35 DictISpell *d;
36 bool affloaded = false,
37 dictloaded = false,
38 stoploaded = false;
39 ListCell *l;
41 d = (DictISpell *) palloc0(sizeof(DictISpell));
43 foreach(l, dictoptions)
45 DefElem *defel = (DefElem *) lfirst(l);
47 if (pg_strcasecmp(defel->defname, "DictFile") == 0)
49 if (dictloaded)
50 ereport(ERROR,
51 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52 errmsg("multiple DictFile parameters")));
53 NIImportDictionary(&(d->obj),
54 get_tsearch_config_filename(defGetString(defel),
55 "dict"));
56 dictloaded = true;
58 else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
60 if (affloaded)
61 ereport(ERROR,
62 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
63 errmsg("multiple AffFile parameters")));
64 NIImportAffixes(&(d->obj),
65 get_tsearch_config_filename(defGetString(defel),
66 "affix"));
67 affloaded = true;
69 else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
71 if (stoploaded)
72 ereport(ERROR,
73 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
74 errmsg("multiple StopWords parameters")));
75 readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
76 stoploaded = true;
78 else
80 ereport(ERROR,
81 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
82 errmsg("unrecognized Ispell parameter: \"%s\"",
83 defel->defname)));
87 if (affloaded && dictloaded)
89 NISortDictionary(&(d->obj));
90 NISortAffixes(&(d->obj));
92 else if (!affloaded)
94 ereport(ERROR,
95 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
96 errmsg("missing AffFile parameter")));
98 else
100 ereport(ERROR,
101 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
102 errmsg("missing DictFile parameter")));
105 MemoryContextDeleteChildren(CurrentMemoryContext);
107 PG_RETURN_POINTER(d);
110 Datum
111 dispell_lexize(PG_FUNCTION_ARGS)
113 DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
114 char *in = (char *) PG_GETARG_POINTER(1);
115 int32 len = PG_GETARG_INT32(2);
116 char *txt;
117 TSLexeme *res;
118 TSLexeme *ptr,
119 *cptr;
121 if (len <= 0)
122 PG_RETURN_POINTER(NULL);
124 txt = lowerstr_with_len(in, len);
125 res = NINormalizeWord(&(d->obj), txt);
127 if (res == NULL)
128 PG_RETURN_POINTER(NULL);
130 ptr = cptr = res;
131 while (ptr->lexeme)
133 if (searchstoplist(&(d->stoplist), ptr->lexeme))
135 pfree(ptr->lexeme);
136 ptr->lexeme = NULL;
137 ptr++;
139 else
141 memcpy(cptr, ptr, sizeof(TSLexeme));
142 cptr++;
143 ptr++;
146 cptr->lexeme = NULL;
148 PG_RETURN_POINTER(res);