pgsql: Fix float-to-integer coercions to handle edge cases correctly.

Поиск
Список
Период
Сортировка
От Tom Lane
Тема pgsql: Fix float-to-integer coercions to handle edge cases correctly.
Дата
Msg-id E1gQc0f-0000px-9I@gemulon.postgresql.org
обсуждение исходный текст
Список pgsql-committers
Fix float-to-integer coercions to handle edge cases correctly.

ftoi4 and its sibling coercion functions did their overflow checks in
a way that looked superficially plausible, but actually depended on an
assumption that the MIN and MAX comparison constants can be represented
exactly in the float4 or float8 domain.  That fails in ftoi4, ftoi8,
and dtoi8, resulting in a possibility that values near the MAX limit will
be wrongly converted (to negative values) when they need to be rejected.

Also, because we compared before rounding off the fractional part,
the other three functions threw errors for values that really ought
to get rounded to the min or max integer value.

Fix by doing rint() first (requiring an assumption that it handles
NaN and Inf correctly; but dtoi8 and ftoi8 were assuming that already),
and by comparing to values that should coerce to float exactly, namely
INTxx_MIN and -INTxx_MIN.  Also remove some random cosmetic discrepancies
between these six functions.

This back-patches commits cbdb8b4c0 and 452b637d4.  In the 9.4 branch,
also back-patch the portion of 62e2a8dc2 that added PG_INTnn_MIN and
related constants to c.h, so that these functions can rely on them.

Per bug #15519 from Victor Petrovykh.

Patch by me; thanks to Andrew Gierth for analysis and discussion.

Discussion: https://postgr.es/m/15519-4fc785b483201ff1@postgresql.org

Branch
------
REL9_4_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/d5231253e3093936e28adc60442841b5ea89e632

Modified Files
--------------
src/backend/utils/adt/float.c                      | 79 +++++++++++++++++++---
src/backend/utils/adt/int8.c                       | 53 ++++++++-------
src/include/c.h                                    | 17 +++++
src/test/regress/expected/float4.out               | 49 ++++++++++++++
src/test/regress/expected/float8-small-is-zero.out | 49 ++++++++++++++
src/test/regress/expected/float8.out               | 49 ++++++++++++++
src/test/regress/sql/float4.sql                    | 14 ++++
src/test/regress/sql/float8.sql                    | 14 ++++
8 files changed, 290 insertions(+), 34 deletions(-)


В списке pgsql-committers по дате отправления:

Предыдущее
От: Andrew Gierth
Дата:
Сообщение: pgsql: Avoid crashes in contrib/intarray gist__int_ops (bug #15518)
Следующее
От: Tom Lane
Дата:
Сообщение: pgsql: Update additional float4/8 expected-output files.