#include "postgres.h"#include <ctype.h>#include "commands/defrem.h"#include "tsearch/ts_locale.h"#include "tsearch/ts_utils.h"
Go to the source code of this file.
Data Structures | |
| struct | Syn |
| struct | DictSyn |
Functions | |
| PG_FUNCTION_INFO_V1 (dxsyn_init) | |
| Datum | dxsyn_init (PG_FUNCTION_ARGS) |
| PG_FUNCTION_INFO_V1 (dxsyn_lexize) | |
| Datum | dxsyn_lexize (PG_FUNCTION_ARGS) |
| 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) |
Variables | |
| PG_MODULE_MAGIC | |
| static int compare_syn | ( | const void * | a, | |
| const void * | b | |||
| ) | [static] |
Definition at line 70 of file dict_xsyn.c.
Referenced by read_dictionary().
| Datum dxsyn_init | ( | PG_FUNCTION_ARGS | ) |
Definition at line 144 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, palloc0(), PG_GETARG_POINTER, PG_RETURN_POINTER, pg_strcasecmp(), read_dictionary(), and DictSyn::syn.
{
List *dictoptions = (List *) PG_GETARG_POINTER(0);
DictSyn *d;
ListCell *l;
char *filename = NULL;
d = (DictSyn *) palloc0(sizeof(DictSyn));
d->len = 0;
d->syn = NULL;
d->matchorig = true;
d->keeporig = true;
d->matchsynonyms = false;
d->keepsynonyms = true;
foreach(l, dictoptions)
{
DefElem *defel = (DefElem *) lfirst(l);
if (pg_strcasecmp(defel->defname, "MATCHORIG") == 0)
{
d->matchorig = defGetBoolean(defel);
}
else if (pg_strcasecmp(defel->defname, "KEEPORIG") == 0)
{
d->keeporig = defGetBoolean(defel);
}
else if (pg_strcasecmp(defel->defname, "MATCHSYNONYMS") == 0)
{
d->matchsynonyms = defGetBoolean(defel);
}
else if (pg_strcasecmp(defel->defname, "KEEPSYNONYMS") == 0)
{
d->keepsynonyms = defGetBoolean(defel);
}
else if (pg_strcasecmp(defel->defname, "RULES") == 0)
{
/* we can't read the rules before parsing all options! */
filename = defGetString(defel);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized xsyn parameter: \"%s\"",
defel->defname)));
}
}
if (filename)
read_dictionary(d, filename);
PG_RETURN_POINTER(d);
}
| Datum dxsyn_lexize | ( | PG_FUNCTION_ARGS | ) |
Definition at line 200 of file dict_xsyn.c.
References 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, value, and Syn::value.
{
DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
int length = PG_GETARG_INT32(2);
Syn word;
Syn *found;
TSLexeme *res = NULL;
if (!length || d->len == 0)
PG_RETURN_POINTER(NULL);
/* Create search pattern */
{
char *temp = pnstrdup(in, length);
word.key = lowerstr(temp);
pfree(temp);
word.value = NULL;
}
/* Look for matching syn */
found = (Syn *) bsearch(&word, d->syn, d->len, sizeof(Syn), compare_syn);
pfree(word.key);
if (!found)
PG_RETURN_POINTER(NULL);
/* Parse string of synonyms and return array of words */
{
char *value = found->value;
char *syn;
char *pos;
char *end;
int nsyns = 0;
res = palloc(sizeof(TSLexeme));
pos = value;
while ((syn = find_word(pos, &end)) != NULL)
{
res = repalloc(res, sizeof(TSLexeme) * (nsyns + 2));
/* The first word is output only if keeporig=true */
if (pos != value || d->keeporig)
{
res[nsyns].lexeme = pnstrdup(syn, end - syn);
res[nsyns].nvariant = 0;
res[nsyns].flags = 0;
nsyns++;
}
pos = end;
/* Stop if we are not to output the synonyms */
if (!d->keepsynonyms)
break;
}
res[nsyns].lexeme = NULL;
}
PG_RETURN_POINTER(res);
}
| static char* find_word | ( | char * | in, | |
| char ** | end | |||
| ) | [static] |
Definition at line 49 of file dict_xsyn.c.
References pg_mblen(), and t_isspace.
Referenced by dxsyn_lexize(), and read_dictionary().
| PG_FUNCTION_INFO_V1 | ( | dxsyn_init | ) |
| PG_FUNCTION_INFO_V1 | ( | dxsyn_lexize | ) |
| static void read_dictionary | ( | DictSyn * | d, | |
| char * | filename | |||
| ) | [static] |
Definition at line 76 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().
{
char *real_filename = get_tsearch_config_filename(filename, "rules");
tsearch_readline_state trst;
char *line;
int cur = 0;
if (!tsearch_readline_begin(&trst, real_filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open synonym file \"%s\": %m",
real_filename)));
while ((line = tsearch_readline(&trst)) != NULL)
{
char *value;
char *key;
char *pos;
char *end;
if (*line == '\0')
continue;
value = lowerstr(line);
pfree(line);
pos = value;
while ((key = find_word(pos, &end)) != NULL)
{
/* Enlarge syn structure if full */
if (cur == d->len)
{
d->len = (d->len > 0) ? 2 * d->len : 16;
if (d->syn)
d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
else
d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
}
/* Save first word only if we will match it */
if (pos != value || d->matchorig)
{
d->syn[cur].key = pnstrdup(key, end - key);
d->syn[cur].value = pstrdup(value);
cur++;
}
pos = end;
/* Don't bother scanning synonyms if we will not match them */
if (!d->matchsynonyms)
break;
}
pfree(value);
}
tsearch_readline_end(&trst);
d->len = cur;
if (cur > 1)
qsort(d->syn, d->len, sizeof(Syn), compare_syn);
pfree(real_filename);
}
Definition at line 21 of file dict_xsyn.c.
1.7.1