Add ssup_datum_uint32_cmp for comparing OIDs

Commit 51cd5d6f0 used ssup_datum_unsigned_cmp for the OID comparator,
which compares entire Datums. That gave wrong results, since the upper
half of a Datum containing a 32-bit type is not reliably zero-extended:
values fetched from tuples are sign-extended, while values returned
by e.g. oidin() are zero-extended. An OID with the high bit set could
therefore compare as larger or smaller depending on its source.

Fix by adding a sort support comparator that only looks at the low 32
bits. Also teach radix sort to normalize Datums the same way. This keeps
OID eligible for radix sort. Add a regression test that sorts OIDs above
2^31 from both kinds of source, taken from Peter Geoghegan's report.

Reported-by: Zsolt Parragi <[email protected]>
Reported-by: Peter Geoghegan <[email protected]>
Suggested-by: David Rowley <[email protected]>
Reviewed-by: David Rowley <[email protected]>
Reviewed-by: Zsolt Parragi <[email protected]>
Discussion: 
https://postgr.es/m/can4czfm2afrzsljjiwknrjqpwl7scm2wd1xxu140dijgujt...@mail.gmail.com
Discussion: 
https://postgr.es/m/CAH2-WznvXyKRah=mq3onghin8ahjcqpmtyikxcoo96a4usd...@mail.gmail.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/94d32ce1a63c67bce7b811207095ee6d41d4caed

Modified Files
--------------
src/backend/access/nbtree/nbtcompare.c |  2 +-
src/backend/utils/sort/tuplesort.c     | 38 ++++++++++++++++++++++++----------
src/include/utils/sortsupport.h        |  1 +
src/test/regress/expected/oid.out      | 16 ++++++++++++++
src/test/regress/sql/oid.sql           |  4 ++++
5 files changed, 49 insertions(+), 12 deletions(-)

Reply via email to