PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
dict_xsyn.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "commands/defrem.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.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, char *filename)
 
Datum dxsyn_init (PG_FUNCTION_ARGS)
 
Datum dxsyn_lexize (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

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

Definition at line 67 of file dict_xsyn.c.

Referenced by dxsyn_lexize(), and read_dictionary().

68 {
69  return strcmp(((const Syn *) a)->key, ((const Syn *) b)->key);
70 }
Definition: dict_xsyn.c:23
Datum dxsyn_init ( PG_FUNCTION_ARGS  )

Definition at line 141 of file dict_xsyn.c.

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

142 {
143  List *dictoptions = (List *) PG_GETARG_POINTER(0);
144  DictSyn *d;
145  ListCell *l;
146  char *filename = NULL;
147 
148  d = (DictSyn *) palloc0(sizeof(DictSyn));
149  d->len = 0;
150  d->syn = NULL;
151  d->matchorig = true;
152  d->keeporig = true;
153  d->matchsynonyms = false;
154  d->keepsynonyms = true;
155 
156  foreach(l, dictoptions)
157  {
158  DefElem *defel = (DefElem *) lfirst(l);
159 
160  if (pg_strcasecmp(defel->defname, "MATCHORIG") == 0)
161  {
162  d->matchorig = defGetBoolean(defel);
163  }
164  else if (pg_strcasecmp(defel->defname, "KEEPORIG") == 0)
165  {
166  d->keeporig = defGetBoolean(defel);
167  }
168  else if (pg_strcasecmp(defel->defname, "MATCHSYNONYMS") == 0)
169  {
170  d->matchsynonyms = defGetBoolean(defel);
171  }
172  else if (pg_strcasecmp(defel->defname, "KEEPSYNONYMS") == 0)
173  {
174  d->keepsynonyms = defGetBoolean(defel);
175  }
176  else if (pg_strcasecmp(defel->defname, "RULES") == 0)
177  {
178  /* we can't read the rules before parsing all options! */
179  filename = defGetString(defel);
180  }
181  else
182  {
183  ereport(ERROR,
184  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
185  errmsg("unrecognized xsyn parameter: \"%s\"",
186  defel->defname)));
187  }
188  }
189 
190  if (filename)
191  read_dictionary(d, filename);
192 
194 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
static void read_dictionary(DictSyn *d, char *filename)
Definition: dict_xsyn.c:73
int len
Definition: dict_xsyn.c:32
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
bool matchorig
Definition: dict_xsyn.c:35
bool defGetBoolean(DefElem *def)
Definition: define.c:111
#define ERROR
Definition: elog.h:43
char * defGetString(DefElem *def)
Definition: define.c:49
bool matchsynonyms
Definition: dict_xsyn.c:37
#define ereport(elevel, rest)
Definition: elog.h:122
bool keepsynonyms
Definition: dict_xsyn.c:38
void * palloc0(Size size)
Definition: mcxt.c:878
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
bool keeporig
Definition: dict_xsyn.c:36
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * defname
Definition: parsenodes.h:708
Definition: pg_list.h:45
Syn * syn
Definition: dict_xsyn.c:33
Datum dxsyn_lexize ( PG_FUNCTION_ARGS  )

Definition at line 197 of file dict_xsyn.c.

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

198 {
199  DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
200  char *in = (char *) PG_GETARG_POINTER(1);
201  int length = PG_GETARG_INT32(2);
202  Syn word;
203  Syn *found;
204  TSLexeme *res = NULL;
205 
206  if (!length || d->len == 0)
208 
209  /* Create search pattern */
210  {
211  char *temp = pnstrdup(in, length);
212 
213  word.key = lowerstr(temp);
214  pfree(temp);
215  word.value = NULL;
216  }
217 
218  /* Look for matching syn */
219  found = (Syn *) bsearch(&word, d->syn, d->len, sizeof(Syn), compare_syn);
220  pfree(word.key);
221 
222  if (!found)
224 
225  /* Parse string of synonyms and return array of words */
226  {
227  char *value = found->value;
228  char *syn;
229  char *pos;
230  char *end;
231  int nsyns = 0;
232 
233  res = palloc(sizeof(TSLexeme));
234 
235  pos = value;
236  while ((syn = find_word(pos, &end)) != NULL)
237  {
238  res = repalloc(res, sizeof(TSLexeme) * (nsyns + 2));
239 
240  /* The first word is output only if keeporig=true */
241  if (pos != value || d->keeporig)
242  {
243  res[nsyns].lexeme = pnstrdup(syn, end - syn);
244  res[nsyns].nvariant = 0;
245  res[nsyns].flags = 0;
246  nsyns++;
247  }
248 
249  pos = end;
250 
251  /* Stop if we are not to output the synonyms */
252  if (!d->keepsynonyms)
253  break;
254  }
255  res[nsyns].lexeme = NULL;
256  }
257 
258  PG_RETURN_POINTER(res);
259 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
int length(const List *list)
Definition: list.c:1271
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1088
char * value
Definition: dict_xsyn.c:26
int len
Definition: dict_xsyn.c:32
char * key
Definition: dict_xsyn.c:25
Definition: dict_xsyn.c:23
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
char * lowerstr(const char *str)
Definition: ts_locale.c:231
static struct @114 value
void pfree(void *pointer)
Definition: mcxt.c:950
char * lexeme
Definition: ts_public.h:111
static char * find_word(char *in, char **end)
Definition: dict_xsyn.c:46
uint16 nvariant
Definition: ts_public.h:107
uint16 flags
Definition: ts_public.h:109
bool keepsynonyms
Definition: dict_xsyn.c:38
static int compare_syn(const void *a, const void *b)
Definition: dict_xsyn.c:67
#define NULL
Definition: c.h:229
bool keeporig
Definition: dict_xsyn.c:36
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1243
void * palloc(Size size)
Definition: mcxt.c:849
Syn * syn
Definition: dict_xsyn.c:33
static char* find_word ( char *  in,
char **  end 
)
static

Definition at line 46 of file dict_xsyn.c.

References NULL, pg_mblen(), and t_isspace.

Referenced by dxsyn_lexize(), and read_dictionary().

47 {
48  char *start;
49 
50  *end = NULL;
51  while (*in && t_isspace(in))
52  in += pg_mblen(in);
53 
54  if (!*in || *in == '#')
55  return NULL;
56  start = in;
57 
58  while (*in && !t_isspace(in))
59  in += pg_mblen(in);
60 
61  *end = in;
62 
63  return start;
64 }
#define t_isspace(x)
Definition: ts_locale.h:58
#define NULL
Definition: c.h:229
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771
PG_FUNCTION_INFO_V1 ( dxsyn_init  )
PG_FUNCTION_INFO_V1 ( dxsyn_lexize  )
static void read_dictionary ( DictSyn d,
char *  filename 
)
static

Definition at line 73 of file dict_xsyn.c.

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

Referenced by dxsyn_init().

74 {
75  char *real_filename = get_tsearch_config_filename(filename, "rules");
77  char *line;
78  int cur = 0;
79 
80  if (!tsearch_readline_begin(&trst, real_filename))
81  ereport(ERROR,
82  (errcode(ERRCODE_CONFIG_FILE_ERROR),
83  errmsg("could not open synonym file \"%s\": %m",
84  real_filename)));
85 
86  while ((line = tsearch_readline(&trst)) != NULL)
87  {
88  char *value;
89  char *key;
90  char *pos;
91  char *end;
92 
93  if (*line == '\0')
94  continue;
95 
96  value = lowerstr(line);
97  pfree(line);
98 
99  pos = value;
100  while ((key = find_word(pos, &end)) != NULL)
101  {
102  /* Enlarge syn structure if full */
103  if (cur == d->len)
104  {
105  d->len = (d->len > 0) ? 2 * d->len : 16;
106  if (d->syn)
107  d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
108  else
109  d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
110  }
111 
112  /* Save first word only if we will match it */
113  if (pos != value || d->matchorig)
114  {
115  d->syn[cur].key = pnstrdup(key, end - key);
116  d->syn[cur].value = pstrdup(value);
117 
118  cur++;
119  }
120 
121  pos = end;
122 
123  /* Don't bother scanning synonyms if we will not match them */
124  if (!d->matchsynonyms)
125  break;
126  }
127 
128  pfree(value);
129  }
130 
131  tsearch_readline_end(&trst);
132 
133  d->len = cur;
134  if (cur > 1)
135  qsort(d->syn, d->len, sizeof(Syn), compare_syn);
136 
137  pfree(real_filename);
138 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1088
char * value
Definition: dict_xsyn.c:26
int len
Definition: dict_xsyn.c:32
char * pstrdup(const char *in)
Definition: mcxt.c:1077
char * key
Definition: dict_xsyn.c:25
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: dict_xsyn.c:23
char * lowerstr(const char *str)
Definition: ts_locale.c:231
bool matchorig
Definition: dict_xsyn.c:35
static struct @114 value
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
char * get_tsearch_config_filename(const char *basename, const char *extension)
Definition: ts_utils.c:33
bool matchsynonyms
Definition: dict_xsyn.c:37
static char * find_word(char *in, char **end)
Definition: dict_xsyn.c:46
#define ereport(elevel, rest)
Definition: elog.h:122
static int compare_syn(const void *a, const void *b)
Definition: dict_xsyn.c:67
#define NULL
Definition: c.h:229
void tsearch_readline_end(tsearch_readline_state *stp)
Definition: ts_locale.c:153
char * tsearch_readline(tsearch_readline_state *stp)
Definition: ts_locale.c:138
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
Definition: ts_locale.c:116
static char * filename
Definition: pg_dumpall.c:87
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define qsort(a, b, c, d)
Definition: port.h:440
Syn * syn
Definition: dict_xsyn.c:33

Variable Documentation

PG_MODULE_MAGIC

Definition at line 21 of file dict_xsyn.c.