mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Postpone aggregate checks until after collation is assigned.
Previously, parseCheckAggregates was run before assign_query_collations, but this causes problems if any expression has already had a collation assigned by some transform function (e.g. transformCaseExpr) before parseCheckAggregates runs. The differing collations would cause expressions not to be recognized as equal to the ones in the GROUP BY clause, leading to spurious errors about unaggregated column references. The result was that CASE expr WHEN val ... would fail when "expr" contained a GROUPING() expression or matched one of the group by expressions, and where collatable types were involved; whereas the supposedly identical CASE WHEN expr = val ... would succeed. Backpatch all the way; this appears to have been wrong ever since collations were introduced. Per report from Guillaume Lelarge, analysis and patch by me. Discussion: https://postgr.es/m/CAECtzeVSO_US8C2Khgfv54ZMUOBR4sWq+6_bLrETnWExHT=rFg@mail.gmail.com Discussion: https://postgr.es/m/87muo0k0c7.fsf@news-spur.riddles.org.uk
This commit is contained in:
@ -418,11 +418,13 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
|
||||
qry->hasSubLinks = pstate->p_hasSubLinks;
|
||||
qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
|
||||
qry->hasAggs = pstate->p_hasAggs;
|
||||
if (pstate->p_hasAggs)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
assign_query_collations(pstate, qry);
|
||||
|
||||
/* this must be done after collations, for reliable comparison of exprs */
|
||||
if (pstate->p_hasAggs)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
@ -1255,8 +1257,6 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
qry->hasSubLinks = pstate->p_hasSubLinks;
|
||||
qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
|
||||
qry->hasAggs = pstate->p_hasAggs;
|
||||
if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
foreach(l, stmt->lockingClause)
|
||||
{
|
||||
@ -1266,6 +1266,10 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
|
||||
assign_query_collations(pstate, qry);
|
||||
|
||||
/* this must be done after collations, for reliable comparison of exprs */
|
||||
if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
@ -1715,8 +1719,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
qry->hasSubLinks = pstate->p_hasSubLinks;
|
||||
qry->hasWindowFuncs = pstate->p_hasWindowFuncs;
|
||||
qry->hasAggs = pstate->p_hasAggs;
|
||||
if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
foreach(l, lockingClause)
|
||||
{
|
||||
@ -1726,6 +1728,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
|
||||
assign_query_collations(pstate, qry);
|
||||
|
||||
/* this must be done after collations, for reliable comparison of exprs */
|
||||
if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual)
|
||||
parseCheckAggregates(pstate, qry);
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user