21 #include "utils/fmgrprotos.h"
28 #define DT_USEASIS 0x1000
109 static int ntres = 0;
135 if (nres + 1 >= ntres)
164 #define TR_WAITSUBS 3
172 bool useasis =
false;
178 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
179 errmsg(
"could not open thesaurus file \"%s\": %m",
186 char *beginwrd = NULL;
196 if (
t_iseq(ptr,
'#') || *ptr ==
'\0' ||
211 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
212 errmsg(
"unexpected delimiter")));
242 else if (
t_iseq(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")));
313 if (lexeme && lexeme->
lexeme)
320 newwrds[*nnw].
lexeme = NULL;
336 if (
a == NULL ||
b == NULL)
339 if (
a->idsubst ==
b->idsubst)
341 if (
a->posinsubst ==
b->posinsubst)
343 if (
a->tnvariant ==
b->tnvariant)
346 return (
a->tnvariant >
b->tnvariant) ? 1 : -1;
349 return (
a->posinsubst >
b->posinsubst) ? 1 : -1;
352 return (
a->idsubst >
b->idsubst) ? 1 : -1;
358 if (
a->lexeme == NULL)
360 if (
b->lexeme == NULL)
365 else if (
b->lexeme == NULL)
368 return strcmp(
a->lexeme,
b->lexeme);
415 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
416 errmsg(
"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)",
421 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
422 errmsg(
"thesaurus sample word \"%s\" is a stop word (rule %d)",
425 errhint(
"Use \"?\" to represent a stop word within a sample phrase.")));
437 if (remptr->
nvariant != (remptr - 1)->nvariant)
471 ptrwrds = d->
wrds + 1;
479 newwrds->
entries = ptrwrds->entries;
482 pfree(ptrwrds->entries);
485 pfree(ptrwrds->lexeme);
514 outptr->lexeme = NULL;
517 while (inptr && inptr->lexeme)
538 if (lexized && lexized->
lexeme)
566 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
567 errmsg(
"thesaurus substitute word \"%s\" is a stop word (rule %d)",
568 inptr->lexeme,
i + 1)));
573 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
574 errmsg(
"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)",
575 inptr->lexeme,
i + 1)));
579 pfree(inptr->lexeme);
585 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
586 errmsg(
"thesaurus substitute phrase is empty (rule %d)",
600 char *subdictname = NULL;
601 bool fileloaded =
false;
607 foreach(l, dictoptions)
611 if (strcmp(defel->
defname,
"dictfile") == 0)
615 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
616 errmsg(
"multiple DictFile parameters")));
620 else if (strcmp(defel->
defname,
"dictionary") == 0)
624 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
625 errmsg(
"multiple Dictionary parameters")));
631 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
632 errmsg(
"unrecognized Thesaurus parameter: \"%s\"",
639 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
640 errmsg(
"missing DictFile parameter")));
643 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
644 errmsg(
"missing Dictionary parameter")));
703 for (
i = 0;
i < newn;
i++)
705 while (newin[
i] && newin[
i]->idsubst < ptr->
idsubst)
708 if (newin[
i] == NULL)
727 if (newin[
i] == NULL)
747 for (
i = 0;
i < newn;
i++)
796 bool moreres =
false;
798 if (
PG_NARGS() != 4 || dstate == NULL)
799 elog(
ERROR,
"forbidden call of thesaurus or nested call");
837 for (
i = 0;
i < nlex;
i++)
848 info =
findVariant(info, stored, curpos, infos, nlex);
855 info =
findVariant(NULL, stored, curpos, &infos, 1);
#define Assert(condition)
static void PGresult * res
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 bool matchIdSubst(LexemeInfo *stored, uint32 idsubst)
static void compileTheSubstitute(DictThesaurus *d)
static void thesaurusRead(const char *filename, DictThesaurus *d)
static LexemeInfo * findTheLexeme(DictThesaurus *d, char *lexeme)
static TheLexeme * addCompiledLexeme(TheLexeme *newwrds, int *nnw, int *tnm, TSLexeme *lexeme, LexemeInfo *src, uint16 tnvariant)
static LexemeInfo * findVariant(LexemeInfo *in, LexemeInfo *stored, uint16 curpos, LexemeInfo **newin, int newn)
static TSLexeme * copyTSLexeme(TheSubstitute *ts)
static int cmpLexeme(const TheLexeme *a, const TheLexeme *b)
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 TSLexeme * checkMatch(DictThesaurus *d, LexemeInfo *info, uint16 curpos, bool *moreres)
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)
if(TABLE==NULL||TABLE_index==NULL)
int pg_mblen(const char *mbstr)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
void * repalloc(void *pointer, 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)
int t_isspace(const char *ptr)
void tsearch_readline_end(tsearch_readline_state *stp)
char * get_tsearch_config_filename(const char *basename, const char *extension)