21#include "utils/fmgrprotos.h"
28#define DT_USEASIS 0x1000
109 static int ntres = 0;
135 if (nres + 1 >= ntres)
173 bool useasis =
false;
178 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
179 errmsg(
"could not open thesaurus file \"%s\": %m",
186 char *beginwrd = NULL;
193 while (*ptr && isspace((
unsigned char) *ptr))
196 if (
t_iseq(ptr,
'#') || *ptr ==
'\0' ||
211 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
212 errmsg(
"unexpected delimiter")));
215 else if (!isspace((
unsigned char) *ptr))
228 else if (isspace((
unsigned char) *ptr))
242 else if (
t_iseq(ptr,
'\\'))
248 else if (!isspace((
unsigned char) *ptr))
257 if (isspace((
unsigned char) *ptr))
261 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
262 errmsg(
"unexpected end of line or lexeme")));
277 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
278 errmsg(
"unexpected end of line or lexeme")));
286 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
287 errmsg(
"unexpected end of line")));
291 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
292 errmsg(
"too many lexemes in thesaurus entry")));
300 pfree(real_filename);
314 if (lexeme && lexeme->
lexeme)
321 newwrds[*nnw].
lexeme = NULL;
337 if (
a == NULL ||
b == NULL)
340 if (
a->idsubst ==
b->idsubst)
342 if (
a->posinsubst ==
b->posinsubst)
344 if (
a->tnvariant ==
b->tnvariant)
347 return (
a->tnvariant >
b->tnvariant) ? 1 : -1;
350 return (
a->posinsubst >
b->posinsubst) ? 1 : -1;
353 return (
a->idsubst >
b->idsubst) ? 1 : -1;
359 if (
a->lexeme == NULL)
361 if (
b->lexeme == NULL)
366 else if (
b->lexeme == NULL)
369 return strcmp(
a->lexeme,
b->lexeme);
416 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
417 errmsg(
"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)",
422 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
423 errmsg(
"thesaurus sample word \"%s\" is a stop word (rule %d)",
426 errhint(
"Use \"?\" to represent a stop word within a sample phrase.")));
438 if (remptr->
nvariant != (remptr - 1)->nvariant)
472 ptrwrds = d->
wrds + 1;
480 newwrds->
entries = ptrwrds->entries;
483 pfree(ptrwrds->entries);
486 pfree(ptrwrds->lexeme);
515 outptr->lexeme = NULL;
518 while (inptr && inptr->lexeme)
539 if (lexized && lexized->
lexeme)
567 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
568 errmsg(
"thesaurus substitute word \"%s\" is a stop word (rule %d)",
569 inptr->lexeme,
i + 1)));
574 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
575 errmsg(
"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)",
576 inptr->lexeme,
i + 1)));
580 pfree(inptr->lexeme);
586 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
587 errmsg(
"thesaurus substitute phrase is empty (rule %d)",
601 char *subdictname = NULL;
602 bool fileloaded =
false;
608 foreach(l, dictoptions)
612 if (strcmp(defel->
defname,
"dictfile") == 0)
616 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
617 errmsg(
"multiple DictFile parameters")));
621 else if (strcmp(defel->
defname,
"dictionary") == 0)
625 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
626 errmsg(
"multiple Dictionary parameters")));
632 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
633 errmsg(
"unrecognized Thesaurus parameter: \"%s\"",
640 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
641 errmsg(
"missing DictFile parameter")));
644 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
645 errmsg(
"missing Dictionary parameter")));
704 for (
i = 0;
i < newn;
i++)
706 while (newin[
i] && newin[
i]->idsubst < ptr->
idsubst)
709 if (newin[
i] == NULL)
728 if (newin[
i] == NULL)
748 for (
i = 0;
i < newn;
i++)
797 bool moreres =
false;
799 if (
PG_NARGS() != 4 || dstate == NULL)
800 elog(
ERROR,
"forbidden call of thesaurus or nested call");
838 for (
i = 0;
i < nlex;
i++)
849 info =
findVariant(info, stored, curpos, infos, nlex);
856 info =
findVariant(NULL, stored, curpos, &infos, 1);
871 if ((res =
checkMatch(d, info, curpos, &moreres)) != NULL)
char * defGetString(DefElem *def)
Datum thesaurus_lexize(PG_FUNCTION_ARGS)
static void addWrd(DictThesaurus *d, char *b, char *e, uint32 idsubst, uint16 nwrd, uint16 posinsubst, bool useasis)
static LexemeInfo * findTheLexeme(DictThesaurus *d, char *lexeme)
static bool matchIdSubst(LexemeInfo *stored, uint32 idsubst)
static void compileTheSubstitute(DictThesaurus *d)
static void thesaurusRead(const char *filename, DictThesaurus *d)
static TSLexeme * copyTSLexeme(TheSubstitute *ts)
static TSLexeme * checkMatch(DictThesaurus *d, LexemeInfo *info, uint16 curpos, bool *moreres)
static LexemeInfo * findVariant(LexemeInfo *in, LexemeInfo *stored, uint16 curpos, LexemeInfo **newin, int newn)
static int cmpLexeme(const TheLexeme *a, const TheLexeme *b)
static TheLexeme * addCompiledLexeme(TheLexeme *newwrds, int *nnw, int *tnm, TSLexeme *lexeme, LexemeInfo *src, uint16 tnvariant)
static void compileTheLexeme(DictThesaurus *d)
Datum thesaurus_init(PG_FUNCTION_ARGS)
struct LexemeInfo LexemeInfo
static int cmpLexemeInfo(LexemeInfo *a, LexemeInfo *b)
static int cmpLexemeQ(const void *a, const void *b)
static void newLexeme(DictThesaurus *d, char *b, char *e, uint32 idsubst, uint16 posinsubst)
static int cmpTheLexeme(const void *a, const void *b)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_DATUM(n)
#define FunctionCall4(flinfo, arg1, arg2, arg3, arg4)
#define PG_RETURN_POINTER(x)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
int pg_mblen(const char *mbstr)
char * pstrdup(const char *in)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
Oid get_ts_dict_oid(List *names, bool missing_ok)
#define qsort(a, b, c, d)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
static Datum Int32GetDatum(int32 X)
List * stringToQualifiedNameList(const char *string, Node *escontext)
TSDictionaryCacheEntry * subdict
struct LexemeInfo * nextvariant
struct LexemeInfo * nextentry
TSDictionaryCacheEntry * lookup_ts_dictionary_cache(Oid dictId)
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
char * tsearch_readline(tsearch_readline_state *stp)
void tsearch_readline_end(tsearch_readline_state *stp)
char * get_tsearch_config_filename(const char *basename, const char *extension)