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 1wZ9BY-000oGo-0v for pgsql-bugs@arkaria.postgresql.org; Mon, 15 Jun 2026 15:25:12 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wZ9BX-00CWyj-0I for pgsql-bugs@arkaria.postgresql.org; Mon, 15 Jun 2026 15:25:11 +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 1wZ9BW-00CWyZ-2L for pgsql-bugs@lists.postgresql.org; Mon, 15 Jun 2026 15:25:10 +0000 Received: from mail-yw1-x112f.google.com ([2607:f8b0:4864:20::112f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wZ9BV-00000000Uhk-1lfr for pgsql-bugs@postgresql.org; Mon, 15 Jun 2026 15:25:09 +0000 Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-7e3b2a435ecso38138007b3.1 for ; Mon, 15 Jun 2026 08:25:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781537108; cv=none; d=google.com; s=arc-20240605; b=jb8rRvOotARsKZd9slotC/vW4dy3I2wVHdogwX+5U+bDjIQ9rOBAO6qTQi8Ze477CD 01+luYjgIRca5mTP1oOjioodjZ3xBPkaaCfUFrIpoec1Hgdpe8W6yvz1Dh3PJ4h6OPcr QFh8F7KzyNKKkzyV/vmIMlN5J0UTynaC5Jr2Z1k9iXuaEMM3ul7mLyWerSPnzvS/IUMm 3dtx627Mq6SSMX3u/AWhMwClzteagaw5YGHoTvRLgVfY8pvlgGOOcZ7ofZIFwt3VPDGi KmhcuUWtHkeqraIIFg7GJNnJUs5va1canuEdmi8w3n43jT0FUzMcmFawfgN/bNx5QlsD 5VRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=MgY/Ds18mlIy8KWVXrve3j/px9TLLELrl8iYudybmTc=; fh=Njd8nARWSKNY4ZGWVLFapfXYCbNOHcTu+rp359SNYsA=; b=P2f2QZGVZV5gqiFf8bCIDsPloHS6VQtbNzIizYdkcPYCFTMS4JjytItILAB+E8PwvD Nqhm9lECthweyexoSwM03K292Smn4HFGRjKE7xKtgrqbPeRKvD5qQ7xng+w/Ff6HVfXg fQrhwXjathNtIRhtWVPr9h/ivZqgH2c2/Y05WQ4BfHqyyfbC9VH8Nt9H8KHqVJltn/Ca K8tGNVWHlxa+6j1dGbW22wjG9mgJQwQNoqpeEOlConQVLTsUP5Qq1RXMG8KpCUe2hkVU q93+WptF9kklf4yf9NT+9+CeUpbIxKJxXbr4QDl97t8VjSv5RrkS5H5KkZ+nJ3s4Lmfx UWeA==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781537108; x=1782141908; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=MgY/Ds18mlIy8KWVXrve3j/px9TLLELrl8iYudybmTc=; b=dUT5H9973mUoRMIF/prlimEEU6nLr1ixOMuocfMy867dIYOS0uj9OgLqT9JRsJroq6 KLgWPsmf0X5GhcFrCfyU8upsKq1REqztyts2j/TaVQXXGEGld75TicDtVK7GEinyp83O gtXUney5/KIty3d+KLeuOGU1Gl4KDZgFyLKIRzlnOiq2asN8lwDK3kkabK4NABjASpFG 0c9DbmfJ7wnq0VCMq6G0xdZpAAI9xlJ6GRz8GwzqsAGrzPAqSe31Yeo9HwqjTgkOx6Pd sJtLAxb2byXNPJZtz8f4WyV47PpohCO7ve89YkwRB5jO/EdPFhh14ibDbVApvQdA0t18 inXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781537108; x=1782141908; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=MgY/Ds18mlIy8KWVXrve3j/px9TLLELrl8iYudybmTc=; b=f8tNZnkoxM/4huaSxsvu4lcb81jOLJblZVZ81hKkh8y6Po/2Vc/8JnzB+4qeIRZWqe elpWfwkB8a8Q365UmtY/ecAa7m/zCTsdLej4UK7Jh2sC0uRFzCYELU8V2dBcbMtAu5/t 7bKNa1lOA60odcmq87c814R6OX/MyMIf5KgTRP6RltkiABjUWBw20c0i0G0WG3U07ujV qOvvgCv1oSN7kOyS6FrfLxBBwfjAyHJDwYEm/kOKv8ak66hVvj0PjOCYc9b/qIs8n9pr s0RS2/Lb/o7J0lcPR3YOl9nxY910QVUhkErxi8TzAQiNgp6hQ7D+3050w0xSRf9CZ0Z+ WF2Q== X-Forwarded-Encrypted: i=1; AFNElJ+f5ppw3t4Z9ZFU8zrNkm0qZg+n9SrJ8SfyZngRf1t7pGXRXfM/GSmU4sRJxAUKAPDlJ51ShJkkJSW/@postgresql.org X-Gm-Message-State: AOJu0YzAVpZ+QSRZVxUP767uMuP1LrnyRp64uVyJjF9iXEmx5X7BJhpJ HN0jczVzG0TNtTekDhZoWcxQ/556HjkQeNOQlI4FMO/q9bw0iJA3NAzcd8flU2n+3UgUMMySfn7 0Qb+kB5vThFZJLX+m2m+cJUFYcntwNl8= X-Gm-Gg: Acq92OFcAs3JZOriHDgp7ZNjzKqM4bmXcSeWJMzZsLXnwz2SO5J6p8D2O3iIRfpa0FE 4c0mWZWLOO11dezxM69DOuBSN3n5Ds2ET7wmWmwKl4/ZIbshG3FjehCxEVYV3lYZ7ZAvT7wxGWM V1wgxXKDV9RoAL7ah1WonsCaxtSuriRxh3X3aPWbiMMsxfw79X/qY5fLOrnBbB7DHid3gbQPcT5 81vU8WENuZJHSke28hz9YQjvaDK4l7d3P9eAMy9xQ02Ha9/z1/YADMwM12PfR8vpae+9YmklgB+ Rjq9Gbm5Qru6WDD4SIUOi81Tv7yeNJ+1OpyHig== X-Received: by 2002:a05:690c:6710:b0:7d1:c256:b5a8 with SMTP id 00721157ae682-7f8c3ed20a2mr110758317b3.40.1781537108102; Mon, 15 Jun 2026 08:25:08 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ayush Tiwari Date: Mon, 15 Jun 2026 20:54:56 +0530 X-Gm-Features: AVVi8CcnUMeIMdKZlZ1h6qoJvHsGBFb3a_36uOhw0LkNhz5Km8lmfXWSM2oUm5Y Message-ID: Subject: Re: Fw:Re: Fw: ltree_compare in contrib/ltree/ltree_op.c overflows int32 on deep ltree comparisons, returning the wrong sign To: Heikki Linnakangas Cc: =?UTF-8?B?546L6LeD5p6X?= , pgsql-bugs@postgresql.org Content-Type: multipart/alternative; boundary="0000000000007b93f306544c6ec3" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000007b93f306544c6ec3 Content-Type: text/plain; charset="UTF-8" Hi, On Mon, 15 Jun 2026 at 20:38, Heikki Linnakangas wrote: > On 13/06/2026 09:12, Ayush Tiwari wrote: > > This looks like a classic case of integer overflow that's > > happening in ltree_compare function in ltree_op.c. > > > > return (al->len - bl->len) * 10 * (an + 1); > > return res * 10 * (an + 1); > > return (a->numlevel - b->numlevel) * 10 * (an + 1); > > > > I think the calculation should be done as int64, something of this sort: > > Yeah, that works. However, I note that the multiplication is only really > needed by the ltree_penalty() caller. All the other callers just check > if the return value is less than, equal, or greater than zero. It feels > a little silly to do all that work of multiplication and clamping for > those callers. And for ltree_penalty(), the caller actually converts the > return value to a float, so clamping it to int32 range feels a little > silly for that too. So I propose the attached, which splits the > ltree_compare() function into two variants: one for ltree_penalty() that > returns a float, and one for others that don't care about the > "magnitude". It duplicates a little code, but I think it's easier to > reason about. What do you think? > I had thought initially of using the method you have added, (not with float return-type though, I thought of planning to create a duplicate function with int64 type just for ltree_penalty(), but float type is better) noting the same thing that rest callers just care about comparison with 0. But thought backpatching it would be harder, hence I used the int64 method. However, your patch looks much better than the ugly behaviour and I agree it did not make sense to do those multiplications at all other comparison functions. Regards, Ayush --0000000000007b93f306544c6ec3 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Mon, 15 Jun 2= 026 at 20:38, Heikki Linnakangas <hli= nnaka@iki.fi> wrote:
On 13/06/2026 09:12, Ayush Tiwari wrote:
> This looks like a classic case of integer overflow that's
> happening in ltree_compare function in ltree_op.c.
>
> return (al->len - bl->len) * 10 * (an + 1);
> return res * 10 * (an + 1);
> return (a->numlevel - b->numlevel) * 10 * (an + 1);
>
> I think the calculation should be done as int64, something of this sor= t:

Yeah, that works. However, I note that the multiplication is only really needed by the ltree_penalty() caller. All the other callers just check
if the return value is less than, equal, or greater than zero. It feels a little silly to do all that work of multiplication and clamping for
those callers. And for ltree_penalty(), the caller actually converts the return value to a float, so clamping it to int32 range feels a little
silly for that too. So I propose the attached, which splits the
ltree_compare() function into two variants: one for ltree_penalty() that returns a float, and one for others that don't care about the
"magnitude". It duplicates a little code, but I think it's ea= sier to
reason about. What do you think?

I had thought ini= tially of using the method you have added,
(not with float return-type t= hough, I thought of planning to create
a duplicate function with int64 t= ype just for ltree_penalty(), but float type
is better) noting the same = thing that rest callers just care about
comparison with 0.

But t= hought backpatching it would be harder, hence I used the int64
method. = However, your patch looks much better than the ugly
behaviour and I agr= ee it did not make sense to do those
multiplications at all other compar= ison functions.

Regards,
Ayush
--0000000000007b93f306544c6ec3--