[teiid-commits] teiid SVN: r923 - in trunk/engine/src: main/java/com/metamatrix/query/rewriter and 2 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Tue May 12 21:37:35 EDT 2009


Author: shawkins
Date: 2009-05-12 21:37:34 -0400 (Tue, 12 May 2009)
New Revision: 923

Modified:
   trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
   trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java
   trunk/engine/src/test/java/com/metamatrix/query/sql/visitor/TestExpressionMappingVisitor.java
Log:
TEIID-582 fixing the expression mapping visitor to prevent recursive mappings.

Modified: trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2009-05-13 01:01:53 UTC (rev 922)
+++ trunk/engine/src/main/java/com/metamatrix/query/optimizer/relational/rules/FrameUtil.java	2009-05-13 01:37:34 UTC (rev 923)
@@ -55,7 +55,6 @@
 import com.metamatrix.query.sql.lang.QueryCommand;
 import com.metamatrix.query.sql.lang.Select;
 import com.metamatrix.query.sql.lang.StoredProcedure;
-import com.metamatrix.query.sql.symbol.AggregateSymbol;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
 import com.metamatrix.query.sql.symbol.Expression;
@@ -264,24 +263,14 @@
             return expression;
         }
         
-        if(expression instanceof ElementSymbol) { 
+        if(expression instanceof SingleElementSymbol) { 
             Expression mappedSymbol = (Expression) symbolMap.get(expression);
             if (mappedSymbol != null) {
                 return mappedSymbol;
             }
             return expression;
         }
-        
-        if(expression instanceof AggregateSymbol) {
-            AggregateSymbol aggSymbol = (AggregateSymbol) expression;
-            
-            // First try to replace the entire aggregate
-            SingleElementSymbol replacement = (SingleElementSymbol) symbolMap.get(aggSymbol);
-            if(replacement != null) {
-                return replacement;
-            }
-        } 
-        
+                
         ExpressionMappingVisitor.mapExpressions(expression, symbolMap);
         
         return expression;
@@ -507,7 +496,7 @@
         if (project != null) {
             return (List<SingleElementSymbol>)project.getProperty(NodeConstants.Info.PROJECT_COLS);
         }
-        Assertion.failed("no top cols in frame");
+        Assertion.failed("no top cols in frame"); //$NON-NLS-1$
         return null;
     }
 

Modified: trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2009-05-13 01:01:53 UTC (rev 922)
+++ trunk/engine/src/main/java/com/metamatrix/query/rewriter/QueryRewriter.java	2009-05-13 01:37:34 UTC (rev 923)
@@ -751,14 +751,14 @@
                 for (SingleElementSymbol symbol : (List<SingleElementSymbol>)query.getSelect().getProjectedSymbols()) {
                     expressionMap.put((Expression)SymbolMap.getExpression(symbol).clone(), (SingleElementSymbol)iter.next());
                 }
-                ExpressionMappingVisitor.mapExpressions(groupBy, expressionMap, true);
+                ExpressionMappingVisitor.mapExpressions(groupBy, expressionMap);
                 outerQuery.setGroupBy(groupBy);
-                ExpressionMappingVisitor.mapExpressions(having, expressionMap, true);
+                ExpressionMappingVisitor.mapExpressions(having, expressionMap);
                 outerQuery.setHaving(having);
-                ExpressionMappingVisitor.mapExpressions(orderBy, expressionMap, true);
+                ExpressionMappingVisitor.mapExpressions(orderBy, expressionMap);
                 outerQuery.setOrderBy(orderBy);
                 outerQuery.setLimit(limit);
-                ExpressionMappingVisitor.mapExpressions(select, expressionMap, true);
+                ExpressionMappingVisitor.mapExpressions(select, expressionMap);
                 outerQuery.setSelect(select);
                 outerQuery.setInto(into);
                 outerQuery.setOption(query.getOption());

Modified: trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java	2009-05-13 01:01:53 UTC (rev 922)
+++ trunk/engine/src/main/java/com/metamatrix/query/sql/visitor/ExpressionMappingVisitor.java	2009-05-13 01:37:34 UTC (rev 923)
@@ -24,9 +24,11 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import com.metamatrix.query.sql.LanguageObject;
 import com.metamatrix.query.sql.LanguageVisitor;
