diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index a944a4d..6465d28 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -45,20 +45,22 @@ typedef struct
 } check_ungrouped_columns_context;
 
 static int	check_agg_arguments(ParseState *pstate, List *args);
 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 **func_grouped_rels);
 static bool check_ungrouped_columns_walker(Node *node,
 							   check_ungrouped_columns_context *context);
+static bool check_functional_grouping_recurse(RangeTblEntry *rte, Var *var,
+									List *grouping_columns);
 
 
 /*
  * 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 args, aggorder, aggdistinct and
  * agglevelsup.  The passed-in args list has been through standard expression
  * transformation, while the passed-in aggorder list hasn't been transformed
@@ -786,20 +788,71 @@ check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry,
 
 	context.pstate = pstate;
 	context.qry = qry;
 	context.groupClauses = groupClauses;
 	context.have_non_var_grouping = have_non_var_grouping;
 	context.func_grouped_rels = func_grouped_rels;
 	context.sublevels_up = 0;
 	check_ungrouped_columns_walker(node, &context);
 }
 
+
+static bool
+check_functional_grouping_recurse(RangeTblEntry *rte, Var *var,
+									List *grouping_columns)
+{
+	TargetEntry *tle;
+	ListCell	*lcell;
+	List		*sq_grouping_columns = NIL;
+	ParseState	*pstate;
+	bool		have_non_var_grouping;
+	List		*func_grouped_rels = NIL;
+
+	/* Assumed that the rte corresponds to the varno in passed in var node */
+	Assert(rte->rtekind == RTE_SUBQUERY);
+	/*
+	 * Fetch those grouping columns which entirely belong to this subquery, i.e
+	 * Var nodes which have the same varno as the given Var node.
+	 */
+	have_non_var_grouping = false;
+	foreach(lcell, grouping_columns)
+	{
+		Var *grouping_var = lfirst(lcell); 
+		if (IsA(grouping_var, Var) &&
+			grouping_var->varno == var->varno)
+		{
+			tle = get_tle_by_resno(rte->subquery->targetList, grouping_var->varattno);
+			Assert(tle && tle->expr);
+			sq_grouping_columns = lappend(sq_grouping_columns, tle->expr);
+			if (!IsA(tle->expr, Var))
+				have_non_var_grouping = true;
+		}
+	}
+
+	/* Obtain the expression corresponding var node */
+	tle = get_tle_by_resno(rte->subquery->targetList, var->varattno);
+	Assert(tle && tle->expr);
+
+	
+	pstate = make_parsestate(NULL);
+	/* Is this correct way to set the p_rtable from ParseState? */
+	pstate->p_rtable = rte->subquery->rtable;
+	/*
+	 * The function would throw error, in case the expression is found to be
+	 * ungrouped, otherwise we are good to go
+	 */
+	check_ungrouped_columns((Node *)tle->expr, pstate, rte->subquery,
+						sq_grouping_columns, have_non_var_grouping, &func_grouped_rels);
+	return true;
+
+}
+
 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))
@@ -893,20 +946,30 @@ check_ungrouped_columns_walker(Node *node,
 										  var->varno,
 										  0,
 										  context->groupClauses,
 										  &context->qry->constraintDeps))
 			{
 				*context->func_grouped_rels =
 					lappend_int(*context->func_grouped_rels, var->varno);
 				return false;	/* acceptable */
 			}
 		}
+		else if (rte->rtekind == RTE_SUBQUERY)
+		{
+			if (check_functional_grouping_recurse(rte, var,
+													context->groupClauses))
+			{
+				*context->func_grouped_rels =
+					lappend_int(*context->func_grouped_rels, var->varno);
+				return false;
+			}
+		}
 
 		/* 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),
 					 parser_errposition(context->pstate, var->location)));
 		else
