Skip to content

Commit c1df4cc

Browse files
author
Artur Zakirov
committed
RUM index access methods with Postgresql 9.3 GIN
0 parents  commit c1df4cc

16 files changed

+10977
-0
lines changed

Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# contrib/rum/Makefile
2+
3+
MODULE_big = rum
4+
OBJS = rumutil.o ruminsert.o $(WIN32RES)
5+
6+
EXTENSION = rum
7+
DATA = rum--1.0.sql
8+
PGFILEDESC = "RUM access method"
9+
10+
REGRESS = rum
11+
12+
ifdef USE_PGXS
13+
PG_CONFIG = pg_config
14+
PGXS := $(shell $(PG_CONFIG) --pgxs)
15+
include $(PGXS)
16+
else
17+
subdir = contrib/rum
18+
top_builddir = ../..
19+
include $(top_builddir)/src/Makefile.global
20+
include $(top_srcdir)/contrib/contrib-global.mk
21+
endif

ginarrayproc.c

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* ginarrayproc.c
4+
* support functions for GIN's indexing of any array
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
* IDENTIFICATION
11+
* src/backend/access/gin/ginarrayproc.c
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include "postgres.h"
15+
16+
#include "access/gin.h"
17+
#include "access/skey.h"
18+
#include "utils/array.h"
19+
#include "utils/builtins.h"
20+
#include "utils/lsyscache.h"
21+
22+
23+
#define GinOverlapStrategy 1
24+
#define GinContainsStrategy 2
25+
#define GinContainedStrategy 3
26+
#define GinEqualStrategy 4
27+
28+
29+
/*
30+
* extractValue support function
31+
*/
32+
Datum
33+
ginarrayextract(PG_FUNCTION_ARGS)
34+
{
35+
/* Make copy of array input to ensure it doesn't disappear while in use */
36+
ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
37+
int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
38+
bool **nullFlags = (bool **) PG_GETARG_POINTER(2);
39+
int16 elmlen;
40+
bool elmbyval;
41+
char elmalign;
42+
Datum *elems;
43+
bool *nulls;
44+
int nelems;
45+
46+
get_typlenbyvalalign(ARR_ELEMTYPE(array),
47+
&elmlen, &elmbyval, &elmalign);
48+
49+
deconstruct_array(array,
50+
ARR_ELEMTYPE(array),
51+
elmlen, elmbyval, elmalign,
52+
&elems, &nulls, &nelems);
53+
54+
*nkeys = nelems;
55+
*nullFlags = nulls;
56+
57+
/* we should not free array, elems[i] points into it */
58+
PG_RETURN_POINTER(elems);
59+
}
60+
61+
/*
62+
* Formerly, ginarrayextract had only two arguments. Now it has three,
63+
* but we still need a pg_proc entry with two args to support reloading
64+
* pre-9.1 contrib/intarray opclass declarations. This compatibility
65+
* function should go away eventually.
66+
*/
67+
Datum
68+
ginarrayextract_2args(PG_FUNCTION_ARGS)
69+
{
70+
if (PG_NARGS() < 3) /* should not happen */
71+
elog(ERROR, "ginarrayextract requires three arguments");
72+
return ginarrayextract(fcinfo);
73+
}
74+
75+
/*
76+
* extractQuery support function
77+
*/
78+
Datum
79+
ginqueryarrayextract(PG_FUNCTION_ARGS)
80+
{
81+
/* Make copy of array input to ensure it doesn't disappear while in use */
82+
ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
83+
int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
84+
StrategyNumber strategy = PG_GETARG_UINT16(2);
85+
86+
/* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */
87+
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
88+
bool **nullFlags = (bool **) PG_GETARG_POINTER(5);
89+
int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
90+
int16 elmlen;
91+
bool elmbyval;
92+
char elmalign;
93+
Datum *elems;
94+
bool *nulls;
95+
int nelems;
96+
97+
get_typlenbyvalalign(ARR_ELEMTYPE(array),
98+
&elmlen, &elmbyval, &elmalign);
99+
100+
deconstruct_array(array,
101+
ARR_ELEMTYPE(array),
102+
elmlen, elmbyval, elmalign,
103+
&elems, &nulls, &nelems);
104+
105+
*nkeys = nelems;
106+
*nullFlags = nulls;
107+
108+
switch (strategy)
109+
{
110+
case GinOverlapStrategy:
111+
*searchMode = GIN_SEARCH_MODE_DEFAULT;
112+
break;
113+
case GinContainsStrategy:
114+
if (nelems > 0)
115+
*searchMode = GIN_SEARCH_MODE_DEFAULT;
116+
else /* everything contains the empty set */
117+
*searchMode = GIN_SEARCH_MODE_ALL;
118+
break;
119+
case GinContainedStrategy:
120+
/* empty set is contained in everything */
121+
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
122+
break;
123+
case GinEqualStrategy:
124+
if (nelems > 0)
125+
*searchMode = GIN_SEARCH_MODE_DEFAULT;
126+
else
127+
*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
128+
break;
129+
default:
130+
elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
131+
strategy);
132+
}
133+
134+
/* we should not free array, elems[i] points into it */
135+
PG_RETURN_POINTER(elems);
136+
}
137+
138+
/*
139+
* consistent support function
140+
*/
141+
Datum
142+
ginarrayconsistent(PG_FUNCTION_ARGS)
143+
{
144+
bool *check = (bool *) PG_GETARG_POINTER(0);
145+
StrategyNumber strategy = PG_GETARG_UINT16(1);
146+
147+
/* ArrayType *query = PG_GETARG_ARRAYTYPE_P(2); */
148+
int32 nkeys = PG_GETARG_INT32(3);
149+
150+
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
151+
bool *recheck = (bool *) PG_GETARG_POINTER(5);
152+
153+
/* Datum *queryKeys = (Datum *) PG_GETARG_POINTER(6); */
154+
bool *nullFlags = (bool *) PG_GETARG_POINTER(7);
155+
bool res;
156+
int32 i;
157+
158+
switch (strategy)
159+
{
160+
case GinOverlapStrategy:
161+
/* result is not lossy */
162+
*recheck = false;
163+
/* must have a match for at least one non-null element */
164+
res = false;
165+
for (i = 0; i < nkeys; i++)
166+
{
167+
if (check[i] && !nullFlags[i])
168+
{
169+
res = true;
170+
break;
171+
}
172+
}
173+
break;
174+
case GinContainsStrategy:
175+
/* result is not lossy */
176+
*recheck = false;
177+
/* must have all elements in check[] true, and no nulls */
178+
res = true;
179+
for (i = 0; i < nkeys; i++)
180+
{
181+
if (!check[i] || nullFlags[i])
182+
{
183+
res = false;
184+
break;
185+
}
186+
}
187+
break;
188+
case GinContainedStrategy:
189+
/* we will need recheck */
190+
*recheck = true;
191+
/* can't do anything else useful here */
192+
res = true;
193+
break;
194+
case GinEqualStrategy:
195+
/* we will need recheck */
196+
*recheck = true;
197+
198+
/*
199+
* Must have all elements in check[] true; no discrimination
200+
* against nulls here. This is because array_contain_compare and
201+
* array_eq handle nulls differently ...
202+
*/
203+
res = true;
204+
for (i = 0; i < nkeys; i++)
205+
{
206+
if (!check[i])
207+
{
208+
res = false;
209+
break;
210+
}
211+
}
212+
break;
213+
default:
214+
elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
215+
strategy);
216+
res = false;
217+
}
218+
219+
PG_RETURN_BOOL(res);
220+
}

0 commit comments

Comments
 (0)