1 /*-------------------------------------------------------------------------
2 *
3 * dict_simple.c
4 * Simple dictionary: just lowercase and check for stopword
5 *
6 * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
7 *
8 *
9 * IDENTIFICATION
10 * src/backend/tsearch/dict_simple.c
11 *
12 *-------------------------------------------------------------------------
13 */
14 #include "postgres.h"
15
16 #include "commands/defrem.h"
17 #include "tsearch/ts_locale.h"
18 #include "tsearch/ts_utils.h"
19
20
21 typedef struct
22 {
23 StopList stoplist;
24 bool accept;
25 } DictSimple;
26
27
28 Datum
dsimple_init(PG_FUNCTION_ARGS)29 dsimple_init(PG_FUNCTION_ARGS)
30 {
31 List *dictoptions = (List *) PG_GETARG_POINTER(0);
32 DictSimple *d = (DictSimple *) palloc0(sizeof(DictSimple));
33 bool stoploaded = false,
34 acceptloaded = false;
35 ListCell *l;
36
37 d->accept = true; /* default */
38
39 foreach(l, dictoptions)
40 {
41 DefElem *defel = (DefElem *) lfirst(l);
42
43 if (pg_strcasecmp("StopWords", defel->defname) == 0)
44 {
45 if (stoploaded)
46 ereport(ERROR,
47 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
48 errmsg("multiple StopWords parameters")));
49 readstoplist(defGetString(defel), &d->stoplist, lowerstr);
50 stoploaded = true;
51 }
52 else if (pg_strcasecmp("Accept", defel->defname) == 0)
53 {
54 if (acceptloaded)
55 ereport(ERROR,
56 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
57 errmsg("multiple Accept parameters")));
58 d->accept = defGetBoolean(defel);
59 acceptloaded = true;
60 }
61 else
62 {
63 ereport(ERROR,
64 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
65 errmsg("unrecognized simple dictionary parameter: \"%s\"",
66 defel->defname)));
67 }
68 }
69
70 PG_RETURN_POINTER(d);
71 }
72
73 Datum
dsimple_lexize(PG_FUNCTION_ARGS)74 dsimple_lexize(PG_FUNCTION_ARGS)
75 {
76 DictSimple *d = (DictSimple *) PG_GETARG_POINTER(0);
77 char *in = (char *) PG_GETARG_POINTER(1);
78 int32 len = PG_GETARG_INT32(2);
79 char *txt;
80 TSLexeme *res;
81
82 txt = lowerstr_with_len(in, len);
83
84 if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
85 {
86 /* reject as stopword */
87 pfree(txt);
88 res = palloc0(sizeof(TSLexeme) * 2);
89 PG_RETURN_POINTER(res);
90 }
91 else if (d->accept)
92 {
93 /* accept */
94 res = palloc0(sizeof(TSLexeme) * 2);
95 res[0].lexeme = txt;
96 PG_RETURN_POINTER(res);
97 }
98 else
99 {
100 /* report as unrecognized */
101 pfree(txt);
102 PG_RETURN_POINTER(NULL);
103 }
104 }
105