PostgreSQL Source Code git master
dict_xsyn.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "catalog/pg_collation_d.h"
#include "commands/defrem.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
#include "utils/formatting.h"
Include dependency graph for dict_xsyn.c:

Go to the source code of this file.

Data Structures

struct  Syn
 
struct  DictSyn
 

Functions

 PG_FUNCTION_INFO_V1 (dxsyn_init)
 
 PG_FUNCTION_INFO_V1 (dxsyn_lexize)
 
static char * find_word (char *in, char **end)
 
static int compare_syn (const void *a, const void *b)
 
static void read_dictionary (DictSyn *d, const char *filename)
 
Datum dxsyn_init (PG_FUNCTION_ARGS)
 
Datum dxsyn_lexize (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

◆ compare_syn()

static int compare_syn ( const void *  a,
const void *  b 
)
static

Definition at line 69 of file dict_xsyn.c.

70{
71 return strcmp(((const Syn *) a)->key, ((const Syn *) b)->key);
72}
int b
Definition: isn.c:69
int a
Definition: isn.c:68
Definition: dict_xsyn.c:26

References a, b, and sort-test::key.

Referenced by dxsyn_lexize(), and read_dictionary().

◆ dxsyn_init()

Datum dxsyn_init ( PG_FUNCTION_ARGS  )

Definition at line 143 of file dict_xsyn.c.

144{
145 List *dictoptions = (List *) PG_GETARG_POINTER(0);
146 DictSyn *d;
147 ListCell *l;
148 char *filename = NULL;
149
150 d = (DictSyn *) palloc0(sizeof(DictSyn));
151 d->len = 0;
152 d->syn = NULL;
153 d->matchorig = true;
154 d->keeporig = true;
155 d->matchsynonyms = false;
156 d->keepsynonyms = true;
157
158 foreach(l, dictoptions)
159 {
160 DefElem *defel = (DefElem *) lfirst(l);
161
162 if (strcmp(defel->defname, "matchorig") == 0)
163 {
164 d->matchorig = defGetBoolean(defel);
165 }
166 else if (strcmp(defel->defname, "keeporig") == 0)
167 {
168 d->keeporig = defGetBoolean(defel);
169 }
170 else if (strcmp(defel->defname, "matchsynonyms") == 0)
171 {
172 d->matchsynonyms = defGetBoolean(defel);
173 }
174 else if (strcmp(defel->defname, "keepsynonyms") == 0)
175 {
176 d->keepsynonyms = defGetBoolean(defel);
177 }
178 else if (strcmp(defel->defname, "rules") == 0)
179 {
180 /* we can't read the rules before parsing all options! */
181 filename = defGetString(defel);
182 }
183 else
184 {
186 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
187 errmsg("unrecognized xsyn parameter: \"%s\"",
188 defel->defname)));
189 }
190 }
191
192 if (filename)
194
196}
char * defGetString(DefElem *def)
Definition: define.c:35
bool defGetBoolean(DefElem *def)
Definition: define.c:94
static void read_dictionary(DictSyn *d, const char *filename)
Definition: dict_xsyn.c:75
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
void * palloc0(Size size)
Definition: mcxt.c:1347
static char * filename
Definition: pg_dumpall.c:119
#define lfirst(lc)
Definition: pg_list.h:172
char * defname
Definition: parsenodes.h:826
bool matchsynonyms
Definition: dict_xsyn.c:39
Syn * syn
Definition: dict_xsyn.c:35
bool keeporig
Definition: dict_xsyn.c:38
int len
Definition: dict_xsyn.c:34
bool matchorig
Definition: dict_xsyn.c:37
bool keepsynonyms
Definition: dict_xsyn.c:40
Definition: pg_list.h:54

