Skip to content

Commit 5ec8103

Browse files
committed
timestamp rum
1 parent 49c9b51 commit 5ec8103

File tree

5 files changed

+272
-4
lines changed

5 files changed

+272
-4
lines changed

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ MODULE_big = rum
44
OBJS = rumsort.o rum_ts_utils.o \
55
rumbtree.o rumbulk.o rumdatapage.o \
66
rumentrypage.o rumfast.o rumget.o ruminsert.o \
7-
rumscan.o rumutil.o rumvacuum.o rumvalidate.o $(WIN32RES)
7+
rumscan.o rumutil.o rumvacuum.o rumvalidate.o \
8+
rum_timestamp.o $(WIN32RES)
89

910
EXTENSION = rum
1011
DATA = rum--1.0.sql
1112
PGFILEDESC = "RUM index access method"
1213

13-
REGRESS = rum
14+
REGRESS = rum timestamp
1415

1516
ifdef USE_PGXS
1617
PG_CONFIG = pg_config

expected/timestamp.out

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
set enable_seqscan=off;
2+
CREATE TABLE test_timestamp (
3+
i timestamp
4+
);
5+
INSERT INTO test_timestamp VALUES
6+
( '2004-10-26 03:55:08' ),
7+
( '2004-10-26 04:55:08' ),
8+
( '2004-10-26 05:55:08' ),
9+
( '2004-10-26 08:55:08' ),
10+
( '2004-10-26 09:55:08' ),
11+
( '2004-10-26 10:55:08' )
12+
;
13+
CREATE INDEX idx_timestamp ON test_timestamp USING rum (i);
14+
SELECT * FROM test_timestamp WHERE i<'2004-10-26 08:55:08'::timestamp ORDER BY i;
15+
i
16+
--------------------------
17+
Tue Oct 26 03:55:08 2004
18+
Tue Oct 26 04:55:08 2004
19+
Tue Oct 26 05:55:08 2004
20+
(3 rows)
21+
22+
SELECT * FROM test_timestamp WHERE i<='2004-10-26 08:55:08'::timestamp ORDER BY i;
23+
i
24+
--------------------------
25+
Tue Oct 26 03:55:08 2004
26+
Tue Oct 26 04:55:08 2004
27+
Tue Oct 26 05:55:08 2004
28+
Tue Oct 26 08:55:08 2004
29+
(4 rows)
30+
31+
SELECT * FROM test_timestamp WHERE i='2004-10-26 08:55:08'::timestamp ORDER BY i;
32+
i
33+
--------------------------
34+
Tue Oct 26 08:55:08 2004
35+
(1 row)
36+
37+
SELECT * FROM test_timestamp WHERE i>='2004-10-26 08:55:08'::timestamp ORDER BY i;
38+
i
39+
--------------------------
40+
Tue Oct 26 08:55:08 2004
41+
Tue Oct 26 09:55:08 2004
42+
Tue Oct 26 10:55:08 2004
43+
(3 rows)
44+
45+
SELECT * FROM test_timestamp WHERE i>'2004-10-26 08:55:08'::timestamp ORDER BY i;
46+
i
47+
--------------------------
48+
Tue Oct 26 09:55:08 2004
49+
Tue Oct 26 10:55:08 2004
50+
(2 rows)
51+

rum--1.0.sql

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ RETURNS internal
2424
AS 'MODULE_PATHNAME'
2525
LANGUAGE C IMMUTABLE STRICT;
2626

