Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions

hstore_gin.c File Reference

#include "postgres.h"
#include "access/gin.h"
#include "access/skey.h"
#include "catalog/pg_type.h"
#include "hstore.h"
Include dependency graph for hstore_gin.c:

Go to the source code of this file.

Defines

#define KEYFLAG   'K'
#define VALFLAG   'V'
#define NULLFLAG   'N'

Functions

 PG_FUNCTION_INFO_V1 (gin_extract_hstore)
Datum gin_extract_hstore (PG_FUNCTION_ARGS)
static textmakeitem (char *str, int len, char flag)
 PG_FUNCTION_INFO_V1 (gin_extract_hstore_query)
Datum gin_extract_hstore_query (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (gin_consistent_hstore)
Datum gin_consistent_hstore (PG_FUNCTION_ARGS)

Define Documentation

#define KEYFLAG   'K'

Definition at line 20 of file hstore_gin.c.

Referenced by gin_extract_hstore(), and gin_extract_hstore_query().

#define NULLFLAG   'N'

Definition at line 22 of file hstore_gin.c.

Referenced by gin_extract_hstore().

#define VALFLAG   'V'

Definition at line 21 of file hstore_gin.c.

Referenced by gin_extract_hstore().


Function Documentation

Datum gin_consistent_hstore ( PG_FUNCTION_ARGS   ) 

Definition at line 154 of file hstore_gin.c.

References elog, ERROR, HStoreContainsStrategyNumber, HStoreExistsAllStrategyNumber, HStoreExistsAnyStrategyNumber, HStoreExistsStrategyNumber, i, PG_GETARG_INT32, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

{
    bool       *check = (bool *) PG_GETARG_POINTER(0);
    StrategyNumber strategy = PG_GETARG_UINT16(1);

    /* HStore      *query = PG_GETARG_HS(2); */
    int32       nkeys = PG_GETARG_INT32(3);

    /* Pointer     *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(5);
    bool        res = true;
    int32       i;

    if (strategy == HStoreContainsStrategyNumber)
    {
        /*
         * Index doesn't have information about correspondence of keys and
         * values, so we need recheck.  However, if not all the keys are
         * present, we can fail at once.
         */
        *recheck = true;
        for (i = 0; i < nkeys; i++)
        {
            if (!check[i])
            {
                res = false;
                break;
            }
        }
    }
    else if (strategy == HStoreExistsStrategyNumber)
    {
        /* Existence of key is guaranteed in default search mode */
        *recheck = false;
        res = true;
    }
    else if (strategy == HStoreExistsAnyStrategyNumber)
    {
        /* Existence of key is guaranteed in default search mode */
        *recheck = false;
        res = true;
    }
    else if (strategy == HStoreExistsAllStrategyNumber)
    {
        /* Testing for all the keys being present gives an exact result */
        *recheck = false;
        for (i = 0; i < nkeys; i++)
        {
            if (!check[i])
            {
                res = false;
                break;
            }
        }
    }
    else
        elog(ERROR, "unrecognized strategy number: %d", strategy);

    PG_RETURN_BOOL(res);
}

Datum gin_extract_hstore ( PG_FUNCTION_ARGS   ) 

Definition at line 45 of file hstore_gin.c.

References ARRPTR, HS_COUNT, HS_KEY, HS_KEYLEN, HS_VAL, HS_VALISNULL, HS_VALLEN, i, KEYFLAG, makeitem(), NULL, NULLFLAG, palloc(), PG_GETARG_HS, PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, STRPTR, and VALFLAG.

Referenced by gin_extract_hstore_query().

{
    HStore     *hs = PG_GETARG_HS(0);
    int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
    Datum      *entries = NULL;
    HEntry     *hsent = ARRPTR(hs);
    char       *ptr = STRPTR(hs);
    int         count = HS_COUNT(hs);
    int         i;

    *nentries = 2 * count;
    if (count)
        entries = (Datum *) palloc(sizeof(Datum) * 2 * count);

    for (i = 0; i < count; ++i)
    {
        text       *item;

        item = makeitem(HS_KEY(hsent, ptr, i), HS_KEYLEN(hsent, i),
                        KEYFLAG);
        entries[2 * i] = PointerGetDatum(item);

        if (HS_VALISNULL(hsent, i))
            item = makeitem(NULL, 0, NULLFLAG);
        else
            item = makeitem(HS_VAL(hsent, ptr, i), HS_VALLEN(hsent, i),
                            VALFLAG);
        entries[2 * i + 1] = PointerGetDatum(item);
    }

    PG_RETURN_POINTER(entries);
}

