Skip to content

Commit 1a4d4b8

Browse files
committed
Merge branch 'master' of git.postgrespro.ru:pgpro-dev/rum
2 parents 3d331aa + 727d692 commit 1a4d4b8

21 files changed

+109
-60
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ RELATIVE_INCLUDES = $(addprefix src/, $(INCLUDES))
2525

2626
LDFLAGS_SL += $(filter -lm, $(LIBS))
2727

28-
REGRESS = rum rum_validate rum_hash ruminv timestamp orderby orderby_hash \
28+
REGRESS = security rum rum_validate rum_hash ruminv timestamp orderby orderby_hash \
2929
altorder altorder_hash limits \
3030
int2 int4 int8 float4 float8 money oid \
3131
time timetz date interval \

expected/int4.out

-4
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ SELECT id FROM test_int4_o WHERE t @@ 'wr&qh' AND id >= 400 ORDER BY id;
145145

146146
RESET enable_indexscan;
147147
RESET enable_indexonlyscan;
148-
RESET enable_bitmapscan;
149148
SET enable_seqscan = off;
150149
EXPLAIN (costs off)
151150
SELECT id, id <=> 400 FROM test_int4_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -258,7 +257,6 @@ CREATE TABLE test_int4_a AS SELECT id::int4, t FROM tsts;
258257
CREATE INDEX test_int4_a_idx ON test_int4_a USING rum
259258
(t rum_tsvector_addon_ops, id)
260259
WITH (attach = 'id', to = 't', order_by_attach='t');
261-
SET enable_bitmapscan=OFF;
262260
EXPLAIN (costs off)
263261
SELECT count(*) FROM test_int4_a WHERE id < 400;
264262
QUERY PLAN
@@ -448,7 +446,6 @@ SELECT id FROM test_int4_h_o WHERE t @@ 'wr&qh' AND id >= 400 ORDER BY id;
448446

449447
RESET enable_indexscan;
450448
RESET enable_indexonlyscan;
451-
RESET enable_bitmapscan;
452449
SET enable_seqscan = off;
453450
EXPLAIN (costs off)
454451
SELECT id, id <=> 400 FROM test_int4_h_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -561,7 +558,6 @@ CREATE TABLE test_int4_h_a AS SELECT id::int4, t FROM tsts;
561558
CREATE INDEX test_int4_h_a_idx ON test_int4_h_a USING rum
562559
(t rum_tsvector_hash_addon_ops, id)
563560
WITH (attach = 'id', to = 't', order_by_attach='t');
564-
SET enable_bitmapscan=OFF;
565561
EXPLAIN (costs off)
566562
SELECT count(*) FROM test_int4_h_a WHERE id < 400;
567563
QUERY PLAN

expected/int8.out

-4
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ SELECT id FROM test_int8_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id;
145145

146146
RESET enable_indexscan;
147147
RESET enable_indexonlyscan;
148-
RESET enable_bitmapscan;
149148
SET enable_seqscan = off;
150149
EXPLAIN (costs off)
151150
SELECT id, id <=> 400 FROM test_int8_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -258,7 +257,6 @@ CREATE TABLE test_int8_a AS SELECT id::int8, t FROM tsts;
258257
CREATE INDEX test_int8_a_idx ON test_int8_a USING rum
259258
(t rum_tsvector_addon_ops, id)
260259
WITH (attach = 'id', to = 't', order_by_attach='t');
261-
SET enable_bitmapscan=OFF;
262260
EXPLAIN (costs off)
263261
SELECT count(*) FROM test_int8_a WHERE id < 400::int8;
264262
QUERY PLAN
@@ -448,7 +446,6 @@ SELECT id FROM test_int8_h_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id
448446

449447
RESET enable_indexscan;
450448
RESET enable_indexonlyscan;
451-
RESET enable_bitmapscan;
452449
SET enable_seqscan = off;
453450
EXPLAIN (costs off)
454451
SELECT id, id <=> 400 FROM test_int8_h_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -561,7 +558,6 @@ CREATE TABLE test_int8_h_a AS SELECT id::int8, t FROM tsts;
561558
CREATE INDEX test_int8_h_a_idx ON test_int8_h_a USING rum
562559
(t rum_tsvector_hash_addon_ops, id)
563560
WITH (attach = 'id', to = 't', order_by_attach='t');
564-
SET enable_bitmapscan=OFF;
565561
EXPLAIN (costs off)
566562
SELECT count(*) FROM test_int8_h_a WHERE id < 400::int8;
567563
QUERY PLAN

