/*-------------------------------------------------------------------------
 *
 * parse_agg.c
 *	  handle aggregates in parser
 *
 * Portioflatten_join_alias_varsns Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/parser/parse_agg.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/htup_details.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/parse_agg.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"

typedef struct
{
	ParseState *pstate;
	int			min_varlevel;
	int			min_agglevel;
	int			sublevels_up;
} check_agg_arguments_context;

typedef struct
{
	ParseState *pstate;
	Query	   *qry;
	bool		hasJoinRTEs;
	List	   *groupClauses;
	List	   *groupClauseCommonVars;
	bool		have_non_var_grouping;
	List	  **func_grouped_rels;
	int			sublevels_up;
	bool		in_agg_direct_args;
} check_ungrouped_columns_context;

typedef struct
{
	int sublevels_up;
} checkHasGroupExtFuncs_context;

static int	check_agg_arguments(ParseState *pstate,
								List *directargs,
								List *args,
								Expr *filter);
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, List *groupClauseCommonVars,
									bool have_non_var_grouping,
									List **func_grouped_rels);
static bool check_ungrouped_columns_walker(Node *node,
										   check_ungrouped_columns_context *context);
static void finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
									List *groupClauses, bool hasJoinRTEs,
									bool have_non_var_grouping);
static bool finalize_grouping_exprs_walker(Node *node,
										   check_ungrouped_columns_context *context);
static void check_agglevels_and_constraints(ParseState *pstate, Node *expr);
static List *expand_groupingset_node(GroupingSet *gs);
static Node *make_agg_arg(Oid argtype, Oid argcollation);


/*
 * transformAggregateCall -
 *		Finish initial transformation of an aggregate call
 *
 * parse_func.c has recognized the function as an aggregate, and has set up
 * all the fields of the Aggref except aggargtypes, aggdirectargs, args,
 * aggorder, aggdistinct and agglevelsup.  The passed-in args list has been
 * through standard expression transformation and type coercion to match the
 * agg's declared arg types, while the passed-in aggorder list hasn't been
 * transformed at all.
 *
 * Here we separate the args list into direct and aggregated args, storing the
 * former in agg->aggdirectargs and the latter in agg->args.  The regular
 * args, but not the direct args, are converted into a targetlist by inserting
 * TargetEntry nodes.  We then transform the aggorder and agg_distinct
 * specifications to produce lists of SortGroupClause nodes for agg->aggorder
 * and agg->aggdistinct.  (For a regular aggregate, this might result in
 * adding resjunk expressions to the targetlist; but for ordered-set
 * aggregates the aggorder list will always be one-to-one with the aggregated
 * args.)
 *
 * We must also determine which query level the aggregate actually belongs to,
 * set agglevelsup accordingly, and mark p_hasAggs true in the corresponding
 * pstate level.
 */
void
transformAggregateCall(ParseState *pstate, Aggref *agg,
					   List *args, List *aggorder, bool agg_distinct)
{
	List	   *argtypes = NIL;
	List	   *tlist = NIL;
	List	   *torder = NIL;
	List	   *tdistinct = NIL;
	AttrNumber	attno = 1;
	int			save_next_resno;
	ListCell   *lc;

	if (AGGKIND_IS_ORDERED_SET(agg->aggkind))
	{
		/*
		 * For an ordered-set agg, the args list includes direct args and
		 * aggregated args; we must split them apart.
		 */
		int			numDirectArgs = list_length(args) - list_length(aggorder);
		List	   *aargs;
		ListCell   *lc2;

		Assert(numDirectArgs >= 0);

		aargs = list_copy_tail(args, numDirectArgs);
		agg->aggdirectargs = list_truncate(args, numDirectArgs);

		/*
		 * Build a tlist from the aggregated args, and make a sortlist entry
		 * for each one.  Note that the expressions in the SortBy nodes are
		 * ignored (they are the raw versions of the transformed args); we are
		 * just looking at the sort information in the SortBy nodes.
		 */
		forboth(lc, aargs, lc2, aggorder)
		{
			Expr	   *arg = (Expr *) lfirst(lc);
			SortBy	   *sortby = (SortBy *) lfirst(lc2);
			TargetEntry *tle;

			/* We don't bother to assign column names to the entries */
			tle = makeTargetEntry(arg, attno++, NULL, false);
			tlist = lappend(tlist, tle);

			torder = addTargetToSortList(pstate, tle,
										 torder, tlist, sortby);
		}

		/* Never any DISTINCT in an ordered-set agg */
		Assert(!agg_distinct);
	}
	else
	{
		/* Regular aggregate, so it has no direct args */
		agg->aggdirectargs = NIL;

		/*
		 * Transform the plain list of Exprs into a targetlist.
		 */
		foreach(lc, args)
		{
			Expr	   *arg = (Expr *) lfirst(lc);
			TargetEntry *tle;

			/* We don't bother to assign column names to the entries */
			tle = makeTargetEntry(arg, attno++, NULL, false);
			tlist = lappend(tlist, tle);
		}

		/*
		 * If we have an ORDER BY, transform it.  This will add columns to the
		 * tlist if they appear in ORDER BY but weren't already in the arg
		 * list.  They will be marked resjunk = true so we can tell them apart
		 * from regular aggregate arguments later.
		 *
		 * We need to mess with p_next_resno since it will be used to number
		 * any new targetlist entries.
		 */
		save_next_resno = pstate->p_next_resno;
		pstate->p_next_resno = attno;

		torder = transformSortClause(pstate,
									 aggorder,
									 &tlist,
									 EXPR_KIND_ORDER_BY,
									 true /* force SQL99 rules */ );

		/*
		 * If we have DISTINCT, transform that to produce a distinctList.
		 */
		if (agg_distinct)
		{
			tdistinct = transformDistinctClause(pstate, &tlist, torder, true);

			/*
			 * Remove this check if executor support for hashed distinct for
			 * aggregates is ever added.
			 */
			foreach(lc, tdistinct)
			{
				SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);

				if (!OidIsValid(sortcl->sortop))
				{
					Node	   *expr = get_sortgroupclause_expr(sortcl, tlist);

					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_FUNCTION),
							 errmsg("could not identify an ordering operator for type %s",
									format_type_be(exprType(expr))),
							 errdetail("Aggregates with DISTINCT must be able to sort their inputs."),
							 parser_errposition(pstate, exprLocation(expr))));
				}
			}
		}

		pstate->p_next_resno = save_next_resno;
	}

	/* Update the Aggref with the transformation results */
	agg->args = tlist;
	agg->aggorder = torder;
	agg->aggdistinct = tdistinct;

	/*
	 * Now build the aggargtypes list with the type OIDs of the direct and
	 * aggregated args, ignoring any resjunk entries that might have been
	 * added by ORDER BY/DISTINCT processing.  We can't do this earlier
	 * because said processing can modify some args' data types, in particular
	 * by resolving previously-unresolved "unknown" literals.
	 */
	foreach(lc, agg->aggdirectargs)
	{
		Expr	   *arg = (Expr *) lfirst(lc);

		argtypes = lappend_oid(argtypes, exprType((Node *) arg));
	}
	foreach(lc, tlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(lc);

		if (tle->resjunk)
			continue;			/* ignore junk */
		argtypes = lappend_oid(argtypes, exprType((Node *) tle->expr));
	}
	agg->aggargtypes = argtypes;

	check_agglevels_and_constraints(pstate, (Node *) agg);
}

/*
 * transformGroupingFunc
 *		Transform a GROUPING expression
 *
 * GROUPING() behaves very like an aggregate.  Processing of levels and nesting
 * is done as for aggregates.  We set p_hasAggs for these expressions too.
 */
Node *
transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
{
	ListCell   *lc;
	List	   *args = p->args;
	List	   *result_list = NIL;
	GroupingFunc *result = makeNode(GroupingFunc);

	if (list_length(args) > 31)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
				 errmsg("GROUPING must have fewer than 32 arguments"),
				 parser_errposition(pstate, p->location)));

	foreach(lc, args)
	{
		Node	   *current_result;

		current_result = transformExpr(pstate, (Node *) lfirst(lc), pstate->p_expr_kind);

		/* acceptability of expressions is checked later */

		result_list = lappend(result_list, current_result);
	}

	result->args = result_list;
	result->location = p->location;

	check_agglevels_and_constraints(pstate, (Node *) result);

	return (Node *) result;
}

