Re: casting operand to proper type in BlockIdGetBlockNumber

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Andres Freund <andres@anarazel.de>
Cc: Zhihong Yu <zyu@yugabyte.com>, PostgreSQL Developers <pgsql-hackers@lists.postgresql.org>
Date: 2022-03-03T21:45:14Z
Lists: pgsql-hackers
Andres Freund <andres@anarazel.de> writes:
> The message says:
> src/backend/utils/adt/tid.c:112:16: runtime error: left shift of 65535 by 16 places cannot be represented in type 'int'

> Afaics that means bi_hi is 65535. So either we're dealing with a very large
> relation or BlockIdGetBlockNumber() is getting passed InvalidBlockNumber?

Presumably the latter, since we surely aren't using any terabyte-size
relations in our tests.

> It might be enough to do something like
> SELECT * FROM pg_class WHERE ctid = '(65535, 17)';
> to trigger the problem?

I tried to provoke it with cases like

# select '(-1,0)'::tid;
      tid       
----------------
 (4294967295,0)
(1 row)

# select '(4000000000,1)'::tid;
      tid       
----------------
 (4000000000,1)
(1 row)

without success.

On a nearby topic, I see that tidin's overflow checks are somewhere
between sloppy and nonexistent:

# select '(40000000000,1)'::tid;
      tid       
----------------
 (1345294336,1)
(1 row)

I think I'll fix that while I'm looking at it ... but it still
doesn't explain why no complaint in tidout.

			regards, tom lane



Commits

  1. Tighten overflow checks in tidin().

  2. Remove some pointless code in block.h.

  3. Fix bogus casting in BlockIdGetBlockNumber().

  4. Clean up assorted failures under clang's -fsanitize=undefined checks.