LCOV - differential code coverage report
Current view: top level - src/backend/tsearch - wparser.c (source / functions) Coverage Total Hit UNC LBC UIC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 95.6 % 226 216 2 2 6 3 114 10 89 6 112 1 13
Current Date: 2023-04-08 15:15:32 Functions: 90.5 % 21 19 2 17 2 2 18 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a