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

Generated by: LCOV version 1.13