/*
 * transformGroupingFunc
 *		Transform a GROUPING expression
 *
 * GROUP_ID() behaves very like an aggregate.  Processing of levels and nesting
 * is done as for aggregates.  We set p_hasAggs for these expressions too.
 */
Node *
transformGroupId(ParseState *pstate, GroupId *p)
{
	GroupId	   *result = makeNode(GroupId);

	result->location = p->location;

	check_agglevels_and_constraints(pstate, (Node *) result);

	return (Node *) result;
}

/*
 * Aggregate functions and grouping operations (which are combined in the spec
 * as <set function specification>) are very similar with regard to level and
 * nesting restrictions (though we allow a lot more things than the spec does).
 * Centralise those restrictions here.
 */
static void
check_agglevels_and_constraints(ParseState *pstate, Node *expr)
{
	List	   *directargs = NIL;
	List	   *args = NIL;
	Expr	   *filter = NULL;
	int			min_varlevel;
	int			location = -1;
	Index	   *p_levelsup;
	const char *err;
	bool		errkind;
	bool		isAgg = IsA(expr, Aggref);

	if (isAgg)
	{
		Aggref	   *agg = (Aggref *) expr;

		directargs = agg->aggdirectargs;
		args = agg->args;
		filter = agg->aggfilter;
		location = agg->location;
		p_levelsup = &agg->agglevelsup;
	}
	else if (IsA(expr, GroupId))
	{
		GroupId *grp = (GroupId *) expr;

		args = NIL;
		location = grp->location;
		p_levelsup = &grp->agglevelsup;
	}
	else
	{
		GroupingFunc *grp = (GroupingFunc *) expr;

		args = grp->args;
		location = grp->location;
		p_levelsup = &grp->agglevelsup;
	}

	/*
	 * Check the arguments to compute the aggregate's level and detect
	 * improper nesting.
	 */
	min_varlevel = check_agg_arguments(pstate,
									   directargs,
									   args,
									   filter);

	*p_levelsup = min_varlevel;

	/* Mark the correct pstate level as having aggregates */
	while (min_varlevel-- > 0)
		pstate = pstate->parentParseState;
	pstate->p_hasAggs = true;

	/*
	 * Check to see if the aggregate function is in an invalid place within
	 * its aggregation query.
	 *
	 * For brevity we support two schemes for reporting an error here: set
	 * "err" to a custom message, or set "errkind" true if the error context
	 * is sufficiently identified by what ParseExprKindName will return, *and*
	 * what it will return is just a SQL keyword.  (Otherwise, use a custom
	 * message to avoid creating translation problems.)
	 */
	err = NULL;
	errkind = false;
	switch (pstate->p_expr_kind)
	{
		case EXPR_KIND_NONE:
			Assert(false);		/* can't happen */
			break;
		case EXPR_KIND_OTHER:
			/*
			 * Accept aggregate/grouping here; caller must throw error if
			 * wanted
			 */
			break;
		case EXPR_KIND_JOIN_ON:
		case EXPR_KIND_JOIN_USING:
			if (isAgg)
				err = _("aggregate functions are not allowed in JOIN conditions");
			else
				err = _("grouping operations are not allowed in JOIN conditions");

			break;
		case EXPR_KIND_FROM_SUBSELECT:

			/*
			 * Aggregate/grouping scope rules make it worth being explicit
			 * here
			 */
			if (isAgg)
				err = _("aggregate functions are not allowed in FROM clause of their own query level");
			else
				err = _("grouping operations are not allowed in FROM clause of their own query level");

			break;
		case EXPR_KIND_FROM_FUNCTION:
			if (isAgg)
				err = _("aggregate functions are not allowed in functions in FROM");
			else
				err = _("grouping operations are not allowed in functions in FROM");

			break;
		case EXPR_KIND_WHERE:
			errkind = true;
			break;
		case EXPR_KIND_POLICY:
			if (isAgg)
				err = _("aggregate functions are not allowed in policy expressions");
			else
				err = _("grouping operations are not allowed in policy expressions");

			break;
		case EXPR_KIND_HAVING:
			/* okay */
			break;
		case EXPR_KIND_FILTER:
			errkind = true;
			break;
		case EXPR_KIND_WINDOW_PARTITION:
			/* okay */
			break;
		case EXPR_KIND_WINDOW_ORDER:
			/* okay */
			break;
		case EXPR_KIND_WINDOW_FRAME_RANGE:
			if (isAgg)
				err = _("aggregate functions are not allowed in window RANGE");
			else
				err = _("grouping operations are not allowed in window RANGE");

			break;
		case EXPR_KIND_WINDOW_FRAME_ROWS:
			if (isAgg)
				err = _("aggregate functions are not allowed in window ROWS");
			else
				err = _("grouping operations are not allowed in window ROWS");

			break;
		case EXPR_KIND_WINDOW_FRAME_GROUPS:
			if (isAgg)
				err = _("aggregate functions are not allowed in window GROUPS");
			else
				err = _("grouping operations are not allowed in window GROUPS");

			break;
		case EXPR_KIND_SELECT_TARGET:
			/* okay */
			break;
		case EXPR_KIND_INSERT_TARGET:
		case EXPR_KIND_UPDATE_SOURCE:
		case EXPR_KIND_UPDATE_TARGET:
			errkind = true;
			break;
		case EXPR_KIND_MERGE_WHEN:
			if (isAgg)
				err = _("aggregate functions are not allowed in MERGE WHEN conditions");
			else
				err = _("grouping operations are not allowed in MERGE WHEN conditions");

			break;
		case EXPR_KIND_GROUP_BY:
			errkind = true;
			break;
		case EXPR_KIND_ORDER_BY:
			/* okay */
			break;
		case EXPR_KIND_DISTINCT_ON:
			/* okay */
			break;
		case EXPR_KIND_LIMIT:
		case EXPR_KIND_OFFSET:
			errkind = true;
			break;
		case EXPR_KIND_RETURNING:
			errkind = true;
			break;
		case EXPR_KIND_VALUES:
		case EXPR_KIND_VALUES_SINGLE:
			errkind = true;
			break;
		case EXPR_KIND_CHECK_CONSTRAINT:
		case EXPR_KIND_DOMAIN_CHECK:
			if (isAgg)
				err = _("aggregate functions are not allowed in check constraints");
			else
				err = _("grouping operations are not allowed in check constraints");

			break;
		case EXPR_KIND_COLUMN_DEFAULT:
		case EXPR_KIND_FUNCTION_DEFAULT:

			if (isAgg)
				err = _("aggregate functions are not allowed in DEFAULT expressions");
			else
				err = _("grouping operations are not allowed in DEFAULT expressions");

			break;
		case EXPR_KIND_INDEX_EXPRESSION:
			if (isAgg)
				err = _("aggregate functions are not allowed in index expressions");
			else
				err = _("grouping operations are not allowed in index expressions");

			break;
		case EXPR_KIND_INDEX_PREDICATE:
			if (isAgg)
				err = _("aggregate functions are not allowed in index predicates");
			else
				err = _("grouping operations are not allowed in index predicates");

			break;
		case EXPR_KIND_STATS_EXPRESSION:
			if (isAgg)
				err = _("aggregate functions are not allowed in statistics expressions");
			else
				err = _("grouping operations are not allowed in statistics expressions");

			break;
		case EXPR_KIND_ALTER_COL_TRANSFORM:
			if (isAgg)
				err = _("aggregate functions are not allowed in transform expressions");
			else
				err = _("grouping operations are not allowed in transform expressions");

			break;
		case EXPR_KIND_EXECUTE_PARAMETER:
			if (isAgg)
				err = _("aggregate functions are not allowed in EXECUTE parameters");
			else
				err = _("grouping operations are not allowed in EXECUTE parameters");

			break;
		case EXPR_KIND_TRIGGER_WHEN:
			if (isAgg)
				err = _("aggregate functions are not allowed in trigger WHEN conditions");
			else
				err = _("grouping operations are not allowed in trigger WHEN conditions");

			break;
		case EXPR_KIND_SCATTER_BY:
			/* okay */
			break;
		case EXPR_KIND_PARTITION_BOUND:
			if (isAgg)
				err = _("aggregate functions are not allowed in partition bound");
			else
				err = _("grouping operations are not allowed in partition bound");

			break;
		case EXPR_KIND_PARTITION_EXPRESSION:
			if (isAgg)
				err = _("aggregate functions are not allowed in partition key expressions");
			else
				err = _("grouping operations are not allowed in partition key expressions");

			break;
		case EXPR_KIND_GENERATED_COLUMN:

			if (isAgg)
				err = _("aggregate functions are not allowed in column generation expressions");
			else
				err = _("grouping operations are not allowed in column generation expressions");

			break;

		case EXPR_KIND_CALL_ARGUMENT:
			if (isAgg)
				err = _("aggregate functions are not allowed in CALL arguments");
			else
				err = _("grouping operations are not allowed in CALL arguments");

			break;

		case EXPR_KIND_COPY_WHERE:
			if (isAgg)
				err = _("aggregate functions are not allowed in COPY FROM WHERE conditions");
			else
				err = _("grouping operations are not allowed in COPY FROM WHERE conditions");

			break;

		case EXPR_KIND_CYCLE_MARK:
			errkind = true;
			break;

			/*
			 * There is intentionally no default: case here, so that the
			 * compiler will warn if we add a new ParseExprKind without
			 * extending this switch.  If we do see an unrecognized value at
			 * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
			 * which is sane anyway.
			 */
	}

	if (err)
		ereport(ERROR,
				(errcode(ERRCODE_GROUPING_ERROR),
				 errmsg_internal("%s", err),
				 parser_errposition(pstate, location)));

	if (errkind)
	{
		if (isAgg)
			/* translator: %s is name of a SQL construct, eg GROUP BY */
			err = _("aggregate functions are not allowed in %s");
		else
			/* translator: %s is name of a SQL construct, eg GROUP BY */
			err = _("grouping operations are not allowed in %s");

		ereport(ERROR,
				(errcode(ERRCODE_GROUPING_ERROR),
				 errmsg_internal(err,
								 ParseExprKindName(pstate->p_expr_kind)),
				 parser_errposition(pstate, location)));
	}
}

