1
1
/*-------------------------------------------------------------------------
2
2
*
3
- * ginvacuum .c
4
- * support function for GIN's indexing of any array
3
+ * ginarrayproc .c
4
+ * support functions for GIN's indexing of any array
5
5
*
6
6
*
7
7
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.4 2006/07/14 14:52:16 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.5 2006/09/10 20: 14:20 tgl Exp $
12
12
*-------------------------------------------------------------------------
13
13
*/
14
-
15
14
#include "postgres.h"
15
+
16
+ #include "access/gin.h"
16
17
#include "utils/array.h"
17
- #include "utils/builtins.h"
18
18
#include "utils/lsyscache.h"
19
- #include "utils/typcache.h"
20
- #include "access/gin.h"
19
+
21
20
22
21
#define GinOverlapStrategy 1
23
22
#define GinContainsStrategy 2
29
28
ereport(ERROR, \
30
29
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
31
30
errmsg("array must not contain nulls"))); \
32
- \
33
- if ( ARR_NDIM(x) != 1 && ARR_NDIM(x) != 0 ) \
34
- ereport(ERROR, \
35
- (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
36
- errmsg("array must be one-dimensional"))); \
37
31
} while(0)
38
32
33
+
39
34
/*
40
35
* Function used as extractValue and extractQuery both
41
36
*/
@@ -70,9 +65,9 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
70
65
bool * check = (bool * )PG_GETARG_POINTER (0 );
71
66
StrategyNumber strategy = PG_GETARG_UINT16 (1 );
72
67
ArrayType * query = PG_GETARG_ARRAYTYPE_P (2 );
73
- int res = FALSE , i , nentries = ArrayGetNItems ( ARR_NDIM ( query ), ARR_DIMS ( query )) ;
68
+ int res , i , nentries ;
74
69
75
- /* we can do not check array carefully, it's done by previous ginarrayextract call */
70
+ /* ARRAYCHECK was already done by previous ginarrayextract call */
76
71
77
72
switch ( strategy ) {
78
73
case GinOverlapStrategy :
@@ -82,6 +77,7 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
82
77
break ;
83
78
case GinContainsStrategy :
84
79
case GinEqualStrategy :
80
+ nentries = ArrayGetNItems (ARR_NDIM (query ), ARR_DIMS (query ));
85
81
res = TRUE;
86
82
for (i = 0 ;i < nentries ;i ++ )
87
83
if ( !check [i ] ) {
@@ -90,168 +86,10 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
90
86
}
91
87
break ;
92
88
default :
93
- elog (ERROR , "ginarrayconsistent: unknown strategy number: %d" , strategy );
89
+ elog (ERROR , "ginarrayconsistent: unknown strategy number: %d" ,
90
+ strategy );
91
+ res = FALSE;
94
92
}
95
93
96
94
PG_RETURN_BOOL (res );
97
95
}
98
-
99
- static TypeCacheEntry *
100
- fillTypeCacheEntry ( TypeCacheEntry * typentry , Oid element_type ) {
101
- if ( typentry && typentry -> type_id == element_type )
102
- return typentry ;
103
-
104
- typentry = lookup_type_cache (element_type , TYPECACHE_EQ_OPR_FINFO );
105
- if (!OidIsValid (typentry -> eq_opr_finfo .fn_oid ))
106
- ereport (ERROR ,
107
- (errcode (ERRCODE_UNDEFINED_FUNCTION ),
108
- errmsg ("could not identify an equality operator for type %s" , format_type_be (element_type ))));
109
-
110
- return typentry ;
111
- }
112
-
113
- static bool
114
- typeEQ (FunctionCallInfoData * locfcinfo , Datum a , Datum b ) {
115
- locfcinfo -> arg [0 ] = a ;
116
- locfcinfo -> arg [1 ] = b ;
117
- locfcinfo -> argnull [0 ] = false;
118
- locfcinfo -> argnull [1 ] = false;
119
- locfcinfo -> isnull = false;
120
-
121
- return DatumGetBool (FunctionCallInvoke (locfcinfo ));
122
- }
123
-
124
- static bool
125
- ginArrayOverlap (TypeCacheEntry * typentry , ArrayType * a , ArrayType * b ) {
126
- Datum * da , * db ;
127
- int na , nb , j , i ;
128
- FunctionCallInfoData locfcinfo ;
129
-
130
- if ( ARR_ELEMTYPE (a ) != ARR_ELEMTYPE (b ) )
131
- ereport (ERROR ,
132
- (errcode (ERRCODE_DATATYPE_MISMATCH ),
133
- errmsg ("cannot compare arrays of different element types" )));
134
-
135
- ARRAYCHECK (a );
136
- ARRAYCHECK (b );
137
-
138
- deconstruct_array (a ,
139
- ARR_ELEMTYPE (a ),
140
- typentry -> typlen , typentry -> typbyval , typentry -> typalign ,
141
- & da , NULL , & na );
142
- deconstruct_array (b ,
143
- ARR_ELEMTYPE (b ),
144
- typentry -> typlen , typentry -> typbyval , typentry -> typalign ,
145
- & db , NULL , & nb );
146
-
147
- InitFunctionCallInfoData (locfcinfo , & typentry -> eq_opr_finfo , 2 ,
148
- NULL , NULL );
149
-
150
- for (i = 0 ;i < na ;i ++ ) {
151
- for (j = 0 ;j < nb ;j ++ ) {
152
- if ( typeEQ (& locfcinfo , da [i ], db [j ]) ) {
153
- pfree ( da );
154
- pfree ( db );
155
- return TRUE;
156
- }
157
- }
158
- }
159
-
160
- pfree ( da );
161
- pfree ( db );
162
-
163
- return FALSE;
164
- }
165
-
166
- static bool
167
- ginArrayContains (TypeCacheEntry * typentry , ArrayType * a , ArrayType * b ) {
168
- Datum * da , * db ;
169
- int na , nb , j , i , n = 0 ;
170
- FunctionCallInfoData locfcinfo ;
171
-
172
- if ( ARR_ELEMTYPE (a ) != ARR_ELEMTYPE (b ) )
173
- ereport (ERROR ,
174
- (errcode (ERRCODE_DATATYPE_MISMATCH ),
175
- errmsg ("cannot compare arrays of different element types" )));
176
-
177
- ARRAYCHECK (a );
178
- ARRAYCHECK (b );
179
-
180
- deconstruct_array (a ,
181
- ARR_ELEMTYPE (a ),
182
- typentry -> typlen , typentry -> typbyval , typentry -> typalign ,
183
- & da , NULL , & na );
184
- deconstruct_array (b ,
185
- ARR_ELEMTYPE (b ),
186
- typentry -> typlen , typentry -> typbyval , typentry -> typalign ,
187
- & db , NULL , & nb );
188
-
189
- InitFunctionCallInfoData (locfcinfo , & typentry -> eq_opr_finfo , 2 ,
190
- NULL , NULL );
191
-
192
- for (i = 0 ;i < nb ;i ++ ) {
193
- for (j = 0 ;j < na ;j ++ ) {
194
- if ( typeEQ (& locfcinfo , db [i ], da [j ]) ) {
195
- n ++ ;
196
- break ;
197
- }
198
- }
199
- }
200
-
201
- pfree ( da );
202
- pfree ( db );
203
-
204
- return ( n == nb ) ? TRUE : FALSE;
205
- }
206
-
207
- Datum
208
- arrayoverlap (PG_FUNCTION_ARGS ) {
209
- ArrayType * a = PG_GETARG_ARRAYTYPE_P (0 );
210
- ArrayType * b = PG_GETARG_ARRAYTYPE_P (1 );
211
- TypeCacheEntry * typentry = fillTypeCacheEntry ( fcinfo -> flinfo -> fn_extra , ARR_ELEMTYPE (a ) );
212
- bool res ;
213
-
214
- fcinfo -> flinfo -> fn_extra = (void * )typentry ;
215
-
216
- res = ginArrayOverlap ( typentry , a , b );
217
-
218
- PG_FREE_IF_COPY (a ,0 );
219
- PG_FREE_IF_COPY (b ,1 );
220
-
221
- PG_RETURN_BOOL (res );
222
- }
223
-
224
- Datum
225
- arraycontains (PG_FUNCTION_ARGS ) {
226
- ArrayType * a = PG_GETARG_ARRAYTYPE_P (0 );
227
- ArrayType * b = PG_GETARG_ARRAYTYPE_P (1 );
228
- TypeCacheEntry * typentry = fillTypeCacheEntry ( fcinfo -> flinfo -> fn_extra , ARR_ELEMTYPE (a ) );
229
- bool res ;
230
-
231
- fcinfo -> flinfo -> fn_extra = (void * )typentry ;
232
-
233
- res = ginArrayContains ( typentry , a , b );
234
-
235
- PG_FREE_IF_COPY (a ,0 );
236
- PG_FREE_IF_COPY (b ,1 );
237
-
238
- PG_RETURN_BOOL (res );
239
- }
240
-
241
- Datum
242
- arraycontained (PG_FUNCTION_ARGS ) {
243
- ArrayType * a = PG_GETARG_ARRAYTYPE_P (0 );
244
- ArrayType * b = PG_GETARG_ARRAYTYPE_P (1 );
245
- TypeCacheEntry * typentry = fillTypeCacheEntry ( fcinfo -> flinfo -> fn_extra , ARR_ELEMTYPE (a ) );
246
- bool res ;
247
-
248
- fcinfo -> flinfo -> fn_extra = (void * )typentry ;
249
-
250
- res = ginArrayContains ( typentry , b , a );
251
-
252
- PG_FREE_IF_COPY (a ,0 );
253
- PG_FREE_IF_COPY (b ,1 );
254
-
255
- PG_RETURN_BOOL (res );
256
- }
257
-
0 commit comments