OSDN Git Service

pgindent run for 8.3.
[pg-rex/syncrep.git] / contrib / hstore / hstore_gin.c
1 #include "hstore.h"
2
3 #include "access/gin.h"
4
5 #define KEYFLAG         'K'
6 #define VALFLAG         'V'
7 #define NULLFLAG        'N'
8
9 PG_FUNCTION_INFO_V1(gin_extract_hstore);
10 Datum           gin_extract_hstore(PG_FUNCTION_ARGS);
11
12 static text *
13 makeitem(char *str, int len)
14 {
15         text       *item;
16
17         item = (text *) palloc(VARHDRSZ + len + 1);
18         SET_VARSIZE(item, VARHDRSZ + len + 1);
19
20         if (str && len > 0)
21                 memcpy(VARDATA(item) + 1, str, len);
22
23         return item;
24 }
25
26 Datum
27 gin_extract_hstore(PG_FUNCTION_ARGS)
28 {
29         HStore     *hs = PG_GETARG_HS(0);
30         int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
31         Datum      *entries = NULL;
32
33         *nentries = 2 * hs->size;
34
35         if (hs->size > 0)
36         {
37                 HEntry     *ptr = ARRPTR(hs);
38                 char       *words = STRPTR(hs);
39                 int                     i = 0;
40
41                 entries = (Datum *) palloc(sizeof(Datum) * 2 * hs->size);
42
43                 while (ptr - ARRPTR(hs) < hs->size)
44                 {
45                         text       *item;
46
47                         item = makeitem(words + ptr->pos, ptr->keylen);
48                         *VARDATA(item) = KEYFLAG;
49                         entries[i++] = PointerGetDatum(item);
50
51                         if (ptr->valisnull)
52                         {
53                                 item = makeitem(NULL, 0);
54                                 *VARDATA(item) = NULLFLAG;
55
56                         }
57                         else
58                         {
59                                 item = makeitem(words + ptr->pos + ptr->keylen, ptr->vallen);
60                                 *VARDATA(item) = VALFLAG;
61                         }
62                         entries[i++] = PointerGetDatum(item);
63
64                         ptr++;
65                 }
66         }
67
68         PG_FREE_IF_COPY(hs, 0);
69         PG_RETURN_POINTER(entries);
70 }
71
72 PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
73 Datum           gin_extract_hstore_query(PG_FUNCTION_ARGS);
74
75 Datum
76 gin_extract_hstore_query(PG_FUNCTION_ARGS)
77 {
78         StrategyNumber strategy = PG_GETARG_UINT16(2);
79
80         if (strategy == HStoreContainsStrategyNumber)
81         {
82                 PG_RETURN_DATUM(DirectFunctionCall2(
83                                                                                         gin_extract_hstore,
84                                                                                         PG_GETARG_DATUM(0),
85                                                                                         PG_GETARG_DATUM(1)
86                                                                                         ));
87         }
88         else if (strategy == HStoreExistsStrategyNumber)
89         {
90                 text       *item,
91                                    *q = PG_GETARG_TEXT_P(0);
92                 int32      *nentries = (int32 *) PG_GETARG_POINTER(1);
93                 Datum      *entries = NULL;
94
95                 *nentries = 1;
96                 entries = (Datum *) palloc(sizeof(Datum));
97
98                 item = makeitem(VARDATA(q), VARSIZE(q) - VARHDRSZ);
99                 *VARDATA(item) = KEYFLAG;
100                 entries[0] = PointerGetDatum(item);
101
102                 PG_RETURN_POINTER(entries);
103         }
104         else
105                 elog(ERROR, "Unsupported strategy number: %d", strategy);
106
107         PG_RETURN_POINTER(NULL);
108 }
109
110 PG_FUNCTION_INFO_V1(gin_consistent_hstore);
111 Datum           gin_consistent_hstore(PG_FUNCTION_ARGS);
112
113 Datum
114 gin_consistent_hstore(PG_FUNCTION_ARGS)
115 {
116         StrategyNumber strategy = PG_GETARG_UINT16(1);
117         bool            res = true;
118
119         if (strategy == HStoreContainsStrategyNumber)
120         {
121                 bool       *check = (bool *) PG_GETARG_POINTER(0);
122                 HStore     *query = PG_GETARG_HS(2);
123                 int                     i;
124
125                 for (i = 0; res && i < 2 * query->size; i++)
126                         if (check[i] == false)
127                                 res = false;
128         }
129         else if (strategy == HStoreExistsStrategyNumber)
130                 res = true;
131         else
132                 elog(ERROR, "Unsupported strategy number: %d", strategy);
133
134         PG_RETURN_BOOL(res);
135 }