LCOV - code coverage report
Current view: top level - contrib/pg_trgm - trgm_gin.c (source / functions) Hit Total Coverage
Test: test.info Lines: 66 78 84.6 %
Date: 2013-01-22 Functions: 6 8 75.0 %
Branches: 29 44 65.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * contrib/pg_trgm/trgm_gin.c
       3                 :            :  */
       4                 :            : #include "postgres.h"
       5                 :            : 
       6                 :            : #include "trgm.h"
       7                 :            : 
       8                 :            : #include "access/gin.h"
       9                 :            : #include "access/skey.h"
      10                 :            : 
      11                 :            : 
      12                 :          0 : PG_FUNCTION_INFO_V1(gin_extract_trgm);
      13                 :            : Datum           gin_extract_trgm(PG_FUNCTION_ARGS);
      14                 :            : 
      15                 :          3 : PG_FUNCTION_INFO_V1(gin_extract_value_trgm);
      16                 :            : Datum           gin_extract_value_trgm(PG_FUNCTION_ARGS);
      17                 :            : 
      18                 :          3 : PG_FUNCTION_INFO_V1(gin_extract_query_trgm);
      19                 :            : Datum           gin_extract_query_trgm(PG_FUNCTION_ARGS);
      20                 :            : 
      21                 :          3 : PG_FUNCTION_INFO_V1(gin_trgm_consistent);
      22                 :            : Datum           gin_trgm_consistent(PG_FUNCTION_ARGS);
      23                 :            : 
      24                 :            : /*
      25                 :            :  * This function can only be called if a pre-9.1 version of the GIN operator
      26                 :            :  * class definition is present in the catalogs (probably as a consequence
      27                 :            :  * of upgrade-in-place).  Cope.
      28                 :            :  */
      29                 :            : Datum
      30                 :          0 : gin_extract_trgm(PG_FUNCTION_ARGS)
      31                 :            : {
      32         [ #  # ]:          0 :         if (PG_NARGS() == 3)
      33                 :          0 :                 return gin_extract_value_trgm(fcinfo);
      34         [ #  # ]:          0 :         if (PG_NARGS() == 7)
      35                 :          0 :                 return gin_extract_query_trgm(fcinfo);
      36                 :          0 :         elog(ERROR, "unexpected number of arguments to gin_extract_trgm");
      37                 :            :         PG_RETURN_NULL();
      38                 :            : }
      39                 :            : 
      40                 :            : Datum
      41                 :       1002 : gin_extract_value_trgm(PG_FUNCTION_ARGS)
      42                 :            : {
      43                 :       1002 :         text       *val = (text *) PG_GETARG_TEXT_P(0);
      44                 :       1002 :         int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
      45                 :       1002 :         Datum      *entries = NULL;
      46                 :            :         TRGM       *trg;
      47                 :            :         int32           trglen;
      48                 :            : 
      49                 :       1002 :         *nentries = 0;
      50                 :            : 
      51                 :       1002 :         trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
      52                 :       1002 :         trglen = ARRNELEM(trg);
      53                 :            : 
      54         [ +  - ]:       1002 :         if (trglen > 0)
      55                 :            :         {
      56                 :            :                 trgm       *ptr;
      57                 :            :                 int32           i;
      58                 :            : 
      59                 :       1002 :                 *nentries = trglen;
      60                 :       1002 :                 entries = (Datum *) palloc(sizeof(Datum) * trglen);
      61                 :            : 
      62                 :       1002 :                 ptr = GETARR(trg);
      63         [ +  + ]:      13015 :                 for (i = 0; i < trglen; i++)
      64                 :            :                 {
      65                 :      12013 :                         int32           item = trgm2int(ptr);
      66                 :            : 
      67                 :      12013 :                         entries[i] = Int32GetDatum(item);
      68                 :      12013 :                         ptr++;
      69                 :            :                 }
      70                 :            :         }
      71                 :            : 
      72                 :       1002 :         PG_RETURN_POINTER(entries);
      73                 :            : }
      74                 :            : 
      75                 :            : Datum
      76                 :         32 : gin_extract_query_trgm(PG_FUNCTION_ARGS)
      77                 :            : {
      78                 :         32 :         text       *val = (text *) PG_GETARG_TEXT_P(0);
      79                 :         32 :         int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
      80                 :         32 :         StrategyNumber strategy = PG_GETARG_UINT16(2);
      81                 :            : 
      82                 :            :         /* bool   **pmatch = (bool **) PG_GETARG_POINTER(3); */
      83                 :         32 :         Pointer   **extra_data = (Pointer **) PG_GETARG_POINTER(4);
      84                 :            :         /* bool   **nullFlags = (bool **) PG_GETARG_POINTER(5); */
      85                 :         32 :         int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
      86                 :         32 :         Datum      *entries = NULL;
      87                 :            :         TRGM       *trg;
      88                 :            :         int32           trglen;
      89                 :            :         trgm       *ptr;
      90                 :            :         int32           i;
      91                 :            :         PackedGraph     *graph;
      92                 :            : 
      93   [ +  +  +  - ]:         32 :         switch (strategy)
      94                 :            :         {
      95                 :            :                 case SimilarityStrategyNumber:
      96                 :          6 :                         trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
      97                 :          6 :                         break;
      98                 :            :                 case ILikeStrategyNumber:
      99                 :            : #ifndef IGNORECASE
     100                 :            :                         elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
     101                 :            : #endif
     102                 :            :                         /* FALL THRU */
     103                 :            :                 case LikeStrategyNumber:
     104                 :            : 
     105                 :            :                         /*
     106                 :            :                          * For wildcard search we extract all the trigrams that every
     107                 :            :                          * potentially-matching string must include.
     108                 :            :                          */
     109                 :         12 :                         trg = generate_wildcard_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
     110                 :         12 :                         break;
     111                 :            :                 case RegExpStrategyNumberICase:
     112                 :            : #ifndef IGNORECASE
     113                 :            :                         elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
     114                 :            : #endif
     115                 :            :                         /* FALL THRU */
     116                 :            :                 case RegExpStrategyNumber:
     117                 :         14 :                         trg = createTrgmCNFA(val, fcinfo->flinfo->fn_mcxt, &graph);
     118 [ +  - ][ +  - ]:         14 :                         if (trg && ARRNELEM(trg) > 0)
     119                 :            :                         {
     120                 :            :                                 /*
     121                 :            :                                  * Successful regex processing: store CNFA-like graph as an
     122                 :            :                                  * extra_data.
     123                 :            :                                  */
     124                 :         14 :                                 *extra_data = (Pointer *) palloc0(sizeof(Pointer) *
     125                 :            :                                                                                                                                 ARRNELEM(trg));
     126         [ +  + ]:        328 :                                 for (i = 0; i < ARRNELEM(trg); i++)
     127                 :        314 :                                         (*extra_data)[i] = (Pointer) graph;
     128                 :            :                         }
     129                 :            :                         else
     130                 :            :                         {
     131                 :            :                                 /* No result: have to do full index scan. */
     132                 :          0 :                                 *nentries = 0;
     133                 :          0 :                                 *searchMode = GIN_SEARCH_MODE_ALL;
     134                 :            :                                 PG_RETURN_POINTER(entries);
     135                 :            :                         }
     136                 :            :                         break;
     137                 :            :                 default:
     138                 :          0 :                         elog(ERROR, "unrecognized strategy number: %d", strategy);
     139                 :            :                         trg = NULL;                     /* keep compiler quiet */
     140                 :            :                         break;
     141                 :            :         }
     142                 :            : 
     143                 :         32 :         trglen = ARRNELEM(trg);
     144                 :         32 :         *nentries = trglen;
     145                 :            : 
     146         [ +  - ]:         32 :         if (trglen > 0)
     147                 :            :         {
     148                 :         32 :                 entries = (Datum *) palloc(sizeof(Datum) * trglen);
     149                 :         32 :                 ptr = GETARR(trg);
     150         [ +  + ]:        434 :                 for (i = 0; i < trglen; i++)
     151                 :            :                 {
     152                 :        402 :                         int32           item = trgm2int(ptr);
     153                 :            : 
     154                 :        402 :                         entries[i] = Int32GetDatum(item);
     155                 :        402 :                         ptr++;
     156                 :            :                 }
     157                 :            :         }
     158                 :            : 
     159                 :            :         /*
     160                 :            :          * If no trigram was extracted then we have to scan all the index.
     161                 :            :          */
     162         [ -  + ]:         32 :         if (trglen == 0)
     163                 :          0 :                 *searchMode = GIN_SEARCH_MODE_ALL;
     164                 :            : 
     165                 :         32 :         PG_RETURN_POINTER(entries);
     166                 :            : }
     167                 :            : 
     168                 :            : Datum
     169                 :       3012 : gin_trgm_consistent(PG_FUNCTION_ARGS)
     170                 :            : {
     171                 :       3012 :         bool       *check = (bool *) PG_GETARG_POINTER(0);
     172                 :       3012 :         StrategyNumber strategy = PG_GETARG_UINT16(1);
     173                 :            : 
     174                 :            :         /* text    *query = PG_GETARG_TEXT_P(2); */
     175                 :       3012 :         int32           nkeys = PG_GETARG_INT32(3);
     176                 :            : 
     177                 :       3012 :         Pointer    *extra_data = (Pointer *) PG_GETARG_POINTER(4);
     178                 :       3012 :         bool       *recheck = (bool *) PG_GETARG_POINTER(5);
     179                 :            :         bool            res;
     180                 :            :         int32           i,
     181                 :            :                                 ntrue;
     182                 :            : 
     183                 :            :         /* All cases served by this function are inexact */
     184                 :       3012 :         *recheck = true;
     185                 :            : 
     186   [ +  +  +  - ]:       3012 :         switch (strategy)
     187                 :            :         {
     188                 :            :                 case SimilarityStrategyNumber:
     189                 :            :                         /* Count the matches */
     190                 :            :                         ntrue = 0;
     191         [ +  + ]:      39000 :                         for (i = 0; i < nkeys; i++)
     192                 :            :                         {
     193         [ +  + ]:      36000 :                                 if (check[i])
     194                 :      17255 :                                         ntrue++;
     195                 :            :                         }
     196                 :            : #ifdef DIVUNION
     197 [ +  + ][ -  + ]:       3000 :                         res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= trgm_limit) ? true : false);
     198                 :            : #else
     199                 :            :                         res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false);
     200                 :            : #endif
     201                 :       3000 :                         break;
     202                 :            :                 case ILikeStrategyNumber:
     203                 :            : #ifndef IGNORECASE
     204                 :            :                         elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
     205                 :            : #endif
     206                 :            :                         /* FALL THRU */
     207                 :            :                 case LikeStrategyNumber:
     208                 :            :                         /* Check if all extracted trigrams are presented. */
     209                 :            :                         res = true;
     210         [ +  + ]:         12 :                         for (i = 0; i < nkeys; i++)
     211                 :            :                         {
     212         [ +  - ]:          7 :                                 if (!check[i])
     213                 :            :                                 {
     214                 :            :                                         res = false;
     215                 :            :                                         break;
     216                 :            :                                 }
     217                 :            :                         }
     218                 :            :                         break;
     219                 :            :                 case RegExpStrategyNumber:
     220                 :            :                 case RegExpStrategyNumberICase:
     221         [ +  - ]:          7 :                         if (nkeys < 1)
     222                 :            :                         {
     223                 :            :                                 /* Regex processing gave no result: do full index scan */
     224                 :            :                                 res = true;
     225                 :            :                                 break;
     226                 :            :                         }
     227                 :          7 :                         res = trigramsMatchGraph((PackedGraph *) extra_data[0], check);
     228                 :            : 
     229                 :          7 :                         break;
     230                 :            :                 default:
     231                 :          0 :                         elog(ERROR, "unrecognized strategy number: %d", strategy);
     232                 :            :                         res = false;            /* keep compiler quiet */
     233                 :            :                         break;
     234                 :            :         }
     235                 :            : 
     236         [ -  + ]:       3012 :         PG_RETURN_BOOL(res);
     237                 :            : }

Generated by: LCOV version 1.9