~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-updates

« back to all changes in this revision

Viewing changes to src/backend/access/gin/ginarrayproc.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * ginarrayproc.c
 
4
 *        support functions for GIN's indexing of any array
 
5
 *
 
6
 *
 
7
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 
8
 * Portions Copyright (c) 1994, Regents of the University of California
 
9
 *
 
10
 * IDENTIFICATION
 
11
 *        $PostgreSQL$
 
12
 *-------------------------------------------------------------------------
 
13
 */
 
14
#include "postgres.h"
 
15
 
 
16
#include "access/gin.h"
 
17
#include "utils/array.h"
 
18
#include "utils/lsyscache.h"
 
19
 
 
20
 
 
21
#define GinOverlapStrategy              1
 
22
#define GinContainsStrategy             2
 
23
#define GinContainedStrategy    3
 
24
#define GinEqualStrategy                4
 
25
 
 
26
#define ARRAYCHECK(x) do {                                                                      \
 
27
        if ( ARR_HASNULL(x) )                                                                   \
 
28
                ereport(ERROR,                                                                          \
 
29
                        (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),               \
 
30
                         errmsg("array must not contain null values")));                \
 
31
} while(0)
 
32
 
 
33
 
 
34
/*
 
35
 * Function used as extractValue and extractQuery both
 
36
 */
 
37
Datum
 
38
ginarrayextract(PG_FUNCTION_ARGS)
 
39
{
 
40
        ArrayType  *array;
 
41
        int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
 
42
        Datum      *entries = NULL;
 
43
        int16           elmlen;
 
44
        bool            elmbyval;
 
45
        char            elmalign;
 
46
 
 
47
        /*
 
48
         * we should guarantee that array will not be destroyed during all
 
49
         * operation
 
50
         */
 
51
        array = PG_GETARG_ARRAYTYPE_P_COPY(0);
 
52
 
 
53
        ARRAYCHECK(array);
 
54
 
 
55
        get_typlenbyvalalign(ARR_ELEMTYPE(array),
 
56
                                                 &elmlen, &elmbyval, &elmalign);
 
57
 
 
58
        deconstruct_array(array,
 
59
                                          ARR_ELEMTYPE(array),
 
60
                                          elmlen, elmbyval, elmalign,
 
61
                                          &entries, NULL, (int *) nentries);
 
62
 
 
63
        if (*nentries == 0 && PG_NARGS() == 3)
 
64
        {
 
65
                switch (PG_GETARG_UINT16(2))    /* StrategyNumber */
 
66
                {
 
67
                        case GinOverlapStrategy:
 
68
                                *nentries = -1; /* nobody can be found */
 
69
                                break;
 
70
                        case GinContainsStrategy:
 
71
                        case GinContainedStrategy:
 
72
                        case GinEqualStrategy:
 
73
                        default:                        /* require fullscan: GIN can't find void
 
74
                                                                 * arrays */
 
75
                                break;
 
76
                }
 
77
        }
 
78
 
 
79
        /* we should not free array, entries[i] points into it */
 
80
        PG_RETURN_POINTER(entries);
 
81
}
 
82
 
 
83
Datum
 
84
ginqueryarrayextract(PG_FUNCTION_ARGS)
 
85
{
 
86
        PG_RETURN_DATUM(DirectFunctionCall3(ginarrayextract,
 
87
                                                                                PG_GETARG_DATUM(0),
 
88
                                                                                PG_GETARG_DATUM(1),
 
89
                                                                                PG_GETARG_DATUM(2)));
 
90
}
 
91
 
 
92
Datum
 
93
ginarrayconsistent(PG_FUNCTION_ARGS)
 
94
{
 
95
        bool       *check = (bool *) PG_GETARG_POINTER(0);
 
96
        StrategyNumber strategy = PG_GETARG_UINT16(1);
 
97
        ArrayType  *query = PG_GETARG_ARRAYTYPE_P(2);
 
98
        /* int32        nkeys = PG_GETARG_INT32(3); */
 
99
        /* Pointer         *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
 
100
        bool       *recheck = (bool *) PG_GETARG_POINTER(5);
 
101
        bool            res;
 
102
        int                     i,
 
103
                                nentries;
 
104
 
 
105
        /* ARRAYCHECK was already done by previous ginarrayextract call */
 
106
 
 
107
        switch (strategy)
 
108
        {
 
109
                case GinOverlapStrategy:
 
110
                        /* result is not lossy */
 
111
                        *recheck = false;
 
112
                        /* at least one element in check[] is true, so result = true */
 
113
                        res = true;
 
114
                        break;
 
115
                case GinContainedStrategy:
 
116
                        /* we will need recheck */
 
117
                        *recheck = true;
 
118
                        /* at least one element in check[] is true, so result = true */
 
119
                        res = true;
 
120
                        break;
 
121
                case GinContainsStrategy:
 
122
                        /* result is not lossy */
 
123
                        *recheck = false;
 
124
                        /* must have all elements in check[] true */
 
125
                        nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
 
126
                        res = true;
 
127
                        for (i = 0; i < nentries; i++)
 
128
                        {
 
129
                                if (!check[i])
 
130
                                {
 
131
                                        res = false;
 
132
                                        break;
 
133
                                }
 
134
                        }
 
135
                        break;
 
136
                case GinEqualStrategy:
 
137
                        /* we will need recheck */
 
138
                        *recheck = true;
 
139
                        /* must have all elements in check[] true */
 
140
                        nentries = ArrayGetNItems(ARR_NDIM(query), ARR_DIMS(query));
 
141
                        res = true;
 
142
                        for (i = 0; i < nentries; i++)
 
143
                        {
 
144
                                if (!check[i])
 
145
                                {
 
146
                                        res = false;
 
147
                                        break;
 
148
                                }
 
149
                        }
 
150
                        break;
 
151
                default:
 
152
                        elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
 
153
                                 strategy);
 
154
                        res = false;
 
155
        }
 
156
 
 
157
        PG_RETURN_BOOL(res);
 
158
}