Header And Logo

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

Defines | Functions

ginarrayproc.c File Reference

#include "postgres.h"
#include "access/gin.h"
#include "access/skey.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
Include dependency graph for ginarrayproc.c:

Go to the source code of this file.

Defines

#define GinOverlapStrategy   1
#define GinContainsStrategy   2
#define GinContainedStrategy   3
#define GinEqualStrategy   4

Functions

Datum ginarrayextract (PG_FUNCTION_ARGS)
Datum ginarrayextract_2args (PG_FUNCTION_ARGS)
Datum ginqueryarrayextract (PG_FUNCTION_ARGS)
Datum ginarrayconsistent (PG_FUNCTION_ARGS)

Define Documentation

#define GinContainedStrategy   3

Definition at line 25 of file ginarrayproc.c.

Referenced by ginarrayconsistent(), and ginqueryarrayextract().

#define GinContainsStrategy   2

Definition at line 24 of file ginarrayproc.c.

Referenced by ginarrayconsistent(), and ginqueryarrayextract().

#define GinEqualStrategy   4

Definition at line 26 of file ginarrayproc.c.

Referenced by ginarrayconsistent(), and ginqueryarrayextract().

#define GinOverlapStrategy   1

Definition at line 23 of file ginarrayproc.c.

Referenced by ginarrayconsistent(), and ginqueryarrayextract().


Function Documentation

Datum ginarrayconsistent ( PG_FUNCTION_ARGS   ) 

Definition at line 142 of file ginarrayproc.c.

References elog, ERROR, GinContainedStrategy, GinContainsStrategy, GinEqualStrategy, GinOverlapStrategy, 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);

    /* ArrayType  *query = PG_GETARG_ARRAYTYPE_P(2); */
    int32       nkeys = PG_GETARG_INT32(3);

    /* Pointer     *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(5);

    /* Datum       *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
    bool       *nullFlags = (bool *) PG_GETARG_POINTER(7);
    bool        res;
    int32       i;

    switch (strategy)
    {
        case GinOverlapStrategy:
            /* result is not lossy */
            *recheck = false;
            /* must have a match for at least one non-null element */
            res = false;
            for (i = 0; i < nkeys; i++)
            {
                if (check[i] && !nullFlags[i])
                {
                    res = true;
                    break;
                }
            }
            break;
        case GinContainsStrategy:
            /* result is not lossy */
            *recheck = false;
            /* must have all elements in check[] true, and no nulls */
            res = true;
            for (i = 0; i < nkeys; i++)
            {
                if (!check[i] || nullFlags[i])
                {
                    res = false;
                    break;
                }
            }
            break;
        case GinContainedStrategy:
            /* we will need recheck */
            *recheck = true;
            /* can't do anything else useful here */
            res = true;
            break;
        case GinEqualStrategy:
            /* we will need recheck */
            *recheck = true;

            /*
             * Must have all elements in check[] true; no discrimination
             * against nulls here.  This is because array_contain_compare and
             * array_eq handle nulls differently ...
             */
            res = true;
            for (i = 0; i < nkeys; i++)
            {
                if (!check[i])
                {
                    res = false;
                    break;
                }
            }
            break;
        default:
            elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
                 strategy);
            res = false;
    }

    PG_RETURN_BOOL(res);
}

Datum ginarrayextract ( PG_FUNCTION_ARGS   ) 

Definition at line 33 of file ginarrayproc.c.

References ARR_ELEMTYPE, deconstruct_array(), get_typlenbyvalalign(), PG_GETARG_ARRAYTYPE_P_COPY, PG_GETARG_POINTER, and PG_RETURN_POINTER.

Referenced by ginarrayextract_2args().

{
    /* Make copy of array input to ensure it doesn't disappear while in use */
    ArrayType  *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
    int32      *nkeys = (int32 *) PG_GETARG_POINTER(1);
    bool      **nullFlags = (bool **) PG_GETARG_POINTER(2);
    int16       elmlen;
    bool        elmbyval;
    char        elmalign;
    Datum      *elems;
    bool       *nulls;
    int         nelems;

    get_typlenbyvalalign(ARR_ELEMTYPE(array),
                         &elmlen, &elmbyval, &elmalign);

    deconstruct_array(array,
                      ARR_ELEMTYPE(array),
                      elmlen, elmbyval, elmalign,
                      &elems, &nulls, &nelems);

    *nkeys = nelems;
    *nullFlags = nulls;

    /* we should not free array, elems[i] points into it */
    PG_RETURN_POINTER(elems);
}

Datum ginarrayextract_2args ( PG_FUNCTION_ARGS   ) 

Definition at line 68 of file ginarrayproc.c.

References elog, ERROR, ginarrayextract(), and PG_NARGS.

{
    if (PG_NARGS() < 3)         /* should not happen */
        elog(ERROR, "ginarrayextract requires three arguments");
    return ginarrayextract(fcinfo);
}

Datum ginqueryarrayextract ( PG_FUNCTION_ARGS   ) 

Definition at line 79 of file ginarrayproc.c.

References ARR_ELEMTYPE, deconstruct_array(), elog, ERROR, get_typlenbyvalalign(), GinContainedStrategy, GinContainsStrategy, GinEqualStrategy, GinOverlapStrategy, PG_GETARG_ARRAYTYPE_P_COPY, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_POINTER.

{
    /* Make copy of array input to ensure it doesn't disappear while in use */
    ArrayType  *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
    int32      *nkeys = (int32 *) PG_GETARG_POINTER(1);
    StrategyNumber strategy = PG_GETARG_UINT16(2);

    /* bool   **pmatch = (bool **) PG_GETARG_POINTER(3); */
    /* Pointer     *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
    bool      **nullFlags = (bool **) PG_GETARG_POINTER(5);
    int32      *searchMode = (int32 *) PG_GETARG_POINTER(6);
    int16       elmlen;
    bool        elmbyval;
    char        elmalign;
    Datum      *elems;
    bool       *nulls;
    int         nelems;

    get_typlenbyvalalign(ARR_ELEMTYPE(array),
                         &elmlen, &elmbyval, &elmalign);

    deconstruct_array(array,
                      ARR_ELEMTYPE(array),
                      elmlen, elmbyval, elmalign,
                      &elems, &nulls, &nelems);

    *nkeys = nelems;
    *nullFlags = nulls;

    switch (strategy)
    {
        case GinOverlapStrategy:
            *searchMode = GIN_SEARCH_MODE_DEFAULT;
            break;
        case GinContainsStrategy:
            if (nelems > 0)
                *searchMode = GIN_SEARCH_MODE_DEFAULT;
            else    /* everything contains the empty set */
                *searchMode = GIN_SEARCH_MODE_ALL;
            break;
        case GinContainedStrategy:
            /* empty set is contained in everything */
            *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
            break;
        case GinEqualStrategy:
            if (nelems > 0)
                *searchMode = GIN_SEARCH_MODE_DEFAULT;
            else
                *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
            break;
        default:
            elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
                 strategy);
    }

    /* we should not free array, elems[i] points into it */
    PG_RETURN_POINTER(elems);
}