Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wq9Ne-0023QE-2T for pgsql-bugs@arkaria.postgresql.org; Sat, 01 Aug 2026 13:03:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wq9Mc-0016e3-16 for pgsql-bugs@arkaria.postgresql.org; Sat, 01 Aug 2026 13:02:54 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wq051-000ZBn-19 for pgsql-bugs@lists.postgresql.org; Sat, 01 Aug 2026 03:08:07 +0000 Received: from mahout.postgresql.org ([2001:4800:3e1:1::227]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wq04z-00000001M6L-24lL for pgsql-bugs@lists.postgresql.org; Sat, 01 Aug 2026 03:08:06 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Message-ID:Date:Reply-To:Cc:From:To:Subject: Content-Transfer-Encoding:MIME-Version:Content-Type:Sender:Content-ID: Content-Description:In-Reply-To:References; bh=mS8phn07tj8OKDRrEMPBIZCodAthwKG9BMWTWe4TRFs=; b=VeG0d69jrSD8J28jT/X66Zu/LQ IyLWxnMXvSqNCxL1jmj8JvlI+DL8ooJTEzysW8DCrvUeB2U8UxOEKJ2dKoiMcmyOqCY5Y0xBWIlej 1geZyxJzMxd6xxAUeUO0yHHe2stbvfeWVnbTputsd+g69ZzcJ2tPEOeEYFxreT0A6mHCpyFv99YQ7 RXLPymK+SQVuTUWCnb+ZE4lAMTSut+9xBZ9JnU/BqFyIb1Z67UKN4LSUS5xLBNm6ueaMAjk47WDeB rlY7q9utOYMuCc+oM7vVe4n5JUcJbey0o5/sjsUUoDn/iQ6guVU/hYB+oMmhWxQnAS6dljQHHddFj tzI8ci3Q==; Received: from wrigleys.postgresql.org ([2a02:16a8:dc51::60]) by mahout.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wq04z-0048zE-0l for pgsql-bugs@lists.postgresql.org; Sat, 01 Aug 2026 03:08:05 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1wq04x-00000009wr9-3AmZ for pgsql-bugs@lists.postgresql.org; Sat, 01 Aug 2026 03:08:03 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19593: area(circle) silently returns Infinity instead of raising "value out of range: overflow" To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: malis@pgrust.com Reply-To: malis@pgrust.com, pgsql-bugs@lists.postgresql.org Date: Sat, 01 Aug 2026 03:07:25 +0000 Message-ID: <19593-d80bd21f90d32234@postgresql.org> X-Auto-Response-Suppress: All Auto-Submitted: auto-generated List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk The following bug has been logged on the website: Bug reference: 19593 Logged by: Michael Malis Email address: malis@pgrust.com PostgreSQL version: 18.3 Operating system: Debian (official Docker image), aarch64 Description: =20 I'm not sure what you'll want to do with this one, but I figured I would at least report it. The cause seems to be a bug in gcc. area(circle) returns Infinity where it must raise ERROR 22003 "value out of range: overflow". The overflow check in float8_mul() is present in the source but is absent from the generated code, because gcc 13 and later delete it at -O1 and above. The same binary raises the error correctly for the equivalent SQL-level expression, and for a circle whose radius overflows one step earlier, so this is not "PostgreSQL does not check circle areas". -- WRONG: no error, returns Infinity SELECT area(circle '<(0,0),1e154>'); area ------------------------ Infinity -- CORRECT (control): the *inner* multiply overflows, so the surviving -- check fires SELECT area(circle '<(0,0),1e200>'); ERROR: value out of range: overflow -- CORRECT (control): the same arithmetic, expressed in SQL SELECT 1e154::float8 * 1e154::float8 * pi(); ERROR: value out of range: overflow -- sane value, for reference SELECT area(circle '<(0,0),1e10>'); area ------------------------- 3.1415926535897933e+20 1e154 * 1e154 =3D 1e308, which is finite (below DBL_MAX); multiplying that = by pi overflows. Behaviour is identical whether the expression is constant-folded at plan time or evaluated at runtime: SELECT area(c) FROM (VALUES (circle '<(0,0),1e154>')) t(c); -- Infinity NaN and Infinity radii behave correctly (NaN -> NaN, Infinity -> Infinity). WHERE IT COMES FROM src/backend/utils/adt/geo_ops.c:5159 static float8 circle_ar(CIRCLE *circle) { return float8_mul(float8_mul(circle->radius, circle->radius), M_PI); } src/include/utils/float.h:207 static inline float8 float8_mul(const float8 val1, const float8 val2) { float8 result; result =3D val1 * val2; if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) float_overflow_error(); ... Two float8_mul calls are inlined into one function. gcc keeps the first copy's overflow check and deletes the second's. Disassembly of the shipped binary (circle_area; symbols are present in .dynsym). gcc lowers isinf(x) to |x| > DBL_MAX, with d30 =3D 0x7fefffffffffffff: ; inner multiply -- check intact 5540dc fmul d31, d29, d29 ; r*r 5540e0 fcmp d31, d30 5540e4 b.le 5540fc 5540e8 fabs d29, d29 ; |r| <- the !isinf(val1) test 5540ec fcmp d29, d30 5540f0 b.le 554154 554154 bl float_overflow_error ; raises ; outer multiply -- operand test gone 554104 adrp x0, 76c000 554108 ldr d29, [x0, #568] ; M_PI 55410c fmul d31, d31, d29 ; (r*r) * M_PI 554110 fcmp d31, d30 554114 b.le 554120 554118 mov x0, #0x7ff0000000000000 ; returns +Infinity 55411c b 55412c Control reaches the outer multiply only via the b.le at 5540e4, i.e. only when r*r <=3D DBL_MAX, and M_PI is a finite constant. So "!isinf(val1) && !isinf(val2)" is true on that path and float_overflow_error() must be called. Building from an unmodified 18.3 tree (git tag stamp 62d6c7d) with gcc 14.2 and the same CFLAGS reproduces it, so this is not specific to Debian's packaging: ./configure --without-readline --without-zlib --without-icu \ CFLAGS=3D"-g -O2 -fno-strict-aliasing -fwrapv -fexcess-precision=3Dstandard" make -C src/backend submake-generated-headers make -C src/backend/utils/adt geo_ops.o objdump -d geo_ops.o circle_area then contains 3 fmul but only 1 call to float_overflow_error. From pristine source the outer check is removed entirely: there is no DBL_MAX comparison after the second fmul at all, only the underflow test.