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