| 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 |
| 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 |