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

Commit5320c6c

Browse files
committed
Make GIN opclass worked with intarray extensions
1 parent2a58f3b commit5320c6c

File tree

8 files changed

+258
-16
lines changed

8 files changed

+258
-16
lines changed

‎contrib/intarray/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# $PostgreSQL: pgsql/contrib/intarray/Makefile,v 1.13 2006/02/27 12:54:39 petere Exp $
1+
# $PostgreSQL: pgsql/contrib/intarray/Makefile,v 1.14 2006/05/03 16:31:07 teodor Exp $
22

33
MODULE_big = _int
4-
OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o
4+
OBJS = _int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o_int_gin.o
55
DATA_built = _int.sql
66
DATA = uninstall__int.sql
77
DOCS = README.intarray

‎contrib/intarray/_int.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,17 @@ typedef struct
151151
#defineCOMPUTESIZE(size)( HDRSIZEQT + size * sizeof(ITEM) )
152152
#defineGETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
153153

154+
#defineEND 0
155+
#defineERR 1
156+
#defineVAL 2
157+
#defineOPR 3
158+
#defineOPEN 4
159+
#defineCLOSE 5
160+
154161
boolsignconsistent(QUERYTYPE*query,BITVECsign,boolcalcnot);
155162
boolexecconsistent(QUERYTYPE*query,ArrayType*array,boolcalcnot);
156-
157-
163+
boolginconsistent(QUERYTYPE*query,bool*check);
164+
int4shorterquery(ITEM*q,int4len);
158165

159166
intcompASC(constvoid*a,constvoid*b);
160167

‎contrib/intarray/_int.sql.in

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
-- opclasses get created.
77
SET search_path = public;
88

9+
BEGIN;
10+
911
-- Query type
1012
CREATE FUNCTION bqarr_in(cstring)
1113
RETURNS query_int
@@ -431,3 +433,35 @@ AS
431433
FUNCTION6g_intbig_picksplit (internal, internal),
432434
FUNCTION7g_intbig_same (internal, internal, internal),
433435
STORAGEintbig_gkey;
436+
437+
--GIN
438+
--mark built-in gin's _int4_ops as non default
439+
update pg_opclass set opcdefault = 'f' where
440+
pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and
441+
opcname = '_int4_ops';
442+
443+
CREATE FUNCTION ginint4_queryextract(internal, internal, int2)
444+
RETURNS internal
445+
AS 'MODULE_PATHNAME'
446+
LANGUAGE C;
447+
448+
CREATE FUNCTION ginint4_consistent(internal, int2, internal)
449+
RETURNS internal
450+
AS 'MODULE_PATHNAME'
451+
LANGUAGE C;
452+
453+
CREATE OPERATOR CLASS gin__int_ops
454+
DEFAULT FOR TYPE _int4 USING gin
455+
AS
456+
OPERATOR3&&,
457+
OPERATOR6= (anyarray, anyarray)RECHECK,
458+
OPERATOR7@,
459+
OPERATOR8~RECHECK,
460+
OPERATOR20@@ (_int4, query_int),
461+
FUNCTION1btint4cmp (int4, int4),
462+
FUNCTION2ginarrayextract (anyarray, internal),
463+
FUNCTION3ginint4_queryextract (internal, internal, int2),
464+
FUNCTION4ginint4_consistent (internal, int2, internal),
465+
STORAGEint4;
466+
467+
COMMIT;

