LCOV - code coverage report
Current view: top level - contrib/hstore - hstore_gin.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 113 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 7 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * contrib/hstore/hstore_gin.c
       3              :  */
       4              : #include "postgres.h"
       5              : 
       6              : #include "access/gin.h"
       7              : #include "access/stratnum.h"
       8              : #include "catalog/pg_type.h"
       9              : 
      10              : #include "hstore.h"
      11              : 
      12              : 
      13              : /*
      14              :  * When using a GIN index for hstore, we choose to index both keys and values.
      15              :  * The storage format is "text" values, with K, V, or N prepended to the string
      16              :  * to indicate key, value, or null values.  (As of 9.1 it might be better to
      17              :  * store null values as nulls, but we'll keep it this way for on-disk
      18              :  * compatibility.)
      19              :  */
      20              : #define KEYFLAG         'K'
      21              : #define VALFLAG         'V'
      22              : #define NULLFLAG        'N'
      23              : 
      24            0 : PG_FUNCTION_INFO_V1(gin_extract_hstore);
      25              : 
      26              : /* Build an indexable text value */
      27              : static text *
      28            0 : makeitem(char *str, int len, char flag)
      29              : {
      30            0 :         text       *item;
      31              : 
      32            0 :         item = (text *) palloc(VARHDRSZ + len + 1);
      33            0 :         SET_VARSIZE(item, VARHDRSZ + len + 1);
      34              : 
      35            0 :         *VARDATA(item) = flag;
      36              : 
      37            0 :         if (str && len > 0)
      38            0 :                 memcpy(VARDATA(item) + 1, str, len);
      39              : 
      40            0 :         return item;
      41            0 : }
      42              : 
      43              : Datum
      44            0 : gin_extract_hstore(PG_FUNCTION_ARGS)
      45              : {
      46            0 :         HStore     *hs = PG_GETARG_HSTORE_P(0);
      47            0 :         int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
      48            0 :         Datum      *entries = NULL;
      49            0 :         HEntry     *hsent = ARRPTR(hs);
      50            0 :         char       *ptr = STRPTR(hs);
      51            0 :         int                     count = HS_COUNT(hs);
      52            0 :         int                     i;
      53              : 
      54            0 :         *nentries = 2 * count;
      55            0 :         if (count)
      56            0 :                 entries = (Datum *) palloc(sizeof(Datum) * 2 * count);
      57              : 
      58            0 :         for (i = 0; i < count; ++i)
      59              :         {
      60            0 :                 text       *item;
      61              : 
      62            0 :                 item = makeitem(HSTORE_KEY(hsent, ptr, i),
      63            0 :                                                 HSTORE_KEYLEN(hsent, i),
      64              :                                                 KEYFLAG);
      65            0 :                 entries[2 * i] = PointerGetDatum(item);
      66              : 
      67            0 :                 if (HSTORE_VALISNULL(hsent, i))
      68            0 :                         item = makeitem(NULL, 0, NULLFLAG);
      69              :                 else
      70            0 :                         item = makeitem(HSTORE_VAL(hsent, ptr, i),
      71            0 :                                                         HSTORE_VALLEN(hsent, i),
      72              :                                                         VALFLAG);
      73            0 :                 entries[2 * i + 1] = PointerGetDatum(item);
      74            0 :         }
      75              : 
      76            0 :         PG_RETURN_POINTER(entries);
      77            0 : }
      78              : 
      79            0 : PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
      80              : 
      81              : Datum
      82            0 : gin_extract_hstore_query(PG_FUNCTION_ARGS)
      83              : {
      84            0 :         int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
      85            0 :         StrategyNumber strategy = PG_GETARG_UINT16(2);
      86            0 :         int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
      87            0 :         Datum      *entries;
      88              : 
      89            0 :         if (strategy == HStoreContainsStrategyNumber)
      90              :         {
      91              :                 /* Query is an hstore, so just apply gin_extract_hstore... */
      92            0 :                 entries = (Datum *)
      93            0 :                         DatumGetPointer(DirectFunctionCall2(gin_extract_hstore,
      94              :                                                                                                 PG_GETARG_DATUM(0),
      95              :                                                                                                 PointerGetDatum(nentries)));
      96              :                 /* ... except that "contains {}" requires a full index scan */
      97            0 :                 if (entries == NULL)
      98            0 :                         *searchMode = GIN_SEARCH_MODE_ALL;
      99            0 :         }
     100            0 :         else if (strategy == HStoreExistsStrategyNumber)
     101              :         {
     102            0 :                 text       *query = PG_GETARG_TEXT_PP(0);
     103            0 :                 text       *item;
     104              : 
     105            0 :                 *nentries = 1;
     106            0 :                 entries = (Datum *) palloc(sizeof(Datum));
     107            0 :                 item = makeitem(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), KEYFLAG);
     108            0 :                 entries[0] = PointerGetDatum(item);
     109            0 :         }
     110            0 :         else if (strategy == HStoreExistsAnyStrategyNumber ||
     111            0 :                          strategy == HStoreExistsAllStrategyNumber)
     112              :         {
     113            0 :                 ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
     114            0 :                 Datum      *key_datums;
     115            0 :                 bool       *key_nulls;
     116            0 :                 int                     key_count;
     117            0 :                 int                     i,
     118              :                                         j;
     119            0 :                 text       *item;
     120              : 
     121            0 :                 deconstruct_array_builtin(query, TEXTOID, &key_datums, &key_nulls, &key_count);
     122              : 
     123            0 :                 entries = (Datum *) palloc(sizeof(Datum) * key_count);
     124              : 
     125            0 :                 for (i = 0, j = 0; i < key_count; ++i)
     126              :                 {
     127              :                         /* Nulls in the array are ignored, cf hstoreArrayToPairs */
     128            0 :                         if (key_nulls[i])
     129            0 :                                 continue;
     130            0 :                         item = makeitem(VARDATA(DatumGetPointer(key_datums[i])), VARSIZE(DatumGetPointer(key_datums[i])) - VARHDRSZ, KEYFLAG);
     131            0 :                         entries[j++] = PointerGetDatum(item);
     132            0 :                 }
     133              : 
     134            0 :                 *nentries = j;
     135              :                 /* ExistsAll with no keys should match everything */
     136            0 :                 if (j == 0 && strategy == HStoreExistsAllStrategyNumber)
     137            0 :                         *searchMode = GIN_SEARCH_MODE_ALL;
     138            0 :         }
     139              :         else
     140              :         {
     141            0 :                 elog(ERROR, "unrecognized strategy number: %d", strategy);
     142            0 :                 entries = NULL;                 /* keep compiler quiet */
     143              :         }
     144              : 
     145            0 :         PG_RETURN_POINTER(entries);
     146            0 : }
     147              : 
     148            0 : PG_FUNCTION_INFO_V1(gin_consistent_hstore);
     149              : 
     150              : Datum
     151            0 : gin_consistent_hstore(PG_FUNCTION_ARGS)
     152              : {
     153            0 :         bool       *check = (bool *) PG_GETARG_POINTER(0);
     154            0 :         StrategyNumber strategy = PG_GETARG_UINT16(1);
     155              : #ifdef NOT_USED
     156              :         HStore     *query = PG_GETARG_HSTORE_P(2);
     157              : #endif
     158            0 :         int32           nkeys = PG_GETARG_INT32(3);
     159              : #ifdef NOT_USED
     160              :         Pointer    *extra_data = (Pointer *) PG_GETARG_POINTER(4);
     161              : #endif
     162            0 :         bool       *recheck = (bool *) PG_GETARG_POINTER(5);
     163            0 :         bool            res = true;
     164            0 :         int32           i;
     165              : 
     166            0 :         if (strategy == HStoreContainsStrategyNumber)
     167              :         {
     168              :                 /*
     169              :                  * Index doesn't have information about correspondence of keys and
     170              :                  * values, so we need recheck.  However, if not all the keys are
     171              :                  * present, we can fail at once.
     172              :                  */
     173            0 :                 *recheck = true;
     174            0 :                 for (i = 0; i < nkeys; i++)
     175              :                 {
     176            0 :                         if (!check[i])
     177              :                         {
     178            0 :                                 res = false;
     179            0 :                                 break;
     180              :                         }
     181            0 :                 }
     182            0 :         }
     183            0 :         else if (strategy == HStoreExistsStrategyNumber)
     184              :         {
     185              :                 /* Existence of key is guaranteed in default search mode */
     186            0 :                 *recheck = false;
     187            0 :                 res = true;
     188            0 :         }
     189            0 :         else if (strategy == HStoreExistsAnyStrategyNumber)
     190              :         {
     191              :                 /* Existence of key is guaranteed in default search mode */
     192            0 :                 *recheck = false;
     193            0 :                 res = true;
     194            0 :         }
     195            0 :         else if (strategy == HStoreExistsAllStrategyNumber)
     196              :         {
     197              :                 /* Testing for all the keys being present gives an exact result */
     198            0 :                 *recheck = false;
     199            0 :                 for (i = 0; i < nkeys; i++)
     200              :                 {
     201            0 :                         if (!check[i])
     202              :                         {
     203            0 :                                 res = false;
     204            0 :                                 break;
     205              :                         }
     206            0 :                 }
     207            0 :         }
     208              :         else
     209            0 :                 elog(ERROR, "unrecognized strategy number: %d", strategy);
     210              : 
     211            0 :         PG_RETURN_BOOL(res);
     212            0 : }
        

Generated by: LCOV version 2.3.2-1