Index: engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
--- engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java	(revision 4187)
+++ engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java	(working copy)
@@ -276,16 +276,11 @@
         }
 
         correctOrderBy(frame, selectSymbols, parentProject);
+
         PlanNode parentSource = NodeEditor.findParent(frame, NodeConstants.Types.SOURCE);        
-        PlanNode parentSetOp = NodeEditor.findParent(parentProject, NodeConstants.Types.SET_OP, NodeConstants.Types.SOURCE);
   
-        if (parentSetOp == null || NodeEditor.findNodePreOrder(parentSetOp, NodeConstants.Types.PROJECT) == parentProject) {
-	        if (parentSource != null) {
-	        	FrameUtil.correctSymbolMap(((SymbolMap)frame.getProperty(NodeConstants.Info.SYMBOL_MAP)).asMap(), parentSource);
-	        }
-	        if (parentSetOp != null) {
-	        	correctOrderBy(frame, selectSymbols, parentSetOp);
-	        }
+        if (parentSource != null && NodeEditor.findNodePreOrder(parentSource, NodeConstants.Types.PROJECT) == parentProject) {
+        	FrameUtil.correctSymbolMap(((SymbolMap)frame.getProperty(NodeConstants.Info.SYMBOL_MAP)).asMap(), parentSource);
         }
         
         prepareFrame(frame);
@@ -301,18 +296,22 @@
         return root;
     }
 
+    /**
+     * special handling is needed since we are retaining the child aliases
+     */
 	private static void correctOrderBy(PlanNode frame,
-			List<SingleElementSymbol> selectSymbols, PlanNode startNode) {
-		PlanNode sort = NodeEditor.findParent(startNode, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE | NodeConstants.Types.SET_OP);
-		if (sort != null) { //special handling is needed since we are retaining the child aliases
-			List<SingleElementSymbol> childProject = (List<SingleElementSymbol>)NodeEditor.findNodePreOrder(frame, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
-			OrderBy elements = (OrderBy)sort.getProperty(NodeConstants.Info.SORT_ORDER);
-			for (OrderByItem item : elements.getOrderByItems()) {
-				item.setSymbol(childProject.get(selectSymbols.indexOf(item.getSymbol())));
-			}
-		    sort.getGroups().clear();
-		    sort.addGroups(GroupsUsedByElementsVisitor.getGroups(elements));
+			List<SingleElementSymbol> selectSymbols, PlanNode parentProject) {
+		PlanNode sort = NodeEditor.findParent(parentProject, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
+		if (sort == null || NodeEditor.findNodePreOrder(sort, NodeConstants.Types.PROJECT, NodeConstants.Types.SOURCE) != parentProject) {
+			return;
 		}
+		List<SingleElementSymbol> childProject = (List<SingleElementSymbol>)NodeEditor.findNodePreOrder(frame, NodeConstants.Types.PROJECT).getProperty(NodeConstants.Info.PROJECT_COLS);
+		OrderBy elements = (OrderBy)sort.getProperty(NodeConstants.Info.SORT_ORDER);
+		for (OrderByItem item : elements.getOrderByItems()) {
+			item.setSymbol(childProject.get(selectSymbols.indexOf(item.getSymbol())));
+		}
+	    sort.getGroups().clear();
+	    sort.addGroups(GroupsUsedByElementsVisitor.getGroups(elements));
 	}
     
     /**
Index: engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java
===================================================================
--- engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java	(revision 4187)
+++ engine/src/test/java/org/teiid/query/optimizer/TestRuleMergeVirtual.java	(working copy)
@@ -408,5 +408,28 @@
     
         TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);                                    
     }
+    
+    @Test public void testSortOverUnion() throws Exception {
+        ProcessorPlan plan = TestOptimizer.helpPlan("select e1 from (select max(e1) as e1 from pm1.g1 having 1 = 0) as y union all select e2 from pm1.g1 union all select e1 from pm1.g1 order by e1", //$NON-NLS-1$
+                                      RealMetadataFactory.example1Cached(), null, new DefaultCapabilitiesFinder(),
+                                      new String[] {
+                                          "SELECT pm1.g1.e2 FROM pm1.g1", "SELECT pm1.g1.e1 FROM pm1.g1"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+        TestOptimizer.checkNodeTypes(plan, new int[] {
+                2,      // Access
+                0,      // DependentAccess
+                0,      // DependentSelect
+                0,      // DependentProject
+                0,      // DupRemove
+                0,      // Grouping
+                0,      // NestedLoopJoinStrategy
+                0,      // MergeJoinStrategy
+                0,      // Null
+                0,      // PlanExecution
+                1,      // Project
+                0,      // Select
+                1,      // Sort
+                1       // UnionAll
+            });                                     
+    }
 
 }
