LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - tsquery_op.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 90.0 % 160 144 16 144
Current Date: 2024-04-14 14:21:10 Functions: 95.0 % 20 19 1 19
Baseline: 16@8cea358b128 Branches: 54.7 % 106 58 48 58
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 90.0 % 160 144 16 144
Function coverage date bins:
(240..) days: 95.0 % 20 19 1 19
Branch coverage date bins:
(240..) days: 54.7 % 106 58 48 58

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

Generated by: LCOV version 2.1-beta2-3-g6141622