diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 37cd175ef5fa6d9275f59ddf9bf699d8f42cf78c..e14452ac726f8383c9cc0261822a467b1f2c13d4 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.46 1999/05/26 12:55:46 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.47 1999/06/21 01:26:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,6 +29,7 @@
 #include "parser/parse_target.h"
 
 #include "parser/analyze.h"
+#include "optimizer/clauses.h"
 #include "optimizer/prep.h"
 
 #include "rewrite/rewriteSupport.h"
@@ -60,6 +61,9 @@ static void modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr);
 static SubLink *modifyAggrefMakeSublink(Expr *origexp, Query *parsetree);
 static void modifyAggrefQual(Node **nodePtr, Query *parsetree);
 static bool checkQueryHasAggs(Node *node);
+static bool checkQueryHasAggs_walker(Node *node, void *context);
+static bool checkQueryHasSubLink(Node *node);
+static bool checkQueryHasSubLink_walker(Node *node, void *context);
 static Query *fireRIRrules(Query *parsetree);
 static Query *Except_Intersect_Rewrite(Query *parsetree);
 static void check_targetlists_are_compatible(List *prev_target,
@@ -1302,242 +1306,41 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree)
 static bool
 checkQueryHasAggs(Node *node)
 {
-	if (node == NULL)
-		return FALSE;
-
-	switch (nodeTag(node))
-	{
-		case T_TargetEntry:
-			{
-				TargetEntry *tle = (TargetEntry *) node;
-
-				return checkQueryHasAggs((Node *) (tle->expr));
-			}
-			break;
-
-		case T_Aggref:
-			return TRUE;
-
-		case T_Expr:
-			{
-				Expr	   *exp = (Expr *) node;
-
-				return checkQueryHasAggs((Node *) (exp->args));
-			}
-			break;
-
-		case T_Iter:
-			{
-				Iter	   *iter = (Iter *) node;
-
-				return checkQueryHasAggs((Node *) (iter->iterexpr));
-			}
-			break;
-
-		case T_ArrayRef:
-			{
-				ArrayRef   *ref = (ArrayRef *) node;
-
-				if (checkQueryHasAggs((Node *) (ref->refupperindexpr)))
-					return TRUE;
-
-				if (checkQueryHasAggs((Node *) (ref->reflowerindexpr)))
-					return TRUE;
-
-				if (checkQueryHasAggs((Node *) (ref->refexpr)))
-					return TRUE;
-
-				if (checkQueryHasAggs((Node *) (ref->refassgnexpr)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		case T_Var:
-			return FALSE;
-
-		case T_Param:
-			return FALSE;
-
-		case T_Const:
-			return FALSE;
-
-		case T_List:
-			{
-				List	   *l;
-
-				foreach(l, (List *) node)
-				{
-					if (checkQueryHasAggs((Node *) lfirst(l)))
-						return TRUE;
-				}
-				return FALSE;
-			}
-			break;
-
-		case T_CaseExpr:
-			{
-				CaseExpr   *exp = (CaseExpr *) node;
-
-				if (checkQueryHasAggs((Node *) (exp->args)))
-					return TRUE;
-
-				if (checkQueryHasAggs((Node *) (exp->defresult)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		case T_CaseWhen:
-			{
-				CaseWhen   *when = (CaseWhen *) node;
-
-				if (checkQueryHasAggs((Node *) (when->expr)))
-					return TRUE;
-
-				if (checkQueryHasAggs((Node *) (when->result)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		default:
-			elog(NOTICE, "unknown node tag %d in checkQueryHasAggs()", nodeTag(node));
-			elog(NOTICE, "Node is: %s", nodeToString(node));
-			break;
-
-
-	}
-
-	return FALSE;
+	return checkQueryHasAggs_walker(node, NULL);
 }
 
+static bool
+checkQueryHasAggs_walker(Node *node, void *context)
+{
+	if (node == NULL)
+		return false;
+	if (IsA(node, Aggref))
+		return true;			/* abort the tree traversal and return true */
+	return expression_tree_walker(node, checkQueryHasAggs_walker, context);
+}
 
 /*
  * checkQueryHasSubLink -
- *	Queries marked hasAggs might not have them any longer after
+ *	Queries marked hasSubLinks might not have them any longer after
  *	rewriting. Check it.
  */
 static bool
 checkQueryHasSubLink(Node *node)
 {
-	if (node == NULL)
-		return FALSE;
-
-	switch (nodeTag(node))
-	{
-		case T_TargetEntry:
-			{
-				TargetEntry *tle = (TargetEntry *) node;
-
-				return checkQueryHasSubLink((Node *) (tle->expr));
-			}
-			break;
-
-		case T_Aggref:
-			return TRUE;
-
-		case T_Expr:
-			{
-				Expr	   *exp = (Expr *) node;
-
-				return checkQueryHasSubLink((Node *) (exp->args));
-			}
-			break;
-
-		case T_Iter:
-			{
-				Iter	   *iter = (Iter *) node;
-
-				return checkQueryHasSubLink((Node *) (iter->iterexpr));
-			}
-			break;
-
-		case T_ArrayRef:
-			{
-				ArrayRef   *ref = (ArrayRef *) node;
-
-				if (checkQueryHasSubLink((Node *) (ref->refupperindexpr)))
-					return TRUE;
-
-				if (checkQueryHasSubLink((Node *) (ref->reflowerindexpr)))
-					return TRUE;
-
-				if (checkQueryHasSubLink((Node *) (ref->refexpr)))
-					return TRUE;
-
-				if (checkQueryHasSubLink((Node *) (ref->refassgnexpr)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		case T_Var:
-			return FALSE;
-
-		case T_Param:
-			return FALSE;
-
-		case T_Const:
-			return FALSE;
-
-		case T_List:
-			{
-				List	   *l;
-
-				foreach(l, (List *) node)
-				{
-					if (checkQueryHasSubLink((Node *) lfirst(l)))
-						return TRUE;
-				}
-				return FALSE;
-			}
-			break;
-
-		case T_CaseExpr:
-			{
-				CaseExpr   *exp = (CaseExpr *) node;
-
-				if (checkQueryHasSubLink((Node *) (exp->args)))
-					return TRUE;
-
-				if (checkQueryHasSubLink((Node *) (exp->defresult)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		case T_CaseWhen:
-			{
-				CaseWhen   *when = (CaseWhen *) node;
-
-				if (checkQueryHasSubLink((Node *) (when->expr)))
-					return TRUE;
-
-				if (checkQueryHasSubLink((Node *) (when->result)))
-					return TRUE;
-
-				return FALSE;
-			}
-			break;
-
-		case T_SubLink:
-			return TRUE;
-
-		default:
-			elog(NOTICE, "unknown node tag %d in checkQueryHasSubLink()", nodeTag(node));
-			elog(NOTICE, "Node is: %s", nodeToString(node));
-			break;
-
-
-	}
+	return checkQueryHasSubLink_walker(node, NULL);
+}
 
-	return FALSE;
+static bool
+checkQueryHasSubLink_walker(Node *node, void *context)
+{
+	if (node == NULL)
+		return false;
+	if (IsA(node, SubLink))
+		return true;			/* abort the tree traversal and return true */
+	/* Note: we assume the tree has not yet been rewritten by subselect.c,
+	 * therefore we will find bare SubLink nodes and not SUBPLAN nodes.
+	 */
+	return expression_tree_walker(node, checkQueryHasSubLink_walker, context);
 }