#include "postgres.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 | |
| 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) |
| static int compareSyn | ( | const void * | a, | |
| const void * | b | |||
| ) | [static] |
Definition at line 84 of file dict_synonym.c.
Referenced by dsynonym_init().
| Datum dsynonym_init | ( | PG_FUNCTION_ARGS | ) |
Definition at line 91 of file dict_synonym.c.
References DictSyn::case_sensitive, compareSyn(), cur, defGetBoolean(), defGetString(), DefElem::defname, end, 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().
{
List *dictoptions = (List *) PG_GETARG_POINTER(0);
DictSyn *d;
ListCell *l;
char *filename = NULL;
bool case_sensitive = false;
tsearch_readline_state trst;
char *starti,
*starto,
*end = NULL;
int cur = 0;
char *line = NULL;
uint16 flags = 0;
foreach(l, dictoptions)
{
DefElem *defel = (DefElem *) lfirst(l);
if (pg_strcasecmp("Synonyms", defel->defname) == 0)
filename = defGetString(defel);
else if (pg_strcasecmp("CaseSensitive", defel->defname) == 0)
case_sensitive = defGetBoolean(defel);
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized synonym parameter: \"%s\"",
defel->defname)));
}
if (!filename)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("missing Synonyms parameter")));
filename = get_tsearch_config_filename(filename, "syn");
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open synonym file \"%s\": %m",
filename)));
d = (DictSyn *) palloc0(sizeof(DictSyn));
while ((line = tsearch_readline(&trst)) != NULL)
{
starti = findwrd(line, &end, NULL);
if (!starti)
{
/* Empty line */
goto skipline;
}
if (*end == '\0')
{
/* A line with only one word. Ignore silently. */
goto skipline;
}
*end = '\0';
starto = findwrd(end + 1, &end, &flags);
if (!starto)
{
/* A line with only one word (+whitespace). Ignore silently. */
goto skipline;
}
*end = '\0';
/*
* starti now points to the first word, and starto to the second word
* on the line, with a \0 terminator at the end of both words.
*/
if (cur >= d->len)
{
if (d->len == 0)
{
d->len = 64;
d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
}
else
{
d->len *= 2;
d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
}
}
if (case_sensitive)
{
d->syn[cur].in = pstrdup(starti);
d->syn[cur].out = pstrdup(starto);
}
else
{
d->syn[cur].in = lowerstr(starti);
d->syn[cur].out = lowerstr(starto);
}
d->syn[cur].outlen = strlen(starto);
d->syn[cur].flags = flags;
cur++;
skipline:
pfree(line);
}
tsearch_readline_end(&trst);
d->len = cur;
qsort(d->syn, d->len, sizeof(Syn), compareSyn);
d->case_sensitive = case_sensitive;
PG_RETURN_POINTER(d);
}
| Datum dsynonym_lexize | ( | PG_FUNCTION_ARGS | ) |
Definition at line 209 of file dict_synonym.c.
References DictSyn::case_sensitive, 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.
{
DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
char *in = (char *) PG_GETARG_POINTER(1);
int32 len = PG_GETARG_INT32(2);
Syn key,
*found;
TSLexeme *res;
/* note: d->len test protects against Solaris bsearch-of-no-items bug */
if (len <= 0 || d->len <= 0)
PG_RETURN_POINTER(NULL);
if (d->case_sensitive)
key.in = pnstrdup(in, len);
else
key.in = lowerstr_with_len(in, len);
key.out = NULL;
found = (Syn *) bsearch(&key, d->syn, d->len, sizeof(Syn), compareSyn);
pfree(key.in);
if (!found)
PG_RETURN_POINTER(NULL);
res = palloc0(sizeof(TSLexeme) * 2);
res[0].lexeme = pnstrdup(found->out, found->outlen);
res[0].flags = found->flags;
PG_RETURN_POINTER(res);
}
| static char* findwrd | ( | char * | in, | |
| char ** | end, | |||
| uint16 * | flags | |||
| ) | [static] |
Definition at line 43 of file dict_synonym.c.
References pg_mblen(), t_iseq, and t_isspace.
Referenced by dsynonym_init().
{
char *start;
char *lastchar;
/* Skip leading spaces */
while (*in && t_isspace(in))
in += pg_mblen(in);
/* Return NULL on empty lines */
if (*in == '\0')
{
*end = NULL;
return NULL;
}
lastchar = start = in;
/* Find end of word */
while (*in && !t_isspace(in))
{
lastchar = in;
in += pg_mblen(in);
}
if (in - lastchar == 1 && t_iseq(lastchar, '*') && flags)
{
*flags = TSL_PREFIX;
*end = lastchar;
}
else
{
if (flags)
*flags = 0;
*end = in;
}
return start;
}
1.7.1