expected/int8_1.out

-4
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ SELECT id FROM test_int8_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id;
130130

131131
RESET enable_indexscan;
132132
RESET enable_indexonlyscan;
133-
RESET enable_bitmapscan;
134133
SET enable_seqscan = off;
135134
EXPLAIN (costs off)
136135
SELECT id, id <=> 400 FROM test_int8_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -220,7 +219,6 @@ CREATE INDEX test_int8_a_idx ON test_int8_a USING rum
220219
(t rum_tsvector_addon_ops, id)
221220
WITH (attach = 'id', to = 't', order_by_attach='t');
222221
ERROR: doesn't support order index over pass-by-reference column
223-
SET enable_bitmapscan=OFF;
224222
EXPLAIN (costs off)
225223
SELECT count(*) FROM test_int8_a WHERE id < 400::int8;
226224
QUERY PLAN
@@ -413,7 +411,6 @@ SELECT id FROM test_int8_h_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id
413411

414412
RESET enable_indexscan;
415413
RESET enable_indexonlyscan;
416-
RESET enable_bitmapscan;
417414
SET enable_seqscan = off;
418415
EXPLAIN (costs off)
419416
SELECT id, id <=> 400 FROM test_int8_h_o WHERE t @@ 'wr&qh' ORDER BY id <=> 400 LIMIT 5;
@@ -503,7 +500,6 @@ CREATE INDEX test_int8_h_a_idx ON test_int8_h_a USING rum
503500
(t rum_tsvector_hash_addon_ops, id)
504501
WITH (attach = 'id', to = 't', order_by_attach='t');
505502
ERROR: doesn't support order index over pass-by-reference column
506-
SET enable_bitmapscan=OFF;
507503
EXPLAIN (costs off)
508504
SELECT count(*) FROM test_int8_h_a WHERE id < 400::int8;
509505
QUERY PLAN

expected/rum.out

+18
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,24 @@ SELECT (a <=> to_tsquery('pg_catalog.english', 'b:*'))::numeric(10,4) AS distanc
381381
16.4493 | the few that escaped destruction in 1693. It is a beautiful, highly | '1693':7 'beauti':11 'destruct':5 'escap':4 'high':12
382382
(20 rows)
383383

384+
-- Test correct work of phrase operator when position information is not in index.
385+
create table test_rum_addon as table test_rum;
386+
alter table test_rum_addon add column id serial;
387+
create index on test_rum_addon using rum (a rum_tsvector_addon_ops, id) with (attach = 'id', to='a');
388+
select * from test_rum_addon where a @@ to_tsquery('pg_catalog.english', 'half <-> way');
389+
t | a | id
390+
---------------------------------------------------------------------+---------------------------------------------------------+----
391+
itself. Put on your "specs" and look at the castle, half way up the | 'castl':10 'half':11 'look':7 'put':2 'spec':5 'way':12 | 9
392+
(1 row)
393+
394+
explain (costs off) select * from test_rum_addon where a @@ to_tsquery('pg_catalog.english', 'half <-> way');
395+
QUERY PLAN
396+
------------------------------------------------------------
397+
Index Scan using test_rum_addon_a_id_idx on test_rum_addon
398+
Index Cond: (a @@ '''half'' <-> ''way'''::tsquery)
399+
(2 rows)
400+
401+
--
384402
select ('bjarn:6237 stroustrup:6238'::tsvector <=> 'bjarn <-> stroustrup'::tsquery)::numeric(10,5) AS distance;
385403
distance
386404
----------

expected/security.out

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Check security CVE-2020-14350
2+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray) RETURNS bool AS $$ SELECT false $$ LANGUAGE SQL;
3+
CREATE EXTENSION rum;
4+
ERROR: function "rum_anyarray_similar" already exists with same argument types
5+
DROP FUNCTION rum_anyarray_similar(anyarray,anyarray);

