diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 5482ab85a7..e751ae21d1 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -98,7 +98,8 @@ static bool is_simple_subquery(PlannerInfo *root, Query *subquery,
 							   JoinExpr *lowest_outer_join);
 static Node *pull_up_simple_values(PlannerInfo *root, Node *jtnode,
 								   RangeTblEntry *rte);
-static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte);
+static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte, 
+											bool allow_multi_values);
 static Node *pull_up_constant_function(PlannerInfo *root, Node *jtnode,
 									   RangeTblEntry *rte,
 									   AppendRelInfo *containing_appendrel);
@@ -910,7 +911,7 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
 		if (rte->rtekind == RTE_VALUES &&
 			lowest_outer_join == NULL &&
 			containing_appendrel == NULL &&
-			is_simple_values(root, rte))
+			is_simple_values(root, rte, false))
 			return pull_up_simple_values(root, jtnode, rte);
 
 		/*
@@ -990,6 +991,33 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
 	return jtnode;
 }
 
+static RangeTblEntry *get_rte_from_values_query(PlannerInfo *root, Query *subquery)
+{
+	RangeTblRef *rtr = NULL;
+	RangeTblEntry *rte = NULL;
+	Node *node;
+
+	if (subquery->jointree == NULL ||
+		list_length(subquery->jointree->fromlist) != 1)
+			return NULL;
+	
+	if (list_length(subquery->rtable) != 1)
+		return NULL;
+
+	node = linitial(subquery->jointree->fromlist);
+	if (!IsA(node, RangeTblRef))
+		return NULL;
+
+	rtr = castNode(RangeTblRef, node);	
+	rte = rt_fetch(rtr->rtindex, subquery->rtable);
+
+	/* elog_node_display(LOG, "YH | rte tree", root->parse, true); */
+	if (rte == NULL || rte->rtekind != RTE_VALUES)
+		return NULL;
+
+	return is_simple_values(root, rte, true) ? rte : NULL;
+}
+
 /*
  * pull_up_simple_subquery
  *		Attempt to pull up a single simple subquery.
@@ -1014,6 +1042,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
 	int			rtoffset;
 	pullup_replace_vars_context rvcontext;
 	ListCell   *lc;
+	RangeTblEntry *values_rte = NULL;
 
 	/*
 	 * Make a modifiable copy of the subquery to hack on, so that the RTE will
@@ -1124,6 +1153,12 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
 		return jtnode;
 	}
 
+	if ((values_rte = get_rte_from_values_query(subroot, subquery)) != NULL)
+	{
+		values_rte->alias = copyObject(rte->alias);
+		values_rte->eref = copyObject(rte->eref);
+	}
+
 	/*
 	 * We must flatten any join alias Vars in the subquery's targetlist,
 	 * because pulling up the subquery's subqueries might have changed their
@@ -1765,7 +1800,7 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
  * rte is the RTE_VALUES RangeTblEntry to check.
  */
 static bool
-is_simple_values(PlannerInfo *root, RangeTblEntry *rte)
+is_simple_values(PlannerInfo *root, RangeTblEntry *rte, bool allow_multi_values)
 {
 	Assert(rte->rtekind == RTE_VALUES);
 
@@ -1774,7 +1809,7 @@ is_simple_values(PlannerInfo *root, RangeTblEntry *rte)
 	 * correct to replace the VALUES RTE with a RESULT RTE, nor would we have
 	 * a unique set of expressions to substitute into the parent query.
 	 */
-	if (list_length(rte->values_lists) != 1)
+	if (!allow_multi_values && list_length(rte->values_lists) != 1)
 		return false;
 
 	/*