/*
 * check_agg_arguments
 *	  Scan the arguments of an aggregate function to determine the
 *	  aggregate's semantic level (zero is the current select's level,
 *	  one is its parent, etc).
 *
 * The aggregate's level is the same as the level of the lowest-level variable
 * or aggregate in its aggregated arguments (including any ORDER BY columns)
 * or filter expression; or if it contains no variables at all, we presume it
 * to be local.
 *
 * Vars/Aggs in direct arguments are *not* counted towards determining the
 * agg's level, as those arguments aren't evaluated per-row but only
 * per-group, and so in some sense aren't really agg arguments.  However,
 * this can mean that we decide an agg is upper-level even when its direct
 * args contain lower-level Vars/Aggs, and that case has to be disallowed.
 * (This is a little strange, but the SQL standard seems pretty definite that
 * direct args are not to be considered when setting the agg's level.)
 *
 * We also take this opportunity to detect any aggregates or window functions
 * nested within the arguments.  We can throw error immediately if we find
 * a window function.  Aggregates are a bit trickier because it's only an
 * error if the inner aggregate is of the same semantic level as the outer,
 * which we can't know until we finish scanning the arguments.
 */
static int
check_agg_arguments(ParseState *pstate,
					List *directargs,
					List *args,
					Expr *filter)
{
	int			agglevel;
	check_agg_arguments_context context;

	context.pstate = pstate;
	context.min_varlevel = -1;	/* signifies nothing found yet */
	context.min_agglevel = -1;
	context.sublevels_up = 0;

	(void) check_agg_arguments_walker((Node *) args, &context);
	(void) check_agg_arguments_walker((Node *) filter, &context);

	/*
	 * If we found no vars nor aggs at all, it's a level-zero aggregate;
	 * otherwise, its level is the minimum of vars or aggs.
	 */
	if (context.min_varlevel < 0)
	{
		if (context.min_agglevel < 0)
			agglevel = 0;
		else
			agglevel = context.min_agglevel;
	}
	else if (context.min_agglevel < 0)
		agglevel = context.min_varlevel;
	else
		agglevel = Min(context.min_varlevel, context.min_agglevel);

	/*
	 * If there's a nested aggregate of the same semantic level, complain.
	 */
	if (agglevel == context.min_agglevel)
	{
		int			aggloc;

		aggloc = locate_agg_of_level((Node *) args, agglevel);
		if (aggloc < 0)
			aggloc = locate_agg_of_level((Node *) filter, agglevel);
		ereport(ERROR,
				(errcode(ERRCODE_GROUPING_ERROR),
				 errmsg("aggregate function calls cannot be nested"),
				 parser_errposition(pstate, aggloc)));
	}

	/*
	 * Now check for vars/aggs in the direct arguments, and throw error if
	 * needed.  Note that we allow a Var of the agg's semantic level, but not
	 * an Agg of that level.  In principle such Aggs could probably be
	 * supported, but it would create an ordering dependency among the
	 * aggregates at execution time.  Since the case appears neither to be
	 * required by spec nor particularly useful, we just treat it as a
	 * nested-aggregate situation.
	 */
	if (directargs)
	{
		context.min_varlevel = -1;
		context.min_agglevel = -1;
		(void) check_agg_arguments_walker((Node *) directargs, &context);
		if (context.min_varlevel >= 0 && context.min_varlevel < agglevel)
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
					 errmsg("outer-level aggregate cannot contain a lower-level variable in its direct arguments"),
					 parser_errposition(pstate,
										locate_var_of_level((Node *) directargs,
															context.min_varlevel))));
		if (context.min_agglevel >= 0 && context.min_agglevel <= agglevel)
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
					 errmsg("aggregate function calls cannot be nested"),
					 parser_errposition(pstate,
										locate_agg_of_level((Node *) directargs,
															context.min_agglevel))));
	}
	return agglevel;
}

static bool
check_agg_arguments_walker(Node *node,
						   check_agg_arguments_context *context)
{
	if (node == NULL)
		return false;
	if (IsA(node, Var))
	{
		int			varlevelsup = ((Var *) node)->varlevelsup;

		/* convert levelsup to frame of reference of original query */
		varlevelsup -= context->sublevels_up;
		/* ignore local vars of subqueries */
		if (varlevelsup >= 0)
		{
			if (context->min_varlevel < 0 ||
				context->min_varlevel > varlevelsup)
				context->min_varlevel = varlevelsup;
		}
		return false;
	}
	if (IsA(node, Aggref))
	{
		int			agglevelsup = ((Aggref *) node)->agglevelsup;

		/* convert levelsup to frame of reference of original query */
		agglevelsup -= context->sublevels_up;
		/* ignore local aggs of subqueries */
		if (agglevelsup >= 0)
		{
			if (context->min_agglevel < 0 ||
				context->min_agglevel > agglevelsup)
				context->min_agglevel = agglevelsup;
		}
		/* Continue and descend into subtree */
	}
	if (IsA(node, GroupingFunc))
	{
		int			agglevelsup = ((GroupingFunc *) node)->agglevelsup;

		/* convert levelsup to frame of reference of original query */
		agglevelsup -= context->sublevels_up;
		/* ignore local aggs of subqueries */
		if (agglevelsup >= 0)
		{
			if (context->min_agglevel < 0 ||
				context->min_agglevel > agglevelsup)
				context->min_agglevel = agglevelsup;
		}
		/* Continue and descend into subtree */
	}
	if (IsA(node, GroupId))
	{
		int			agglevelsup = ((GroupId *) node)->agglevelsup;

		/* convert levelsup to frame of reference of original query */
		agglevelsup -= context->sublevels_up;
		/* ignore local aggs of subqueries */
		if (agglevelsup >= 0)
		{
			if (context->min_agglevel < 0 ||
				context->min_agglevel > agglevelsup)
				context->min_agglevel = agglevelsup;
		}
		/* Continue and descend into subtree */
	}
	/*
	 * SRFs and window functions can be rejected immediately, unless we are
	 * within a sub-select within the aggregate's arguments; in that case
	 * they're OK.
	 */
	if (context->sublevels_up == 0)
	{
		if ((IsA(node, FuncExpr) && ((FuncExpr *) node)->funcretset) ||
			(IsA(node, OpExpr) && ((OpExpr *) node)->opretset))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("aggregate function calls cannot contain set-returning function calls"),
					 errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
					 parser_errposition(context->pstate, exprLocation(node))));
		if (IsA(node, WindowFunc))
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
					 errmsg("aggregate function calls cannot contain window function calls"),
					 parser_errposition(context->pstate,
										((WindowFunc *) node)->location)));
	}
	if (IsA(node, Query))
	{
		/* Recurse into subselects */
		bool		result;

		context->sublevels_up++;
		result = query_tree_walker((Query *) node,
								   check_agg_arguments_walker,
								   (void *) context,
								   0);
		context->sublevels_up--;
		return result;
	}

	return expression_tree_walker(node,
								  check_agg_arguments_walker,
								  (void *) context);
}

/*
 * transformWindowFuncCall -
 *		Finish initial transformation of a window function call
 *
 * parse_func.c has recognized the function as a window function, and has set
 * up all the fields of the WindowFunc except winref.  Here we must (1) add
 * the WindowDef to the pstate (if not a duplicate of one already present) and
 * set winref to link to it; and (2) mark p_hasWindowFuncs true in the pstate.
 * Unlike aggregates, only the most closely nested pstate level need be
 * considered --- there are no "outer window functions" per SQL spec.
 */
void
transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
						WindowDef *windef)
{
	const char *err;
	bool		errkind;
	char	   *name;

	/*
	 * A window function call can't contain another one (but aggs are OK). XXX
	 * is this required by spec, or just an unimplemented feature?
	 *
	 * Note: we don't need to check the filter expression here, because the
	 * context checks done below and in transformAggregateCall would have
	 * already rejected any window funcs or aggs within the filter.
	 */
	if (pstate->p_hasWindowFuncs &&
		contain_windowfuncs((Node *) wfunc->args))
		ereport(ERROR,
				(errcode(ERRCODE_WINDOWING_ERROR),
				 errmsg("window function calls cannot be nested"),
				 parser_errposition(pstate,
									locate_windowfunc((Node *) wfunc->args))));

	/*
	 * Check to see if the window function is in an invalid place within the
	 * query.
	 *
	 * For brevity we support two schemes for reporting an error here: set
	 * "err" to a custom message, or set "errkind" true if the error context
	 * is sufficiently identified by what ParseExprKindName will return, *and*
	 * what it will return is just a SQL keyword.  (Otherwise, use a custom
	 * message to avoid creating translation problems.)
	 */
	err = NULL;
	errkind = false;
	switch (pstate->p_expr_kind)
	{
		case EXPR_KIND_NONE:
			Assert(false);		/* can't happen */
			break;
		case EXPR_KIND_OTHER:
			/* Accept window func here; caller must throw error if wanted */
			break;
		case EXPR_KIND_JOIN_ON:
		case EXPR_KIND_JOIN_USING:
			err = _("window functions are not allowed in JOIN conditions");
			break;
		case EXPR_KIND_FROM_SUBSELECT:
			/* can't get here, but just in case, throw an error */
			errkind = true;
			break;
		case EXPR_KIND_FROM_FUNCTION:
			err = _("window functions are not allowed in functions in FROM");
			break;
		case EXPR_KIND_WHERE:
			errkind = true;
			break;
		case EXPR_KIND_POLICY:
			err = _("window functions are not allowed in policy expressions");
			break;
		case EXPR_KIND_HAVING:
			errkind = true;
			break;
		case EXPR_KIND_FILTER:
			errkind = true;
			break;
		case EXPR_KIND_WINDOW_PARTITION:
		case EXPR_KIND_WINDOW_ORDER:
		case EXPR_KIND_WINDOW_FRAME_RANGE:
		case EXPR_KIND_WINDOW_FRAME_ROWS:
		case EXPR_KIND_WINDOW_FRAME_GROUPS:
			err = _("window functions are not allowed in window definitions");
			break;
		case EXPR_KIND_SELECT_TARGET:
			/* okay */
			break;
		case EXPR_KIND_INSERT_TARGET:
		case EXPR_KIND_UPDATE_SOURCE:
		case EXPR_KIND_UPDATE_TARGET:
			errkind = true;
			break;
		case EXPR_KIND_MERGE_WHEN:
			err = _("window functions are not allowed in MERGE WHEN conditions");
			break;
		case EXPR_KIND_GROUP_BY:
			errkind = true;
			break;
		case EXPR_KIND_ORDER_BY:
			/* okay */
			break;
		case EXPR_KIND_DISTINCT_ON:
			/* okay */
			break;
		case EXPR_KIND_LIMIT:
		case EXPR_KIND_OFFSET:
			errkind = true;
			break;
		case EXPR_KIND_RETURNING:
			errkind = true;
			break;
		case EXPR_KIND_VALUES:
		case EXPR_KIND_VALUES_SINGLE:
			errkind = true;
			break;
		case EXPR_KIND_CHECK_CONSTRAINT:
		case EXPR_KIND_DOMAIN_CHECK:
			err = _("window functions are not allowed in check constraints");
			break;
		case EXPR_KIND_COLUMN_DEFAULT:
		case EXPR_KIND_FUNCTION_DEFAULT:
			err = _("window functions are not allowed in DEFAULT expressions");
			break;
		case EXPR_KIND_INDEX_EXPRESSION:
			err = _("window functions are not allowed in index expressions");
			break;
		case EXPR_KIND_STATS_EXPRESSION:
			err = _("window functions are not allowed in statistics expressions");
			break;
		case EXPR_KIND_INDEX_PREDICATE:
			err = _("window functions are not allowed in index predicates");
			break;
		case EXPR_KIND_ALTER_COL_TRANSFORM:
			err = _("window functions are not allowed in transform expressions");
			break;
		case EXPR_KIND_EXECUTE_PARAMETER:
			err = _("window functions are not allowed in EXECUTE parameters");
			break;
		case EXPR_KIND_TRIGGER_WHEN:
			err = _("window functions are not allowed in trigger WHEN conditions");
			break;
		case EXPR_KIND_SCATTER_BY:
			/* okay */
			break;
		case EXPR_KIND_PARTITION_BOUND:
			err = _("window functions are not allowed in partition bound");
			break;
		case EXPR_KIND_PARTITION_EXPRESSION:
			err = _("window functions are not allowed in partition key expressions");
			break;
		case EXPR_KIND_CALL_ARGUMENT:
			err = _("window functions are not allowed in CALL arguments");
			break;
		case EXPR_KIND_COPY_WHERE:
			err = _("window functions are not allowed in COPY FROM WHERE conditions");
			break;
		case EXPR_KIND_GENERATED_COLUMN:
			err = _("window functions are not allowed in column generation expressions");
			break;
		case EXPR_KIND_CYCLE_MARK:
			errkind = true;
			break;

			/*
			 * There is intentionally no default: case here, so that the
			 * compiler will warn if we add a new ParseExprKind without
			 * extending this switch.  If we do see an unrecognized value at
			 * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
			 * which is sane anyway.
			 */
	}
	if (err)
		ereport(ERROR,
				(errcode(ERRCODE_WINDOWING_ERROR),
				 errmsg_internal("%s", err),
				 parser_errposition(pstate, wfunc->location)));
	if (errkind)
		ereport(ERROR,
				(errcode(ERRCODE_WINDOWING_ERROR),
		/* translator: %s is name of a SQL construct, eg GROUP BY */
				 errmsg("window functions are not allowed in %s",
						ParseExprKindName(pstate->p_expr_kind)),
				 parser_errposition(pstate, wfunc->location)));

	/*
	 * If the OVER clause just specifies a window name, find that WINDOW
	 * clause (which had better be present).  Otherwise, try to match all the
	 * properties of the OVER clause, and make a new entry in the p_windowdefs
	 * list if no luck.
	 *
	 * In PostgreSQL, the syntax for this is "agg() OVER w". In GPDB, we also
	 * accept "agg() OVER (w)", with the extra parens.
	 */
	if (windef->name)
	{
		name = windef->name;

		Assert(windef->refname == NULL &&
			   windef->partitionClause == NIL &&
			   windef->orderClause == NIL &&
			   windef->frameOptions == FRAMEOPTION_DEFAULTS);
	}
	else if (windef->refname &&
			 !windef->partitionClause &&
			 !windef->orderClause &&
			 (windef->frameOptions & FRAMEOPTION_NONDEFAULT) == 0)
	{
		/* This is "agg() OVER (w)" */
		name = windef->refname;
	}
	else
		name = NULL;

	if (name)
	{
		Index		winref = 0;
		ListCell   *lc;

		foreach(lc, pstate->p_windowdefs)
		{
			WindowDef  *refwin = (WindowDef *) lfirst(lc);

			winref++;
			if (refwin->name && strcmp(refwin->name, name) == 0)
			{
				wfunc->winref = winref;
				break;
			}
		}
		if (lc == NULL)			/* didn't find it? */
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("window \"%s\" does not exist", name),
					 parser_errposition(pstate, windef->location)));
	}
	else
	{
		Index		winref = 0;
		ListCell   *lc;

		foreach(lc, pstate->p_windowdefs)
		{
			WindowDef  *refwin = (WindowDef *) lfirst(lc);

			winref++;
			if (refwin->refname && windef->refname &&
				strcmp(refwin->refname, windef->refname) == 0)
				 /* matched on refname */ ;
			else if (!refwin->refname && !windef->refname)
				 /* matched, no refname */ ;
			else
				continue;

			/*
			 * Also see similar de-duplication code in optimize_window_clauses
			 */
			if (equal(refwin->partitionClause, windef->partitionClause) &&
				equal(refwin->orderClause, windef->orderClause) &&
				refwin->frameOptions == windef->frameOptions &&
				equal(refwin->startOffset, windef->startOffset) &&
				equal(refwin->endOffset, windef->endOffset))
			{
				/* found a duplicate window specification */
				wfunc->winref = winref;
				break;
			}
		}
		if (lc == NULL)			/* didn't find it? */
		{
			pstate->p_windowdefs = lappend(pstate->p_windowdefs, windef);
			wfunc->winref = list_length(pstate->p_windowdefs);
		}
	}

	pstate->p_hasWindowFuncs = true;
}

/*
 * parseCheckAggregates
 *	Check for aggregates where they shouldn't be and improper grouping.
 *	This function should be called after the target list and qualifications
 *	are finalized.
 *
 *	Misplaced aggregates are now mostly detected in transformAggregateCall,
 *	but it seems more robust to check for aggregates in recursive queries
 *	only after everything is finalized.  In any case it's hard to detect
 *	improper grouping on-the-fly, so we have to make another pass over the
 *	query for that.
 */
void
parseCheckAggregates(ParseState *pstate, Query *qry)
{
	List	   *gset_common = NIL;
	List	   *groupClauses = NIL;
	List	   *groupClauseCommonVars = NIL;
	bool		have_non_var_grouping;
	List	   *func_grouped_rels = NIL;
	ListCell   *l;
	bool		hasJoinRTEs;
	bool		hasSelfRefRTEs;
	Node	   *clause;

	/* This should only be called if we found aggregates or grouping */
	Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual || qry->groupingSets);

	/*
	 * If we have grouping sets, expand them and find the intersection of all
	 * sets.
	 */
	if (qry->groupingSets)
	{
		/*
		 * The limit of 4096 is arbitrary and exists simply to avoid resource
		 * issues from pathological constructs.
		 */
		List	   *gsets = expand_grouping_sets(qry->groupingSets, qry->groupDistinct, 4096);

		if (!gsets)
			ereport(ERROR,
					(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
					 errmsg("too many grouping sets present (maximum 4096)"),
					 parser_errposition(pstate,
										qry->groupClause
										? exprLocation((Node *) qry->groupClause)
										: exprLocation((Node *) qry->groupingSets))));

		/*
		 * The intersection will often be empty, so help things along by
		 * seeding the intersect with the smallest set.
		 */
		gset_common = linitial(gsets);

		if (gset_common)
		{
			for_each_from(l, gsets, 1)
			{
				gset_common = list_intersection_int(gset_common, lfirst(l));
				if (!gset_common)
					break;
			}
		}

		/*
		 * If there was only one grouping set in the expansion, AND if the
		 * groupClause is non-empty (meaning that the grouping set is not
		 * empty either), then we can ditch the grouping set and pretend we
		 * just had a normal GROUP BY.
		 */
		if (list_length(gsets) == 1 && qry->groupClause)
			qry->groupingSets = NIL;
	}

	/*
	 * Scan the range table to see if there are JOIN or self-reference CTE
	 * entries.  We'll need this info below.
	 */
	hasJoinRTEs = hasSelfRefRTEs = false;
	foreach(l, pstate->p_rtable)
	{
		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);

		if (rte->rtekind == RTE_JOIN)
			hasJoinRTEs = true;
		else if (rte->rtekind == RTE_CTE && rte->self_reference)
			hasSelfRefRTEs = true;
	}

	/*
	 * Build a list of the acceptable GROUP BY expressions for use by
	 * check_ungrouped_columns().
	 *
	 * We get the TLE, not just the expr, because GROUPING wants to know the
	 * sortgroupref.
	 */
	foreach(l, qry->groupClause)
	{
		SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
		TargetEntry *expr;

		expr = get_sortgroupclause_tle(grpcl, qry->targetList);
		if (expr == NULL)
			continue;			/* probably cannot happen */

		groupClauses = lappend(groupClauses, expr);
	}

	/*
	 * If there are join alias vars involved, we have to flatten them to the
	 * underlying vars, so that aliased and unaliased vars will be correctly
	 * taken as equal.  We can skip the expense of doing this if no rangetable
	 * entries are RTE_JOIN kind.
	 */
	if (hasJoinRTEs)
		groupClauses = (List *) flatten_join_alias_vars(NULL, qry,
														(Node *) groupClauses);

	/*
	 * 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.)
	 *
	 * Track Vars that are included in all grouping sets separately in
	 * groupClauseCommonVars, since these are the only ones we can use to
	 * check for functional dependencies.
	 */
	have_non_var_grouping = false;
	foreach(l, groupClauses)
	{
		TargetEntry *tle = lfirst(l);

		if (!IsA(tle->expr, Var))
		{
			have_non_var_grouping = true;
		}
		else if (!qry->groupingSets ||
				 list_member_int(gset_common, tle->ressortgroupref))
		{
			groupClauseCommonVars = lappend(groupClauseCommonVars, tle->expr);
		}
	}

	/*
	 * Check the targetlist and HAVING clause for ungrouped variables.
	 *
	 * Note: because we check resjunk tlist elements as well as regular ones,
	 * this will also find ungrouped variables that came from ORDER BY and
	 * WINDOW clauses.  For that matter, it's also going to examine the
	 * grouping expressions themselves --- but they'll all pass the test ...
	 *
	 * We also finalize GROUPING expressions, but for that we need to traverse
	 * the original (unflattened) clause in order to modify nodes.
	 */
	clause = (Node *) qry->targetList;
	finalize_grouping_exprs(clause, pstate, qry,
							groupClauses, hasJoinRTEs,
							have_non_var_grouping);
	if (hasJoinRTEs)
		clause = flatten_join_alias_vars(NULL, qry, clause);
	check_ungrouped_columns(clause, pstate, qry,
							groupClauses, groupClauseCommonVars,
							have_non_var_grouping,
							&func_grouped_rels);

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

	/*
	 * Per spec, aggregates can't appear in a recursive term.
	 */
	if (pstate->p_hasAggs && hasSelfRefRTEs)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_RECURSION),
				 errmsg("aggregate functions are not allowed in a recursive query's recursive term"),
				 parser_errposition(pstate,
									locate_agg_of_level((Node *) qry, 0))));
}

/*
 * check_ungrouped_columns -
 *	  Scan the given expression tree for ungrouped variables (variables
 *	  that are not listed in the groupClauses list and are not within
 *	  the arguments of aggregate functions).  Emit a suitable error message
 *	  if any are found.
 *
 * NOTE: we assume that the given clause has been transformed suitably for
 * parser output.  This means we can use expression_tree_walker.
 *
 * NOTE: we recognize grouping expressions in the main query, but only
 * grouping Vars in subqueries.  For example, this will be rejected,
 * although it could be allowed:
 *		SELECT
 *			(SELECT x FROM bar where y = (foo.a + foo.b))
 *		FROM foo
 *		GROUP BY a + b;
 * The difficulty is the need to account for different sublevels_up.
 * This appears to require a whole custom version of equal(), which is
 * way more pain than the feature seems worth.
 */
static void
check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,
						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.hasJoinRTEs = false;	/* assume caller flattened join Vars */
	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;
	context.in_agg_direct_args = false;
	check_ungrouped_columns_walker(node, &context);
}

static bool
check_ungrouped_columns_walker(Node *node,
							   check_ungrouped_columns_context *context)
{
	ListCell   *gl;

	if (node == NULL)
		return false;
	if (IsA(node, Const) ||
		IsA(node, Param))
		return false;			/* constants are always acceptable */

	if (IsA(node, Aggref))
	{
		Aggref	   *agg = (Aggref *) node;

		if ((int) agg->agglevelsup == context->sublevels_up)
		{
			/*
			 * If we find an aggregate call of the original level, do not
			 * recurse into its normal arguments, ORDER BY arguments, or
			 * filter; ungrouped vars there are not an error.  But we should
			 * check direct arguments as though they weren't in an aggregate.
			 * We set a special flag in the context to help produce a useful
			 * error message for ungrouped vars in direct arguments.
			 */
			bool		result;

			Assert(!context->in_agg_direct_args);
			context->in_agg_direct_args = true;
			result = check_ungrouped_columns_walker((Node *) agg->aggdirectargs,
													context);
			context->in_agg_direct_args = false;
			return result;
		}

		/*
		 * We can skip recursing into aggregates of higher levels altogether,
		 * since they could not possibly contain Vars of concern to us (see
		 * transformAggregateCall).  We do need to look at aggregates of lower
		 * levels, however.
		 */
		if ((int) agg->agglevelsup > context->sublevels_up)
			return false;
	}

	if (IsA(node, GroupingFunc))
	{
		GroupingFunc *grp = (GroupingFunc *) node;

		/* handled GroupingFunc separately, no need to recheck at this level */

		if ((int) grp->agglevelsup >= context->sublevels_up)
			return false;
	}

	if (IsA(node, GroupId))
	{
		GroupId	   *grp = (GroupId *) node;

		/* handled GroupId separately, no need to recheck at this level */

		if ((int) grp->agglevelsup >= context->sublevels_up)
			return false;
	}

	/*
	 * If we have any GROUP BY items that are not simple Vars, check to see if
	 * subexpression as a whole matches any GROUP BY item. We need to do this
	 * at every recursion level so that we recognize GROUPed-BY expressions
	 * before reaching variables within them. But this only works at the outer
	 * query level, as noted above.
	 */
	if (context->have_non_var_grouping && context->sublevels_up == 0)
	{
		foreach(gl, context->groupClauses)
		{
			TargetEntry *tle = lfirst(gl);

			if (equal(node, tle->expr))
				return false;	/* acceptable, do not descend more */
		}
	}

	/*
	 * If we have an ungrouped Var of the original query level, we have a
	 * failure.  Vars below the original query level are not a problem, and
	 * neither are Vars from above it.  (If such Vars are ungrouped as far as
	 * their own query level is concerned, that's someone else's problem...)
	 */
	if (IsA(node, Var))
	{
		Var		   *var = (Var *) node;
		RangeTblEntry *rte;
		const char *attname;

		if (var->varlevelsup != context->sublevels_up)
			return false;		/* it's not local to my query, ignore */

		/*
		 * Check for a match, if we didn't do it above.
		 */
		if (!context->have_non_var_grouping || context->sublevels_up != 0)
		{
			foreach(gl, context->groupClauses)
			{
				Var		   *gvar = (Var *) ((TargetEntry *) lfirst(gl))->expr;

				if (IsA(gvar, Var) &&
					gvar->varno == var->varno &&
					gvar->varattno == var->varattno &&
					gvar->varlevelsup == 0)
					return false;	/* acceptable, we're okay */
			}
		}

		/*
		 * Check whether the Var is known functionally dependent on the GROUP
		 * BY columns.  If so, we can allow the Var to be used, because the
		 * grouping is really a no-op for this table.  However, this deduction
		 * depends on one or more constraints of the table, so we have to add
		 * those constraints to the query's constraintDeps list, because it's
		 * not semantically valid anymore if the constraint(s) get dropped.
		 * (Therefore, this check must be the last-ditch effort before raising
		 * error: we don't want to add dependencies unnecessarily.)
		 *
		 * Because this is a pretty expensive check, and will have the same
		 * outcome for all columns of a table, we remember which RTEs we've
		 * already proven functional dependency for in the func_grouped_rels
		 * list.  This test also prevents us from adding duplicate entries to
		 * the constraintDeps list.
		 */
		if (list_member_int(*context->func_grouped_rels, var->varno))
			return false;		/* previously proven acceptable */

		Assert(var->varno > 0 &&
			   (int) var->varno <= list_length(context->pstate->p_rtable));
		rte = rt_fetch(var->varno, context->pstate->p_rtable);
		if (rte->rtekind == RTE_RELATION)
		{
			if (check_functional_grouping(rte->relid,
										  var->varno,
										  0,
										  context->groupClauseCommonVars,
										  &context->qry->constraintDeps))
			{
				*context->func_grouped_rels =
					lappend_int(*context->func_grouped_rels, var->varno);
				return false;	/* acceptable */
			}
		}

		/* Found an ungrouped local variable; generate error message */
		attname = get_rte_attribute_name(rte, var->varattno);
		if (context->sublevels_up == 0)
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
					 errmsg("column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function",
							rte->eref->aliasname, attname),
					 context->in_agg_direct_args ?
					 errdetail("Direct arguments of an ordered-set aggregate must use only grouped columns.") : 0,
					 parser_errposition(context->pstate, var->location)));
		else
			ereport(ERROR,
					(errcode(ERRCODE_GROUPING_ERROR),
					 errmsg("subquery uses ungrouped column \"%s.%s\" from outer query",
							rte->eref->aliasname, attname),
					 parser_errposition(context->pstate, var->location)));
	}

	if (IsA(node, Query))
	{
		/* Recurse into subselects */
		bool		result;

		context->sublevels_up++;
		result = query_tree_walker((Query *) node,
								   check_ungrouped_columns_walker,
								   (void *) context,
								   0);
		context->sublevels_up--;
		return result;
	}
	return expression_tree_walker(node, check_ungrouped_columns_walker,
								  (void *) context);
}

/*
 * finalize_grouping_exprs -
 *	  Scan the given expression tree for GROUPING() and related calls,
 *	  and validate and process their arguments.
 *
 * This is split out from check_ungrouped_columns above because it needs
 * to modify the nodes (which it does in-place, not via a mutator) while
 * check_ungrouped_columns may see only a copy of the original thanks to
 * flattening of join alias vars. So here, we flatten each individual
 * GROUPING argument as we see it before comparing it.
 */
static void
finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
						List *groupClauses, bool hasJoinRTEs,
						bool have_non_var_grouping)
{
	check_ungrouped_columns_context context;

	context.pstate = pstate;
	context.qry = qry;
	context.hasJoinRTEs = hasJoinRTEs;
	context.groupClauses = groupClauses;
	context.groupClauseCommonVars = NIL;
	context.have_non_var_grouping = have_non_var_grouping;
	context.func_grouped_rels = NULL;
	context.sublevels_up = 0;
	context.in_agg_direct_args = false;
	finalize_grouping_exprs_walker(node, &context);
}

static bool
finalize_grouping_exprs_walker(Node *node,
							   check_ungrouped_columns_context *context)
{
	ListCell   *gl;

	if (node == NULL)
		return false;
	if (IsA(node, Const) ||
		IsA(node, Param))
		return false;			/* constants are always acceptable */

	if (IsA(node, Aggref))
	{
		Aggref	   *agg = (Aggref *) node;

		if ((int) agg->agglevelsup == context->sublevels_up)
		{
			/*
			 * If we find an aggregate call of the original level, do not
			 * recurse into its normal arguments, ORDER BY arguments, or
			 * filter; GROUPING exprs of this level are not allowed there. But
			 * check direct arguments as though they weren't in an aggregate.
			 */
			bool		result;

			Assert(!context->in_agg_direct_args);
			context->in_agg_direct_args = true;
			result = finalize_grouping_exprs_walker((Node *) agg->aggdirectargs,
													context);
			context->in_agg_direct_args = false;
			return result;
		}

		/*
		 * We can skip recursing into aggregates of higher levels altogether,
		 * since they could not possibly contain exprs of concern to us (see
		 * transformAggregateCall).  We do need to look at aggregates of lower
		 * levels, however.
		 */
		if ((int) agg->agglevelsup > context->sublevels_up)
			return false;
	}

	if (IsA(node, GroupingFunc))
	{
		GroupingFunc *grp = (GroupingFunc *) node;

		/*
		 * We only need to check GroupingFunc nodes at the exact level to
		 * which they belong, since they cannot mix levels in arguments.
		 */

		if ((int) grp->agglevelsup == context->sublevels_up)
		{
			ListCell   *lc;
			List	   *ref_list = NIL;

			foreach(lc, grp->args)
			{
				Node	   *expr = lfirst(lc);
				Index		ref = 0;

				if (context->hasJoinRTEs)
					expr = flatten_join_alias_vars(NULL, context->qry, expr);

				/*
				 * Each expression must match a grouping entry at the current
				 * query level. Unlike the general expression case, we don't
				 * allow functional dependencies or outer references.
				 */

				if (IsA(expr, Var))
				{
					Var		   *var = (Var *) expr;

					if (var->varlevelsup == context->sublevels_up)
					{
						foreach(gl, context->groupClauses)
						{
							TargetEntry *tle = lfirst(gl);
							Var		   *gvar = (Var *) tle->expr;

							if (IsA(gvar, Var) &&
								gvar->varno == var->varno &&
								gvar->varattno == var->varattno &&
								gvar->varlevelsup == 0)
							{
								ref = tle->ressortgroupref;
								break;
							}
						}
					}
				}
				else if (context->have_non_var_grouping &&
						 context->sublevels_up == 0)
				{
					foreach(gl, context->groupClauses)
					{
						TargetEntry *tle = lfirst(gl);

						if (equal(expr, tle->expr))
						{
							ref = tle->ressortgroupref;
							break;
						}
					}
				}

				if (ref == 0)
					ereport(ERROR,
							(errcode(ERRCODE_GROUPING_ERROR),
							 errmsg("arguments to GROUPING must be grouping expressions of the associated query level"),
							 parser_errposition(context->pstate,
												exprLocation(expr))));

				ref_list = lappend_int(ref_list, ref);
			}

			grp->refs = ref_list;
		}

		if ((int) grp->agglevelsup > context->sublevels_up)
			return false;
	}

	if (IsA(node, Query))
	{
		/* Recurse into subselects */
		bool		result;

		context->sublevels_up++;
		result = query_tree_walker((Query *) node,
								   finalize_grouping_exprs_walker,
								   (void *) context,
								   0);
		context->sublevels_up--;
		return result;
	}
	return expression_tree_walker(node, finalize_grouping_exprs_walker,
								  (void *) context);
}


/*
 * Given a GroupingSet node, expand it and return a list of lists.
 *
 * For EMPTY nodes, return a list of one empty list.
 *
 * For SIMPLE nodes, return a list of one list, which is the node content.
 *
 * For CUBE and ROLLUP nodes, return a list of the expansions.
 *
 * For SET nodes, recursively expand contained CUBE and ROLLUP.
 */
static List *
expand_groupingset_node(GroupingSet *gs)
{
	List	   *result = NIL;

	switch (gs->kind)
	{
		case GROUPING_SET_EMPTY:
			result = list_make1(NIL);
			break;

		case GROUPING_SET_SIMPLE:
			result = list_make1(gs->content);
			break;

		case GROUPING_SET_ROLLUP:
			{
				List	   *rollup_val = gs->content;
				ListCell   *lc;
				int			curgroup_size = list_length(gs->content);

				while (curgroup_size > 0)
				{
					List	   *current_result = NIL;
					int			i = curgroup_size;

					foreach(lc, rollup_val)
					{
						GroupingSet *gs_current = (GroupingSet *) lfirst(lc);

						Assert(gs_current->kind == GROUPING_SET_SIMPLE);

						current_result = list_concat(current_result,
													 gs_current->content);

						/* If we are done with making the current group, break */
						if (--i == 0)
							break;
					}

					result = lappend(result, current_result);
					--curgroup_size;
				}

				result = lappend(result, NIL);
			}
			break;

		case GROUPING_SET_CUBE:
			{
				List	   *cube_list = gs->content;
				int			number_bits = list_length(cube_list);
				uint32		num_sets;
				uint32		i;

				/* parser should cap this much lower */
				Assert(number_bits < 31);

				num_sets = (1U << number_bits);

				for (i = 0; i < num_sets; i++)
				{
					List	   *current_result = NIL;
					ListCell   *lc;
					uint32		mask = 1U;

					foreach(lc, cube_list)
					{
						GroupingSet *gs_current = (GroupingSet *) lfirst(lc);

						Assert(gs_current->kind == GROUPING_SET_SIMPLE);

						if (mask & i)
							current_result = list_concat(current_result,
														 gs_current->content);

						mask <<= 1;
					}

					result = lappend(result, current_result);
				}
			}
			break;

		case GROUPING_SET_SETS:
			{
				ListCell   *lc;

				foreach(lc, gs->content)
				{
					List	   *current_result = expand_groupingset_node(lfirst(lc));

					result = list_concat(result, current_result);
				}
			}
			break;
	}

	return result;
}

/* list_sort comparator to sort sub-lists by length */
static int
cmp_list_len_asc(const ListCell *a, const ListCell *b)
{
	int			la = list_length((const List *) lfirst(a));
	int			lb = list_length((const List *) lfirst(b));

	return (la > lb) ? 1 : (la == lb) ? 0 : -1;
}

/* list_sort comparator to sort sub-lists by length and contents */
static int
cmp_list_len_contents_asc(const ListCell *a, const ListCell *b)
{
	int			res = cmp_list_len_asc(a, b);

	if (res == 0)
	{
		List	   *la = (List *) lfirst(a);
		List	   *lb = (List *) lfirst(b);
		ListCell   *lca;
		ListCell   *lcb;

		forboth(lca, la, lcb, lb)
		{
			int			va = lfirst_int(lca);
			int			vb = lfirst_int(lcb);

			if (va > vb)
				return 1;
			if (va < vb)
				return -1;
		}
	}

	return res;
}

/*
 * Expand a groupingSets clause to a flat list of grouping sets.
 * The returned list is sorted by length, shortest sets first.
 *
 * This is mainly for the planner, but we use it here too to do
 * some consistency checks.
 */
List *
expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
{
	List	   *expanded_groups = NIL;
	List	   *result = NIL;
	double		numsets = 1;
	ListCell   *lc;

	if (groupingSets == NIL)
		return NIL;

	foreach(lc, groupingSets)
	{
		List	   *current_result = NIL;
		GroupingSet *gs = lfirst(lc);

		current_result = expand_groupingset_node(gs);

		Assert(current_result != NIL);

		numsets *= list_length(current_result);

		if (limit >= 0 && numsets > limit)
			return NIL;

		expanded_groups = lappend(expanded_groups, current_result);
	}

	/*
	 * Do cartesian product between sublists of expanded_groups. While at it,
	 * remove any duplicate elements from individual grouping sets (we must
	 * NOT change the number of sets though)
	 */

	foreach(lc, (List *) linitial(expanded_groups))
	{
		result = lappend(result, list_union_int(NIL, (List *) lfirst(lc)));
	}

	for_each_from(lc, expanded_groups, 1)
	{
		List	   *p = lfirst(lc);
		List	   *new_result = NIL;
		ListCell   *lc2;

		foreach(lc2, result)
		{
			List	   *q = lfirst(lc2);
			ListCell   *lc3;

			foreach(lc3, p)
			{
				new_result = lappend(new_result,
									 list_union_int(q, (List *) lfirst(lc3)));
			}
		}
		result = new_result;
	}

	/* Now sort the lists by length and deduplicate if necessary */
	if (!groupDistinct || list_length(result) < 2)
		list_sort(result, cmp_list_len_asc);
	else
	{
		ListCell   *cell;
		List	   *prev;

		/* Sort each groupset individually */
		foreach(cell, result)
			list_sort(lfirst(cell), list_int_cmp);

		/* Now sort the list of groupsets by length and contents */
		list_sort(result, cmp_list_len_contents_asc);

		/* Finally, remove duplicates */
		prev = linitial(result);
		for_each_from(cell, result, 1)
		{
			if (equal(lfirst(cell), prev))
				result = foreach_delete_current(result, cell);
			else
				prev = lfirst(cell);
		}
	}

	return result;
}

/*
 * get_aggregate_argtypes
 *	Identify the specific datatypes passed to an aggregate call.
 *
 * Given an Aggref, extract the actual datatypes of the input arguments.
 * The input datatypes are reported in a way that matches up with the
 * aggregate's declaration, ie, any ORDER BY columns attached to a plain
 * aggregate are ignored, but we report both direct and aggregated args of
 * an ordered-set aggregate.
 *
 * Datatypes are returned into inputTypes[], which must reference an array
 * of length FUNC_MAX_ARGS.
 *
 * The function result is the number of actual arguments.
 */
int
get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes)
{
	int			numArguments = 0;
	ListCell   *lc;

	Assert(list_length(aggref->aggargtypes) <= FUNC_MAX_ARGS);

	foreach(lc, aggref->aggargtypes)
	{
		inputTypes[numArguments++] = lfirst_oid(lc);
	}

	return numArguments;
}

