PostgreSQL Source Code git master
dict_ispell.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * dict_ispell.c
4 * Ispell dictionary interface
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 *
8 *
9 * IDENTIFICATION
10 * src/backend/tsearch/dict_ispell.c
11 *
12 *-------------------------------------------------------------------------
13 */
14#include "postgres.h"
15
16#include "catalog/pg_collation_d.h"
17#include "commands/defrem.h"
18#include "tsearch/dicts/spell.h"
19#include "tsearch/ts_public.h"
20#include "utils/fmgrprotos.h"
21#include "utils/formatting.h"
22
23
24typedef struct
25{
29
32{
33 List *dictoptions = (List *) PG_GETARG_POINTER(0);
34 DictISpell *d;
35 bool affloaded = false,
36 dictloaded = false,
37 stoploaded = false;
38 ListCell *l;
39
40 d = (DictISpell *) palloc0(sizeof(DictISpell));
41
42 NIStartBuild(&(d->obj));
43
44 foreach(l, dictoptions)
45 {
46 DefElem *defel = (DefElem *) lfirst(l);
47
48 if (strcmp(defel->defname, "dictfile") == 0)
49 {
50 char *filename;
51
52 if (dictloaded)
54 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
55 errmsg("multiple DictFile parameters")));
57 "dict");
60 dictloaded = true;
61 }
62 else if (strcmp(defel->defname, "afffile") == 0)
63 {
64 char *filename;
65
66 if (affloaded)
68 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
69 errmsg("multiple AffFile parameters")));
71 "affix");
74 affloaded = true;
75 }
76 else if (strcmp(defel->defname, "stopwords") == 0)
77 {
78 if (stoploaded)
80 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
81 errmsg("multiple StopWords parameters")));
83 stoploaded = true;
84 }
85 else
86 {
88 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
89 errmsg("unrecognized Ispell parameter: \"%s\"",
90 defel->defname)));
91 }
92 }
93
94 if (affloaded && dictloaded)
95 {
96 NISortDictionary(&(d->obj));
97 NISortAffixes(&(d->obj));
98 }
99 else if (!affloaded)
100 {
102 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
103 errmsg("missing AffFile parameter")));
104 }
105 else
106 {
108 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
109 errmsg("missing DictFile parameter")));
110 }
111
112 NIFinishBuild(&(d->obj));
113
115}
116
117Datum
119{
121 char *in = (char *) PG_GETARG_POINTER(1);
123 char *txt;
124 TSLexeme *res;
125 TSLexeme *ptr,
126 *cptr;
127
128 if (len <= 0)
129 PG_RETURN_POINTER(NULL);
130
131 txt = str_tolower(in, len, DEFAULT_COLLATION_OID);
132 res = NINormalizeWord(&(d->obj), txt);
133
134 if (res == NULL)
135 PG_RETURN_POINTER(NULL);
136
137 cptr = res;
138 for (ptr = cptr; ptr->lexeme; ptr++)
139 {
140 if (searchstoplist(&(d->stoplist), ptr->lexeme))
141 {
142 pfree(ptr->lexeme);
143 ptr->lexeme = NULL;
144 }
145 else
146 {
147 if (cptr != ptr)
148 memcpy(cptr, ptr, sizeof(TSLexeme));
149 cptr++;
150 }
151 }
152 cptr->lexeme = NULL;
153
155}
int32_t int32
Definition: c.h:537
char * defGetString(DefElem *def)
Definition: define.c:35
Datum dispell_lexize(PG_FUNCTION_ARGS)
Definition: dict_ispell.c:118
Datum dispell_init(PG_FUNCTION_ARGS)
Definition: dict_ispell.c:31
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
char * str_tolower(const char *buff, size_t nbytes, Oid collid)
Definition: formatting.c:1626
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc0(Size size)
Definition: mcxt.c:1395
const void size_t len
static char * filename
Definition: pg_dumpall.c:120
#define lfirst(lc)
Definition: pg_list.h:172
uint64_t Datum
Definition: postgres.h:70
void NIStartBuild(IspellDict *Conf)
Definition: spell.c:89
void NIFinishBuild(IspellDict *Conf)
Definition: spell.c:104
void NIImportAffixes(IspellDict *Conf, const char *filename)
Definition: spell.c:1429
void NISortDictionary(IspellDict *Conf)
Definition: spell.c:1726
void NISortAffixes(IspellDict *Conf)
Definition: spell.c:1981
void NIImportDictionary(IspellDict *Conf, const char *filename)
Definition: spell.c:519
TSLexeme * NINormalizeWord(IspellDict *Conf, const char *word)
Definition: spell.c:2545
char * defname
Definition: parsenodes.h:843
StopList stoplist
Definition: dict_ispell.c:26
IspellDict obj
Definition: dict_ispell.c:27
Definition: pg_list.h:54
char * lexeme
Definition: ts_public.h:138
void readstoplist(const char *fname, StopList *s, char *(*wordop)(const char *, size_t, Oid))
Definition: ts_utils.c:69
bool searchstoplist(StopList *s, char *key)
Definition: ts_utils.c:141
char * get_tsearch_config_filename(const char *basename, const char *extension)
Definition: ts_utils.c:34