gen_rum_sql--1.1--1.2.pl

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
LANGUAGE C IMMUTABLE STRICT;
8383
8484
85-
CREATE OR REPLACE FUNCTION rum_anyarray_similar(anyarray,anyarray)
85+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray)
8686
RETURNS bool
8787
AS 'MODULE_PATHNAME'
8888
LANGUAGE C STRICT STABLE;
@@ -97,7 +97,7 @@
9797
);
9898
9999
100-
CREATE OR REPLACE FUNCTION rum_anyarray_distance(anyarray,anyarray)
100+
CREATE FUNCTION rum_anyarray_distance(anyarray,anyarray)
101101
RETURNS float8
102102
AS 'MODULE_PATHNAME'
103103
LANGUAGE C STRICT STABLE;

rum--1.0.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE OR REPLACE FUNCTION rumhandler(internal)
1+
CREATE FUNCTION rumhandler(internal)
22
RETURNS index_am_handler
33
AS 'MODULE_PATHNAME'
44
LANGUAGE C;

rum--1.1--1.2.sql

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ AS 'MODULE_PATHNAME'
1010
LANGUAGE C IMMUTABLE STRICT;
1111

1212

13-
CREATE OR REPLACE FUNCTION rum_anyarray_similar(anyarray,anyarray)
13+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray)
1414
RETURNS bool
1515
AS 'MODULE_PATHNAME'
1616
LANGUAGE C STRICT STABLE;
@@ -25,7 +25,7 @@ CREATE OPERATOR % (
2525
);
2626

2727

28-
CREATE OR REPLACE FUNCTION rum_anyarray_distance(anyarray,anyarray)
28+
CREATE FUNCTION rum_anyarray_distance(anyarray,anyarray)
2929
RETURNS float8
3030
AS 'MODULE_PATHNAME'
3131
LANGUAGE C STRICT STABLE;

rum--1.1.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE OR REPLACE FUNCTION rumhandler(internal)
1+
CREATE FUNCTION rumhandler(internal)
22
RETURNS index_am_handler
33
AS 'MODULE_PATHNAME'
44
LANGUAGE C;

rum--1.2.sql

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE OR REPLACE FUNCTION rumhandler(internal)
1+
CREATE FUNCTION rumhandler(internal)
22
RETURNS index_am_handler
33
AS 'MODULE_PATHNAME'
44
LANGUAGE C;
@@ -1527,7 +1527,7 @@ AS 'MODULE_PATHNAME'
15271527
LANGUAGE C IMMUTABLE STRICT;
15281528

15291529

1530-
CREATE OR REPLACE FUNCTION rum_anyarray_similar(anyarray,anyarray)
1530+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray)
15311531
RETURNS bool
15321532
AS 'MODULE_PATHNAME'
15331533
LANGUAGE C STRICT STABLE;
@@ -1542,7 +1542,7 @@ CREATE OPERATOR % (
15421542
);
15431543

15441544

1545-
CREATE OR REPLACE FUNCTION rum_anyarray_distance(anyarray,anyarray)
1545+
CREATE FUNCTION rum_anyarray_distance(anyarray,anyarray)
15461546
RETURNS float8
15471547
AS 'MODULE_PATHNAME'
15481548
LANGUAGE C STRICT STABLE;

rum--1.3.sql

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CREATE OR REPLACE FUNCTION rumhandler(internal)
1+
CREATE FUNCTION rumhandler(internal)
22
RETURNS index_am_handler
33
AS 'MODULE_PATHNAME'
44
LANGUAGE C;
@@ -1527,7 +1527,7 @@ AS 'MODULE_PATHNAME'
15271527
LANGUAGE C IMMUTABLE STRICT;
15281528

15291529

1530-
CREATE OR REPLACE FUNCTION rum_anyarray_similar(anyarray,anyarray)
1530+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray)
15311531
RETURNS bool
15321532
AS 'MODULE_PATHNAME'
15331533
LANGUAGE C STRICT STABLE;
@@ -1542,7 +1542,7 @@ CREATE OPERATOR % (
15421542
);
15431543

15441544

1545-
CREATE OR REPLACE FUNCTION rum_anyarray_distance(anyarray,anyarray)
1545+
CREATE FUNCTION rum_anyarray_distance(anyarray,anyarray)
15461546
RETURNS float8
15471547
AS 'MODULE_PATHNAME'
15481548
LANGUAGE C STRICT STABLE;

sql/int4.sql

-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ SELECT id FROM test_int4_o WHERE t @@ 'wr&qh' AND id >= 400 ORDER BY id;
4040

4141
RESET enable_indexscan;
4242
RESET enable_indexonlyscan;
43-
RESET enable_bitmapscan;
4443
SET enable_seqscan = off;
4544

4645
EXPLAIN (costs off)
@@ -66,8 +65,6 @@ CREATE INDEX test_int4_a_idx ON test_int4_a USING rum
6665
(t rum_tsvector_addon_ops, id)
6766
WITH (attach = 'id', to = 't', order_by_attach='t');
6867

69-
SET enable_bitmapscan=OFF;
70-
7168
EXPLAIN (costs off)
7269
SELECT count(*) FROM test_int4_a WHERE id < 400;
7370
SELECT count(*) FROM test_int4_a WHERE id < 400;
@@ -107,7 +104,6 @@ SELECT id FROM test_int4_h_o WHERE t @@ 'wr&qh' AND id >= 400 ORDER BY id;
107104

108105
RESET enable_indexscan;
109106
RESET enable_indexonlyscan;
110-
RESET enable_bitmapscan;
111107
SET enable_seqscan = off;
112108

113109
EXPLAIN (costs off)
@@ -133,8 +129,6 @@ CREATE INDEX test_int4_h_a_idx ON test_int4_h_a USING rum
133129
(t rum_tsvector_hash_addon_ops, id)
134130
WITH (attach = 'id', to = 't', order_by_attach='t');
135131

136-
SET enable_bitmapscan=OFF;
137-
138132
EXPLAIN (costs off)
139133
SELECT count(*) FROM test_int4_h_a WHERE id < 400;
140134
SELECT count(*) FROM test_int4_h_a WHERE id < 400;

sql/int8.sql

+1-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ SELECT id FROM test_int8_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id;
4040

4141
RESET enable_indexscan;
4242
RESET enable_indexonlyscan;
43-
RESET enable_bitmapscan;
4443
SET enable_seqscan = off;
4544

4645
EXPLAIN (costs off)
@@ -66,8 +65,6 @@ CREATE INDEX test_int8_a_idx ON test_int8_a USING rum
6665
(t rum_tsvector_addon_ops, id)
6766
WITH (attach = 'id', to = 't', order_by_attach='t');
6867

69-
SET enable_bitmapscan=OFF;
70-
7168
EXPLAIN (costs off)
7269
SELECT count(*) FROM test_int8_a WHERE id < 400::int8;
7370
SELECT count(*) FROM test_int8_a WHERE id < 400::int8;
@@ -107,7 +104,6 @@ SELECT id FROM test_int8_h_o WHERE t @@ 'wr&qh' AND id >= 400::int8 ORDER BY id
107104

108105
RESET enable_indexscan;
109106
RESET enable_indexonlyscan;
110-
RESET enable_bitmapscan;
111107
SET enable_seqscan = off;
112108

113109
EXPLAIN (costs off)
@@ -120,6 +116,7 @@ EXPLAIN (costs off)
120116
SELECT id, id |=> 400 FROM test_int8_h_o WHERE t @@ 'wr&qh' ORDER BY id |=> 400 LIMIT 5;
121117
SELECT id, id |=> 400 FROM test_int8_h_o WHERE t @@ 'wr&qh' ORDER BY id |=> 400 LIMIT 5;
122118

119+
123120
EXPLAIN (costs off)
124121
SELECT id FROM test_int8_h_o WHERE t @@ 'wr&qh' AND id <= 400::int8 ORDER BY id;
125122
SELECT id FROM test_int8_h_o WHERE t @@ 'wr&qh' AND id <= 400::int8 ORDER BY id;
@@ -133,8 +130,6 @@ CREATE INDEX test_int8_h_a_idx ON test_int8_h_a USING rum
133130
(t rum_tsvector_hash_addon_ops, id)
134131
WITH (attach = 'id', to = 't', order_by_attach='t');
135132

136-
SET enable_bitmapscan=OFF;
137-
138133
EXPLAIN (costs off)
139134
SELECT count(*) FROM test_int8_h_a WHERE id < 400::int8;
140135
SELECT count(*) FROM test_int8_h_a WHERE id < 400::int8;