Datum gin_extract_hstore_query ( PG_FUNCTION_ARGS   ) 

Definition at line 82 of file hstore_gin.c.

References DatumGetPointer, deconstruct_array(), DirectFunctionCall2, elog, ERROR, gin_extract_hstore(), HStoreContainsStrategyNumber, HStoreExistsAllStrategyNumber, HStoreExistsAnyStrategyNumber, HStoreExistsStrategyNumber, i, KEYFLAG, makeitem(), NULL, palloc(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_GETARG_TEXT_PP, PG_GETARG_UINT16, PG_RETURN_POINTER, PointerGetDatum, TEXTOID, VARDATA, VARDATA_ANY, VARHDRSZ, VARSIZE, and VARSIZE_ANY_EXHDR.

{
    int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
    StrategyNumber strategy = PG_GETARG_UINT16(2);
    int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
    Datum      *entries;

    if (strategy == HStoreContainsStrategyNumber)
    {
        /* Query is an hstore, so just apply gin_extract_hstore... */
        entries = (Datum *)
            DatumGetPointer(DirectFunctionCall2(gin_extract_hstore,
                                                PG_GETARG_DATUM(0),
                                                PointerGetDatum(nentries)));
        /* ... except that "contains {}" requires a full index scan */
        if (entries == NULL)
            *searchMode = GIN_SEARCH_MODE_ALL;
    }
    else if (strategy == HStoreExistsStrategyNumber)
    {
        text       *query = PG_GETARG_TEXT_PP(0);
        text       *item;

        *nentries = 1;
        entries = (Datum *) palloc(sizeof(Datum));
        item = makeitem(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), KEYFLAG);
        entries[0] = PointerGetDatum(item);
    }
    else if (strategy == HStoreExistsAnyStrategyNumber ||
             strategy == HStoreExistsAllStrategyNumber)
    {
        ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
        Datum      *key_datums;
        bool       *key_nulls;
        int         key_count;
        int         i,
                    j;
        text       *item;

        deconstruct_array(query,
                          TEXTOID, -1, false, 'i',
                          &key_datums, &key_nulls, &key_count);

        entries = (Datum *) palloc(sizeof(Datum) * key_count);

        for (i = 0, j = 0; i < key_count; ++i)
        {
            /* Nulls in the array are ignored, cf hstoreArrayToPairs */
            if (key_nulls[i])
                continue;
            item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG);
            entries[j++] = PointerGetDatum(item);
        }

        *nentries = j;
        /* ExistsAll with no keys should match everything */
        if (j == 0 && strategy == HStoreExistsAllStrategyNumber)
            *searchMode = GIN_SEARCH_MODE_ALL;
    }
    else
    {
        elog(ERROR, "unrecognized strategy number: %d", strategy);
        entries = NULL;         /* keep compiler quiet */
    }

    PG_RETURN_POINTER(entries);
}

static text* makeitem ( char *  str,
int  len,
char  flag 
) [static]

Definition at line 29 of file hstore_gin.c.

References palloc(), SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by gin_extract_hstore(), and gin_extract_hstore_query().

{
    text       *item;

    item = (text *) palloc(VARHDRSZ + len + 1);
    SET_VARSIZE(item, VARHDRSZ + len + 1);

    *VARDATA(item) = flag;

    if (str && len > 0)
        memcpy(VARDATA(item) + 1, str, len);

    return item;
}

PG_FUNCTION_INFO_V1 ( gin_extract_hstore_query   ) 
PG_FUNCTION_INFO_V1 ( gin_extract_hstore   ) 
PG_FUNCTION_INFO_V1 ( gin_consistent_hstore   )