Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf5b4d9a

Browse files
committed
If we're going to advertise the array overlap/containment operators,
we probably should make them work reliably for all arrays. Fix codeto handle NULLs and multidimensional arrays, move it into arrayfuncs.c.GIN is still restricted to indexing arrays with no null elements, however.
1 parent69b7c99 commitf5b4d9a

File tree

4 files changed

+245
-183
lines changed

4 files changed

+245
-183
lines changed

‎src/backend/access/gin/ginarrayproc.c

Lines changed: 13 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
/*-------------------------------------------------------------------------
22
*
3-
*ginvacuum.c
4-
* supportfunction for GIN's indexing of any array
3+
*ginarrayproc.c
4+
* supportfunctions for GIN's indexing of any array
55
*
66
*
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
*$PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.4 2006/07/1414:52:16 momjian Exp $
11+
*$PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.5 2006/09/10 20:14:20 tgl Exp $
1212
*-------------------------------------------------------------------------
1313
*/
14-
1514
#include"postgres.h"
15+
16+
#include"access/gin.h"
1617
#include"utils/array.h"
17-
#include"utils/builtins.h"
1818
#include"utils/lsyscache.h"
19-
#include"utils/typcache.h"
20-
#include"access/gin.h"
19+
2120

2221
#defineGinOverlapStrategy1
2322
#defineGinContainsStrategy2
@@ -29,13 +28,9 @@
2928
ereport(ERROR, \
3029
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
3130
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"))); \
3731
} while(0)
3832

33+
3934
/*
4035
* Function used as extractValue and extractQuery both
4136
*/
@@ -70,9 +65,9 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
7065
bool*check= (bool*)PG_GETARG_POINTER(0);
7166
StrategyNumberstrategy=PG_GETARG_UINT16(1);
7267
ArrayType*query=PG_GETARG_ARRAYTYPE_P(2);
73-
intres=FALSE,i,nentries=ArrayGetNItems(ARR_NDIM(query),ARR_DIMS(query));
68+
intres,i,nentries;
7469

75-
/*we can do not check array carefully, it's done by previous ginarrayextract call */
70+
/*ARRAYCHECK was already done by previous ginarrayextract call */
7671

7772
switch(strategy ) {
7873
caseGinOverlapStrategy:
@@ -82,6 +77,7 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
8277
break;
8378
caseGinContainsStrategy:
8479
caseGinEqualStrategy:
80+
nentries=ArrayGetNItems(ARR_NDIM(query),ARR_DIMS(query));
8581
res= TRUE;
8682
for(i=0;i<nentries;i++)
8783
if ( !check[i] ) {
@@ -90,168 +86,10 @@ ginarrayconsistent(PG_FUNCTION_ARGS) {
9086
}
9187
break;
9288
default:
93-
elog(ERROR,"ginarrayconsistent: unknown strategy number: %d",strategy);
89+
elog(ERROR,"ginarrayconsistent: unknown strategy number: %d",
90+
strategy);
91+
res= FALSE;
9492
}
9593

9694
PG_RETURN_BOOL(res);
9795
}
98-
99-
staticTypeCacheEntry*
100-
fillTypeCacheEntry(TypeCacheEntry*typentry,Oidelement_type ) {
101-
if (typentry&&typentry->type_id==element_type )
102-
returntypentry;
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-
returntypentry;
111-
}
112-
113-
staticbool
114-
typeEQ(FunctionCallInfoData*locfcinfo,Datuma,Datumb) {
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-
returnDatumGetBool(FunctionCallInvoke(locfcinfo));
122-
}
123-
124-
staticbool
125-
ginArrayOverlap(TypeCacheEntry*typentry,ArrayType*a,ArrayType*b) {
126-
Datum*da,*db;
127-
intna,nb,j,i;
128-
FunctionCallInfoDatalocfcinfo;
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-
staticbool
167-
ginArrayContains(TypeCacheEntry*typentry,ArrayType*a,ArrayType*b) {
168-
Datum*da,*db;
169-
intna,nb,j,i,n=0;
170-
FunctionCallInfoDatalocfcinfo;
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-
boolres;
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-
boolres;
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-
boolres;
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

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp