Datum ts_headline_byid_opt(PG_FUNCTION_ARGS) { Oid tsconfig = PG_GETARG_OID(0); text *in = PG_GETARG_TEXT_PP(1); TSQuery query = PG_GETARG_TSQUERY(2); text *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_PP(3) : NULL; HeadlineParsedText prs; List *prsoptions; text *out; TSConfigCacheEntry *cfg; TSParserCacheEntry *prsobj; cfg = lookup_ts_config_cache(tsconfig); prsobj = lookup_ts_parser_cache(cfg->prsId); if (!OidIsValid(prsobj->headlineOid)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("text search parser does not support headline creation"))); memset(&prs, 0, sizeof(HeadlineParsedText)); prs.lenwords = 32; prs.words = (HeadlineWordEntry *) palloc(sizeof(HeadlineWordEntry) * prs.lenwords); hlparsetext(cfg->cfgId, &prs, query, VARDATA_ANY(in), VARSIZE_ANY_EXHDR(in)); if (opt) prsoptions = deserialize_deflist(PointerGetDatum(opt)); else prsoptions = NIL; FunctionCall3(&(prsobj->prsheadline), PointerGetDatum(&prs), PointerGetDatum(prsoptions), PointerGetDatum(query)); out = generateHeadline(&prs); PG_FREE_IF_COPY(in, 1); PG_FREE_IF_COPY(query, 2); if (opt) PG_FREE_IF_COPY(opt, 3); pfree(prs.words); pfree(prs.startsel); pfree(prs.stopsel); PG_RETURN_POINTER(out); }
Datum ts_headline_json_byid_opt(PG_FUNCTION_ARGS) { Oid tsconfig = PG_GETARG_OID(0); text *json = PG_GETARG_TEXT_P(1); TSQuery query = PG_GETARG_TSQUERY(2); text *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL; text *out; JsonTransformStringValuesAction action = (JsonTransformStringValuesAction) headline_json_value; HeadlineParsedText prs; HeadlineJsonState *state = palloc0(sizeof(HeadlineJsonState)); memset(&prs, 0, sizeof(HeadlineParsedText)); prs.lenwords = 32; prs.words = (HeadlineWordEntry *) palloc(sizeof(HeadlineWordEntry) * prs.lenwords); state->prs = &prs; state->cfg = lookup_ts_config_cache(tsconfig); state->prsobj = lookup_ts_parser_cache(state->cfg->prsId); state->query = query; if (opt) state->prsoptions = deserialize_deflist(PointerGetDatum(opt)); else state->prsoptions = NIL; if (!OidIsValid(state->prsobj->headlineOid)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("text search parser does not support headline creation"))); out = transform_json_string_values(json, state, action); PG_FREE_IF_COPY(json, 1); PG_FREE_IF_COPY(query, 2); if (opt) PG_FREE_IF_COPY(opt, 3); pfree(prs.words); if (state->transformed) { pfree(prs.startsel); pfree(prs.stopsel); } PG_RETURN_TEXT_P(out); }
void hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int buflen) { int type, lenlemm; char *lemm = NULL; LexizeData ldata; TSLexeme *norms; ParsedLex *lexs; TSConfigCacheEntry *cfg; TSParserCacheEntry *prsobj; void *prsdata; cfg = lookup_ts_config_cache(cfgId); prsobj = lookup_ts_parser_cache(cfg->prsId); prsdata = (void *) DatumGetPointer(FunctionCall2(&(prsobj->prsstart), PointerGetDatum(buf), Int32GetDatum(buflen))); LexizeInit(&ldata, cfg); do { type = DatumGetInt32(FunctionCall3(&(prsobj->prstoken), PointerGetDatum(prsdata), PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); if (type > 0 && lenlemm >= MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long to be indexed"), errdetail("Words longer than %d characters are ignored.", MAXSTRLEN))); continue; #else ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long to be indexed"), errdetail("Words longer than %d characters are ignored.", MAXSTRLEN))); #endif } LexizeAddLemm(&ldata, type, lemm, lenlemm); do { if ((norms = LexizeExec(&ldata, &lexs)) != NULL) addHLParsedLex(prs, query, lexs, norms); else addHLParsedLex(prs, query, lexs, NULL); } while (norms); } while (type > 0); FunctionCall1(&(prsobj->prsend), PointerGetDatum(prsdata)); }
/* * Parse string and lexize words. * * prs will be filled in. */ void parsetext(Oid cfgId, ParsedText *prs, char *buf, int buflen) { int type, lenlemm; char *lemm = NULL; LexizeData ldata; TSLexeme *norms; TSConfigCacheEntry *cfg; TSParserCacheEntry *prsobj; void *prsdata; cfg = lookup_ts_config_cache(cfgId); prsobj = lookup_ts_parser_cache(cfg->prsId); prsdata = (void *) DatumGetPointer(FunctionCall2(&prsobj->prsstart, PointerGetDatum(buf), Int32GetDatum(buflen))); LexizeInit(&ldata, cfg); do { type = DatumGetInt32(FunctionCall3(&(prsobj->prstoken), PointerGetDatum(prsdata), PointerGetDatum(&lemm), PointerGetDatum(&lenlemm))); if (type > 0 && lenlemm >= MAXSTRLEN) { #ifdef IGNORE_LONGLEXEME ereport(NOTICE, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long to be indexed"), errdetail("Words longer than %d characters are ignored.", MAXSTRLEN))); continue; #else ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("word is too long to be indexed"), errdetail("Words longer than %d characters are ignored.", MAXSTRLEN))); #endif } LexizeAddLemm(&ldata, type, lemm, lenlemm); while ((norms = LexizeExec(&ldata, NULL)) != NULL) { TSLexeme *ptr = norms; prs->pos++; /* set pos */ while (ptr->lexeme) { if (prs->curwords == prs->lenwords) { prs->lenwords *= 2; prs->words = (ParsedWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(ParsedWord)); } if (ptr->flags & TSL_ADDPOS) prs->pos++; prs->words[prs->curwords].len = strlen(ptr->lexeme); prs->words[prs->curwords].word = ptr->lexeme; prs->words[prs->curwords].nvariant = ptr->nvariant; prs->words[prs->curwords].flags = ptr->flags & TSL_PREFIX; prs->words[prs->curwords].alen = 0; prs->words[prs->curwords].pos.pos = LIMITPOS(prs->pos); ptr++; prs->curwords++; } pfree(norms); } } while (type > 0); FunctionCall1(&(prsobj->prsend), PointerGetDatum(prsdata)); }