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

Commit8c153fc

Browse files
committed
Fix GIN's shimTriConsistentFn to not corrupt its input.
Commit0f21db3 made an assumption that GIN triConsistentFnswould not modify their input entryRes[] arrays. But in fact,the "shim" triConsistentFn that we use for opclasses that don'tsupply their own did exactly that, potentially leading to wronganswers from a GIN index search. Through bad luck, none of thetest cases that we have for such opclasses exposed the bug.One response to this could be that the assumption of consistency checkfunctions not modifying entryRes[] arrays is a bad one, but it stillseems reasonable to me. Notably, shimTriConsistentFn is itselfassuming that with respect to the underlying boolean consistentFn,so it's sure being self-centered in supposing that it gets to do so.Fortunately, it's quite simple to fix shimTriConsistentFn to restorethe entry-time state of entryRes[], so let's do that instead.This issue doesn't affect any core GIN opclasses, since they allsupply their own triConsistentFns. It does affect contrib modulesbtree_gin, hstore, and intarray.Along the way, I (tgl) noticed that shimTriConsistentFn failed topick up on a "recheck" flag returned by its first call to the booleanconsistentFn. This may be only a latent problem, since it would beunlikely for a consistentFn to set recheck for the all-false caseand not any other cases. (Indeed, none of our contrib modules dothat.) Nonetheless, it's formally wrong.Reported-by: Vinod Sridharan <vsridh90@gmail.com>Author: Vinod Sridharan <vsridh90@gmail.com>Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/CAFMdLD7XzsXfi1+DpTqTgrD8XU0i2C99KuF=5VHLWjx4C1pkcg@mail.gmail.comBackpatch-through: 13
1 parent3339847 commit8c153fc

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

‎contrib/intarray/expected/_int.out

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
492492
6344
493493
(1 row)
494494

495+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
496+
count
497+
-------
498+
12
499+
(1 row)
500+
495501
SET enable_seqscan = off; -- not all of these would use index by default
496502
CREATE INDEX text_idx on test__int using gist ( a gist__int_ops );
497503
SELECT count(*) from test__int WHERE a && '{23,50}';
@@ -566,6 +572,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
566572
6344
567573
(1 row)
568574

575+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
576+
count
577+
-------
578+
12
579+
(1 row)
580+
569581
INSERT INTO test__int SELECT array(SELECT x FROM generate_series(1, 1001) x); -- should fail
570582
ERROR: input array is too big (199 maximum allowed, 1001 current), use gist__intbig_ops opclass instead
571583
DROP INDEX text_idx;
@@ -648,6 +660,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
648660
6344
649661
(1 row)
650662

663+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
664+
count
665+
-------
666+
12
667+
(1 row)
668+
651669
DROP INDEX text_idx;
652670
CREATE INDEX text_idx on test__int using gist (a gist__intbig_ops(siglen = 0));
653671
ERROR: value 0 out of bounds for option "siglen"
@@ -728,6 +746,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
728746
6344
729747
(1 row)
730748

749+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
750+
count
751+
-------
752+
12
753+
(1 row)
754+
731755
DROP INDEX text_idx;
732756
CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops );
733757
SELECT count(*) from test__int WHERE a && '{23,50}';
@@ -802,6 +826,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
802826
6344
803827
(1 row)
804828

829+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
830+
count
831+
-------
832+
12
833+
(1 row)
834+
805835
DROP INDEX text_idx;
806836
CREATE INDEX text_idx on test__int using gin ( a gin__int_ops );
807837
SELECT count(*) from test__int WHERE a && '{23,50}';
@@ -876,6 +906,12 @@ SELECT count(*) from test__int WHERE a @@ '!20 & !21';
876906
6344
877907
(1 row)
878908

909+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
910+
count
911+
-------
912+
12
913+
(1 row)
914+
879915
DROP INDEX text_idx;
880916
-- Repeat the same queries with an extended data set. The data set is the
881917
-- same that we used before, except that each element in the array is
@@ -968,4 +1004,10 @@ SELECT count(*) from more__int WHERE a @@ '!20 & !21';
9681004
6344
9691005
(1 row)
9701006

1007+
SELECT count(*) from test__int WHERE a @@ '!2733 & (2738 | 254)';
1008+
count
1009+
-------
1010+
12
1011+
(1 row)
1012+
9711013
RESET enable_seqscan;

‎contrib/intarray/sql/_int.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
107107
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
108108
SELECTcount(*)from test__intWHERE a @@'20 | !21';
109109
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
110+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
110111