27-
CREATE FUNCTION rum_extract_tsquery(tsvector,internal,smallint,internal,internal,internal,internal)
27+
CREATE FUNCTION rum_extract_tsquery(tsquery,internal,smallint,internal,internal,internal,internal)
2828
RETURNS internal
2929
AS 'MODULE_PATHNAME'
3030
LANGUAGE C IMMUTABLE STRICT;
@@ -56,11 +56,50 @@ AS
5656
OPERATOR 2 >< (tsvector, tsquery) FOR ORDER BY pg_catalog.float_ops,
5757
FUNCTION 1 gin_cmp_tslexeme(text, text),
5858
FUNCTION 2 rum_extract_tsvector(tsvector,internal,internal,internal,internal),
59-
FUNCTION 3 rum_extract_tsquery(tsvector,internal,smallint,internal,internal,internal,internal),
59+
FUNCTION 3 rum_extract_tsquery(tsquery,internal,smallint,internal,internal,internal,internal),
6060
FUNCTION 4 rum_tsquery_consistent(internal,smallint,tsvector,int,internal,internal,internal,internal),
6161
FUNCTION 5 gin_cmp_prefix(text,text,smallint,internal),
6262
FUNCTION 6 gin_tsquery_triconsistent(internal,smallint,tsvector,int,internal,internal,internal),
6363
FUNCTION 7 rum_tsvector_config(internal),
6464
FUNCTION 8 rum_tsquery_pre_consistent(internal,smallint,tsvector,int,internal,internal,internal,internal),
6565
FUNCTION 9 rum_tsquery_distance(internal,smallint,tsvector,int,internal,internal,internal,internal,internal),
6666
STORAGE text;
67+
68+
69+
-- timestamp
70+
71+
CREATE FUNCTION rum_timestamp_extract_value(timestamp,internal,internal,internal,internal)
72+
RETURNS internal
73+
AS 'MODULE_PATHNAME'
74+
LANGUAGE C STRICT IMMUTABLE;
75+
76+
CREATE FUNCTION rum_timestamp_compare_prefix(timestamp,timestamp,smallint,internal)
77+
RETURNS int4
78+
AS 'MODULE_PATHNAME'
79+
LANGUAGE C STRICT IMMUTABLE;
80+
81+
CREATE FUNCTION rum_timestamp_extract_query(timestamp,internal,smallint,internal,internal,internal,internal)
82+
RETURNS internal
83+
AS 'MODULE_PATHNAME'
84+
LANGUAGE C STRICT IMMUTABLE;
85+
86+
CREATE FUNCTION rum_timestamp_consistent(internal,smallint,timestamp,int,internal,internal,internal,internal)
87+
RETURNS bool
88+
AS 'MODULE_PATHNAME'
89+
LANGUAGE C STRICT IMMUTABLE;
90+
91+
CREATE OPERATOR CLASS timestamp_ops
92+
DEFAULT FOR TYPE timestamp USING rum
93+
AS
94+
OPERATOR 1 <,
95+
OPERATOR 2 <=,
96+
OPERATOR 3 =,
97+
OPERATOR 4 >=,
98+
OPERATOR 5 >,
99+
FUNCTION 1 timestamp_cmp(timestamp,timestamp),
100+
FUNCTION 2 rum_timestamp_extract_value(timestamp,internal,internal,internal,internal),
101+
FUNCTION 3 rum_timestamp_extract_query(timestamp,internal,smallint,internal,internal,internal,internal),
102+
FUNCTION 4 rum_timestamp_consistent(internal,smallint,timestamp,int,internal,internal,internal,internal),
103+
FUNCTION 5 rum_timestamp_compare_prefix(timestamp,timestamp,smallint,internal),
104+
STORAGE timestamp;
105+