References defGetBoolean(), defGetString(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, filename, DictSyn::keeporig, DictSyn::keepsynonyms, DictSyn::len, lfirst, DictSyn::matchorig, DictSyn::matchsynonyms, palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, read_dictionary(), and DictSyn::syn.

◆ dxsyn_lexize()

Datum dxsyn_lexize ( PG_FUNCTION_ARGS  )

Definition at line 199 of file dict_xsyn.c.

200{
202 char *in = (char *) PG_GETARG_POINTER(1);
203 int length = PG_GETARG_INT32(2);
204 Syn word;
205 Syn *found;
206 TSLexeme *res = NULL;
207
208 if (!length || d->len == 0)
209 PG_RETURN_POINTER(NULL);
210
211 /* Create search pattern */
212 {
213 char *temp = pnstrdup(in, length);
214
215 word.key = str_tolower(temp, length, DEFAULT_COLLATION_OID);
216 pfree(temp);
217 word.value = NULL;
218 }
219
220 /* Look for matching syn */
221 found = (Syn *) bsearch(&word, d->syn, d->len, sizeof(Syn), compare_syn);
222 pfree(word.key);
223
224 if (!found)
225 PG_RETURN_POINTER(NULL);
226
227 /* Parse string of synonyms and return array of words */
228 {
229 char *value = found->value;
230 char *syn;
231 char *pos;
232 char *end;
233 int nsyns = 0;
234
235 res = palloc(sizeof(TSLexeme));
236
237 pos = value;
238 while ((syn = find_word(pos, &end)) != NULL)
239 {
240 res = repalloc(res, sizeof(TSLexeme) * (nsyns + 2));
241
242 /* The first word is output only if keeporig=true */
243 if (pos != value || d->keeporig)
244 {
245 res[nsyns].lexeme = pnstrdup(syn, end - syn);
246 res[nsyns].nvariant = 0;
247 res[nsyns].flags = 0;
248 nsyns++;
249 }
250
251 pos = end;
252
253 /* Stop if we are not to output the synonyms */
254 if (!d->keepsynonyms)
255 break;
256 }
257 res[nsyns].lexeme = NULL;
258 }
259
261}
static int compare_syn(const void *a, const void *b)
Definition: dict_xsyn.c:69
static char * find_word(char *in, char **end)
Definition: dict_xsyn.c:48
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
char * str_tolower(const char *buff, size_t nbytes, Oid collid)
Definition: formatting.c:1637
static struct @162 value
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1707
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1476
char * value
Definition: dict_xsyn.c:28

References compare_syn(), find_word(), DictSyn::keeporig, DictSyn::keepsynonyms, DictSyn::len, palloc(), pfree(), PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_POINTER, pnstrdup(), repalloc(), res, str_tolower(), DictSyn::syn, Syn::value, value, and word().

◆ find_word()

static char * find_word ( char *  in,
char **  end 
)
static

Definition at line 48 of file dict_xsyn.c.

49{
50 char *start;
51
52 *end = NULL;
53 while (*in && isspace((unsigned char) *in))
54 in += pg_mblen(in);
55
56 if (!*in || *in == '#')
57 return NULL;
58 start = in;
59
60 while (*in && !isspace((unsigned char) *in))
61 in += pg_mblen(in);
62
63 *end = in;
64
65 return start;
66}
return str start
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023

References pg_mblen(), and start.

Referenced by dxsyn_lexize(), and read_dictionary().

◆ PG_FUNCTION_INFO_V1() [1/2]

PG_FUNCTION_INFO_V1 ( dxsyn_init  )

◆ PG_FUNCTION_INFO_V1() [2/2]

PG_FUNCTION_INFO_V1 ( dxsyn_lexize  )

◆ read_dictionary()

static void read_dictionary ( DictSyn d,
const char *  filename 
)
static

Definition at line 75 of file dict_xsyn.c.

76{
77 char *real_filename = get_tsearch_config_filename(filename, "rules");
79 char *line;
80 int cur = 0;
81
82 if (!tsearch_readline_begin(&trst, real_filename))
84 (errcode(ERRCODE_CONFIG_FILE_ERROR),
85 errmsg("could not open synonym file \"%s\": %m",
86 real_filename)));
87
88 while ((line = tsearch_readline(&trst)) != NULL)
89 {
90 char *value;
91 char *key;
92 char *pos;
93 char *end;
94
95 if (*line == '\0')
96 continue;
97
98 value = str_tolower(line, strlen(line), DEFAULT_COLLATION_OID);
99 pfree(line);
100
101 pos = value;
102 while ((key = find_word(pos, &end)) != NULL)
103 {
104 /* Enlarge syn structure if full */
105 if (cur == d->len)
106 {
107 d->len = (d->len > 0) ? 2 * d->len : 16;
108 if (d->syn)
109 d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
110 else
111 d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
112 }
113
114 /* Save first word only if we will match it */
115 if (pos != value || d->matchorig)
116 {
117 d->syn[cur].key = pnstrdup(key, end - key);
118 d->syn[cur].value = pstrdup(value);
119
120 cur++;
121 }
122
123 pos = end;
124
125 /* Don't bother scanning synonyms if we will not match them */
126 if (!d->matchsynonyms)
127 break;
128 }
129
130 pfree(value);
131 }
132
134
135 d->len = cur;
136 if (cur > 1)
137 qsort(d->syn, d->len, sizeof(Syn), compare_syn);
138
139 pfree(real_filename);
140}
struct cursor * cur
Definition: ecpg.c:29
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
char * pstrdup(const char *in)
Definition: mcxt.c:1696
#define qsort(a, b, c, d)
Definition: port.h:475
char * key
Definition: dict_xsyn.c:27
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
Definition: ts_locale.c:89
char * tsearch_readline(tsearch_readline_state *stp)
Definition: ts_locale.c:112
void tsearch_readline_end(tsearch_readline_state *stp)
Definition: ts_locale.c:157
char * get_tsearch_config_filename(const char *basename, const char *extension)
Definition: ts_utils.c:34

References compare_syn(), cur, ereport, errcode(), errmsg(), ERROR, filename, find_word(), get_tsearch_config_filename(), if(), Syn::key, sort-test::key, DictSyn::len, DictSyn::matchorig, DictSyn::matchsynonyms, palloc(), pfree(), pnstrdup(), pstrdup(), qsort, repalloc(), str_tolower(), DictSyn::syn, tsearch_readline(), tsearch_readline_begin(), tsearch_readline_end(), Syn::value, and value.

Referenced by dxsyn_init().

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 23 of file dict_xsyn.c.