+ /*
+ * A HAVING clause without aggregates is equivalent to a WHERE clause
+ * (except it can only refer to grouped fields). Transfer any agg-free
+ * clauses of the HAVING qual into WHERE. This may seem like wasting
+ * cycles to cater to stupidly-written queries, but there are other
+ * reasons for doing it. Firstly, if the query contains no aggs at all,
+ * then we aren't going to generate an Agg plan node, and so there'll be
+ * no place to execute HAVING conditions; without this transfer, we'd
+ * lose the HAVING condition entirely, which is wrong. Secondly, when
+ * we push down a qual condition into a sub-query, it's easiest to push
+ * the qual into HAVING always, in case it contains aggs, and then let
+ * this code sort it out.
+ *
+ * Note that both havingQual and parse->jointree->quals are in
+ * implicitly-ANDed-list form at this point, even though they are
+ * declared as Node *. Also note that contain_agg_clause does not
+ * recurse into sub-selects, which is exactly what we need here.
+ */
+ newHaving = NIL;
+ foreach(lst, (List *) parse->havingQual)
+ {
+ Node *havingclause = (Node *) lfirst(lst);
+
+ if (contain_agg_clause(havingclause))
+ newHaving = lappend(newHaving, havingclause);
+ else
+ parse->jointree->quals = (Node *)
+ lappend((List *) parse->jointree->quals, havingclause);
+ }
+ parse->havingQual = (Node *) newHaving;
+