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

Commit4ad0f88

Browse files
committed
Add btree_gin support for enum types
Reviewed by Tom Lane and Anastasia LubennikovaDiscussion:http://postgr.es/m/56EA8A71.8060107@dunslane.net
1 parentf7946a9 commit4ad0f88

File tree

6 files changed

+199
-11
lines changed

6 files changed

+199
-11
lines changed

‎contrib/btree_gin/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ MODULE_big = btree_gin
44
OBJS = btree_gin.o$(WIN32RES)
55

66
EXTENSION = btree_gin
7-
DATA = btree_gin--1.0.sql btree_gin--1.0--1.1.sql btree_gin--unpackaged--1.0.sql
7+
DATA = btree_gin--1.0.sql btree_gin--1.0--1.1.sql btree_gin--1.1--1.2.sql\
8+
btree_gin--unpackaged--1.0.sql
89
PGFILEDESC = "btree_gin - B-tree equivalent GIN operator classes"
910

1011
REGRESS = install_btree_gin int2 int4 int8 float4 float8 money oid\
1112
timestamp timestamptz time timetz date interval\
1213
macaddr macaddr8 inet cidr text varchar char bytea bit varbit\
13-
numeric
14+
numeric enum
1415

1516
ifdefUSE_PGXS
1617
PG_CONFIG = pg_config
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* contrib/btree_gin/btree_gin--1.1--1.2.sql*/
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use"ALTER EXTENSION btree_gin UPDATE TO '1.1'" to load this file. \quit
5+
6+
--
7+
--
8+
--
9+
-- enum ops
10+
--
11+
--
12+
13+
14+
CREATEFUNCTIONgin_extract_value_anyenum(anyenum, internal)
15+
RETURNS internal
16+
AS'MODULE_PATHNAME'
17+
LANGUAGE C STRICT IMMUTABLE;
18+
19+
CREATEFUNCTIONgin_compare_prefix_anyenum(anyenum, anyenum, int2, internal)
20+
RETURNS int4
21+
AS'MODULE_PATHNAME'
22+
LANGUAGE C STRICT IMMUTABLE;
23+
24+
CREATEFUNCTIONgin_extract_query_anyenum(anyenum, internal, int2, internal, internal)
25+
RETURNS internal
26+
AS'MODULE_PATHNAME'
27+
LANGUAGE C STRICT IMMUTABLE;
28+
29+
CREATEFUNCTIONgin_enum_cmp(anyenum, anyenum)
30+
RETURNS int4
31+
AS'MODULE_PATHNAME'
32+
LANGUAGE C STRICT IMMUTABLE;
33+
34+
CREATEOPERATOR CLASSenum_ops
35+
DEFAULT FOR TYPE anyenum USING gin
36+
AS
37+
OPERATOR1<,
38+
OPERATOR2<=,
39+
OPERATOR3=,
40+
OPERATOR4>=,
41+
OPERATOR5>,
42+
FUNCTION1 gin_enum_cmp(anyenum,anyenum),
43+
FUNCTION2 gin_extract_value_anyenum(anyenum, internal),
44+
FUNCTION3 gin_extract_query_anyenum(anyenum, internal, int2, internal, internal),
45+
FUNCTION4 gin_btree_consistent(internal, int2, anyelement, int4, internal, internal),
46+
FUNCTION5 gin_compare_prefix_anyenum(anyenum,anyenum,int2, internal),
47+
STORAGE anyenum;

‎contrib/btree_gin/btree_gin.c

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ typedef struct QueryInfo
2525
Datum(*typecmp) (FunctionCallInfo);
2626
}QueryInfo;
2727

28-
2928
/*** GIN support functions shared by all datatypes ***/
3029

3130
staticDatum
@@ -112,13 +111,14 @@ gin_btree_compare_prefix(FunctionCallInfo fcinfo)
112111
int32res,
113112
cmp;
114113

115-
cmp=DatumGetInt32(DirectFunctionCall2Coll(
116-
data->typecmp,
117-
PG_GET_COLLATION(),
118-
(data->strategy==BTLessStrategyNumber||
119-
data->strategy==BTLessEqualStrategyNumber)
120-
?data->datum :a,
121-
b));
114+
cmp=DatumGetInt32(CallerFInfoFunctionCall2(
115+
data->typecmp,
116+
fcinfo->flinfo,
117+
PG_GET_COLLATION(),
118+
(data->strategy==BTLessStrategyNumber||
119+
data->strategy==BTLessEqualStrategyNumber)
120+
?data->datum :a,
121+
b));
122122

123123
switch (data->strategy)
124124
{
@@ -426,3 +426,54 @@ leftmostvalue_numeric(void)
426426
}
427427

