PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
dict_synonym.c File Reference
#include "postgres.h"
#include "commands/defrem.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
Include dependency graph for dict_synonym.c:

Go to the source code of this file.

Data Structures

struct  Syn
 
struct  DictSyn
 

Functions

static char * findwrd (char *in, char **end, uint16 *flags)
 
static int compareSyn (const void *a, const void *b)
 
Datum dsynonym_init (PG_FUNCTION_ARGS)
 
Datum dsynonym_lexize (PG_FUNCTION_ARGS)
 

Function Documentation

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

Definition at line 85 of file dict_synonym.c.

Referenced by dsynonym_init(), and dsynonym_lexize().

86 {
87  return strcmp(((const Syn *) a)->in, ((const Syn *) b)->in);
88 }
Definition: dict_xsyn.c:23
Datum dsynonym_init ( PG_FUNCTION_ARGS  )

Definition at line 92 of file dict_synonym.c.

References DictSyn::case_sensitive, compareSyn(), cur, defGetBoolean(), defGetString(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, filename, findwrd(), Syn::flags, get_tsearch_config_filename(), Syn::in, DictSyn::len, lfirst, lowerstr(), NULL, Syn::out, Syn::outlen, palloc(), palloc0(), pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, pg_strcasecmp(), pstrdup(), qsort, repalloc(), DictSyn::syn, tsearch_readline(), tsearch_readline_begin(), and tsearch_readline_end().

93 {
94  List *dictoptions = (List *) PG_GETARG_POINTER(0);
95  DictSyn *d;
96  ListCell *l;
97  char *filename = NULL;
98  bool case_sensitive = false;
100  char *starti,
101  *starto,
102  *end = NULL;
103  int cur = 0;
104  char *line = NULL;
105  uint16 flags = 0;
106 
107  foreach(l, dictoptions)
108  {
109  DefElem *defel = (DefElem *) lfirst(l);
110 
111  if (pg_strcasecmp("Synonyms", defel->defname) == 0)
112  filename = defGetString(defel);
113  else if (pg_strcasecmp("CaseSensitive", defel->defname) == 0)
114  case_sensitive = defGetBoolean(defel);
115  else
116  ereport(ERROR,
117  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
118  errmsg("unrecognized synonym parameter: \"%s\"",
119  defel->defname)));
120  }
121 
122  if (!filename)
123  ereport(ERROR,
124  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
125  errmsg("missing Synonyms parameter")));
126 
127  filename = get_tsearch_config_filename(filename, "syn");
128 
129  if (!tsearch_readline_begin(&trst, filename))
130  ereport(ERROR,
131  (errcode(ERRCODE_CONFIG_FILE_ERROR),
132  errmsg("could not open synonym file \"%s\": %m",
133  filename)));
134 
135  d = (DictSyn *) palloc0(sizeof(DictSyn));
136 
137  while ((line = tsearch_readline(&trst)) != NULL)
138  {
139  starti = findwrd(line, &end, NULL);
140  if (!starti)
141  {
142  /* Empty line */
143  goto skipline;
144  }
145  if (*end == '\0')
146  {
147  /* A line with only one word. Ignore silently. */
148  goto skipline;
149  }
150  *end = '\0';
151 
152  starto = findwrd(end + 1, &end, &flags);
153  if (!starto)
154  {
155  /* A line with only one word (+whitespace). Ignore silently. */
156  goto skipline;
157  }
158  *end = '\0';
159 
160  /*
161  * starti now points to the first word, and starto to the second word
162  * on the line, with a \0 terminator at the end of both words.
163  */
164 
165  if (cur >= d->len)
166  {
167  if (d->len == 0)
168  {
169  d->len = 64;
170  d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
171  }
172  else
173  {
174  d->len *= 2;
175  d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
176  }
177  }
178 
179  if (case_sensitive)
180  {
181  d->syn[cur].in = pstrdup(starti);
182  d->syn[cur].out = pstrdup(starto);
183  }
184  else
185  {
186  d->syn[cur].in = lowerstr(starti);
187  d->syn[cur].out = lowerstr(starto);
188  }
189 
190  d->syn[cur].outlen = strlen(starto);
191  d->syn[cur].flags = flags;
192 
193  cur++;
194 
195 skipline:
196  pfree(line);
197  }
198 
199  tsearch_readline_end(&trst);
200 
201  d->len = cur;
202  qsort(d->syn, d->len, sizeof(Syn), compareSyn);
203 
204  d->case_sensitive = case_sensitive;
205 
207 }
uint16 flags
Definition: dict_synonym.c:26
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
static char * findwrd(char *in, char **end, uint16 *flags)
Definition: dict_synonym.c:44
int len
Definition: dict_xsyn.c:32
char * pstrdup(const char *in)
Definition: mcxt.c:1077
struct cursor * cur
Definition: ecpg.c:28
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: dict_xsyn.c:23
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
char * lowerstr(const char *str)
Definition: ts_locale.c:231
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
bool case_sensitive
Definition: dict_synonym.c:33
bool defGetBoolean(DefElem *def)
Definition: define.c:111
unsigned short uint16
Definition: c.h:267
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
char * defGetString(DefElem *def)
Definition: define.c:49
#define ereport(elevel, rest)
Definition: elog.h:122
int outlen
Definition: dict_synonym.c:25
void * palloc0(Size size)
Definition: mcxt.c:878
static int compareSyn(const void *a, const void *b)
Definition: dict_synonym.c:85
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
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
char * out
Definition: dict_synonym.c:24
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
char * defname
Definition: parsenodes.h:708
char * in
Definition: dict_synonym.c:23
#define qsort(a, b, c, d)
Definition: port.h:440
Definition: pg_list.h:45
Syn * syn
Definition: dict_xsyn.c:33
Datum dsynonym_lexize ( PG_FUNCTION_ARGS  )

Definition at line 210 of file dict_synonym.c.

References DictSyn::case_sensitive, compareSyn(), Syn::flags, TSLexeme::flags, Syn::in, DictSyn::len, TSLexeme::lexeme, lowerstr_with_len(), NULL, Syn::out, Syn::outlen, palloc0(), pfree(), PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_POINTER, pnstrdup(), and DictSyn::syn.

211 {
212  DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
213  char *in = (char *) PG_GETARG_POINTER(1);
214  int32 len = PG_GETARG_INT32(2);
215  Syn key,
216  *found;
217  TSLexeme *res;
218 
219  /* note: d->len test protects against Solaris bsearch-of-no-items bug */
220  if (len <= 0 || d->len <= 0)
222 
223  if (d->case_sensitive)
224  key.in = pnstrdup(in, len);
225  else
226  key.in = lowerstr_with_len(in, len);
227 
228  key.out = NULL;
229 
230  found = (Syn *) bsearch(&key, d->syn, d->len, sizeof(Syn), compareSyn);
231  pfree(key.in);
232 
233  if (!found)
235 
236  res = palloc0(sizeof(TSLexeme) * 2);
237  res[0].lexeme = pnstrdup(found->out, found->outlen);
238  res[0].flags = found->flags;
239 
240  PG_RETURN_POINTER(res);
241 }
uint16 flags
Definition: dict_synonym.c:26
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1088
int len
Definition: dict_xsyn.c:32
char * lowerstr_with_len(const char *str, int len)
Definition: ts_locale.c:244
Definition: dict_xsyn.c:23
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
bool case_sensitive
Definition: dict_synonym.c:33
signed int int32
Definition: c.h:256
void pfree(void *pointer)
Definition: mcxt.c:950
char * lexeme
Definition: ts_public.h:111
uint16 flags
Definition: ts_public.h:109
int outlen
Definition: dict_synonym.c:25
void * palloc0(Size size)
Definition: mcxt.c:878
static int compareSyn(const void *a, const void *b)
Definition: dict_synonym.c:85
#define NULL
Definition: c.h:229
char * out
Definition: dict_synonym.c:24
char * in
Definition: dict_synonym.c:23
Syn * syn
Definition: dict_xsyn.c:33
static char* findwrd ( char *  in,
char **  end,
uint16 flags 
)
static

Definition at line 44 of file dict_synonym.c.

References NULL, pg_mblen(), t_iseq, t_isspace, and TSL_PREFIX.

Referenced by dsynonym_init().

45 {
46  char *start;
47  char *lastchar;
48 
49  /* Skip leading spaces */
50  while (*in && t_isspace(in))
51  in += pg_mblen(in);
52 
53  /* Return NULL on empty lines */
54  if (*in == '\0')
55  {
56  *end = NULL;
57  return NULL;
58  }
59 
60  lastchar = start = in;
61 
62  /* Find end of word */
63  while (*in && !t_isspace(in))
64  {
65  lastchar = in;
66  in += pg_mblen(in);
67  }
68 
69  if (in - lastchar == 1 && t_iseq(lastchar, '*') && flags)
70  {
71  *flags = TSL_PREFIX;
72  *end = lastchar;
73  }
74  else
75  {
76  if (flags)
77  *flags = 0;
78  *end = in;
79  }
80 
81  return start;
82 }
#define t_isspace(x)
Definition: ts_locale.h:58
#define TSL_PREFIX
Definition: ts_public.h:116
#define t_iseq(x, c)
Definition: ts_locale.h:61
#define NULL
Definition: c.h:229
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771