Thread
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
ecpg: Fix memory leaks in ecpg_auto_prepare()
- 3151c264d460 19 (unreleased) cited
-
BUG #19000: gist index returns inconsistent result with gist_inet_ops
PG Bug reporting form <noreply@postgresql.org> — 2025-07-27T05:00:02Z
The following bug has been logged on the website: Bug reference: 19000 Logged by: Alexander Lakhin Email address: exclusion@gmail.com PostgreSQL version: 18beta2 Operating system: Ubuntu 24.04 Description: The following script: CREATE EXTENSION btree_gist; CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; i ---------------- 192.168.1.0/25 CREATE INDEX ON t USING gist(i); SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; i --- (0 rows) shows an inconsistency when using the "<<" operator with a gist index. Reproduced starting from be1cc9aaf. -
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Richard Guo <guofenglinux@gmail.com> — 2025-07-28T02:23:13Z
On Mon, Jul 28, 2025 at 5:16 AM PG Bug reporting form <noreply@postgresql.org> wrote: > CREATE EXTENSION btree_gist; > > CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > i > ---------------- > 192.168.1.0/25 > > CREATE INDEX ON t USING gist(i); > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > i > --- > (0 rows) It seems that with gist_inet_ops the index's opfamily does not support the '<<' operator correctly. With inet_ops, the query works correctly. CC'ing Peter to have a look. Thanks Richard
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Stepan Neretin <slpmcf@gmail.com> — 2025-07-28T06:38:54Z
On Mon, Jul 28, 2025 at 9:23 AM Richard Guo <guofenglinux@gmail.com> wrote: > On Mon, Jul 28, 2025 at 5:16 AM PG Bug reporting form > <noreply@postgresql.org> wrote: > > CREATE EXTENSION btree_gist; > > > > CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; > > > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > > i > > ---------------- > > 192.168.1.0/25 > > > > CREATE INDEX ON t USING gist(i); > > > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > > i > > --- > > (0 rows) > > It seems that with gist_inet_ops the index's opfamily does not support > the '<<' operator correctly. > > With inet_ops, the query works correctly. > > CC'ing Peter to have a look. > > Thanks > Richard > > > Hi, I tried to reproduce this issue on PostgreSQL 18beta2 (commit 3151c264) on Ubuntu 24.04, but I could not observe the incorrect behavior described. Here’s what I did: psql (19devel) Type "help" for help. postgres=# CREATE EXTENSION btree_gist; CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; CREATE EXTENSION SELECT 1 postgres=# CREATE INDEX ON t USING gist(i); CREATE INDEX postgres=# SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; i ---------------- 192.168.1.0/25 (1 row) So the query still returns the expected row after the GiST index is created. If there are any additional settings or steps required to reproduce, please let me know. Best regards, Stepan Neretin -
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Richard Guo <guofenglinux@gmail.com> — 2025-07-28T08:20:45Z
On Mon, Jul 28, 2025 at 3:39 PM Stepan Neretin <slpmcf@gmail.com> wrote: > I tried to reproduce this issue on PostgreSQL 18beta2 (commit 3151c264) on Ubuntu 24.04, but I could not observe the incorrect behavior described. > So the query still returns the expected row after the GiST index is created. > If there are any additional settings or steps required to reproduce, please let me know. You'll need to ensure that the plan uses an index scan. Setting enable_seqscan to off should be sufficient to do so. Thanks Richard
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tender Wang <tndrwang@gmail.com> — 2025-07-31T05:30:45Z
Richard Guo <guofenglinux@gmail.com> 于2025年7月28日周一 10:23写道: > On Mon, Jul 28, 2025 at 5:16 AM PG Bug reporting form > <noreply@postgresql.org> wrote: > > CREATE EXTENSION btree_gist; > > > > CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; > > > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > > i > > ---------------- > > 192.168.1.0/25 > > > > CREATE INDEX ON t USING gist(i); > > > > SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; > > i > > --- > > (0 rows) > > It seems that with gist_inet_ops the index's opfamily does not support > the '<<' operator correctly. > > With inet_ops, the query works correctly. > > CC'ing Peter to have a look. > Before be1cc9aaf, because : if (opfamily != NETWORK_BTREE_FAM_OID) return NIL; So the planner creates seqscan. After be1cc9aaf, above if block was removed, so the planner creates an index scan, as below: postgres=# explain SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; QUERY PLAN ------------------------------------------------------------------------------- Index Scan using t_i_idx on t (cost=0.12..8.15 rows=1 width=32) Index Cond: ((i > '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) Filter: (i << '192.168.1.0/24'::inet) (3 rows) However, the gistgettuple() function returned NULL, so the above query has no output. I created another table t2 and used btree index, its plan was same with t, as below: postgres=# explain SELECT * FROM t2 WHERE i << '192.168.1.0/24'::cidr; QUERY PLAN ------------------------------------------------------------------------------- Index Scan using t2_i_idx on t2 (cost=0.12..8.15 rows=1 width=32) Index Cond: ((i > '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) Filter: (i << '192.168.1.0/24'::inet) (3 rows) I hacked match_network_sub (), changing is_eq to true, so the plan of t is as below: postgres=# explain SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; QUERY PLAN ------------------------------------------------------------------------------- Index Scan using t_i_idx on t (cost=0.12..8.15 rows=1 width=32) Index Cond: ((i >= '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) Filter: (i << '192.168.1.0/24'::inet) (3 rows) The above plan will return a tuple. It seems that gist_inet_ops the index's opfamily does not support the '<<' operator correctly, as Richard said. Or the Index Cond for the gist index is not correct. -- Thanks, Tender Wang -
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Peter Eisentraut <peter@eisentraut.org> — 2025-07-31T15:43:18Z
On 28.07.25 04:23, Richard Guo wrote: > On Mon, Jul 28, 2025 at 5:16 AM PG Bug reporting form > <noreply@postgresql.org> wrote: >> CREATE EXTENSION btree_gist; >> >> CREATE TABLE t AS SELECT '192.168.1.0/25'::inet AS i; >> >> SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; >> i >> ---------------- >> 192.168.1.0/25 >> >> CREATE INDEX ON t USING gist(i); >> >> SELECT * FROM t WHERE i << '192.168.1.0/24'::cidr; >> i >> --- >> (0 rows) > > It seems that with gist_inet_ops the index's opfamily does not support > the '<<' operator correctly. > > With inet_ops, the query works correctly. The generated index condition is the same for the gist and the btree index, namely: ((i > '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) If I run the query with the lower bound directly, like SELECT * FROM t WHERE i > '192.168.1.0/24'::inet; then I also get no result rows for the gist index, but I do get one for the btree index. (The upper bound works correctly in either case.) This can be reproduced even in PG17. My mind is a bit boggled about what the actual meaning of the > operator should be in this case, but in any case it seems there might be a pre-existing discrepancy in the btree_gist module.
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tom Lane <tgl@sss.pgh.pa.us> — 2025-07-31T18:17:35Z
Peter Eisentraut <peter@eisentraut.org> writes: > On 28.07.25 04:23, Richard Guo wrote: >> It seems that with gist_inet_ops the index's opfamily does not support >> the '<<' operator correctly. >> With inet_ops, the query works correctly. > This can be reproduced even in PG17. > My mind is a bit boggled about what the actual meaning of the > operator > should be in this case, but in any case it seems there might be a > pre-existing discrepancy in the btree_gist module. We've known about this for, um, decades: btree_gist's support for inet/cidr is fundamentally broken [1][2]. It's still there only because nobody's been able to think of a way of removing it without causing pain for anyone who has indexes like that. But maybe we should just accept that it's going to cause pain and remove it. Actually ... I vaguely recall that we have, or once had, a kluge in CREATE INDEX that would silently substitute another opclass name for a user-specified opclass that wasn't there anymore. That would help with dump/restore scenarios, although it'd be pretty disastrous in pg_upgrade. But we could add a preflight check to pg_upgrade that looked for gist_inet_ops indexes and told users to replace them with network_ops indexes. So maybe there is a way forward? regards, tom lane [1] https://www.postgresql.org/message-id/flat/201010112055.o9BKtZf7011251%40wwwmaster.postgresql.org [2] https://www.postgresql.org/message-id/flat/7891efc1-8378-2cf2-617b-4143848ec895%40proxel.se
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Richard Guo <guofenglinux@gmail.com> — 2025-08-01T02:38:31Z
On Fri, Aug 1, 2025 at 3:17 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > We've known about this for, um, decades: btree_gist's support for > inet/cidr is fundamentally broken [1][2]. It's still there > only because nobody's been able to think of a way of removing it > without causing pain for anyone who has indexes like that. > But maybe we should just accept that it's going to cause pain > and remove it. I think correctness should take priority over avoiding pain. Thanks Richard
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tom Lane <tgl@sss.pgh.pa.us> — 2025-08-01T03:33:28Z
Richard Guo <guofenglinux@gmail.com> writes: > On Fri, Aug 1, 2025 at 3:17 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: >> We've known about this for, um, decades: btree_gist's support for >> inet/cidr is fundamentally broken [1][2]. It's still there >> only because nobody's been able to think of a way of removing it >> without causing pain for anyone who has indexes like that. >> But maybe we should just accept that it's going to cause pain >> and remove it. > I think correctness should take priority over avoiding pain. Yeah. I spent a little time investigating this today, and hope to have a patch to propose tomorrow. regards, tom lane
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tender Wang <tndrwang@gmail.com> — 2025-08-01T04:38:00Z
Tom Lane <tgl@sss.pgh.pa.us> 于2025年8月1日周五 11:33写道: > Richard Guo <guofenglinux@gmail.com> writes: > > On Fri, Aug 1, 2025 at 3:17 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > >> We've known about this for, um, decades: btree_gist's support for > >> inet/cidr is fundamentally broken [1][2]. It's still there > >> only because nobody's been able to think of a way of removing it > >> without causing pain for anyone who has indexes like that. > >> But maybe we should just accept that it's going to cause pain > >> and remove it. > > > I think correctness should take priority over avoiding pain. > > Yeah. I spent a little time investigating this today, and hope > to have a patch to propose tomorrow. > What I debugged yesterday was, in gbt_inet_consistent(), query = convert_network_to_scalar(dquery, INETOID, &failure); (gdb) p query $2 = 11822170368 then in gbt_num_consistent(), called tinfo->f_lt(query, key->upper, flinfo), which is gbt_inetlt() and (gdb) p *(double *) b $5 = 11822170368 a is equal to b, gbt_inet_consistent() returned false, no index tuple found. -- Thanks, Tender Wang
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tom Lane <tgl@sss.pgh.pa.us> — 2025-08-01T04:53:23Z
Tender Wang <tndrwang@gmail.com> writes: > Tom Lane <tgl@sss.pgh.pa.us> 于2025年8月1日周五 11:33写道: >> Richard Guo <guofenglinux@gmail.com> writes: >>> On Fri, Aug 1, 2025 at 3:17 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: >>>> We've known about this for, um, decades: btree_gist's support for >>>> inet/cidr is fundamentally broken [1][2]. > What I debugged yesterday was, in gbt_inet_consistent(), > query = convert_network_to_scalar(dquery, INETOID, &failure); Right --- as I mentioned in one of the linked threads, the thing that is fundamentally wrong here is relying on convert_network_to_scalar in the first place. That has no charter to deliver exact results, and it doesn't. In the present example I think the issue is that it doesn't consider the netmask at all; but there are many other cases where it's not an exact representation of inet's sort order. That's not a big problem for its intended purpose for statistical estimates, but it's completely fatal for index infrastructure. regards, tom lane
-
Re: BUG #19000: gist index returns inconsistent result with gist_inet_ops
Tom Lane <tgl@sss.pgh.pa.us> — 2025-08-01T19:04:48Z
I wrote: > Richard Guo <guofenglinux@gmail.com> writes: >> I think correctness should take priority over avoiding pain. > Yeah. I spent a little time investigating this today, and hope > to have a patch to propose tomorrow. Done at https://www.postgresql.org/message-id/2483812.1754072263%40sss.pgh.pa.us regards, tom lane