@@ -47,7 +49,6 @@
 import com.metamatrix.query.sql.lang.StoredProcedure;
 import com.metamatrix.query.sql.lang.SubqueryCompareCriteria;
 import com.metamatrix.query.sql.lang.SubquerySetCriteria;
-import com.metamatrix.query.sql.navigator.PostOrderNavigator;
 import com.metamatrix.query.sql.navigator.PreOrderNavigator;
 import com.metamatrix.query.sql.proc.AssignmentStatement;
 import com.metamatrix.query.sql.symbol.AggregateSymbol;
@@ -74,7 +75,7 @@
     public ExpressionMappingVisitor(Map symbolMap) {
         this.symbolMap = symbolMap;
     }
-    
+        
     protected boolean createAliases() {
     	return true;
     }
@@ -293,27 +294,25 @@
     }
     
     /**
-     * Take a language object (currently only criteria and expressions will be 
-     * properly mapped) and use the map to swap out expressions with new expressions.
-     * If an expression is not found in the map, it is not swapped.  The object
-     * is modified in place, so is not returned.
+     * The object is modified in place, so is not returned.
      * @param obj Language object
      * @param exprMap Expression map, Expression to Expression
      */
     public static void mapExpressions(LanguageObject obj, Map exprMap) {
-        mapExpressions(obj, exprMap, false);
-    }
-    
-    public static void mapExpressions(LanguageObject obj, Map exprMap, boolean preOrder) {
         if(obj == null || exprMap == null || exprMap.isEmpty()) { 
             return;
         }
-        ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(exprMap);
-        if (preOrder) {
-            PreOrderNavigator.doVisit(obj, visitor);
-        } else {
-            PostOrderNavigator.doVisit(obj, visitor);
-        }
+        final Set reverseSet = new HashSet(exprMap.values());
+        final ExpressionMappingVisitor visitor = new ExpressionMappingVisitor(exprMap);
+        PreOrderNavigator pon = new PreOrderNavigator(visitor) {
+        	@Override
+        	protected void visitNode(LanguageObject obj) {
+        		if (!(obj instanceof Expression) || !reverseSet.contains(obj)) {
+            		super.visitNode(obj);
+        		}
+        	}
+        };
+        obj.acceptVisitor(pon);
     }
     
     protected void setVariableValues(Map variableValues) {

Modified: trunk/engine/src/test/java/com/metamatrix/query/sql/visitor/TestExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/test/java/com/metamatrix/query/sql/visitor/TestExpressionMappingVisitor.java	2009-05-13 01:01:53 UTC (rev 922)
+++ trunk/engine/src/test/java/com/metamatrix/query/sql/visitor/TestExpressionMappingVisitor.java	2009-05-13 01:37:34 UTC (rev 923)
@@ -22,18 +22,23 @@
 
 package com.metamatrix.query.sql.visitor;
 
+import static org.junit.Assert.*;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.teiid.connector.api.SourceSystemFunctions;
 
 import com.metamatrix.query.sql.LanguageObject;
+import com.metamatrix.query.sql.ReservedWords;
 import com.metamatrix.query.sql.lang.CompareCriteria;
 import com.metamatrix.query.sql.lang.Select;
 import com.metamatrix.query.sql.lang.SetCriteria;
+import com.metamatrix.query.sql.symbol.AggregateSymbol;
 import com.metamatrix.query.sql.symbol.CaseExpression;
 import com.metamatrix.query.sql.symbol.Constant;
 import com.metamatrix.query.sql.symbol.ElementSymbol;
@@ -44,19 +49,15 @@
 import com.metamatrix.query.sql.symbol.TestSearchedCaseExpression;
 
 
-public class TestExpressionMappingVisitor extends TestCase {
+public class TestExpressionMappingVisitor {
 
-    public TestExpressionMappingVisitor(String arg0) {
-        super(arg0);
-    }
-
     public void helpTest(LanguageObject original, Map map, LanguageObject expected) {
         ExpressionMappingVisitor.mapExpressions(original, map);
         
         assertEquals("Did not get expected mapped expression", expected, original);     //$NON-NLS-1$
     }
     
-    public void testCompareCriteria1() {
+    @Test public void testCompareCriteria1() {
         ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
         Function f = new Function("+", new Expression[] { new Constant(new Integer(2)), new Constant(new Integer(5)) }); //$NON-NLS-1$
         Map map = new HashMap();
@@ -66,7 +67,7 @@
         helpTest(before, map, after);
     }
     
-    public void testCompareCriteria2() {
+    @Test public void testCompareCriteria2() {
         ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
         Function f = new Function("+", new Expression[] { new Constant(new Integer(2)), new Constant(new Integer(5)) }); //$NON-NLS-1$
         Map map = new HashMap();
@@ -76,7 +77,7 @@
         helpTest(before, map, after);
     }
 
-    public void testFunction1() {
+    @Test public void testFunction1() {
         ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
         ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
         ElementSymbol e3 = new ElementSymbol("e3"); //$NON-NLS-1$
@@ -100,7 +101,7 @@
         helpTest(f3, map, f7);
     }
 
-    public void testSetCriteria() {
+    @Test public void testSetCriteria() {
         ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
         ElementSymbol e2 = new ElementSymbol("e2"); //$NON-NLS-1$
         Constant c1 = new Constant("xyz"); //$NON-NLS-1$
@@ -122,7 +123,7 @@
         helpTest(before, map, after);
     }
     
-    public void testCaseExpression1() {
+    @Test public void testCaseExpression1() {
         ElementSymbol x = new ElementSymbol("x"); //$NON-NLS-1$
         ElementSymbol y = new ElementSymbol("y"); //$NON-NLS-1$
         Constant a = new Constant(String.valueOf('a'));
@@ -145,7 +146,7 @@
         helpTest(TestCaseExpression.example(3), map, mapped);
     }
     
-    public void testCaseExpression2() {
+    @Test public void testCaseExpression2() {
         ElementSymbol x = new ElementSymbol("x"); //$NON-NLS-1$
         ElementSymbol y = new ElementSymbol("y"); //$NON-NLS-1$
         
@@ -168,7 +169,7 @@
     /**
      * We do not need to create an alias if the canonical short names match
      */
-    public void testSelectAlias() {
+    @Test public void testSelectAlias() {
         ElementSymbol x = new ElementSymbol("y.x"); //$NON-NLS-1$
         ElementSymbol y = new ElementSymbol("z.X"); //$NON-NLS-1$
         
@@ -181,6 +182,26 @@
         
         assertEquals("Did not get expected mapped expression", "SELECT z.X", toMap.toString());     //$NON-NLS-1$ //$NON-NLS-2$
     }
-
     
+    /**
+     * we are not careful about ensuring that that every symbol is
+     * unique in a plan, so there's a chance mapping the expression in an
+     * aggregate in a project node will cause the same symbol to be 
+     * updated in a sort node.  to ensure that we don't get into
+     * recursion trouble we detect if we're replacing an expression
+     * that already exists as a mapping.
+     * 
+     * we simulate that situation here using the same aggregate twice in
+     * a function.
+     */
+    @Test public void testRecursionDetection() {
+    	ElementSymbol e1 = new ElementSymbol("e1"); //$NON-NLS-1$
+    	AggregateSymbol a1 = new AggregateSymbol("x", ReservedWords.SUM, false, e1); //$NON-NLS-1$
+    	Function f = new Function(SourceSystemFunctions.ADD_OP, new Expression[] {a1, a1});
+    	HashMap<AggregateSymbol, AggregateSymbol> map = new HashMap<AggregateSymbol, AggregateSymbol>();
+    	map.put(a1, new AggregateSymbol("x", ReservedWords.SUM, false, a1)); //$NON-NLS-1$
+    	ExpressionMappingVisitor.mapExpressions(f, map);
+        assertEquals("(SUM(SUM(e1)) + SUM(SUM(e1)))", f.toString()); //$NON-NLS-1$
+    }
+    
 }




More information about the teiid-commits mailing list