postgresql/src/tools
Richard Guo 98d5d7ee64 Fix qual pushdown past grouping with mismatched equivalence
The planner has two optimizations that move a qual clause across a
grouping boundary: subquery_planner transfers HAVING clauses to WHERE
so they can be evaluated before aggregation, and qual_is_pushdown_safe
pushes outer restriction clauses into a subquery past its DISTINCT,
DISTINCT ON, window PARTITION BY, or set-operation grouping layer.
Both produce wrong results when the moved clause's equivalence
relation disagrees with the grouping's, since the clause then filters
rows the grouping would have merged.

The disagreement has two forms.  A type may belong to multiple btree
opfamilies whose equality operators disagree (e.g. record_ops vs
record_image_ops); or the grouping may use a nondeterministic
collation, where comparing the column under a different collation, or
wrapping it in a function or operator, can distinguish values the
collation considers equal.  Because we cannot prove an arbitrary
expression preserves that equality, a grouping column with a
nondeterministic collation is safe to push only as a direct operand of
a comparison under its own collation.

Fix both call sites through a shared walker parameterized by a
callback that maps each Var to the grouping equality operator for its
column (or InvalidOid for non-grouping Vars).  For HAVING, the
callback recovers the SortGroupClause's eqop via the GROUP Var's
varattno, which requires running before flatten_group_exprs while
havingQual still contains GROUP Vars.  For subquery pushdown, the
callback recovers the eqop from subquery->distinctClause, a window's
partitionClause, or any grouping node in the SetOperationStmt tree.
The walker fires only when there is an equivalence boundary to cross,
gated by either the existing UNSAFE_NOTIN_DISTINCTON_CLAUSE and
UNSAFE_NOTIN_PARTITIONBY_CLAUSE flags or by a recursive check for any
grouping node in the set-op tree.

Back-patch to v18 only.  The HAVING half relies on the RTE_GROUP
mechanism introduced in v18 (commit 247dea89f), which is what lets us
identify grouping expressions via GROUP Vars on pre-flatten
havingQual.  Pre-v18 branches lack that machinery, so a back-patch
there would need a different approach.  Given the absence of field
reports of these bugs on back branches, the risk of carrying a
different fix on stable branches is not justified.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Thom Brown <thom@linux.com>
Reviewed-by: Florin Irion <irionr@gmail.com>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>
Discussion: https://postgr.es/m/CAMbWs4-QLZpn3UVOpeG2fOxxhdnkDNMZ_3Zcm3dqJwRAphz68g@mail.gmail.com
Backpatch-through: 18
2026-07-06 16:14:13 +09:00
..
ci ci: Improve ccache handling 2026-06-08 15:26:47 -04:00
editors Make Emacs perl-mode indent more like perltidy. 2019-01-13 11:32:31 -08:00
ifaddrs Update copyright for 2026 2026-01-01 13:24:10 -05:00
perlcheck Use "grep -E" not "egrep". 2026-05-13 12:07:19 -04:00
pg_bsd_indent Modernize pg_bsd_indent's error/warning reporting code. 2026-06-15 12:22:55 -04:00
pginclude libpq: Split PGOAUTHDEBUG=UNSAFE into multiple options 2026-04-07 08:15:14 -07:00
pgindent Fix qual pushdown past grouping with mismatched equivalence 2026-07-06 16:14:13 +09:00
add_commit_links.pl Pre-beta mechanical code beautification, step 2: run pgperltidy. 2026-05-13 10:37:42 -04:00
ccsym tools/ccsym: update for modern versions of gcc 2015-01-20 13:02:58 -05:00
check_bison_recursion.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00
copyright.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00
darwin_sysroot Move darwin sysroot determination into separate file 2022-09-01 16:54:19 -07:00
find_badmacros
find_meson meson: Add initial version of meson based build system 2022-09-21 22:37:17 -07:00
find_static Fix trap in a few shell scripts 2022-09-20 18:50:16 +02:00
find_typedef Use "grep -E" not "egrep". 2026-05-13 12:07:19 -04:00
gen_export.pl Restore AIX support. 2026-02-23 13:34:22 -05:00
gen_keywordlist.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00
generate_editorconfig.py Add script to keep .editorconfig in sync with .gitattributes 2025-02-01 10:09:45 +01:00
git-external-diff Preserve information on use of git-external-diff 2018-05-24 23:45:31 +09:30
git_changelog Update copyright for 2026 2026-01-01 13:24:10 -05:00
install_files meson: make install_test_files more generic, rename to install_files 2023-03-23 21:20:18 -07:00
make_ctags Fix make_etags breakage on certain platforms. 2023-06-14 11:02:50 +09:00
make_etags Fix make_etags failure on Mac. 2023-02-15 09:52:42 +09:00
make_mkid Add another pgdefine path check, and a cvs-git change. 2011-08-26 21:52:35 -04:00
mark_pgdllimport.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00
msvc_gendef.pl MSVC: Support building for AArch64. 2026-01-07 13:42:57 -06:00
PerfectHash.pm Update copyright for 2026 2026-01-01 13:24:10 -05:00
pgflex pgflex: propagate environment to flex subprocess 2025-06-30 12:24:48 +02:00
pgtest pgtest: fix spacing 2023-08-14 14:03:29 -04:00
rcgen meson: Add windows resource files 2022-10-05 09:56:05 -07:00
RELEASE_CHANGES Remove gen_node_support.pl's ad-hoc ABI stability check. 2026-04-21 10:58:00 -04:00
testwrap Add 'make check-tests' behavior to the meson based builds 2025-11-21 17:12:22 -05:00
valgrind.supp Fix typos and inconsistencies in code and comments 2026-01-05 09:19:15 +09:00
version_stamp.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00
win32tzlist.pl Update copyright for 2026 2026-01-01 13:24:10 -05:00