[teiid-commits] teiid SVN: r4567 - in branches/7.7.x/engine/src: test/java/org/teiid/query/processor and 1 other directory.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Tue May 14 15:02:36 EDT 2013


Author: jolee
Date: 2013-05-14 15:02:36 -0400 (Tue, 14 May 2013)
New Revision: 4567

Modified:
   branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
   branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java
Log:
TEIID-2455: fix for unrelated sort of view

Modified: branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java
===================================================================
--- branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java	2013-05-14 16:35:36 UTC (rev 4566)
+++ branches/7.7.x/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleAssignOutputElements.java	2013-05-14 19:02:36 UTC (rev 4567)
@@ -44,10 +44,10 @@
 import org.teiid.query.optimizer.relational.OptimizerRule;
 import org.teiid.query.optimizer.relational.RuleStack;
 import org.teiid.query.optimizer.relational.plantree.NodeConstants;
+import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
 import org.teiid.query.optimizer.relational.plantree.NodeEditor;
 import org.teiid.query.optimizer.relational.plantree.NodeFactory;
 import org.teiid.query.optimizer.relational.plantree.PlanNode;
-import org.teiid.query.optimizer.relational.plantree.NodeConstants.Info;
 import org.teiid.query.processor.relational.RelationalNode;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.lang.Criteria;
@@ -203,6 +203,7 @@
 	            break;
 		    }
 		    default: {
+		    	PlanNode sortNode = null;
 		    	if (root.getType() == NodeConstants.Types.PROJECT) {
 		    		GroupSymbol intoGroup = (GroupSymbol)root.getProperty(NodeConstants.Info.INTO_GROUP);
 		            if (intoGroup != null) { //if this is a project into, treat the nodes under the source as a new plan root
@@ -211,28 +212,13 @@
 		                return;
 		            }
 	            	List<SingleElementSymbol> projectCols = outputElements;
-	            	boolean modifiedProject = false;
-	            	PlanNode sortNode = NodeEditor.findParent(root, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
-	            	if (sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
-	            		//if this is the initial rule run, remove unrelated order before changing the project cols
-			            if (!finalRun) {
-		            		OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
-		            		projectCols = new ArrayList<SingleElementSymbol>(projectCols);
-		            		for (OrderByItem item : elements.getOrderByItems()) {
-		            			if (item.getExpressionPosition() == -1) {
-		            				projectCols.remove(item.getSymbol());
-		            			}
-		            		}
-	            		} else {
-	            			modifiedProject = true;
-	            		}
+	            	sortNode = NodeEditor.findParent(root, NodeConstants.Types.SORT, NodeConstants.Types.SOURCE);
+	            	if (finalRun && sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
+            			root.getGroups().clear();
+		            	root.addGroups(GroupsUsedByElementsVisitor.getGroups(projectCols));
+		            	root.addGroups(GroupsUsedByElementsVisitor.getGroups(root.getCorrelatedReferenceElements()));
 		            }
 		            root.setProperty(NodeConstants.Info.PROJECT_COLS, projectCols);
-	            	if (modifiedProject) {
-		            	root.getGroups().clear();
-		            	root.addGroups(GroupsUsedByElementsVisitor.getGroups(projectCols));
-		            	root.addGroups(GroupsUsedByElementsVisitor.getGroups(root.getCorrelatedReferenceElements()));
-	            	}
 	            	if (root.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
 	            		Set<WindowFunction> windowFunctions = getWindowFunctions(projectCols);
 	            		if (windowFunctions.isEmpty()) {
@@ -275,6 +261,17 @@
 	            // Call children recursively
 	            if(root.getChildCount() == 1) {
 	                assignOutputElements(root.getLastChild(), requiredInput, metadata, capFinder, rules, analysisRecord, context);
+	                if (!finalRun && root.getType() == NodeConstants.Types.PROJECT && sortNode != null && sortNode.hasBooleanProperty(NodeConstants.Info.UNRELATED_SORT)) {
+                		//if this is the initial rule run, remove unrelated order to preserve the original projection
+	            		OrderBy elements = (OrderBy) sortNode.getProperty(NodeConstants.Info.SORT_ORDER);
+	            		outputElements = new ArrayList<SingleElementSymbol>(outputElements);
+	            		for (OrderByItem item : elements.getOrderByItems()) {
+	            			if (item.getExpressionPosition() == -1) {
+	            				outputElements.remove(item.getSymbol());
+	            			}
+	            		}
+	            		root.setProperty(NodeConstants.Info.PROJECT_COLS, outputElements);
+	                }
 	            } else {
 	                //determine which elements go to each side of the join
 	                for (PlanNode childNode : root.getChildren()) {
@@ -406,7 +403,7 @@
         boolean updateGroups = outputColumns.size() != originalOrder.size();
         boolean[] seenIndex = new boolean[outputColumns.size()];
         boolean newSymbols = false;
-        
+        int newSymbolIndex = 0;
         for (int i = 0; i < outputColumns.size(); i++) {
             Expression expr = outputColumns.get(i);
             filteredIndex[i] = originalOrder.indexOf(expr);
@@ -414,6 +411,8 @@
             	updateGroups = true;
             	//we're adding this symbol, which needs to be updated against respective symbol maps
             	newSymbols = true;
+            } else {
+            	newSymbolIndex++;
             }
             if (!updateGroups) {
             	seenIndex[filteredIndex[i]] = true;
@@ -445,7 +444,7 @@
 					SingleElementSymbol ex = (SingleElementSymbol) outputColumns.get(j).clone();
 					ExpressionMappingVisitor.mapExpressions(ex, childMap.asMap());
 					newCols.set(j, ex);
-					filteredIndex[j] = j;
+					filteredIndex[j] = newSymbolIndex++;
 				}
             }
             
@@ -471,7 +470,10 @@
             List<Expression> originalExpressionOrder = symbolMap.getValues();
 
         	for (int i = 0; i < filteredIndex.length; i++) {
-        		newMap.addMapping(originalOrder.get(filteredIndex[i]), originalExpressionOrder.get(filteredIndex[i]));
+        		if (filteredIndex[i] < originalOrder.size()) {
+        			newMap.addMapping(originalOrder.get(filteredIndex[i]), originalExpressionOrder.get(filteredIndex[i]));
+        		}
+        		//else TODO: we may need to create a fake symbol
 			}
         	sourceNode.setProperty(NodeConstants.Info.SYMBOL_MAP, newMap);
         }
@@ -621,10 +623,10 @@
         requiredSymbols.addAll(tempRequired);
 */        
         // Add any columns to required that are in this node's output but were not created here
-        for (SingleElementSymbol currentOutputSymbol : outputCols) {
-            if(!(createdSymbols.contains(currentOutputSymbol)) ) {
-                requiredSymbols.add(currentOutputSymbol);
-            }
+        for (Expression currentOutputSymbol : outputCols) {
+			if (!createdSymbols.contains(currentOutputSymbol) && (finalRun || node.getType() != NodeConstants.Types.PROJECT || currentOutputSymbol instanceof ElementSymbol)) {
+				requiredSymbols.add((SingleElementSymbol) currentOutputSymbol);
+			}
         }
         
         //further minimize the required symbols based upon underlying expression (accounts for aliasing)

Modified: branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java
===================================================================
--- branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java	2013-05-14 16:35:36 UTC (rev 4566)
+++ branches/7.7.x/engine/src/test/java/org/teiid/query/processor/TestOrderByProcessing.java	2013-05-14 19:02:36 UTC (rev 4567)
@@ -205,5 +205,24 @@
         ProcessorPlan plan = TestOptimizer.getPlan(TestOptimizer.helpGetCommand("select e1 from pm1.g1 order by e1 desc, e2 asc", metadata, null), metadata, capFinder, null, true, cc);
         TestOptimizer.checkAtomicQueries(new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0 DESC NULLS LAST, g_0.e2 NULLS FIRST"}, plan);  //$NON-NLS-1$
         TestOptimizer.checkNodeTypes(plan, TestOptimizer.FULL_PUSHDOWN);
-	}
+    }
+    
+    @Test public void testSortFunctionOverView() {
+    	String sql = "select * from (select * from pm1.g1) as x order by cast(e2 as string) limit 1"; //$NON-NLS-1$
+
+        ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached());
+        FakeDataManager fdm = new FakeDataManager();
+        sampleData1(fdm);
+        helpProcess(plan, fdm, new List[] {Arrays.asList("a", 0, false, 2.0d)});
+    }
+    
+    @Test public void testSortFunctionOverView1() {
+    	String sql = "select e1 from (select * from pm1.g1) as x order by cast(e3 as string) desc, cast(e2 as string) limit 1"; //$NON-NLS-1$
+
+        ProcessorPlan plan = helpGetPlan(sql, RealMetadataFactory.example1Cached());
+        FakeDataManager fdm = new FakeDataManager();
+        sampleData1(fdm);
+        helpProcess(plan, fdm, new List[] {Arrays.asList("c")});
+    }
+
 }



More information about the teiid-commits mailing list