/*
 * resolve_aggregate_transtype
 *	Identify the transition state value's datatype for an aggregate call.
 *
 * This function resolves a polymorphic aggregate's state datatype.
 * It must be passed the aggtranstype from the aggregate's catalog entry,
 * as well as the actual argument types extracted by get_aggregate_argtypes.
 * (We could fetch pg_aggregate.aggtranstype internally, but all existing
 * callers already have the value at hand, so we make them pass it.)
 */
Oid
resolve_aggregate_transtype(Oid aggfuncid,
							Oid aggtranstype,
							Oid *inputTypes,
							int numArguments)
{
	/* resolve actual type of transition state, if polymorphic */
	if (IsPolymorphicType(aggtranstype))
	{
		/* have to fetch the agg's declared input types... */
		Oid		   *declaredArgTypes;
		int			agg_nargs;

		(void) get_func_signature(aggfuncid, &declaredArgTypes, &agg_nargs);

		/*
		 * VARIADIC ANY aggs could have more actual than declared args, but
		 * such extra args can't affect polymorphic type resolution.
		 */
		Assert(agg_nargs <= numArguments);

		aggtranstype = enforce_generic_type_consistency(inputTypes,
														declaredArgTypes,
														agg_nargs,
														aggtranstype,
														false);
		pfree(declaredArgTypes);
	}
	return aggtranstype;
}

/*
 * agg_args_support_sendreceive
 *		Returns true if all non-byval types of aggref's args have send and
 *		receive functions.
 */
bool
agg_args_support_sendreceive(Aggref *aggref)
{
	ListCell   *lc;

	foreach(lc, aggref->args)
	{
		HeapTuple	typeTuple;
		Form_pg_type pt;
		TargetEntry *tle = (TargetEntry *) lfirst(lc);
		Oid			type = exprType((Node *) tle->expr);

		/*
		 * RECORD is a special case: it has typsend/typreceive functions, but
		 * record_recv only works if passed the correct typmod to identify the
		 * specific anonymous record type.  array_agg_deserialize cannot do
		 * that, so we have to disclaim support for the case.
		 */
		if (type == RECORDOID)
			return false;

		typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
		if (!HeapTupleIsValid(typeTuple))
			elog(ERROR, "cache lookup failed for type %u", type);

		pt = (Form_pg_type) GETSTRUCT(typeTuple);

		if (!pt->typbyval &&
			(!OidIsValid(pt->typsend) || !OidIsValid(pt->typreceive)))
		{
			ReleaseSysCache(typeTuple);
			return false;
		}
		ReleaseSysCache(typeTuple);
	}
	return true;
}

/*
 * Create an expression tree for the transition function of an aggregate.
 * This is needed so that polymorphic functions can be used within an
 * aggregate --- without the expression tree, such functions would not know
 * the datatypes they are supposed to use.  (The trees will never actually
 * be executed, however, so we can skimp a bit on correctness.)
 *
 * agg_input_types and agg_state_type identifies the input types of the
 * aggregate.  These should be resolved to actual types (ie, none should
 * ever be ANYELEMENT etc).
 * agg_input_collation is the aggregate function's input collation.
 *
 * For an ordered-set aggregate, remember that agg_input_types describes
 * the direct arguments followed by the aggregated arguments.
 *
 * transfn_oid and invtransfn_oid identify the funcs to be called; the
 * latter may be InvalidOid, however if invtransfn_oid is set then
 * transfn_oid must also be set.
 *
 * transfn_oid may also be passed as the aggcombinefn when the *transfnexpr is
 * to be used for a combine aggregate phase.  We expect invtransfn_oid to be
 * InvalidOid in this case since there is no such thing as an inverse
 * combinefn.
 *
 * Pointers to the constructed trees are returned into *transfnexpr,
 * *invtransfnexpr. If there is no invtransfn, the respective pointer is set
 * to NULL.  Since use of the invtransfn is optional, NULL may be passed for
 * invtransfnexpr.
 */
void
build_aggregate_transfn_expr(Oid *agg_input_types,
							 int agg_num_inputs,
							 int agg_num_direct_inputs,
							 bool agg_variadic,
							 Oid agg_state_type,
							 Oid agg_input_collation,
							 Oid transfn_oid,
							 Oid invtransfn_oid,
							 Expr **transfnexpr,
							 Expr **invtransfnexpr)
{
	List	   *args;
	FuncExpr   *fexpr;
	int			i;

	/*
	 * Build arg list to use in the transfn FuncExpr node.
	 */
	args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));

	for (i = agg_num_direct_inputs; i < agg_num_inputs; i++)
	{
		args = lappend(args,
					   make_agg_arg(agg_input_types[i], agg_input_collation));
	}

	fexpr = makeFuncExpr(transfn_oid,
						 agg_state_type,
						 args,
						 InvalidOid,
						 agg_input_collation,
						 COERCE_EXPLICIT_CALL);
	fexpr->funcvariadic = agg_variadic;
	*transfnexpr = (Expr *) fexpr;

	/*
	 * Build invtransfn expression if requested, with same args as transfn
	 */
	if (invtransfnexpr != NULL)
	{
		if (OidIsValid(invtransfn_oid))
		{
			fexpr = makeFuncExpr(invtransfn_oid,
								 agg_state_type,
								 args,
								 InvalidOid,
								 agg_input_collation,
								 COERCE_EXPLICIT_CALL);
			fexpr->funcvariadic = agg_variadic;
			*invtransfnexpr = (Expr *) fexpr;
		}
		else
			*invtransfnexpr = NULL;
	}
}

/*
 * Like build_aggregate_transfn_expr, but creates an expression tree for the
 * serialization function of an aggregate.
 */
void
build_aggregate_serialfn_expr(Oid serialfn_oid,
							  Expr **serialfnexpr)
{
	List	   *args;
	FuncExpr   *fexpr;

	/* serialfn always takes INTERNAL and returns BYTEA */
	args = list_make1(make_agg_arg(INTERNALOID, InvalidOid));

	fexpr = makeFuncExpr(serialfn_oid,
						 BYTEAOID,
						 args,
						 InvalidOid,
						 InvalidOid,
						 COERCE_EXPLICIT_CALL);
	*serialfnexpr = (Expr *) fexpr;
}

/*
 * Like build_aggregate_transfn_expr, but creates an expression tree for the
 * deserialization function of an aggregate.
 */
void
build_aggregate_deserialfn_expr(Oid deserialfn_oid,
								Expr **deserialfnexpr)
{
	List	   *args;
	FuncExpr   *fexpr;

	/* deserialfn always takes BYTEA, INTERNAL and returns INTERNAL */
	args = list_make2(make_agg_arg(BYTEAOID, InvalidOid),
					  make_agg_arg(INTERNALOID, InvalidOid));

	fexpr = makeFuncExpr(deserialfn_oid,
						 INTERNALOID,
						 args,
						 InvalidOid,
						 InvalidOid,
						 COERCE_EXPLICIT_CALL);
	*deserialfnexpr = (Expr *) fexpr;
}

/*
 * Like build_aggregate_transfn_expr, but creates an expression tree for the
 * final function of an aggregate, rather than the transition function.
 */
void
build_aggregate_finalfn_expr(Oid *agg_input_types,
							 int num_finalfn_inputs,
							 Oid agg_state_type,
							 Oid agg_result_type,
							 Oid agg_input_collation,
							 Oid finalfn_oid,
							 Expr **finalfnexpr)
{
	List	   *args;
	int			i;

	/*
	 * Build expr tree for final function
	 */
	args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));

	/* finalfn may take additional args, which match agg's input types */
	for (i = 0; i < num_finalfn_inputs - 1; i++)
	{
		args = lappend(args,
					   make_agg_arg(agg_input_types[i], agg_input_collation));
	}

	*finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
										 agg_result_type,
										 args,
										 InvalidOid,
										 agg_input_collation,
										 COERCE_EXPLICIT_CALL);
	/* finalfn is currently never treated as variadic */
}

/*
 * Convenience function to build dummy argument expressions for aggregates.
 *
 * We really only care that an aggregate support function can discover its
 * actual argument types at runtime using get_fn_expr_argtype(), so it's okay
 * to use Param nodes that don't correspond to any real Param.
 */
static Node *
make_agg_arg(Oid argtype, Oid argcollation)
{
	Param	   *argp = makeNode(Param);

	argp->paramkind = PARAM_EXEC;
	argp->paramid = -1;
	argp->paramtype = argtype;
	argp->paramtypmod = -1;
	argp->paramcollid = argcollation;
	argp->location = -1;
	return (Node *) argp;
}