rum_timestamp.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include "postgres.h"
2+
3+
#include <limits.h>
4+
5+
#include "access/stratnum.h"
6+
#include "utils/builtins.h"
7+
#include "utils/timestamp.h"
8+
9+
typedef struct QueryInfo
10+
{
11+
StrategyNumber strategy;
12+
Datum datum;
13+
} QueryInfo;
14+
15+
16+
PG_FUNCTION_INFO_V1(rum_timestamp_extract_value);
17+
Datum
18+
rum_timestamp_extract_value(PG_FUNCTION_ARGS)
19+
{
20+
Datum datum = PG_GETARG_DATUM(0);
21+
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
22+
Datum *entries = (Datum *) palloc(sizeof(Datum));
23+
24+
entries[0] = datum;
25+
*nentries = 1;
26+
27+
PG_RETURN_POINTER(entries);
28+
}
29+
30+
PG_FUNCTION_INFO_V1(rum_timestamp_extract_query);
31+
Datum
32+
rum_timestamp_extract_query(PG_FUNCTION_ARGS)
33+
{
34+
Datum datum = PG_GETARG_DATUM(0);
35+
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
36+
StrategyNumber strategy = PG_GETARG_UINT16(2);
37+
bool **partialmatch = (bool **) PG_GETARG_POINTER(3);
38+
Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4);
39+
Datum *entries = (Datum *) palloc(sizeof(Datum));
40+
QueryInfo *data = (QueryInfo *) palloc(sizeof(QueryInfo));
41+
bool *ptr_partialmatch;
42+
43+
*nentries = 1;
44+
ptr_partialmatch = *partialmatch = (bool *) palloc(sizeof(bool));
45+
*ptr_partialmatch = false;
46+
data->strategy = strategy;
47+
data->datum = datum;
48+
*extra_data = (Pointer *) palloc(sizeof(Pointer));
49+
**extra_data = (Pointer) data;
50+
51+
switch(strategy)
52+
{
53+
case BTLessStrategyNumber:
54+
case BTLessEqualStrategyNumber:
55+
entries[0] = TimestampGetDatum(DT_NOBEGIN); /* leftmost */
56+
*ptr_partialmatch = true;
57+
break;
58+
case BTGreaterEqualStrategyNumber:
59+
case BTGreaterStrategyNumber:
60+
*ptr_partialmatch = true;
61+
case BTEqualStrategyNumber:
62+
entries[0] = datum;
63+
break;
64+
default:
65+
elog(ERROR, "unrecognized strategy number: %d", strategy);
66+
}
67+
68+
PG_RETURN_POINTER(entries);
69+
}
70+
71+
PG_FUNCTION_INFO_V1(rum_timestamp_compare_prefix);
72+
Datum
73+
rum_timestamp_compare_prefix(PG_FUNCTION_ARGS)
74+
{
75+
Datum a = PG_GETARG_DATUM(0);
76+
Datum b = PG_GETARG_DATUM(1);
77+
QueryInfo *data = (QueryInfo *) PG_GETARG_POINTER(3);
78+
int32 res, cmp;
79+
80+
cmp = DatumGetInt32(DirectFunctionCall2Coll(timestamp_cmp,
81+
PG_GET_COLLATION(),
82+
(data->strategy == BTLessStrategyNumber ||
83+
data->strategy == BTLessEqualStrategyNumber)
84+
? data->datum : a, b));
85+
86+
switch (data->strategy)
87+
{
88+
case BTLessStrategyNumber:
89+
/* If original datum > indexed one then return match */
90+
if (cmp > 0)
91+
res = 0;
92+
else
93+
res = 1;
94+
break;
95+
case BTLessEqualStrategyNumber:
96+
/* The same except equality */
97+
if (cmp >= 0)
98+
res = 0;
99+
else
100+
res = 1;
101+
break;
102+
case BTEqualStrategyNumber:
103+
if (cmp != 0)
104+
res = 1;
105+
else
106+
res = 0;
107+
break;
108+
case BTGreaterEqualStrategyNumber:
109+
/* If original datum <= indexed one then return match */
110+
if (cmp <= 0)
111+
res = 0;
112+
else
113+
res = 1;
114+
break;
115+
case BTGreaterStrategyNumber:
116+
/* If original datum <= indexed one then return match */
117+
/* If original datum == indexed one then continue scan */
118+
if (cmp < 0)
119+
res = 0;
120+
else if (cmp == 0)
121+
res = -1;
122+
else
123+
res = 1;
124+
break;
125+
default:
126+
elog(ERROR, "unrecognized strategy number: %d", data->strategy);
127+
res = 0;
128+
}
129+
130+
PG_RETURN_INT32(res);
131+
}
132+
133+
PG_FUNCTION_INFO_V1(rum_timestamp_consistent);
134+
Datum
135+
rum_timestamp_consistent(PG_FUNCTION_ARGS)
136+
{
137+
bool *recheck = (bool *) PG_GETARG_POINTER(5);
138+
139+
*recheck = false;
140+
PG_RETURN_BOOL(true);
141+
}

sql/timestamp.sql

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
set enable_seqscan=off;
2+
3+
CREATE TABLE test_timestamp (
4+
i timestamp
5+
);
6+
7+
INSERT INTO test_timestamp VALUES
8+
( '2004-10-26 03:55:08' ),
9+
( '2004-10-26 04:55:08' ),
10+
( '2004-10-26 05:55:08' ),
11+
( '2004-10-26 08:55:08' ),
12+
( '2004-10-26 09:55:08' ),
13+
( '2004-10-26 10:55:08' )
14+
;
15+
16+
CREATE INDEX idx_timestamp ON test_timestamp USING rum (i);
17+
18+
explain (costs off)
19+
SELECT * FROM test_timestamp WHERE i<'2004-10-26 08:55:08'::timestamp ORDER BY i;
20+
SELECT * FROM test_timestamp WHERE i<'2004-10-26 08:55:08'::timestamp ORDER BY i;
21+
22+
explain (costs off)
23+
SELECT * FROM test_timestamp WHERE i<='2004-10-26 08:55:08'::timestamp ORDER BY i;
24+
SELECT * FROM test_timestamp WHERE i<='2004-10-26 08:55:08'::timestamp ORDER BY i;
25+
26+
explain (costs off)
27+
SELECT * FROM test_timestamp WHERE i='2004-10-26 08:55:08'::timestamp ORDER BY i;
28+
SELECT * FROM test_timestamp WHERE i='2004-10-26 08:55:08'::timestamp ORDER BY i;
29+
30+
explain (costs off)
31+
SELECT * FROM test_timestamp WHERE i>='2004-10-26 08:55:08'::timestamp ORDER BY i;
32+
SELECT * FROM test_timestamp WHERE i>='2004-10-26 08:55:08'::timestamp ORDER BY i;
33+
34+
explain (costs off)
35+
SELECT * FROM test_timestamp WHERE i>'2004-10-26 08:55:08'::timestamp ORDER BY i;
36+
SELECT * FROM test_timestamp WHERE i>'2004-10-26 08:55:08'::timestamp ORDER BY i;

0 commit comments

Comments
 (0)