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 1wp3LD-001OvL-2H for pgsql-bugs@arkaria.postgresql.org; Wed, 29 Jul 2026 12:24:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wp3LC-005tjx-2C for pgsql-bugs@arkaria.postgresql.org; Wed, 29 Jul 2026 12:24: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 1wotN2-003FOm-2z for pgsql-bugs@lists.postgresql.org; Wed, 29 Jul 2026 01:46:08 +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 1wotMz-00000000pSp-2mx4 for pgsql-bugs@lists.postgresql.org; Wed, 29 Jul 2026 01:46:08 +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=v4ho3kdQqsJyjcTRghXmn1ea4j627Tnw6Fi8X6PgW0Y=; b=oSqvGnXHx2aItdNs5DtSd1g+GN lgu3jH0XCFXj54xIcj3NraC8CstR3I6rO2X7v71iUUa8Xm7VR/RDwnEvwE5S1F8Mb7c2aAlILrSdp ThBOxnhX7PmabfvYzF44w/ovbjlRy/WD96yz9l9ztpKKoafMuMXQBBy0PCU5AF5WqRxZxQfaZCTEN 7J742APLTJTwB+PDkfXIVQHvDz+VtyMKNgaBQVM1Dl29Dh6Y62UgyADRAU7cbjxBSbkDmNe2gjd8b aHyPJ/o8cFUv2NCs4nmMjfwpfcB4bAmSqMPW9KNIwBR9f+mLJ/UrKOQYcW3FaC/BURELlC9s+Q/dT rAJIswfw==; 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 1wotMz-002d48-0R for pgsql-bugs@lists.postgresql.org; Wed, 29 Jul 2026 01:46: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 1wotMx-000000067ks-2PtV for pgsql-bugs@lists.postgresql.org; Wed, 29 Jul 2026 01:46:03 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19584: tid input acceptance is platform-dependent: '(,5)'::tid yields (0,5) on glibc, errors on macOS 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: Wed, 29 Jul 2026 01:45:38 +0000 Message-ID: <19584-e60c446ba6f57c9c@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: 19584 Logged by: Michael Malis Email address: malis@pgrust.com PostgreSQL version: 19beta2 Operating system: Debian 13/aarch64 (glibc) and macOS 15/aarch64 Description: =20 The tid type accepts or rejects the same input string depending on the platform's C library, and on glibc platforms it converts empty coordinate fields to 0 rather than rejecting them. On Debian (official postgres:18 Docker image): SELECT version(); version ---------------------------------------------------------------------------= ----------------------------------------------- PostgreSQL 18.4 (Debian 18.4-1.pgdg13+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit (1 row) SELECT '(,5)'::tid; tid ------- (0,5) (1 row) (likewise '(5,)' =E2=86=92 (5,0) and '(,)' =E2=86=92 (0,0)) On macOS (Homebrew build): SELECT version(); version ---------------------------------------------------------------------------= -------------------------------------------------- PostgreSQL 18.4 (Homebrew) on aarch64-apple-darwin24.6.0, compiled by Apple clang version 17.0.0 (clang-1700.6.4.2), 64-bit (1 row) SELECT '(,5)'::tid; ERROR: invalid input syntax for type tid: "(,5)" LINE 1: SELECT '(,5)'::tid; ^ Expected behavior: the same literal is either valid or invalid on every platform. I would expect rejection everywhere, since an empty block or offset field matches no documented form of the type, but either consistent behavior would resolve this report. Cause, from the source: tidin (src/backend/utils/adt/tid.c) parses each coordinate with errno =3D 0; cvt =3D strtoul(coord[0], &badp, 10); if (errno || *badp !=3D DELIM) ereturn(...); When the field is empty, strtoul performs no conversion: it returns 0 and sets *endptr to the start of the field, so badp points at the delimiter and the second test passes. Rejection then depends entirely on errno =E2=80=94 and setting EINVAL for "no conversion could be performed" is optional per POSIX ("may fail"). glibc does not set it; macOS libc does. tidin never tests whether any digits were consumed (badp =3D=3D coord[0]). Notably, uint32in_subr() in numutils.c =E2=80=94 wh= ich tidin's own comment cites as "similar code" =E2=80=94 does carry exactly th= at check ("|| endptr =3D=3D s"), so the deterministic form already exists in the tree. This same platform difference was reported and diagnosed in April 2004 ("invalid input syntax for type tid: '(,)'", e.g. 200404061432.i36EWab06319@candle.pha.pa.us), where Tom Lane noted "the reason for the platform dependency is probably that strtoul() is setting errno on some machines and not others" and that "the TID input parser ... should never allow this". The trigger in that thread (an ODBC driver emitting '(,)') was fixed on the driver side; the parser was not changed. Happy to provide additional cases or a patch.