LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - tsquery_op.c (source / functions) Coverage Total Hit LBC UIC UBC GIC GNC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 90.0 % 160 144 3 7 6 95 1 48 10 93
Current Date: 2023-04-08 17:13:01 Functions: 95.0 % 20 19 1 19 1 19
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 1 1 1
Legend: Lines: hit not hit (240..) days: 89.9 % 159 143 3 7 6 95 48 10 93
Function coverage date bins:
(240..) days: 47.5 % 40 19 1 19 1 19

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * tsquery_op.c
                                  4                 :  *    Various operations with tsquery
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/backend/utils/adt/tsquery_op.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : 
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include "lib/qunique.h"
                                 18                 : #include "tsearch/ts_utils.h"
                                 19                 : #include "utils/builtins.h"
                                 20                 : #include "varatt.h"
                                 21                 : 
                                 22                 : Datum
 5710 tgl                        23 GIC           9 : tsquery_numnode(PG_FUNCTION_ARGS)
 5710 tgl                        24 ECB             : {
 5710 tgl                        25 GIC           9 :     TSQuery     query = PG_GETARG_TSQUERY(0);
 5710 tgl                        26 CBC           9 :     int         nnode = query->size;
 5710 tgl                        27 ECB             : 
 5710 tgl                        28 GIC           9 :     PG_FREE_IF_COPY(query, 0);
 5710 tgl                        29 CBC           9 :     PG_RETURN_INT32(nnode);
 5710 tgl                        30 ECB             : }
                                 31                 : 
                                 32                 : static QTNode *
 2558 teodor                     33 GIC          54 : join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance)
 5710 tgl                        34 ECB             : {
 5710 tgl                        35 GIC          54 :     QTNode     *res = (QTNode *) palloc0(sizeof(QTNode));
 5710 tgl                        36 ECB             : 
 5710 tgl                        37 GIC          54 :     res->flags |= QTN_NEEDFREE;
 5710 tgl                        38 ECB             : 
 5710 tgl                        39 GIC          54 :     res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
 5693 teodor                     40 CBC          54 :     res->valnode->type = QI_OPR;
 5015 peter_e                    41              54 :     res->valnode->qoperator.oper = operator;
 2558 teodor                     42              54 :     if (operator == OP_PHRASE)
                                 43              24 :         res->valnode->qoperator.distance = distance;
 5710 tgl                        44 ECB             : 
 5710 tgl                        45 GIC          54 :     res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
 5710 tgl                        46 CBC          54 :     res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
                                 47              54 :     res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
                                 48              54 :     res->nchild = 2;
 5710 tgl                        49 ECB             : 
 5710 tgl                        50 GIC          54 :     return res;
 5710 tgl                        51 ECB             : }
                                 52                 : 
                                 53                 : Datum
 5710 tgl                        54 GIC          18 : tsquery_and(PG_FUNCTION_ARGS)
 5710 tgl                        55 ECB             : {
 5710 tgl                        56 GIC          18 :     TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
 5710 tgl                        57 CBC          18 :     TSQuery     b = PG_GETARG_TSQUERY_COPY(1);
 5710 tgl                        58 ECB             :     QTNode     *res;
                                 59                 :     TSQuery     query;
                                 60                 : 
 5710 tgl                        61 GIC          18 :     if (a->size == 0)
 5710 tgl                        62 ECB             :     {
 5710 tgl                        63 UIC           0 :         PG_FREE_IF_COPY(a, 1);
 5710 tgl                        64 UBC           0 :         PG_RETURN_POINTER(b);
 5710 tgl                        65 EUB             :     }
 5710 tgl                        66 GIC          18 :     else if (b->size == 0)
 5710 tgl                        67 ECB             :     {
 5710 tgl                        68 UIC           0 :         PG_FREE_IF_COPY(b, 1);
 5710 tgl                        69 UBC           0 :         PG_RETURN_POINTER(a);
 5710 tgl                        70 EUB             :     }
                                 71                 : 
 2558 teodor                     72 GIC          18 :     res = join_tsqueries(a, b, OP_AND, 0);
 5710 tgl                        73 ECB             : 
 5710 tgl                        74 GIC          18 :     query = QTN2QT(res);
 5710 tgl                        75 ECB             : 
 5710 tgl                        76 GIC          18 :     QTNFree(res);
 5710 tgl                        77 CBC          18 :     PG_FREE_IF_COPY(a, 0);
                                 78              18 :     PG_FREE_IF_COPY(b, 1);
 5710 tgl                        79 ECB             : 
 5710 tgl                        80 GIC          18 :     PG_RETURN_TSQUERY(query);
 5710 tgl                        81 ECB             : }
                                 82                 : 
                                 83                 : Datum
 5710 tgl                        84 GIC          12 : tsquery_or(PG_FUNCTION_ARGS)
 5710 tgl                        85 ECB             : {
 5710 tgl                        86 GIC          12 :     TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
 5710 tgl                        87 CBC          12 :     TSQuery     b = PG_GETARG_TSQUERY_COPY(1);
 5710 tgl                        88 ECB             :     QTNode     *res;
                                 89                 :     TSQuery     query;
                                 90                 : 
 5710 tgl                        91 GIC          12 :     if (a->size == 0)
 5710 tgl                        92 ECB             :     {
 5710 tgl                        93 UIC           0 :         PG_FREE_IF_COPY(a, 1);
 5710 tgl                        94 UBC           0 :         PG_RETURN_POINTER(b);
 5710 tgl                        95 EUB             :     }
 5710 tgl                        96 GIC          12 :     else if (b->size == 0)
 5710 tgl                        97 ECB             :     {
 5710 tgl                        98 UIC           0 :         PG_FREE_IF_COPY(b, 1);
 5710 tgl                        99 UBC           0 :         PG_RETURN_POINTER(a);
 5710 tgl                       100 EUB             :     }
                                101                 : 
 2558 teodor                    102 GIC          12 :     res = join_tsqueries(a, b, OP_OR, 0);
 5710 tgl                       103 ECB             : 
 5710 tgl                       104 GIC          12 :     query = QTN2QT(res);
 5710 tgl                       105 ECB             : 
 5710 tgl                       106 GIC          12 :     QTNFree(res);
 5710 tgl                       107 CBC          12 :     PG_FREE_IF_COPY(a, 0);
                                108              12 :     PG_FREE_IF_COPY(b, 1);
 5710 tgl                       109 ECB             : 
 2300 tgl                       110 GIC          12 :     PG_RETURN_TSQUERY(query);
 5710 tgl                       111 ECB             : }
                                112                 : 
                                113                 : Datum
 2558 teodor                    114 GIC          24 : tsquery_phrase_distance(PG_FUNCTION_ARGS)
 2558 teodor                    115 ECB             : {
 2558 teodor                    116 GIC          24 :     TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
 2558 teodor                    117 CBC          24 :     TSQuery     b = PG_GETARG_TSQUERY_COPY(1);
 2558 teodor                    118 ECB             :     QTNode     *res;
                                119                 :     TSQuery     query;
 2554 peter_e                   120 GIC          24 :     int32       distance = PG_GETARG_INT32(2);
 2558 teodor                    121 ECB             : 
 2558 teodor                    122 GIC          24 :     if (distance < 0 || distance > MAXENTRYPOS)
 2558 teodor                    123 LBC           0 :         ereport(ERROR,
 2558 teodor                    124 EUB             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                125                 :                  errmsg("distance in phrase operator must be an integer value between zero and %d inclusive",
                                126                 :                         MAXENTRYPOS)));
 2558 teodor                    127 GIC          24 :     if (a->size == 0)
 2558 teodor                    128 ECB             :     {
 2558 teodor                    129 UIC           0 :         PG_FREE_IF_COPY(a, 1);
 2558 teodor                    130 UBC           0 :         PG_RETURN_POINTER(b);
 2558 teodor                    131 EUB             :     }
 2558 teodor                    132 GIC          24 :     else if (b->size == 0)
 2558 teodor                    133 ECB             :     {
 2558 teodor                    134 UIC           0 :         PG_FREE_IF_COPY(b, 1);
 2558 teodor                    135 UBC           0 :         PG_RETURN_POINTER(a);
 2558 teodor                    136 EUB             :     }
                                137                 : 
 2558 teodor                    138 GIC          24 :     res = join_tsqueries(a, b, OP_PHRASE, (uint16) distance);
 2558 teodor                    139 ECB             : 
 2558 teodor                    140 GIC          24 :     query = QTN2QT(res);
 2558 teodor                    141 ECB             : 
 2558 teodor                    142 GIC          24 :     QTNFree(res);
 2558 teodor                    143 CBC          24 :     PG_FREE_IF_COPY(a, 0);
                                144              24 :     PG_FREE_IF_COPY(b, 1);
 2558 teodor                    145 ECB             : 
 2300 tgl                       146 GIC          24 :     PG_RETURN_TSQUERY(query);
 2558 teodor                    147 ECB             : }
                                148                 : 
                                149                 : Datum
 2558 teodor                    150 GIC          21 : tsquery_phrase(PG_FUNCTION_ARGS)
 2558 teodor                    151 ECB             : {
  224 peter                     152 GNC          21 :     PG_RETURN_DATUM(DirectFunctionCall3(tsquery_phrase_distance,
 2495 rhaas                     153 ECB             :                                           PG_GETARG_DATUM(0),
                                154                 :                                           PG_GETARG_DATUM(1),
                                155                 :                                           Int32GetDatum(1)));
                                156                 : }
                                157                 : 
                                158                 : Datum
 5710 tgl                       159 GIC           6 : tsquery_not(PG_FUNCTION_ARGS)
 5710 tgl                       160 ECB             : {
 5710 tgl                       161 GIC           6 :     TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
 5710 tgl                       162 ECB             :     QTNode     *res;
                                163                 :     TSQuery     query;
                                164                 : 
 5710 tgl                       165 GIC           6 :     if (a->size == 0)
 5710 tgl                       166 LBC           0 :         PG_RETURN_POINTER(a);
 5710 tgl                       167 EUB             : 
 5710 tgl                       168 GIC           6 :     res = (QTNode *) palloc0(sizeof(QTNode));
 5710 tgl                       169 ECB             : 
 5710 tgl                       170 GIC           6 :     res->flags |= QTN_NEEDFREE;
 5710 tgl                       171 ECB             : 
 5710 tgl                       172 GIC           6 :     res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
 5693 teodor                    173 CBC           6 :     res->valnode->type = QI_OPR;
 5015 peter_e                   174               6 :     res->valnode->qoperator.oper = OP_NOT;
 5710 tgl                       175 ECB             : 
 5710 tgl                       176 GIC           6 :     res->child = (QTNode **) palloc0(sizeof(QTNode *));
 5710 tgl                       177 CBC           6 :     res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
                                178               6 :     res->nchild = 1;
 5710 tgl                       179 ECB             : 
 5710 tgl                       180 GIC           6 :     query = QTN2QT(res);
 5710 tgl                       181 ECB             : 
 5710 tgl                       182 GIC           6 :     QTNFree(res);
 5710 tgl                       183 CBC           6 :     PG_FREE_IF_COPY(a, 0);
 5710 tgl                       184 ECB             : 
 5710 tgl                       185 GIC           6 :     PG_RETURN_POINTER(query);
 5710 tgl                       186 ECB             : }
                                187                 : 
                                188                 : static int
 5710 tgl                       189 GIC         211 : CompareTSQ(TSQuery a, TSQuery b)
 5710 tgl                       190 ECB             : {
 5710 tgl                       191 GIC         211 :     if (a->size != b->size)
 5710 tgl                       192 ECB             :     {
 5710 tgl                       193 GIC          90 :         return (a->size < b->size) ? -1 : 1;
 5710 tgl                       194 ECB             :     }
 5710 tgl                       195 GIC         121 :     else if (VARSIZE(a) != VARSIZE(b))
 5710 tgl                       196 ECB             :     {
 5710 tgl                       197 GIC          81 :         return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
 5710 tgl                       198 ECB             :     }
 4632 tgl                       199 GIC          40 :     else if (a->size != 0)
 5710 tgl                       200 ECB             :     {
 5710 tgl                       201 GIC          40 :         QTNode     *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
 5710 tgl                       202 CBC          40 :         QTNode     *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
                                203              40 :         int         res = QTNodeCompare(an, bn);
 5710 tgl                       204 ECB             : 
 5710 tgl                       205 GIC          40 :         QTNFree(an);
 5710 tgl                       206 CBC          40 :         QTNFree(bn);
 5710 tgl                       207 ECB             : 
 5710 tgl                       208 GIC          40 :         return res;
 5710 tgl                       209 ECB             :     }
                                210                 : 
 5710 tgl                       211 UIC           0 :     return 0;
 5710 tgl                       212 EUB             : }
                                213                 : 
                                214                 : Datum
 5710 tgl                       215 GIC          57 : tsquery_cmp(PG_FUNCTION_ARGS)
 5710 tgl                       216 ECB             : {
 5710 tgl                       217 GIC          57 :     TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
 5710 tgl                       218 CBC          57 :     TSQuery     b = PG_GETARG_TSQUERY_COPY(1);
                                219              57 :     int         res = CompareTSQ(a, b);
 5710 tgl                       220 ECB             : 
 5710 tgl                       221 GIC          57 :     PG_FREE_IF_COPY(a, 0);
 5710 tgl                       222 CBC          57 :     PG_FREE_IF_COPY(b, 1);
 5710 tgl                       223 ECB             : 
 5710 tgl                       224 GIC          57 :     PG_RETURN_INT32(res);
 5710 tgl                       225 ECB             : }
                                226                 : 
                                227                 : #define CMPFUNC( NAME, CONDITION )              \
                                228                 : Datum                                           \
                                229                 : NAME(PG_FUNCTION_ARGS) {                        \
                                230                 :     TSQuery  a = PG_GETARG_TSQUERY_COPY(0);     \
                                231                 :     TSQuery  b = PG_GETARG_TSQUERY_COPY(1);     \
                                232                 :     int res = CompareTSQ(a,b);                  \
                                233                 :                                                 \
                                234                 :     PG_FREE_IF_COPY(a,0);                       \
                                235                 :     PG_FREE_IF_COPY(b,1);                       \
                                236                 :                                                 \
                                237                 :     PG_RETURN_BOOL( CONDITION );                \
                                238                 : }   \
                                239                 : /* keep compiler quiet - no extra ; */          \
                                240                 : extern int no_such_variable
                                241                 : 
 5710 tgl                       242 GIC          39 : CMPFUNC(tsquery_lt, res < 0);
 5710 tgl                       243 CBC          30 : CMPFUNC(tsquery_le, res <= 0);
                                244              25 : CMPFUNC(tsquery_eq, res == 0);
                                245              30 : CMPFUNC(tsquery_ge, res >= 0);
                                246              30 : CMPFUNC(tsquery_gt, res > 0);
 5710 tgl                       247 LBC           0 : CMPFUNC(tsquery_ne, res != 0);
 5710 tgl                       248 EUB             : 
                                249                 : TSQuerySign
 5710 tgl                       250 GIC          90 : makeTSQuerySign(TSQuery a)
 5710 tgl                       251 ECB             : {
                                252                 :     int         i;
 5710 tgl                       253 GIC          90 :     QueryItem  *ptr = GETQUERY(a);
 5710 tgl                       254 CBC          90 :     TSQuerySign sign = 0;
 5710 tgl                       255 ECB             : 
 5710 tgl                       256 GIC         222 :     for (i = 0; i < a->size; i++)
 5710 tgl                       257 ECB             :     {
 5693 teodor                    258 GIC         132 :         if (ptr->type == QI_VAL)
 4632 tgl                       259 CBC         111 :             sign |= ((TSQuerySign) 1) << (((unsigned int) ptr->qoperand.valcrc) % TSQS_SIGLEN);
 5710                           260             132 :         ptr++;
 5710 tgl                       261 ECB             :     }
                                262                 : 
 5710 tgl                       263 GIC          90 :     return sign;
 5710 tgl                       264 ECB             : }
                                265                 : 
                                266                 : static char **
 3086 heikki.linnakangas        267 GIC         162 : collectTSQueryValues(TSQuery a, int *nvalues_p)
 5710 tgl                       268 ECB             : {
 3086 heikki.linnakangas        269 GIC         162 :     QueryItem  *ptr = GETQUERY(a);
 3086 heikki.linnakangas        270 CBC         162 :     char       *operand = GETOPERAND(a);
 3086 heikki.linnakangas        271 ECB             :     char      **values;
 3086 heikki.linnakangas        272 GIC         162 :     int         nvalues = 0;
 3086 heikki.linnakangas        273 ECB             :     int         i;
                                274                 : 
 3086 heikki.linnakangas        275 GIC         162 :     values = (char **) palloc(sizeof(char *) * a->size);
 3086 heikki.linnakangas        276 ECB             : 
 3086 heikki.linnakangas        277 GIC         498 :     for (i = 0; i < a->size; i++)
 5710 tgl                       278 ECB             :     {
 3086 heikki.linnakangas        279 GIC         336 :         if (ptr->type == QI_VAL)
 3086 heikki.linnakangas        280 ECB             :         {
 3086 heikki.linnakangas        281 GIC         249 :             int         len = ptr->qoperand.length;
 3086 heikki.linnakangas        282 ECB             :             char       *val;
                                283                 : 
 3086 heikki.linnakangas        284 GIC         249 :             val = palloc(len + 1);
 3086 heikki.linnakangas        285 CBC         249 :             memcpy(val, operand + ptr->qoperand.distance, len);
                                286             249 :             val[len] = '\0';
 5710 tgl                       287 ECB             : 
 3086 heikki.linnakangas        288 GIC         249 :             values[nvalues++] = val;
 3086 heikki.linnakangas        289 ECB             :         }
 3086 heikki.linnakangas        290 GIC         336 :         ptr++;
 5710 tgl                       291 ECB             :     }
                                292                 : 
 3086 heikki.linnakangas        293 GIC         162 :     *nvalues_p = nvalues;
 3086 heikki.linnakangas        294 CBC         162 :     return values;
 3086 heikki.linnakangas        295 ECB             : }
                                296                 : 
                                297                 : static int
 3086 heikki.linnakangas        298 GIC         198 : cmp_string(const void *a, const void *b)
 3086 heikki.linnakangas        299 ECB             : {
 1475 peter                     300 GIC         198 :     const char *sa = *((char *const *) a);
 1475 peter                     301 CBC         198 :     const char *sb = *((char *const *) b);
 2878 bruce                     302 ECB             : 
 3086 heikki.linnakangas        303 GIC         198 :     return strcmp(sa, sb);
 3086 heikki.linnakangas        304 ECB             : }
                                305                 : 
                                306                 : Datum
 3086 heikki.linnakangas        307 GIC          81 : tsq_mcontains(PG_FUNCTION_ARGS)
 3086 heikki.linnakangas        308 ECB             : {
 3086 heikki.linnakangas        309 GIC          81 :     TSQuery     query = PG_GETARG_TSQUERY(0);
 3086 heikki.linnakangas        310 CBC          81 :     TSQuery     ex = PG_GETARG_TSQUERY(1);
 3086 heikki.linnakangas        311 ECB             :     char      **query_values;
                                312                 :     int         query_nvalues;
                                313                 :     char      **ex_values;
                                314                 :     int         ex_nvalues;
 3086 heikki.linnakangas        315 GIC          81 :     bool        result = true;
 3086 heikki.linnakangas        316 ECB             : 
                                317                 :     /* Extract the query terms into arrays */
 3086 heikki.linnakangas        318 GIC          81 :     query_values = collectTSQueryValues(query, &query_nvalues);
 3086 heikki.linnakangas        319 CBC          81 :     ex_values = collectTSQueryValues(ex, &ex_nvalues);
 3086 heikki.linnakangas        320 ECB             : 
                                321                 :     /* Sort and remove duplicates from both arrays */
 3086 heikki.linnakangas        322 GIC          81 :     qsort(query_values, query_nvalues, sizeof(char *), cmp_string);
 1249 tmunro                    323 CBC          81 :     query_nvalues = qunique(query_values, query_nvalues, sizeof(char *),
 1249 tmunro                    324 ECB             :                             cmp_string);
 3086 heikki.linnakangas        325 GIC          81 :     qsort(ex_values, ex_nvalues, sizeof(char *), cmp_string);
 1249 tmunro                    326 CBC          81 :     ex_nvalues = qunique(ex_values, ex_nvalues, sizeof(char *), cmp_string);
 3086 heikki.linnakangas        327 ECB             : 
 3086 heikki.linnakangas        328 GIC          81 :     if (ex_nvalues > query_nvalues)
 3086 heikki.linnakangas        329 CBC          30 :         result = false;
 3086 heikki.linnakangas        330 ECB             :     else
                                331                 :     {
                                332                 :         int         i;
 2878 bruce                     333 GIC          51 :         int         j = 0;
 3086 heikki.linnakangas        334 ECB             : 
 3086 heikki.linnakangas        335 GIC          69 :         for (i = 0; i < ex_nvalues; i++)
 4632 tgl                       336 ECB             :         {
 3086 heikki.linnakangas        337 GIC         123 :             for (; j < query_nvalues; j++)
 3086 heikki.linnakangas        338 ECB             :             {
 3086 heikki.linnakangas        339 GIC          90 :                 if (strcmp(ex_values[i], query_values[j]) == 0)
 3086 heikki.linnakangas        340 CBC          18 :                     break;
 3086 heikki.linnakangas        341 ECB             :             }
 3086 heikki.linnakangas        342 GIC          51 :             if (j == query_nvalues)
 3086 heikki.linnakangas        343 ECB             :             {
 3086 heikki.linnakangas        344 GIC          33 :                 result = false;
 5710 tgl                       345 CBC          33 :                 break;
 3086 heikki.linnakangas        346 ECB             :             }
                                347                 :         }
                                348                 :     }
                                349                 : 
 3086 heikki.linnakangas        350 GIC          81 :     PG_RETURN_BOOL(result);
 5710 tgl                       351 ECB             : }
                                352                 : 
                                353                 : Datum
 5710 tgl                       354 GIC          39 : tsq_mcontained(PG_FUNCTION_ARGS)
 5710 tgl                       355 ECB             : {
 1165 alvherre                  356 GIC          39 :     PG_RETURN_DATUM(DirectFunctionCall2(tsq_mcontains,
 5710 tgl                       357 ECB             :                                         PG_GETARG_DATUM(1),
                                358                 :                                         PG_GETARG_DATUM(0)));
                                359                 : }
        

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