‎contrib/intarray/_int_bool.c

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ typedef struct
232232
* is there value 'val' in array or not ?
233233
*/
234234
staticbool
235-
checkcondition_arr(void*checkval,int4val)
235+
checkcondition_arr(void*checkval,ITEM*item)
236236
{
237237
int4*StopLow= ((CHKVAL*)checkval)->arrb;
238238
int4*StopHigh= ((CHKVAL*)checkval)->arre;
@@ -243,9 +243,9 @@ checkcondition_arr(void *checkval, int4 val)
243243
while (StopLow<StopHigh)
244244
{
245245
StopMiddle=StopLow+ (StopHigh-StopLow) /2;
246-
if (*StopMiddle==val)
246+
if (*StopMiddle==item->val)
247247
return (true);
248-
elseif (*StopMiddle<val)
248+
elseif (*StopMiddle<item->val)
249249
StopLow=StopMiddle+1;
250250
else
251251
StopHigh=StopMiddle;
@@ -254,20 +254,20 @@ checkcondition_arr(void *checkval, int4 val)
254254
}
255255

256256
staticbool
257-
checkcondition_bit(void*checkval,int4val)
257+
checkcondition_bit(void*checkval,ITEM*item)
258258
{
259-
returnGETBIT(checkval,HASHVAL(val));
259+
returnGETBIT(checkval,HASHVAL(item->val));
260260
}
261261

262262
/*
263263
* check for boolean condition
264264
*/
265265
staticbool
266-
execute(ITEM*curitem,void*checkval,boolcalcnot,bool (*chkcond) (void*checkval,int4val))
266+
execute(ITEM*curitem,void*checkval,boolcalcnot,bool (*chkcond) (void*checkval,ITEM*item))
267267
{
268268

269269
if (curitem->type==VAL)
270-
return (*chkcond) (checkval,curitem->val);
270+
return (*chkcond) (checkval,curitem);
271271
elseif (curitem->val== (int4)'!')
272272
{
273273
return (calcnot) ?
@@ -319,6 +319,40 @@ execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
319319
);
320320
}
321321

322+
typedefstruct {
323+
ITEM*first;
324+
bool*mapped_check;
325+
}GinChkVal;
326+
327+
staticbool
328+
checkcondition_gin(void*checkval,ITEM*item) {
329+
GinChkVal*gcv= (GinChkVal*)checkval;
330+
331+
returngcv->mapped_check[item-gcv->first ];
332+
}
333+
334+
bool
335+
ginconsistent(QUERYTYPE*query,bool*check) {
336+
GinChkValgcv;
337+
ITEM*items=GETQUERY(query);
338+
inti,j=0;
339+
340+
if (query->size<0 )
341+
return FALSE;
342+
343+
gcv.first=items;
344+
gcv.mapped_check= (bool*)palloc(sizeof(bool)*query->size );
345+
for(i=0;i<query->size;i++)
346+
if (items[i].type==VAL )
347+
gcv.mapped_check[i ]=check[j++ ];
348+
349+
returnexecute(
350+
GETQUERY(query)+query->size-1,
351+
(void*)&gcv, true,
352+
checkcondition_gin
353+
);
354+
}
355+
322356
/*
323357
* boolean operations
324358
*/
@@ -588,7 +622,7 @@ countdroptree(ITEM * q, int4 pos)
588622
* result of all '!' will be = 'true', so
589623
* we can modify query tree for clearing
590624
*/
591-
staticint4
625+
int4
592626
shorterquery(ITEM*q,int4len)
593627
{
594628
int4index,

‎contrib/intarray/_int_gin.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include"_int.h"
2+
3+
PG_FUNCTION_INFO_V1(ginint4_queryextract);
4+
Datumginint4_queryextract(PG_FUNCTION_ARGS);
5+
6+
Datum
7+
ginint4_queryextract(PG_FUNCTION_ARGS) {
8+
uint32*nentries= (uint32*)PG_GETARG_POINTER(1);
9+
StrategyNumberstrategy=PG_GETARG_UINT16(2);
10+
Datum*res=NULL;
11+
12+
*nentries=0;
13+
14+
if (strategy==BooleanSearchStrategy ) {
15+
QUERYTYPE*query= (QUERYTYPE*)PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0));
16+
ITEM*items=GETQUERY(query);
17+
inti;
18+
19+
if (query->size==0)
20+
PG_RETURN_POINTER(NULL);
21+
22+
if (shorterquery(items,query->size)==0 )
23+
elog(ERROR,"Query requires full scan, GIN doesn't support it");
24+
25+
pfree(query );
26+
27+
query= (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
28+
items=GETQUERY(query);
29+
30+
res= (Datum*)palloc(sizeof(Datum)*query->size);
31+
*nentries=0;
32+
33+
for(i=0;i<query->size;i++)
34+
if (items[i].type==VAL ) {
35+
res[*nentries]=Int32GetDatum(items[i].val );
36+
(*nentries)++;
37+
}
38+
}else {
39+
ArrayType*query=PG_GETARG_ARRAYTYPE_P(0);
40+
int4*arr;
41+
uint32i;
42+
43+
CHECKARRVALID(query);
44+
*nentries=ARRNELEMS(query);
45+
if (*nentries>0 ) {
46+
res= (Datum*)palloc(sizeof(Datum)* (*nentries));
47+
48+
arr=ARRPTR(query);
49+
for(i=0;i<*nentries;i++)
50+
res[i]=Int32GetDatum(arr[i] );
51+
}
52+
}
53+
54+
PG_RETURN_POINTER(res );
55+
}
56+
57+
PG_FUNCTION_INFO_V1(ginint4_consistent);
58+
Datumginint4_consistent(PG_FUNCTION_ARGS);
59+
60+
Datum
61+
ginint4_consistent(PG_FUNCTION_ARGS) {
62+
bool*check= (bool*)PG_GETARG_POINTER(0);
63+
StrategyNumberstrategy=PG_GETARG_UINT16(1);
64+
intres=FALSE;
65+
66+
/* we can do not check array carefully, it's done by previous ginarrayextract call */
67+
68+
switch(strategy ) {
69+
caseRTOverlapStrategyNumber:
70+
caseRTContainedByStrategyNumber:
71+
/* at least one element in check[] is true, so result = true */
72+
73+
res= TRUE;
74+
break;
75+
caseRTSameStrategyNumber:
76+
caseRTContainsStrategyNumber:
77+
res= TRUE;
78+
do {
79+
ArrayType*query=PG_GETARG_ARRAYTYPE_P(2);
80+
inti,nentries=ARRNELEMS(query);
81+
82+
for(i=0;i<nentries;i++)
83+
if ( !check[i] ) {
84+
res= FALSE;
85+
break;
86+
}
87+
}while(0);
88+
break;
89+
caseBooleanSearchStrategy:
90+
do {
91+
QUERYTYPE*query= (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(2));
92+
res=ginconsistent(query,check );
93+
}while(0);
94+
break;
95+
default:
96+
elog(ERROR,"ginint4_consistent: unknown strategy number: %d",strategy);
97+
}
98+
99+
PG_RETURN_BOOL(res);
100+
}

‎contrib/intarray/expected/_int.out

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
-- does not depend on contents of _int.sql.
44
--
55
\set ECHO none
6-
psql:_int.sql:13: NOTICE: type "query_int" is not yet defined
6+
psql:_int.sql:15: NOTICE: type "query_int" is not yet defined
77
DETAIL: Creating a shell type definition.
8-
psql:_int.sql:18: NOTICE: argument type query_int is only a shell
9-
psql:_int.sql:368: NOTICE: type "intbig_gkey" is not yet defined
8+
psql:_int.sql:20: NOTICE: argument type query_int is only a shell
9+
psql:_int.sql:370: NOTICE: type "intbig_gkey" is not yet defined
1010
DETAIL: Creating a shell type definition.
11-
psql:_int.sql:373: NOTICE: argument type intbig_gkey is only a shell
11+
psql:_int.sql:375: NOTICE: argument type intbig_gkey is only a shell
1212
SELECT intset(1234);
1313
intset
1414
--------
@@ -519,3 +519,53 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
519519
21
520520
(1 row)
521521

522+
DROP INDEX text_idx;
523+
CREATE INDEX text_idx on test__int using gin ( a );
524+
SELECT count(*) from test__int WHERE a && '{23,50}';
525+
count
526+
-------
527+
403
528+
(1 row)
529+
530+
SELECT count(*) from test__int WHERE a @@ '23|50';
531+
count
532+
-------
533+
403
534+
(1 row)
535+
536+
SELECT count(*) from test__int WHERE a @ '{23,50}';
537+
count
538+
-------
539+
12
540+
(1 row)
541+
542+
SELECT count(*) from test__int WHERE a @@ '23&50';
543+
count
544+
-------
545+
12
546+
(1 row)
547+
548+
SELECT count(*) from test__int WHERE a @ '{20,23}';
549+
count
550+
-------
551+
12
552+
(1 row)
553+
554+
SELECT count(*) from test__int WHERE a @@ '50&68';
555+
count
556+
-------
557+
9
558+
(1 row)
559+
560+
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
561+
count
562+
-------
563+
21
564+
(1 row)
565+
566+
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
567+
count
568+
-------
569+
21
570+
(1 row)
571+

‎contrib/intarray/sql/_int.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,15 @@ SELECT count(*) from test__int WHERE a @ '{20,23}';
107107
SELECTcount(*)from test__intWHERE a @@'50&68';
108108
SELECTcount(*)from test__intWHERE a @'{20,23}'or a @'{50,68}';
109109
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
110+
111+
DROPINDEX text_idx;
112+
CREATEINDEXtext_idxon test__int using gin ( a );
113+
114+
SELECTcount(*)from test__intWHERE a &&'{23,50}';
115+
SELECTcount(*)from test__intWHERE a @@'23|50';
116+
SELECTcount(*)from test__intWHERE a @'{23,50}';
117+
SELECTcount(*)from test__intWHERE a @@'23&50';
118+
SELECTcount(*)from test__intWHERE a @'{20,23}';
119+
SELECTcount(*)from test__intWHERE a @@'50&68';
120+
SELECTcount(*)from test__intWHERE a @'{20,23}'or a @'{50,68}';
121+
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';

‎contrib/intarray/uninstall__int.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,8 @@ DROP FUNCTION boolop(_int4, query_int);
113113
DROPFUNCTION querytree(query_int);
114114

115115
DROPTYPE query_int CASCADE;
116+
117+
update pg_opclassset opcdefault='t'where
118+
pg_opclass.opcamid= (selectpg_am.oidfrom pg_amwhere amname='gin')and
119+
opcname='_int4_ops';
120+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp