*** pgsql/src/backend/parser/parse_agg.c 2008/09/01 20:42:44 1.83 --- pgsql/src/backend/parser/parse_agg.c 2008/10/04 21:56:54 1.84 *************** *** 8,14 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.82 2008/08/28 23:09:47 tgl Exp $ * *------------------------------------------------------------------------- */ --- 8,14 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.83 2008/09/01 20:42:44 tgl Exp $ * *------------------------------------------------------------------------- */ *************** parseCheckAggregates(ParseState *pstate, *** 102,107 **** --- 102,108 ---- bool have_non_var_grouping; ListCell *l; bool hasJoinRTEs; + bool hasSelfRefRTEs; PlannerInfo *root; Node *clause; *************** parseCheckAggregates(ParseState *pstate, *** 109,114 **** --- 110,130 ---- Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual); /* + * 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; + } + + /* * Aggregates must never appear in WHERE or JOIN/ON clauses. * * (Note this check should appear first to deliver an appropriate error *************** parseCheckAggregates(ParseState *pstate, *** 157,176 **** * 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. - */ - hasJoinRTEs = false; - foreach(l, pstate->p_rtable) - { - RangeTblEntry *rte = (RangeTblEntry *) lfirst(l); - - if (rte->rtekind == RTE_JOIN) - { - hasJoinRTEs = true; - break; - } - } - - /* * We use the planner's flatten_join_alias_vars routine to do the * flattening; it wants a PlannerInfo root node, which fortunately can be * mostly dummy. --- 173,178 ---- *************** parseCheckAggregates(ParseState *pstate, *** 217,222 **** --- 219,234 ---- clause = flatten_join_alias_vars(root, clause); check_ungrouped_columns(clause, pstate, groupClauses, have_non_var_grouping); + + /* + * Per spec, aggregates can't appear in a recursive term. + */ + if (pstate->p_hasAggs && hasSelfRefRTEs) + ereport(ERROR, + (errcode(ERRCODE_INVALID_RECURSION), + errmsg("aggregates not allowed in a recursive query's recursive term"), + parser_errposition(pstate, + locate_agg_of_level((Node *) qry, 0)))); }