Missing SELECT output on btree_gin char, BTLess* strategy

Started by Jason Kimover 4 years ago3 messagesbugs
Jump to latest
#1Jason Kim
git@jasonk.me

The expected output in contrib/btree_gin/expected/char.out is wrong for the
first two SELECTs using the BTLess* strategies: they should not be empty.

set enable_seqscan=off;

CREATE TABLE test_char (
i "char"
);

INSERT INTO test_char VALUES ('a'),('b'),('c'),('d'),('e'),('f');

CREATE INDEX idx_char ON test_char USING gin (i);

SELECT * FROM test_char WHERE i<'d'::"char" ORDER BY i;
SELECT * FROM test_char WHERE i<='d'::"char" ORDER BY i;

gives

i
---
(0 rows)

i
---
(0 rows)

If Bitmap Scan is turned off, we get output, as expected:

set enable_bitmapscan=off;
SELECT * FROM test_char WHERE i<'d'::"char" ORDER BY i;
SELECT * FROM test_char WHERE i<='d'::"char" ORDER BY i;

gives

i
---
a
b
c
(3 rows)

i
---
a
b
c
d
(4 rows)

I tried the following and got the same results:

- Do the inserts after the CREATE INDEX.
- Create the index with fastupdate turned off: CREATE INDEX ... WITH
(fastupdate = off).
- Reconnect (and don't forget to disable sequential scan).
- Stop and start the server: pg_ctl restart.

I'm on 15devel, but this issue appears to have been around for years.

In reply to: Jason Kim (#1)
Re: Missing SELECT output on btree_gin char, BTLess* strategy

On Mon, Aug 9, 2021 at 6:15 PM Jason Kim <git@jasonk.me> wrote:

The expected output in contrib/btree_gin/expected/char.out is wrong for the
first two SELECTs using the BTLess* strategies: they should not be empty.

Isn't this index corruption, or at least an inconsistent opclass? It
may be true that the tests show the wrong output, and always have. But
isn't the more concerning problem that the index gives wrong answers
in general, not the tests?

--
Peter Geoghegan

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Geoghegan (#2)
Re: Missing SELECT output on btree_gin char, BTLess* strategy

Peter Geoghegan <pg@bowt.ie> writes:

On Mon, Aug 9, 2021 at 6:15 PM Jason Kim <git@jasonk.me> wrote:

The expected output in contrib/btree_gin/expected/char.out is wrong for the
first two SELECTs using the BTLess* strategies: they should not be empty.

Isn't this index corruption, or at least an inconsistent opclass?

Indeed. After a bit of poking around, I realized that btree_gin's
leftmostvalue_char() is not on the same page as btcharcmp() about
whether type "char" is signed or unsigned.

AFAICT, only the latter function matters while making index entries,
while the wrong value from leftmostvalue_char() affects only search
results. So we can just fix it, as attached.

regards, tom lane

Attachments:

btree_gin-is-wrong-about-char-signedness.patchtext/x-diff; charset=us-ascii; name=btree_gin-is-wrong-about-char-signedness.patchDownload+10-3