LCOV - code coverage report
Current view: top level - src/backend/tsearch - wparser.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 215 225 95.6 %
Date: 2024-02-28 05:11:08 Functions: 19 21 90.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * wparser.c
       4             :  *      Standard interface to word parser
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  *
       8             :  *
       9             :  * IDENTIFICATION
      10             :  *    src/backend/tsearch/wparser.c
      11             :  *
      12             :  *-------------------------------------------------------------------------
      13             :  */
      14             : #include "postgres.h"
      15             : 
      16             : #include "catalog/namespace.h"
      17             : #include "catalog/pg_type.h"
      18             : #include "commands/defrem.h"
      19             : #include "common/jsonapi.h"
      20             : #include "funcapi.h"
      21             : #include "tsearch/ts_cache.h"
      22             : #include "tsearch/ts_utils.h"
      23             : #include "utils/builtins.h"
      24             : #include "utils/jsonfuncs.h"
      25             : #include "utils/varlena.h"
      26             : 
      27             : /******sql-level interface******/
      28             : 
      29             : typedef struct
      30             : {
      31             :     int         cur;
      32             :     LexDescr   *list;
      33             : } TSTokenTypeStorage;
      34             : 
      35             : /* state for ts_headline_json_* */
      36             : typedef struct HeadlineJsonState
      37             : {
      38             :     HeadlineParsedText *prs;
      39             :     TSConfigCacheEntry *cfg;
      40             :     TSParserCacheEntry *prsobj;
      41             :     TSQuery     query;
      42             :     List       *prsoptions;
      43             :     bool        transformed;
      44             : } HeadlineJsonState;
      45             : 
      46             : static text *headline_json_value(void *_state, char *elem_value, int elem_len);
      47             : 
      48             : static void
      49         388 : tt_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
      50             :                    Oid prsid)
      51             : {
      52             :     TupleDesc   tupdesc;
      53             :     MemoryContext oldcontext;
      54             :     TSTokenTypeStorage *st;
      55         388 :     TSParserCacheEntry *prs = lookup_ts_parser_cache(prsid);
      56             : 
      57         388 :     if (!OidIsValid(prs->lextypeOid))
      58           0 :         elog(ERROR, "method lextype isn't defined for text search parser %u",
      59             :              prsid);
      60             : 
      61         388 :     oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
      62             : 
      63         388 :     st = (TSTokenTypeStorage *) palloc(sizeof(TSTokenTypeStorage));
      64         388 :     st->cur = 0;
      65             :     /* lextype takes one dummy argument */
      66         388 :     st->list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
      67             :                                                              (Datum) 0));
      68         388 :     funcctx->user_fctx = (void *) st;
      69             : 
      70         388 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
      71           0 :         elog(ERROR, "return type must be a row type");
      72         388 :     funcctx->tuple_desc = tupdesc;
      73         388 :     funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
      74             : 
      75         388 :     MemoryContextSwitchTo(oldcontext);
      76         388 : }
      77             : 
      78             : static Datum
      79        9312 : tt_process_call(FuncCallContext *funcctx)
      80             : {
      81             :     TSTokenTypeStorage *st;
      82             : 
      83        9312 :     st = (TSTokenTypeStorage *) funcctx->user_fctx;
      84        9312 :     if (st->list && st->list[st->cur].lexid)
      85             :     {
      86             :         Datum       result;
      87             :         char       *values[3];
      88             :         char        txtid[16];
      89             :         HeapTuple   tuple;
      90             : 
      91        8924 :         sprintf(txtid, "%d", st->list[st->cur].lexid);
      92        8924 :         values[0] = txtid;
      93        8924 :         values[1] = st->list[st->cur].alias;
      94        8924 :         values[2] = st->list[st->cur].descr;
      95             : 
      96        8924 :         tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
      97        8924 :         result = HeapTupleGetDatum(tuple);
      98             : 
      99        8924 :         pfree(values[1]);
     100        8924 :         pfree(values[2]);
     101        8924 :         st->cur++;
     102        8924 :         return result;
     103             :     }
     104         388 :     return (Datum) 0;
     105             : }
     106             : 
     107             : Datum
     108        9168 : ts_token_type_byid(PG_FUNCTION_ARGS)
     109             : {
     110             :     FuncCallContext *funcctx;
     111             :     Datum       result;
     112             : 
     113        9168 :     if (SRF_IS_FIRSTCALL())
     114             :     {
     115         382 :         funcctx = SRF_FIRSTCALL_INIT();
     116         382 :         tt_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0));
     117             :     }
     118             : 
     119        9168 :     funcctx = SRF_PERCALL_SETUP();
     120             : 
     121        9168 :     if ((result = tt_process_call(funcctx)) != (Datum) 0)
     122        8786 :         SRF_RETURN_NEXT(funcctx, result);
     123         382 :     SRF_RETURN_DONE(funcctx);
     124             : }
     125             : 
     126             : Datum
     127         144 : ts_token_type_byname(PG_FUNCTION_ARGS)
     128             : {
     129             :     FuncCallContext *funcctx;
     130             :     Datum       result;
     131             : 
     132         144 :     if (SRF_IS_FIRSTCALL())
     133             :     {
     134           6 :         text       *prsname = PG_GETARG_TEXT_PP(0);
     135             :         Oid         prsId;
     136             : 
     137           6 :         funcctx = SRF_FIRSTCALL_INIT();
     138           6 :         prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
     139           6 :         tt_setup_firstcall(funcctx, fcinfo, prsId);
     140             :     }
     141             : 
     142         144 :     funcctx = SRF_PERCALL_SETUP();
     143             : 
     144         144 :     if ((result = tt_process_call(funcctx)) != (Datum) 0)
     145         138 :         SRF_RETURN_NEXT(funcctx, result);
     146           6 :     SRF_RETURN_DONE(funcctx);
     147             : }
     148             : 
     149             : typedef struct
     150             : {
     151             :     int         type;
     152             :     char       *lexeme;
     153             : } LexemeEntry;
     154             : 
     155             : typedef struct
     156             : {
     157             :     int         cur;
     158             :     int         len;
     159             :     LexemeEntry *list;
     160             : } PrsStorage;
     161             : 
     162             : 
     163             : static void
     164          44 : prs_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
     165             :                     Oid prsid, text *txt)
     166             : {
     167             :     TupleDesc   tupdesc;
     168             :     MemoryContext oldcontext;
     169             :     PrsStorage *st;
     170          44 :     TSParserCacheEntry *prs = lookup_ts_parser_cache(prsid);
     171          44 :     char       *lex = NULL;
     172          44 :     int         llen = 0,
     173          44 :                 type = 0;
     174             :     void       *prsdata;
     175             : 
     176          44 :     oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
     177             : 
     178          44 :     st = (PrsStorage *) palloc(sizeof(PrsStorage));
     179          44 :     st->cur = 0;
     180          44 :     st->len = 16;
     181          44 :     st->list = (LexemeEntry *) palloc(sizeof(LexemeEntry) * st->len);
     182             : 
     183          44 :     prsdata = (void *) DatumGetPointer(FunctionCall2(&prs->prsstart,
     184             :                                                      PointerGetDatum(VARDATA_ANY(txt)),
     185             :                                                      Int32GetDatum(VARSIZE_ANY_EXHDR(txt))));
     186             : 
     187        1082 :     while ((type = DatumGetInt32(FunctionCall3(&prs->prstoken,
     188             :                                                PointerGetDatum(prsdata),
     189             :                                                PointerGetDatum(&lex),
     190             :                                                PointerGetDatum(&llen)))) != 0)
     191             :     {
     192        1038 :         if (st->cur >= st->len)
     193             :         {
     194          24 :             st->len = 2 * st->len;
     195          24 :             st->list = (LexemeEntry *) repalloc(st->list, sizeof(LexemeEntry) * st->len);
     196             :         }
     197        1038 :         st->list[st->cur].lexeme = palloc(llen + 1);
     198        1038 :         memcpy(st->list[st->cur].lexeme, lex, llen);
     199        1038 :         st->list[st->cur].lexeme[llen] = '\0';
     200        1038 :         st->list[st->cur].type = type;
     201        1038 :         st->cur++;
     202             :     }
     203             : 
     204          44 :     FunctionCall1(&prs->prsend, PointerGetDatum(prsdata));
     205             : 
     206          44 :     st->len = st->cur;
     207          44 :     st->cur = 0;
     208             : 
     209          44 :     funcctx->user_fctx = (void *) st;
     210          44 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
     211           0 :         elog(ERROR, "return type must be a row type");
     212          44 :     funcctx->tuple_desc = tupdesc;
     213          44 :     funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
     214          44 :     MemoryContextSwitchTo(oldcontext);
     215          44 : }
     216             : 
     217             : static Datum
     218        1082 : prs_process_call(FuncCallContext *funcctx)
     219             : {
     220             :     PrsStorage *st;
     221             : 
     222        1082 :     st = (PrsStorage *) funcctx->user_fctx;
     223        1082 :     if (st->cur < st->len)
     224             :     {
     225             :         Datum       result;
     226             :         char       *values[2];
     227             :         char        tid[16];
     228             :         HeapTuple   tuple;
     229             : 
     230        1038 :         values[0] = tid;
     231        1038 :         sprintf(tid, "%d", st->list[st->cur].type);
     232        1038 :         values[1] = st->list[st->cur].lexeme;
     233        1038 :         tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
     234        1038 :         result = HeapTupleGetDatum(tuple);
     235             : 
     236        1038 :         pfree(values[1]);
     237        1038 :         st->cur++;
     238        1038 :         return result;
     239             :     }
     240          44 :     return (Datum) 0;
     241             : }
     242             : 
     243             : Datum
     244         210 : ts_parse_byid(PG_FUNCTION_ARGS)
     245             : {
     246             :     FuncCallContext *funcctx;
     247             :     Datum       result;
     248             : 
     249         210 :     if (SRF_IS_FIRSTCALL())
     250             :     {
     251          36 :         text       *txt = PG_GETARG_TEXT_PP(1);
     252             : 
     253          36 :         funcctx = SRF_FIRSTCALL_INIT();
     254          36 :         prs_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0), txt);
     255          36 :         PG_FREE_IF_COPY(txt, 1);
     256             :     }
     257             : 
     258         210 :     funcctx = SRF_PERCALL_SETUP();
     259             : 
     260         210 :     if ((result = prs_process_call(funcctx)) != (Datum) 0)
     261         174 :         SRF_RETURN_NEXT(funcctx, result);
     262          36 :     SRF_RETURN_DONE(funcctx);
     263             : }
     264             : 
     265             : Datum
     266         872 : ts_parse_byname(PG_FUNCTION_ARGS)
     267             : {
     268             :     FuncCallContext *funcctx;
     269             :     Datum       result;
     270             : 
     271         872 :     if (SRF_IS_FIRSTCALL())
     272             :     {
     273           8 :         text       *prsname = PG_GETARG_TEXT_PP(0);
     274           8 :         text       *txt = PG_GETARG_TEXT_PP(1);
     275             :         Oid         prsId;
     276             : 
     277           8 :         funcctx = SRF_FIRSTCALL_INIT();
     278           8 :         prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
     279           8 :         prs_setup_firstcall(funcctx, fcinfo, prsId, txt);
     280             :     }
     281             : 
     282         872 :     funcctx = SRF_PERCALL_SETUP();
     283             : 
     284         872 :     if ((result = prs_process_call(funcctx)) != (Datum) 0)
     285         864 :         SRF_RETURN_NEXT(funcctx, result);
     286           8 :     SRF_RETURN_DONE(funcctx);
     287             : }
     288             : 
     289             : Datum
     290         146 : ts_headline_byid_opt(PG_FUNCTION_ARGS)
     291             : {
     292         146 :     Oid         tsconfig = PG_GETARG_OID(0);
     293         146 :     text       *in = PG_GETARG_TEXT_PP(1);
     294         146 :     TSQuery     query = PG_GETARG_TSQUERY(2);
     295         146 :     text       *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_PP(3) : NULL;
     296             :     HeadlineParsedText prs;
     297             :     List       *prsoptions;
     298             :     text       *out;
     299             :     TSConfigCacheEntry *cfg;
     300             :     TSParserCacheEntry *prsobj;
     301             : 
     302         146 :     cfg = lookup_ts_config_cache(tsconfig);
     303         146 :     prsobj = lookup_ts_parser_cache(cfg->prsId);
     304             : 
     305         146 :     if (!OidIsValid(prsobj->headlineOid))
     306           0 :         ereport(ERROR,
     307             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     308             :                  errmsg("text search parser does not support headline creation")));
     309             : 
     310         146 :     memset(&prs, 0, sizeof(HeadlineParsedText));
     311         146 :     prs.lenwords = 32;
     312         146 :     prs.words = (HeadlineWordEntry *) palloc(sizeof(HeadlineWordEntry) * prs.lenwords);
     313             : 
     314         292 :     hlparsetext(cfg->cfgId, &prs, query,
     315         292 :                 VARDATA_ANY(in), VARSIZE_ANY_EXHDR(in));
     316             : 
     317         146 :     if (opt)
     318          66 :         prsoptions = deserialize_deflist(PointerGetDatum(opt));
     319             :     else
     320          80 :         prsoptions = NIL;
     321             : 
     322         146 :     FunctionCall3(&(prsobj->prsheadline),
     323             :                   PointerGetDatum(&prs),
     324             :                   PointerGetDatum(prsoptions),
     325             :                   PointerGetDatum(query));
     326             : 
     327         146 :     out = generateHeadline(&prs);
     328             : 
     329         146 :     PG_FREE_IF_COPY(in, 1);
     330         146 :     PG_FREE_IF_COPY(query, 2);
     331         146 :     if (opt)
     332          66 :         PG_FREE_IF_COPY(opt, 3);
     333         146 :     pfree(prs.words);
     334         146 :     pfree(prs.startsel);
     335         146 :     pfree(prs.stopsel);
     336             : 
     337         146 :     PG_RETURN_POINTER(out);
     338             : }
     339             : 
     340             : Datum
     341          80 : ts_headline_byid(PG_FUNCTION_ARGS)
     342             : {
     343          80 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
     344             :                                         PG_GETARG_DATUM(0),
     345             :                                         PG_GETARG_DATUM(1),
     346             :                                         PG_GETARG_DATUM(2)));
     347             : }
     348             : 
     349             : Datum
     350           0 : ts_headline(PG_FUNCTION_ARGS)
     351             : {
     352           0 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
     353             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     354             :                                         PG_GETARG_DATUM(0),
     355             :                                         PG_GETARG_DATUM(1)));
     356             : }
     357             : 
     358             : Datum
     359           0 : ts_headline_opt(PG_FUNCTION_ARGS)
     360             : {
     361           0 :     PG_RETURN_DATUM(DirectFunctionCall4(ts_headline_byid_opt,
     362             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     363             :                                         PG_GETARG_DATUM(0),
     364             :                                         PG_GETARG_DATUM(1),
     365             :                                         PG_GETARG_DATUM(2)));
     366             : }
     367             : 
     368             : Datum
     369          42 : ts_headline_jsonb_byid_opt(PG_FUNCTION_ARGS)
     370             : {
     371          42 :     Oid         tsconfig = PG_GETARG_OID(0);
     372          42 :     Jsonb      *jb = PG_GETARG_JSONB_P(1);
     373          42 :     TSQuery     query = PG_GETARG_TSQUERY(2);
     374          42 :     text       *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
     375             :     Jsonb      *out;
     376          42 :     JsonTransformStringValuesAction action = (JsonTransformStringValuesAction) headline_json_value;
     377             :     HeadlineParsedText prs;
     378          42 :     HeadlineJsonState *state = palloc0(sizeof(HeadlineJsonState));
     379             : 
     380          42 :     memset(&prs, 0, sizeof(HeadlineParsedText));
     381          42 :     prs.lenwords = 32;
     382          42 :     prs.words = (HeadlineWordEntry *) palloc(sizeof(HeadlineWordEntry) * prs.lenwords);
     383             : 
     384          42 :     state->prs = &prs;
     385          42 :     state->cfg = lookup_ts_config_cache(tsconfig);
     386          42 :     state->prsobj = lookup_ts_parser_cache(state->cfg->prsId);
     387          42 :     state->query = query;
     388          42 :     if (opt)
     389          12 :         state->prsoptions = deserialize_deflist(PointerGetDatum(opt));
     390             :     else
     391          30 :         state->prsoptions = NIL;
     392             : 
     393          42 :     if (!OidIsValid(state->prsobj->headlineOid))
     394           0 :         ereport(ERROR,
     395             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     396             :                  errmsg("text search parser does not support headline creation")));
     397             : 
     398          42 :     out = transform_jsonb_string_values(jb, state, action);
     399             : 
     400          42 :     PG_FREE_IF_COPY(jb, 1);
     401          42 :     PG_FREE_IF_COPY(query, 2);
     402          42 :     if (opt)
     403          12 :         PG_FREE_IF_COPY(opt, 3);
     404             : 
     405          42 :     pfree(prs.words);
     406             : 
     407          42 :     if (state->transformed)
     408             :     {
     409          24 :         pfree(prs.startsel);
     410          24 :         pfree(prs.stopsel);
     411             :     }
     412             : 
     413          42 :     PG_RETURN_JSONB_P(out);
     414             : }
     415             : 
     416             : Datum
     417          24 : ts_headline_jsonb(PG_FUNCTION_ARGS)
     418             : {
     419          24 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_jsonb_byid_opt,
     420             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     421             :                                         PG_GETARG_DATUM(0),
     422             :                                         PG_GETARG_DATUM(1)));
     423             : }
     424             : 
     425             : Datum
     426           6 : ts_headline_jsonb_byid(PG_FUNCTION_ARGS)
     427             : {
     428           6 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_jsonb_byid_opt,
     429             :                                         PG_GETARG_DATUM(0),
     430             :                                         PG_GETARG_DATUM(1),
     431             :                                         PG_GETARG_DATUM(2)));
     432             : }
     433             : 
     434             : Datum
     435           6 : ts_headline_jsonb_opt(PG_FUNCTION_ARGS)
     436             : {
     437           6 :     PG_RETURN_DATUM(DirectFunctionCall4(ts_headline_jsonb_byid_opt,
     438             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     439             :                                         PG_GETARG_DATUM(0),
     440             :                                         PG_GETARG_DATUM(1),
     441             :                                         PG_GETARG_DATUM(2)));
     442             : }
     443             : 
     444             : Datum
     445          42 : ts_headline_json_byid_opt(PG_FUNCTION_ARGS)
     446             : {
     447          42 :     Oid         tsconfig = PG_GETARG_OID(0);
     448          42 :     text       *json = PG_GETARG_TEXT_P(1);
     449          42 :     TSQuery     query = PG_GETARG_TSQUERY(2);
     450          42 :     text       *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
     451             :     text       *out;
     452          42 :     JsonTransformStringValuesAction action = (JsonTransformStringValuesAction) headline_json_value;
     453             : 
     454             :     HeadlineParsedText prs;
     455          42 :     HeadlineJsonState *state = palloc0(sizeof(HeadlineJsonState));
     456             : 
     457          42 :     memset(&prs, 0, sizeof(HeadlineParsedText));
     458          42 :     prs.lenwords = 32;
     459          42 :     prs.words = (HeadlineWordEntry *) palloc(sizeof(HeadlineWordEntry) * prs.lenwords);
     460             : 
     461          42 :     state->prs = &prs;
     462          42 :     state->cfg = lookup_ts_config_cache(tsconfig);
     463          42 :     state->prsobj = lookup_ts_parser_cache(state->cfg->prsId);
     464          42 :     state->query = query;
     465          42 :     if (opt)
     466          12 :         state->prsoptions = deserialize_deflist(PointerGetDatum(opt));
     467             :     else
     468          30 :         state->prsoptions = NIL;
     469             : 
     470          42 :     if (!OidIsValid(state->prsobj->headlineOid))
     471           0 :         ereport(ERROR,
     472             :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     473             :                  errmsg("text search parser does not support headline creation")));
     474             : 
     475          42 :     out = transform_json_string_values(json, state, action);
     476             : 
     477          42 :     PG_FREE_IF_COPY(json, 1);
     478          42 :     PG_FREE_IF_COPY(query, 2);
     479          42 :     if (opt)
     480          12 :         PG_FREE_IF_COPY(opt, 3);
     481          42 :     pfree(prs.words);
     482             : 
     483          42 :     if (state->transformed)
     484             :     {
     485          24 :         pfree(prs.startsel);
     486          24 :         pfree(prs.stopsel);
     487             :     }
     488             : 
     489          42 :     PG_RETURN_TEXT_P(out);
     490             : }
     491             : 
     492             : Datum
     493          24 : ts_headline_json(PG_FUNCTION_ARGS)
     494             : {
     495          24 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_json_byid_opt,
     496             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     497             :                                         PG_GETARG_DATUM(0),
     498             :                                         PG_GETARG_DATUM(1)));
     499             : }
     500             : 
     501             : Datum
     502           6 : ts_headline_json_byid(PG_FUNCTION_ARGS)
     503             : {
     504           6 :     PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_json_byid_opt,
     505             :                                         PG_GETARG_DATUM(0),
     506             :                                         PG_GETARG_DATUM(1),
     507             :                                         PG_GETARG_DATUM(2)));
     508             : }
     509             : 
     510             : Datum
     511           6 : ts_headline_json_opt(PG_FUNCTION_ARGS)
     512             : {
     513           6 :     PG_RETURN_DATUM(DirectFunctionCall4(ts_headline_json_byid_opt,
     514             :                                         ObjectIdGetDatum(getTSCurrentConfig(true)),
     515             :                                         PG_GETARG_DATUM(0),
     516             :                                         PG_GETARG_DATUM(1),
     517             :                                         PG_GETARG_DATUM(2)));
     518             : }
     519             : 
     520             : 
     521             : /*
     522             :  * Return headline in text from, generated from a json(b) element
     523             :  */
     524             : static text *
     525         228 : headline_json_value(void *_state, char *elem_value, int elem_len)
     526             : {
     527         228 :     HeadlineJsonState *state = (HeadlineJsonState *) _state;
     528             : 
     529         228 :     HeadlineParsedText *prs = state->prs;
     530         228 :     TSConfigCacheEntry *cfg = state->cfg;
     531         228 :     TSParserCacheEntry *prsobj = state->prsobj;
     532         228 :     TSQuery     query = state->query;
     533         228 :     List       *prsoptions = state->prsoptions;
     534             : 
     535         228 :     prs->curwords = 0;
     536         228 :     hlparsetext(cfg->cfgId, prs, query, elem_value, elem_len);
     537         228 :     FunctionCall3(&(prsobj->prsheadline),
     538             :                   PointerGetDatum(prs),
     539             :                   PointerGetDatum(prsoptions),
     540             :                   PointerGetDatum(query));
     541             : 
     542         228 :     state->transformed = true;
     543         228 :     return generateHeadline(prs);
     544             : }

Generated by: LCOV version 1.14