111112
SET enable_seqscan= off;-- not all of these would use index by default
112113

@@ -124,6 +125,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
124125
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
125126
SELECTcount(*)from test__intWHERE a @@'20 | !21';
126127
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
128+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
127129

128130
INSERT INTO test__intSELECT array(SELECT xFROM generate_series(1,1001) x);-- should fail
129131

@@ -144,6 +146,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
144146
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
145147
SELECTcount(*)from test__intWHERE a @@'20 | !21';
146148
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
149+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
147150

148151
DROPINDEX text_idx;
149152
CREATEINDEXtext_idxon test__int using gist (a gist__intbig_ops(siglen=0));
@@ -162,6 +165,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
162165
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
163166
SELECTcount(*)from test__intWHERE a @@'20 | !21';
164167
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
168+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
165169

166170
DROPINDEX text_idx;
167171
CREATEINDEXtext_idxon test__int using gist ( a gist__intbig_ops );
@@ -178,6 +182,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
178182
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
179183
SELECTcount(*)from test__intWHERE a @@'20 | !21';
180184
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
185+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
181186

182187
DROPINDEX text_idx;
183188
CREATEINDEXtext_idxon test__int using gin ( a gin__int_ops );
@@ -194,6 +199,7 @@ SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}';
194199
SELECTcount(*)from test__intWHERE a @@'(20&23)|(50&68)';
195200
SELECTcount(*)from test__intWHERE a @@'20 | !21';
196201
SELECTcount(*)from test__intWHERE a @@'!20 & !21';
202+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
197203

198204
DROPINDEX text_idx;
199205

@@ -229,6 +235,7 @@ SELECT count(*) from more__int WHERE a @> '{20,23}' or a @> '{50,68}';
229235
SELECTcount(*)from more__intWHERE a @@'(20&23)|(50&68)';
230236
SELECTcount(*)from more__intWHERE a @@'20 | !21';
231237
SELECTcount(*)from more__intWHERE a @@'!20 & !21';
238+
SELECTcount(*)from test__intWHERE a @@'!2733 & (2738 | 254)';
232239

233240

234241
RESET enable_seqscan;

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ shimBoolConsistentFn(GinScanKey key)
140140
* every combination is O(n^2), so this is only feasible for a small number of
141141
* MAYBE inputs.
142142
*
143-
* NB: This function modifies the key->entryRes array!
143+
* NB: This function modifies the key->entryRes array. For now that's okay
144+
* so long as we restore the entry-time contents before returning. This may
145+
* need revisiting if we ever invent multithreaded GIN scans, though.
144146
*/
145147
staticGinTernaryValue
146148
shimTriConsistentFn(GinScanKeykey)
@@ -149,7 +151,7 @@ shimTriConsistentFn(GinScanKey key)
149151
intmaybeEntries[MAX_MAYBE_ENTRIES];
150152
inti;
151153
boolboolResult;
152-
boolrecheck= false;
154+
boolrecheck;
153155
GinTernaryValuecurResult;
154156

155157
/*
@@ -169,8 +171,8 @@ shimTriConsistentFn(GinScanKey key)
169171
}
170172

171173
/*
172-
* If none of the inputs were MAYBE,sowe can just call consistent
173-
* function asis.
174+
* If none of the inputs were MAYBE, we can just call the consistent
175+
* function as-is.
174176
*/
175177
if (nmaybe==0)
176178
returndirectBoolConsistentFn(key);
@@ -179,6 +181,7 @@ shimTriConsistentFn(GinScanKey key)
179181
for (i=0;i<nmaybe;i++)
180182
key->entryRes[maybeEntries[i]]=GIN_FALSE;
181183
curResult=directBoolConsistentFn(key);
184+
recheck=key->recheckCurItem;
182185

183186
for (;;)
184187
{
@@ -200,13 +203,20 @@ shimTriConsistentFn(GinScanKey key)
200203
recheck |=key->recheckCurItem;
201204

202205
if (curResult!=boolResult)
203-
returnGIN_MAYBE;
206+
{
207+
curResult=GIN_MAYBE;
208+
break;
209+
}
204210
}
205211

206212
/* TRUE with recheck is taken to mean MAYBE */
207213
if (curResult==GIN_TRUE&&recheck)
208214
curResult=GIN_MAYBE;
209215

216+
/* We must restore the original state of the entryRes array */
217+
for (i=0;i<nmaybe;i++)
218+
key->entryRes[maybeEntries[i]]=GIN_MAYBE;
219+
210220
returncurResult;
211221
}
212222

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp