Re: Convert ALL SubLinks to ANY SubLinks

From: Rui Zhao <zhaorui126(at)gmail(dot)com>
To: Richard Guo <guofenglinux(at)gmail(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Convert ALL SubLinks to ANY SubLinks
Date: 2026-11-09 07:50:17
Message-ID: CAHWVJhHumJO_s7R8Uy2s0Q_8XwQMqW7dPaawP_znqGNH-ryhxQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Richard,

Thanks for working on this optimization.

I found a valid custom operator class for which v2 turns a working
row-comparison ALL query into an error. Using the existing int4_tbl
regression table:

CREATE OPERATOR #< (LEFTARG = integer, RIGHTARG = integer,
FUNCTION = int4lt, NEGATOR = #>=);
CREATE OPERATOR #>= (LEFTARG = integer, RIGHTARG = integer,
FUNCTION = int4ge, NEGATOR = #<);
CREATE OPERATOR CLASS regress_all_int_ops
FOR TYPE integer USING btree AS
OPERATOR 1 #<,
OPERATOR 2 <=,
OPERATOR 3 =,
OPERATOR 4 >=,
OPERATOR 5 >,
FUNCTION 1 btint4cmp(integer, integer);

SELECT f1 FROM int4_tbl
WHERE (f1, f1) OPERATOR(#<) ALL
(SELECT f1, f1 FROM int4_tbl WHERE f1 = 123456)
ORDER BY f1;

Master returns -2147483647, -123456 and 0. On v2 I get:

ERROR: operator 16417 is not a member of opfamily 16419

NOT ALL fails too. The operator class passes amvalidate(). Its strategy
4 operator is the built-in >=, while the negator of #< is #>=. Both >=
and #>= call int4ge, but only >= belongs to this family.

negate_sublink_testexpr() replaces the operators with their negators
but keeps rcexpr->opfamilies. ExecInitExprRec() then calls
get_op_opfamily_properties() with #>= and the original family, which
causes the error.

The attached patch checks op_in_opfamily() before making that change.
If a negator is outside the original family, it leaves the ALL sublink
unchanged.

I also considered two other fixes:

1. Find a B-tree family containing the negator and update the
corresponding entry in rcexpr->opfamilies.
2. Keep the original family and use get_opfamily_member() to find its
operator for the opposite comparison. For example, when negating <,
use the family's strategy 4 operator (>=).

In the built-in B-tree families and extensions I checked, including
citext, pgvector and pg_roaringbitmap, the negators were already in the
same family. So I think the attached small check is sufficient.

The patch includes regression tests for ALL and NOT ALL; both fail on
v2 and return the expected rows with the fix.

Regards,
Rui

Attachment Content-Type Size
nocfbot-0001-Fix-operator-family-checks-when-negating-ALL-row-com.patch application/octet-stream 4.4 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2026-11-09 07:53:29 Re: Add sortsupport to money_ops, pg_lsn_ops and xid8_ops
Previous Message David Rowley 2026-11-09 07:36:17 Re: Wrong results with initplans moved by setrefs.c