Skip to content

Commit

Permalink
Fix parser to check ungrouped attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
mos65o2 committed Nov 12, 2024
1 parent 431a01f commit 6144e37
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions src/backend/parser/parse_agg.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef struct
ParseState *pstate;
Query *qry;
List *groupClauses;
List *groupClauseCommonVars;
bool have_non_var_grouping;
List **func_grouped_rels;
int sublevels_up;
Expand All @@ -64,7 +65,8 @@ static int check_agg_arguments(ParseState *pstate,
static bool check_agg_arguments_walker(Node *node,
check_agg_arguments_context *context);
static void check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,
List *groupClauses, bool have_non_var_grouping,
List *groupClauses, List *groupClauseCommonVars,
bool have_non_var_grouping,
List **func_grouped_rels);
static bool check_ungrouped_columns_walker(Node *node,
check_ungrouped_columns_context *context);
Expand Down Expand Up @@ -814,12 +816,14 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
{
List *groupClauses = NIL;
bool have_non_var_grouping;
List *groupClauseCommonVars = NIL;
List *func_grouped_rels = NIL;
ListCell *l;
bool hasJoinRTEs;
bool hasSelfRefRTEs;
PlannerInfo *root;
Node *clause;
bool hasGroupingSets = false;

/* This should only be called if we found aggregates or grouping */
Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual);
Expand Down Expand Up @@ -854,6 +858,14 @@ parseCheckAggregates(ParseState *pstate, Query *qry)

Assert(IsA(grpcl, SortGroupClause) || IsA(grpcl, GroupingClause));

/* Check grouping set is similar to regular group by */
if(IsA(grpcl, GroupingClause)){
GroupingClause *gc = (GroupingClause*) grpcl;
if(gc->groupType == GROUPINGTYPE_GROUPING_SETS && gc->groupsets->length > 1){
hasGroupingSets = true;
}
}

exprs = get_groupclause_exprs(grpcl, qry->targetList);

foreach(l2, exprs)
Expand Down Expand Up @@ -894,14 +906,21 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
* Detect whether any of the grouping expressions aren't simple Vars; if
* they're all Vars then we don't have to work so hard in the recursive
* scans. (Note we have to flatten aliases before this.)
*
* Save Vars to check functional dependency in case of simple
* grouping sets or regular group by.
*/
have_non_var_grouping = false;
foreach(l, groupClauses)
{
if (!IsA((Node *) lfirst(l), Var))
{
have_non_var_grouping = true;
break;
}
else if (!hasGroupingSets)
{
Var *var = lfirst(l);
groupClauseCommonVars = lappend(groupClauseCommonVars, var);
}
}

Expand All @@ -917,14 +936,16 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
if (hasJoinRTEs)
clause = flatten_join_alias_vars(root, clause);
check_ungrouped_columns(clause, pstate, qry,
groupClauses, have_non_var_grouping,
groupClauses, groupClauseCommonVars,
have_non_var_grouping,
&func_grouped_rels);

clause = (Node *) qry->havingQual;
if (hasJoinRTEs)
clause = flatten_join_alias_vars(root, clause);
check_ungrouped_columns(clause, pstate, qry,
groupClauses, have_non_var_grouping,
groupClauses, groupClauseCommonVars,
have_non_var_grouping,
&func_grouped_rels);

/*
Expand Down Expand Up @@ -961,14 +982,16 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
*/
static void
check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,
List *groupClauses, bool have_non_var_grouping,
List *groupClauses, List *groupClauseCommonVars,
bool have_non_var_grouping,
List **func_grouped_rels)
{
check_ungrouped_columns_context context;

context.pstate = pstate;
context.qry = qry;
context.groupClauses = groupClauses;
context.groupClauseCommonVars = groupClauseCommonVars;
context.have_non_var_grouping = have_non_var_grouping;
context.func_grouped_rels = func_grouped_rels;
context.sublevels_up = 0;
Expand Down Expand Up @@ -1097,7 +1120,7 @@ check_ungrouped_columns_walker(Node *node,
if (check_functional_grouping(rte->relid,
var->varno,
0,
context->groupClauses,
context->groupClauseCommonVars,
&context->qry->constraintDeps))
{
*context->func_grouped_rels =
Expand Down

0 comments on commit 6144e37

Please sign in to comment.