PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_MODULE_MAGIC_EXT (.name="dict_xsyn",.version=PG_VERSION)
 
 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)
 

Function Documentation

◆ compare_syn()

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

Definition at line 72 of file dict_xsyn.c.

73{
74 return strcmp(((const Syn *) a)->key, ((const Syn *) b)->key);
75}
int b
Definition: isn.c:74
int a
Definition: isn.c:73
Definition: dict_xsyn.c:29

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 146 of file dict_xsyn.c.

147{
148 List *dictoptions = (List *) PG_GETARG_POINTER(0);
149 DictSyn *d;
150 ListCell *l;
151 char *filename = NULL;
152
153 d = (DictSyn *) palloc0(sizeof(DictSyn));
154 d->len = 0;
155 d->syn = NULL;
156 d->matchorig = true;
157 d->keeporig = true;
158 d->matchsynonyms = false;
159 d->keepsynonyms = true;
160
161 foreach(l, dictoptions)
162 {
163 DefElem *defel = (DefElem *) lfirst(l);
164
165 if (strcmp(defel->defname, "matchorig") == 0)
166 {
167 d->matchorig = defGetBoolean(defel);
168 }
169 else if (strcmp(defel->defname, "keeporig") == 0)
170 {
171 d->keeporig = defGetBoolean(defel);
172 }
173 else if (strcmp(defel->defname, "matchsynonyms") == 0)
174 {
175 d->matchsynonyms = defGetBoolean(defel);
176 }
177 else if (strcmp(defel->defname, "keepsynonyms") == 0)
178 {
179 d->keepsynonyms = defGetBoolean(defel);
180 }
181 else if (strcmp(defel->defname, "rules") == 0)
182 {
183 /* we can't read the rules before parsing all options! */
184 filename = defGetString(defel);
185 }
186 else
187 {
189 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
190 errmsg("unrecognized xsyn parameter: \"%s\"",
191 defel->defname)));
192 }
193 }
194
195 if (filename)
197
199}
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:78
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#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:1973
static char * filename
Definition: pg_dumpall.c:123
#define lfirst(lc)
Definition: pg_list.h:172
char * defname
Definition: parsenodes.h:826
bool matchsynonyms
Definition: dict_xsyn.c:42
Syn * syn
Definition: dict_xsyn.c:38
bool keeporig
Definition: dict_xsyn.c:41
int len
Definition: dict_xsyn.c:37
bool matchorig
Definition: dict_xsyn.c:40
bool keepsynonyms
Definition: dict_xsyn.c:43
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 202 of file dict_xsyn.c.

203{
205 char *in = (char *) PG_GETARG_POINTER(1);
206 int length = PG_GETARG_INT32(2);
207 Syn word;
208 Syn *found;
209 TSLexeme *res = NULL;
210
211 if (!length || d->len == 0)
212 PG_RETURN_POINTER(NULL);
213
214 /* Create search pattern */
215 {
216 char *temp = pnstrdup(in, length);
217
218 word.key = str_tolower(temp, length, DEFAULT_COLLATION_OID);
219 pfree(temp);
220 word.value = NULL;
221 }
222
223 /* Look for matching syn */
224 found = (Syn *) bsearch(&word, d->syn, d->len, sizeof(Syn), compare_syn);
225 pfree(word.key);
226
227 if (!found)
228 PG_RETURN_POINTER(NULL);
229
230 /* Parse string of synonyms and return array of words */
231 {
232 char *value = found->value;
233 char *syn;
234 char *pos;
235 char *end;
236 int nsyns = 0;
237
238 res = palloc(sizeof(TSLexeme));
239
240 pos = value;
241 while ((syn = find_word(pos, &end)) != NULL)
242 {
243 res = repalloc(res, sizeof(TSLexeme) * (nsyns + 2));
244
245 /* The first word is output only if keeporig=true */
246 if (pos != value || d->keeporig)
247 {
248 res[nsyns].lexeme = pnstrdup(syn, end - syn);
249 res[nsyns].nvariant = 0;
250 res[nsyns].flags = 0;
251 nsyns++;
252 }
253
254 pos = end;
255
256 /* Stop if we are not to output the synonyms */
257 if (!d->keepsynonyms)
258 break;
259 }
260 res[nsyns].lexeme = NULL;
261 }
262
264}
static int compare_syn(const void *a, const void *b)
Definition: dict_xsyn.c:72
static char * find_word(char *in, char **end)
Definition: dict_xsyn.c:51
#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 @165 value
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2170
void pfree(void *pointer)
Definition: mcxt.c:2150
void * palloc(Size size)
Definition: mcxt.c:1943
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:2336
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1476
char * value
Definition: dict_xsyn.c:31
uint16 nvariant
Definition: ts_public.h:134
char * lexeme
Definition: ts_public.h:138
uint16 flags
Definition: ts_public.h:136

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

◆ find_word()

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

Definition at line 51 of file dict_xsyn.c.

52{
53 char *start;
54
55 *end = NULL;
56 while (*in && isspace((unsigned char) *in))
57 in += pg_mblen(in);
58
59 if (!*in || *in == '#')
60 return NULL;
61 start = in;
62
63 while (*in && !isspace((unsigned char) *in))
64 in += pg_mblen(in);
65
66 *end = in;
67
68 return start;
69}
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  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "dict_xsyn",
version = PG_VERSION 
)

◆ read_dictionary()

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

Definition at line 78 of file dict_xsyn.c.

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