diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 5777cb2..3334b91 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -94,6 +94,8 @@ static void compare_tlist_datatypes(List *tlist, List *colTypes,
 						bool *unsafeColumns);
 static bool qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
 					  bool *unsafeColumns);
+static bool var_exists_in_all_query_partition_by_clauses(Query *subquery,
+															Var *var);
 static void subquery_push_qual(Query *subquery,
 				   RangeTblEntry *rte, Index rti, Node *qual);
 static void recurse_push_qual(Node *setOp, Query *topquery,
@@ -1664,10 +1666,7 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
  * 1. If the subquery has a LIMIT clause, we must not push down any quals,
  * since that could change the set of rows returned.
  *
- * 2. If the subquery contains any window functions, we can't push quals
- * into it, because that could change the results.
- *
- * 3. If the subquery contains EXCEPT or EXCEPT ALL set ops we cannot push
+ * 2. If the subquery contains EXCEPT or EXCEPT ALL set ops we cannot push
  * quals into it, because that could change the results.
  *
  * In addition, we make several checks on the subquery's output columns
@@ -1690,10 +1689,6 @@ subquery_is_pushdown_safe(Query *subquery, Query *topquery,
 	if (subquery->limitOffset != NULL || subquery->limitCount != NULL)
 		return false;
 
-	/* Check point 2 */
-	if (subquery->hasWindowFuncs)
-		return false;
-
 	/*
 	 * If we're at a leaf query, check for unsafe expressions in its target
 	 * list, and mark any unsafe ones in unsafeColumns[].  (Non-leaf nodes in
@@ -1888,6 +1883,10 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
  *
  * 3. The qual must not refer to any subquery output columns that were
  * found to be unsafe to reference by subquery_is_pushdown_safe().
+ *
+ * 4. If the subquery contains window functions then the qual may be
+ * pushed down if it is part of the PARTITION BY in every window frame
+ * that is defined in the subquery.
  */
 static bool
 qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
@@ -1948,6 +1947,13 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
 			safe = false;
 			break;
 		}
+
+		if (subquery->hasWindowFuncs &&
+			!var_exists_in_all_query_partition_by_clauses(subquery, var))
+		{
+			safe = false;
+			break;
+		}
 	}
 
 	list_free(vars);
@@ -1956,6 +1962,24 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
 }
 
 /*
+ * var_exists_in_all_query_partition_by_clauses
+ * returns true if the given Var exists in the PARTITION BY clause in every
+ * WINDOW defined in the subquery
+ */
+static bool var_exists_in_all_query_partition_by_clauses(Query *subquery, Var *var)
+{
+	ListCell *lc;
+	TargetEntry *tle = get_tle_by_resno(subquery->targetList, var->varattno);
+
+	foreach(lc, subquery->windowClause)
+	{
+		WindowClause *wc = (WindowClause *) lfirst(lc);
+		if (!targetIsInSortList(tle, InvalidOid, wc->partitionClause))
+			return false;
+	}
+	return true;
+}
+/*
  * subquery_push_qual - push down a qual that we have determined is safe
  */
 static void