sql/rum.sql

+9
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,14 @@ SELECT (a <=> to_tsquery('pg_catalog.english', 'b:*'))::numeric(10,4) AS distanc
141141
WHERE a @@ to_tsquery('pg_catalog.english', 'b:*')
142142
ORDER BY a <=> to_tsquery('pg_catalog.english', 'b:*');
143143

144+
-- Test correct work of phrase operator when position information is not in index.
145+
create table test_rum_addon as table test_rum;
146+
alter table test_rum_addon add column id serial;
147+
create index on test_rum_addon using rum (a rum_tsvector_addon_ops, id) with (attach = 'id', to='a');
148+
149+
select * from test_rum_addon where a @@ to_tsquery('pg_catalog.english', 'half <-> way');
150+
explain (costs off) select * from test_rum_addon where a @@ to_tsquery('pg_catalog.english', 'half <-> way');
151+
--
152+
144153
select ('bjarn:6237 stroustrup:6238'::tsvector <=> 'bjarn <-> stroustrup'::tsquery)::numeric(10,5) AS distance;
145154
SELECT ('stroustrup:5508B,6233B,6238B bjarn:6235B,6237B' <=> 'bjarn <-> stroustrup'::tsquery)::numeric(10,5) AS distance;

sql/security.sql

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Check security CVE-2020-14350
2+
CREATE FUNCTION rum_anyarray_similar(anyarray,anyarray) RETURNS bool AS $$ SELECT false $$ LANGUAGE SQL;
3+
CREATE EXTENSION rum;
4+
DROP FUNCTION rum_anyarray_similar(anyarray,anyarray);
5+

src/rum_ts_utils.c

+18-9
Original file line numberDiff line numberDiff line change
@@ -244,19 +244,15 @@ rum_tsquery_pre_consistent(PG_FUNCTION_ARGS)
244244
gcv.map_item_operand = (int *) (extra_data[0]);
245245
gcv.need_recheck = &recheck;
246246

247-
#if PG_VERSION_NUM >= 130000
248-
res = TS_execute(GETQUERY(query),
249-
&gcv,
250-
TS_EXEC_PHRASE_NO_POS | TS_EXEC_SKIP_NOT,
251-
pre_checkcondition_rum);
252-
#else
253247
res = TS_execute(GETQUERY(query),
254248
&gcv,
255-
TS_EXEC_PHRASE_NO_POS,
256-
pre_checkcondition_rum);
249+
TS_EXEC_PHRASE_NO_POS
250+
#if PG_VERSION_NUM >= 130000
251+
| TS_EXEC_SKIP_NOT
257252
#endif
253+
,
254+
pre_checkcondition_rum);
258255
}
259-
260256
PG_RETURN_BOOL(res);
261257
}
262258

@@ -604,6 +600,14 @@ rum_phrase_execute(QueryItem *curitem, void *arg, uint32 flags,
604600

605601
if (curitem->qoperator.oper == OP_PHRASE)
606602
{
603+
/* In case of index where position is not available
604+
* (e.g. addon_ops) output TS_MAYBE even in case both
605+
* lmatch and rmatch are TS_YES. Otherwise we can lose
606+
* results of phrase queries.
607+
*/
608+
if (flags & TS_EXEC_PHRASE_NO_POS)
609+
return TS_MAYBE;
610+
607611
/*
608612
* Compute Loffset and Roffset suitable for phrase match, and
609613
* compute overall width of whole phrase match.
@@ -840,6 +844,11 @@ rum_TS_execute(QueryItem *curitem, void *arg, uint32 flags,
840844
* converting at the topmost phrase operator gives results that
841845
* are bug-compatible with the old implementation, so do it like
842846
* this for now.
847+
*
848+
* Checking for TS_EXEC_PHRASE_NO_POS has been moved inside
849+
* rum_phrase_execute, otherwise we can lose results of phrase
850+
* operator when position information is not available in index
851+
* (e.g. index built with addon_ops)
843852
*/
844853
switch (rum_phrase_execute(curitem, arg, flags, chkcond, NULL))
845854
{

0 commit comments

Comments
 (0)