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

Generated by: LCOV version 1.11