Base de données relationnelle
Find a file
Tom Lane 415100aa62 Support grouping-expression references and GROUPING() in subqueries.
Until now, substitute_grouped_columns and its predecessor
check_ungrouped_columns intentionally did not cope with references
to GROUP BY expressions (anything more complex than a Var) within
subqueries of the query having GROUP BY.  Because they didn't try to
match subexpressions of subqueries to the GROUP BY list, they'd drill
down to raw Vars of the grouping level and then fail with "subquery
uses ungrouped column from outer query".  There have been remarkably
few complaints about this deficiency, so nobody ever did anything
about it.

The reason for not wanting to deal with it is that within a subquery,
Vars will have varlevelsup different from zero and will thus not be
equal() to the expressions seen in the outer query.  We recognized
this at least as far back as 96ca8ffeb, although I think the comment
I added about it then was just documenting a pre-existing deficiency.
It looks like at the time, the solutions I considered were
(1) write a version of equal() that permits an offset in varlevelsup,
or (2) dynamically apply IncrementVarSublevelsUp at each
subexpression.  (1) would require an amount of new code that seems
rather out of proportion to the benefit, while (2) would add an
exponential amount of cost to the matching process.  But rethinking
it now, what seems attractive is (3) apply IncrementVarSublevelsUp to
the groupingClause list not the subexpressions, and do so only once
per subquery depth level.  Then we can still use plain equal() to
check for matches, and we're not incurring cost proportional to some
power of the subquery's complexity.

This patch continues to use the old logic when the GROUP BY list is
all Vars.  We could discard the special comparison logic for that and
always do it the more general way, but that would be a good deal
slower.  (Micro-benchmarking just parse analysis suggests it's about
50% slower than the Vars-only path.  But we've not heard complaints
about the speed of matching within the main query, so I doubt that
applying the same matching logic within subqueries will be a problem.)
The lack of complaints suggests strongly that this is a very minority
use-case, so I don't want to make the typical case slower to fix it.

While testing that, I was surprised to discover a nearby bug:
GROUPING() within a subquery fails to match GROUP BY Vars that are
join alias Vars.  It tries to apply flatten_join_alias_vars to make
such cases work, but that fails to work inside a subquery because
varlevelsup is wrong.  Therefore, this patch invents a new entry point
flatten_join_alias_for_parser() that allows specification of a
sublevels_up offset.  (It seems cleaner to give the parser its own
entry point rather than abuse the planner's conventions even further.)

While this is pretty clearly a bug fix, I'm hesitant to take the risk
of back-patching, seeing that the existing behavior has stood for so
long with so few complaints.  Maybe we can reconsider once this patch
has baked awhile in master.

Reported-by: PALAYRET Jacques <jacques.palayret@meteo.fr>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/531183.1772058731@sss.pgh.pa.us
2026-03-06 13:40:55 -05:00
.github Add CODE_OF_CONDUCT.md, CONTRIBUTING.md, and SECURITY.md. 2024-07-02 13:03:58 -05:00
config Portable StaticAssertExpr 2026-03-06 09:27:54 +01:00
contrib CREATE SUBSCRIPTION ... SERVER. 2026-03-06 08:27:56 -08:00
doc CREATE SUBSCRIPTION ... SERVER. 2026-03-06 08:27:56 -08:00
src Support grouping-expression references and GROUPING() in subqueries. 2026-03-06 13:40:55 -05:00
.cirrus.star ci: Simplify ci-os-only handling 2025-08-14 12:09:34 -04:00
.cirrus.tasks.yml Revert "Change default value of default_toast_compression to "lz4"" 2026-03-05 08:25:35 +09:00
.cirrus.yml ci: Per-repo configuration for manually trigger tasks 2025-08-14 11:54:03 -04:00
.dir-locals.el Make Emacs perl-mode indent more like perltidy. 2019-01-13 11:32:31 -08:00
.editorconfig Update .editorconfig and .gitattributes for postgresql.conf.sample. 2025-11-18 10:28:36 -06:00
.git-blame-ignore-revs Add commit 7b24959434 to .git-blame-ignore-revs. 2026-03-02 13:23:28 -06:00
.gitattributes Update .editorconfig and .gitattributes for postgresql.conf.sample. 2025-11-18 10:28:36 -06:00
.gitignore Update top-level .gitignore. 2022-12-04 15:23:00 -05:00
.mailmap Add a Git .mailmap file 2024-11-05 13:56:02 +01:00
aclocal.m4 autoconf: Move export_dynamic determination to configure 2022-12-06 18:55:28 -08:00
configure Portable StaticAssertExpr 2026-03-06 09:27:54 +01:00
configure.ac Portable StaticAssertExpr 2026-03-06 09:27:54 +01:00
COPYRIGHT Update copyright for 2026 2026-01-01 13:24:10 -05:00
GNUmakefile.in Allow selecting the git revision to be packaged by "make dist". 2024-05-03 11:08:50 -04:00
HISTORY Canonicalize some URLs 2020-02-10 20:47:50 +01:00
Makefile Restore AIX support. 2026-02-23 13:34:22 -05:00
meson.build Portable StaticAssertExpr 2026-03-06 09:27:54 +01:00
meson_options.txt Update copyright for 2026 2026-01-01 13:24:10 -05:00
README.md Revise the style of a paragraph in README.md. 2024-03-21 10:16:41 -05:00

PostgreSQL Database Management System

This directory contains the source code distribution of the PostgreSQL database management system.

PostgreSQL is an advanced object-relational database management system that supports an extended subset of the SQL standard, including transactions, foreign keys, subqueries, triggers, user-defined types and functions. This distribution also contains C language bindings.

Copyright and license information can be found in the file COPYRIGHT.

General documentation about this version of PostgreSQL can be found at https://www.postgresql.org/docs/devel/. In particular, information about building PostgreSQL from the source code can be found at https://www.postgresql.org/docs/devel/installation.html.

The latest version of this software, and related software, may be obtained at https://www.postgresql.org/download/. For more information look at our web site located at https://www.postgresql.org/.