428428
GIN_SUPPORT(numeric, true,leftmostvalue_numeric,gin_numeric_cmp)
429+
430+
/*
431+
* Use a similar trick to that used for numeric for enums, since we don't
432+
* actually know the leftmost value of any enum without knowing the concrete
433+
* type, so we use a dummy leftmost value of InvalidOid.
434+
*
435+
* Note that we use CallerFInfoFunctionCall2 here so that enum_cmp
436+
* gets a valid fn_extra to work with. Unlike most other type comparison
437+
* routines it needs it, so we can't use DirectFunctionCall2.
438+
*/
439+
440+
441+
#defineENUM_IS_LEFTMOST(x)((x) == InvalidOid)
442+
443+
PG_FUNCTION_INFO_V1(gin_enum_cmp);
444+
445+
Datum
446+
gin_enum_cmp(PG_FUNCTION_ARGS)
447+
{
448+
Oida=PG_GETARG_OID(0);
449+
Oidb=PG_GETARG_OID(1);
450+
intres=0;
451+
452+
if (ENUM_IS_LEFTMOST(a))
453+
{
454+
res= (ENUM_IS_LEFTMOST(b)) ?0 :-1;
455+
}
456+
elseif (ENUM_IS_LEFTMOST(b))
457+
{
458+
res=1;
459+
}
460+
else
461+
{
462+
res=DatumGetInt32(CallerFInfoFunctionCall2(
463+
enum_cmp,
464+
fcinfo->flinfo,
465+
PG_GET_COLLATION(),
466+
ObjectIdGetDatum(a),
467+
ObjectIdGetDatum(b)));
468+
}
469+
470+
PG_RETURN_INT32(res);
471+
}
472+
473+
staticDatum
474+
leftmostvalue_enum(void)
475+
{
476+
returnObjectIdGetDatum(InvalidOid);
477+
}
478+
479+
GIN_SUPPORT(anyenum, false,leftmostvalue_enum,gin_enum_cmp)

‎contrib/btree_gin/btree_gin.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# btree_gin extension
22
comment = 'support for indexing common datatypes in GIN'
3-
default_version = '1.1'
3+
default_version = '1.2'
44
module_pathname = '$libdir/btree_gin'
55
relocatable = true

‎contrib/btree_gin/expected/enum.out

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
set enable_seqscan=off;
2+
CREATE TYPE rainbow AS ENUM ('r','o','y','g','b','i','v');
3+
CREATE TABLE test_enum (
4+
i rainbow
5+
);
6+
INSERT INTO test_enum VALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
7+
CREATE INDEX idx_enum ON test_enum USING gin (i);
8+
SELECT * FROM test_enum WHERE i<'g'::rainbow ORDER BY i;
9+
i
10+
---
11+
r
12+
o
13+
y
14+
(3 rows)
15+
16+
SELECT * FROM test_enum WHERE i<='g'::rainbow ORDER BY i;
17+
i
18+
---
19+
r
20+
o
21+
y
22+
g
23+
(4 rows)
24+
25+
SELECT * FROM test_enum WHERE i='g'::rainbow ORDER BY i;
26+
i
27+
---
28+
g
29+
(1 row)
30+
31+
SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
32+
i
33+
---
34+
g
35+
b
36+
i
37+
v
38+
(4 rows)
39+
40+
SELECT * FROM test_enum WHERE i>'g'::rainbow ORDER BY i;
41+
i
42+
---
43+
b
44+
i
45+
v
46+
(3 rows)
47+
48+
explain (costs off) SELECT * FROM test_enum WHERE i>='g'::rainbow ORDER BY i;
49+
QUERY PLAN
50+
-----------------------------------------------
51+
Sort
52+
Sort Key: i
53+
-> Bitmap Heap Scan on test_enum
54+
Recheck Cond: (i >= 'g'::rainbow)
55+
-> Bitmap Index Scan on idx_enum
56+
Index Cond: (i >= 'g'::rainbow)
57+
(6 rows)
58+
59+
-- make sure we handle the non-evenly-numbered oid case for enums
60+
create type e as enum ('0', '2', '3');
61+
alter type e add value '1' after '0';
62+
create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
63+
create index on t using gin (e);

‎contrib/btree_gin/sql/enum.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
set enable_seqscan=off;
2+
3+
CREATETYPErainbowAS ENUM ('r','o','y','g','b','i','v');
4+
5+
CREATETABLEtest_enum (
6+
i rainbow
7+
);
8+
9+
INSERT INTO test_enumVALUES ('v'),('y'),('r'),('g'),('o'),('i'),('b');
10+
11+
CREATEINDEXidx_enumON test_enum USING gin (i);
12+
13+
SELECT*FROM test_enumWHERE i<'g'::rainbowORDER BY i;
14+
SELECT*FROM test_enumWHERE i<='g'::rainbowORDER BY i;
15+
SELECT*FROM test_enumWHERE i='g'::rainbowORDER BY i;
16+
SELECT*FROM test_enumWHERE i>='g'::rainbowORDER BY i;
17+
SELECT*FROM test_enumWHERE i>'g'::rainbowORDER BY i;
18+
19+
explain (costs off)SELECT*FROM test_enumWHERE i>='g'::rainbowORDER BY i;
20+
21+
22+
-- make sure we handle the non-evenly-numbered oid case for enums
23+
createtypeeas enum ('0','2','3');
24+
altertype e add value'1' after'0';
25+
createtabletasselect (i %4)::text::efrom generate_series(0,100000)as i;
26+
createindexon t using gin (e);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp