[teiid-commits] teiid SVN: r3330 - in trunk: api/src/main/java/org/teiid/language/visitor and 16 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Fri Jul 22 17:13:21 EDT 2011


Author: shawkins
Date: 2011-07-22 17:13:20 -0400 (Fri, 22 Jul 2011)
New Revision: 3330

Added:
   trunk/api/src/main/java/org/teiid/language/WindowFunction.java
   trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
Modified:
   trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
   trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
   trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
   trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
   trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
   trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java
   trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
   trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
   trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
   trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
   trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
   trunk/engine/src/main/resources/org/teiid/query/i18n.properties
   trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
   trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
   trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java
   trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
Log:
TEIID-1667 refining aggregate validation and adding pushdown support for window functions

Added: trunk/api/src/main/java/org/teiid/language/WindowFunction.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/WindowFunction.java	                        (rev 0)
+++ trunk/api/src/main/java/org/teiid/language/WindowFunction.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+ 
+ package org.teiid.language;
+
+import java.util.List;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.core.util.HashCodeUtil;
+import org.teiid.language.visitor.LanguageObjectVisitor;
+
+public class WindowFunction extends BaseLanguageObject implements Expression {
+	
+	private AggregateFunction function;
+	private List<Expression> partition;
+	private OrderBy orderBy;
+	
+	public WindowFunction() {
+		
+	}
+	
+	public AggregateFunction getFunction() {
+		return function;
+	}
+	
+	public void setFunction(AggregateFunction expression) {
+		this.function = expression;
+	}
+	
+	public List<Expression> getPartition() {
+		return partition;
+	}
+	
+	public void setPartition(List<Expression> grouping) {
+		this.partition = grouping;
+	}
+	
+	public OrderBy getOrderBy() {
+		return orderBy;
+	}
+	
+	public void setOrderBy(OrderBy orderBy) {
+		this.orderBy = orderBy;
+	}
+
+	@Override
+	public Class<?> getType() {
+		return function.getType();
+	}
+
+	@Override
+	public void acceptVisitor(LanguageObjectVisitor visitor) {
+		visitor.visit(this);
+	}
+	
+	@Override
+	public int hashCode() {
+		return HashCodeUtil.hashCode(function.hashCode(), partition, orderBy);
+	}
+	
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+		if (!(obj instanceof WindowFunction)) {
+			return false;
+		}
+		WindowFunction other = (WindowFunction)obj;
+		return EquivalenceUtil.areEqual(this.function, other.function) &&
+		EquivalenceUtil.areEqual(this.partition, other.partition) &&
+		EquivalenceUtil.areEqual(this.orderBy, other.orderBy);
+	}
+	
+}


Property changes on: trunk/api/src/main/java/org/teiid/language/WindowFunction.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/CollectorVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -27,44 +27,9 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import org.teiid.language.AggregateFunction;
-import org.teiid.language.AndOr;
-import org.teiid.language.Argument;
-import org.teiid.language.BatchedUpdates;
-import org.teiid.language.Call;
 import org.teiid.language.ColumnReference;
-import org.teiid.language.Comparison;
-import org.teiid.language.Delete;
-import org.teiid.language.DerivedColumn;
-import org.teiid.language.DerivedTable;
-import org.teiid.language.Exists;
-import org.teiid.language.ExpressionValueSource;
-import org.teiid.language.Function;
-import org.teiid.language.GroupBy;
-import org.teiid.language.In;
-import org.teiid.language.Insert;
-import org.teiid.language.IsNull;
-import org.teiid.language.IteratorValueSource;
-import org.teiid.language.Join;
 import org.teiid.language.LanguageObject;
-import org.teiid.language.Like;
-import org.teiid.language.Limit;
-import org.teiid.language.Literal;
 import org.teiid.language.NamedTable;
-import org.teiid.language.Not;
-import org.teiid.language.OrderBy;
-import org.teiid.language.ScalarSubquery;
-import org.teiid.language.SearchedCase;
-import org.teiid.language.SearchedWhenClause;
-import org.teiid.language.Select;
-import org.teiid.language.SetClause;
-import org.teiid.language.SetQuery;
-import org.teiid.language.SortSpecification;
-import org.teiid.language.SubqueryComparison;
-import org.teiid.language.SubqueryIn;
-import org.teiid.language.Update;
-import org.teiid.language.With;
-import org.teiid.language.WithItem;
 
 
 /**
@@ -72,7 +37,7 @@
  * tree.  Each visit method does an instanceof method to check whether the object
  * is of the expected type.
  */
-public class CollectorVisitor<T> implements LanguageObjectVisitor {
+public class CollectorVisitor<T> extends HierarchyVisitor {
 
     private Class<T> type;
     private Collection<T> objects = new ArrayList<T>();
@@ -80,171 +45,20 @@
     public CollectorVisitor(Class<T> type) {
         this.type = type;
     }
-
+    
     @SuppressWarnings("unchecked")
-	private void checkInstance(LanguageObject obj) {
+    @Override
+    public void visitNode(LanguageObject obj) {
         if(type.isInstance(obj)) {
             this.objects.add((T)obj);
         }
+    	super.visitNode(obj);
     }
-    
+
     public Collection<T> getCollectedObjects() {
         return this.objects;
     }
 
-    public void visit(AggregateFunction obj) {
-        checkInstance(obj);        
-    }
-    
-    public void visit(BatchedUpdates obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Comparison obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(AndOr obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Delete obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(ColumnReference obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Exists obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Function obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(NamedTable obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(GroupBy obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(In obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(DerivedTable obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Insert obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(ExpressionValueSource obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(IsNull obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Join obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Like obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Limit obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Literal obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Not obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(OrderBy obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(SortSpecification obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Argument obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Call obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Select obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(ScalarSubquery obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(SearchedCase obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(DerivedColumn obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(SubqueryComparison obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(SubqueryIn obj) {
-        checkInstance(obj);
-    }
-
-    public void visit(Update obj) {
-        checkInstance(obj);
-    }
-    
-    public void visit(SetQuery obj) {
-        checkInstance(obj);
-    }
-    
-    @Override
-    public void visit(SetClause obj) {
-        checkInstance(obj);
-    }
-    
-    @Override
-    public void visit(SearchedWhenClause obj) {
-    	checkInstance(obj);    	
-    }
-    
-    @Override
-    public void visit(IteratorValueSource obj) {
-    	checkInstance(obj);    	
-    }
-    
-    @Override
-    public void visit(With obj) {
-    	checkInstance(obj); 
-    }
-    
-    @Override
-    public void visit(WithItem obj) {
-    	checkInstance(obj); 
-    }
-
     /**
      * This is a utility method to instantiate and run the visitor in conjunction 
      * with a HierarchyVisitor to collect all objects of the specified type
@@ -255,8 +69,7 @@
      */
     public static <T> Collection<T> collectObjects(Class<T> type, LanguageObject object) {
         CollectorVisitor<T> visitor = new CollectorVisitor<T>(type);
-        DelegatingHierarchyVisitor hierarchyVisitor = new DelegatingHierarchyVisitor(visitor, null);
-        hierarchyVisitor.visitNode(object);
+        visitor.visitNode(object);
         return visitor.getCollectedObjects();
     }
     

Modified: trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/HierarchyVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -51,6 +51,7 @@
 import org.teiid.language.SubqueryComparison;
 import org.teiid.language.SubqueryIn;
 import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
 import org.teiid.language.With;
 import org.teiid.language.WithItem;
 
@@ -249,5 +250,11 @@
     	}
     }
     
-
+    @Override
+    public void visit(WindowFunction windowFunction) {
+    	visitNode(windowFunction.getFunction());
+    	visitNodes(windowFunction.getPartition());
+    	visitNode(windowFunction.getOrderBy());
+    }
+    
 }

Modified: trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/LanguageObjectVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -22,7 +22,44 @@
 
 package org.teiid.language.visitor;
 
-import org.teiid.language.*;
+import org.teiid.language.AggregateFunction;
+import org.teiid.language.AndOr;
+import org.teiid.language.Argument;
+import org.teiid.language.BatchedUpdates;
+import org.teiid.language.Call;
+import org.teiid.language.ColumnReference;
+import org.teiid.language.Comparison;
+import org.teiid.language.Delete;
+import org.teiid.language.DerivedColumn;
+import org.teiid.language.DerivedTable;
+import org.teiid.language.Exists;
+import org.teiid.language.ExpressionValueSource;
+import org.teiid.language.Function;
+import org.teiid.language.GroupBy;
+import org.teiid.language.In;
+import org.teiid.language.Insert;
+import org.teiid.language.IsNull;
+import org.teiid.language.IteratorValueSource;
+import org.teiid.language.Join;
+import org.teiid.language.Like;
+import org.teiid.language.Limit;
+import org.teiid.language.Literal;
+import org.teiid.language.NamedTable;
+import org.teiid.language.Not;
+import org.teiid.language.OrderBy;
+import org.teiid.language.ScalarSubquery;
+import org.teiid.language.SearchedCase;
+import org.teiid.language.SearchedWhenClause;
+import org.teiid.language.Select;
+import org.teiid.language.SetClause;
+import org.teiid.language.SetQuery;
+import org.teiid.language.SortSpecification;
+import org.teiid.language.SubqueryComparison;
+import org.teiid.language.SubqueryIn;
+import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
+import org.teiid.language.With;
+import org.teiid.language.WithItem;
 
 /**
  */
@@ -64,4 +101,5 @@
 	public void visit(IteratorValueSource obj);
 	public void visit(With obj);
 	public void visit(WithItem obj);
+	public void visit(WindowFunction windowFunction);
 }

Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -72,6 +72,7 @@
 import org.teiid.language.SubqueryIn;
 import org.teiid.language.TableReference;
 import org.teiid.language.Update;
+import org.teiid.language.WindowFunction;
 import org.teiid.language.With;
 import org.teiid.language.WithItem;
 import org.teiid.language.Argument.Direction;
@@ -916,6 +917,31 @@
 		append(obj.getSubquery());
 		buffer.append(Tokens.RPAREN);
     }
+    
+    @Override
+    public void visit(WindowFunction windowFunction) {
+    	append(windowFunction.getFunction());
+    	buffer.append(Tokens.SPACE);
+    	buffer.append(OVER);
+    	buffer.append(Tokens.SPACE);
+    	buffer.append(Tokens.LPAREN);
+    	boolean needsSpace = false;
+    	if (windowFunction.getPartition() != null) {
+    		buffer.append(PARTITION);
+    		buffer.append(Tokens.SPACE);
+    		buffer.append(BY);
+    		buffer.append(Tokens.SPACE);
+    		append(windowFunction.getPartition());
+    		needsSpace = true;
+    	}
+    	if (windowFunction.getOrderBy() != null) {
+    		if (needsSpace) {
+    			buffer.append(Tokens.SPACE);
+    		}
+    		append(windowFunction.getOrderBy());
+    	}
+    	buffer.append(Tokens.RPAREN);
+    }
  
     /**
      * Gets the SQL string representation for a given ILanguageObject.

Modified: trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java
===================================================================
--- trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/api/src/main/java/org/teiid/translator/ExecutionFactory.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -860,7 +860,7 @@
     }
     
     /**
-     * @return true if Advanced OLAP operations are supporting
+     * @return true if Advanced OLAP operations are supported
      *  including the aggregate function filter clause.
      * @since 7.5
      */
@@ -869,8 +869,9 @@
     }
     
     /**
-     * @return true if Elementary OLAP operations are supporting
-     *  including window functions
+     * @return true if Elementary OLAP operations are supported
+     *  including window functions and inline window specifications that include 
+     *  simple expressions in partitioning and ordering 
      * @since 7.5
      */
     public boolean supportsElementaryOlapOperations() {

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/postgresql/PostgreSQLExecutionFactory.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -487,4 +487,14 @@
     	return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
     }
     
+    @Override
+    public boolean supportsArrayAgg() {
+    	return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
+    }
+    
+    @Override
+    public boolean supportsElementaryOlapOperations() {
+    	return getDatabaseVersion().compareTo(EIGHT_4) >= 0;
+    }
+    
 }

Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/datamgr/LanguageBridgeFactory.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -117,6 +117,7 @@
 import org.teiid.query.sql.symbol.SearchedCaseExpression;
 import org.teiid.query.sql.symbol.SelectSymbol;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
 import org.teiid.translator.TranslatorException;
 
 
@@ -487,9 +488,25 @@
             return translate((SingleElementSymbol)expr);
         } else if (expr instanceof Criteria) {
         	return translate((Criteria)expr);
+        } else if (expr instanceof WindowFunction) {
+        	return translate((WindowFunction)expr);
         }
         throw new AssertionError();
     }
+    
+    org.teiid.language.WindowFunction translate(WindowFunction windowFunction) {
+    	org.teiid.language.WindowFunction result = new org.teiid.language.WindowFunction();
+    	result.setFunction(translate(windowFunction.getFunction()));
+    	result.setOrderBy(translate(windowFunction.getOrderBy(), false));
+    	if (windowFunction.getPartition() != null) {
+	    	ArrayList<org.teiid.language.Expression> partition = new ArrayList<org.teiid.language.Expression>(windowFunction.getPartition().size());
+	    	for (Expression ex : windowFunction.getPartition()) {
+	    		partition.add(translate(ex));
+	    	}
+	    	result.setPartition(partition);
+    	}
+    	return result;
+    }
 
     Literal translate(Constant constant) {
         Literal result = new Literal(constant.getValue(), constant.getType());

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -28,6 +28,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -112,16 +113,17 @@
 import org.teiid.query.sql.proc.TriggerAction;
 import org.teiid.query.sql.symbol.AggregateSymbol;
 import org.teiid.query.sql.symbol.AliasSymbol;
-import org.teiid.query.sql.symbol.MultipleElementSymbol;
 import org.teiid.query.sql.symbol.Constant;
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.ExpressionSymbol;
 import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.MultipleElementSymbol;
 import org.teiid.query.sql.symbol.Reference;
 import org.teiid.query.sql.symbol.ScalarSubquery;
 import org.teiid.query.sql.symbol.SelectSymbol;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
 import org.teiid.query.sql.util.SymbolMap;
 import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
 import org.teiid.query.sql.visitor.CorrelatedReferenceCollectorVisitor;
@@ -723,6 +725,8 @@
 
         PlanNode plan = null;
 
+		LinkedHashSet<WindowFunction> windowFunctions = new LinkedHashSet<WindowFunction>();
+
         if(query.getFrom() != null){
             FromClause fromClause = mergeClauseTrees(query.getFrom());
             
@@ -741,7 +745,8 @@
     		}
 
     		// Attach grouping node on top
-    		Collection<AggregateSymbol> aggs = AggregateSymbolCollectorVisitor.getAggregates(query.getSelect(), true);
+    		LinkedHashSet<AggregateSymbol> aggs = new LinkedHashSet<AggregateSymbol>();
+    		AggregateSymbolCollectorVisitor.getAggregates(query.getSelect(), aggs, null, null, windowFunctions, null);
     		boolean hasGrouping = !aggs.isEmpty();
     		if (query.getHaving() != null) {
     			aggs.addAll(AggregateSymbolCollectorVisitor.getAggregates(query.getHaving(), true));
@@ -764,6 +769,12 @@
 
 		// Attach project on top
 		plan = attachProject(plan, query.getSelect());
+		if (query.getOrderBy() != null) {
+			AggregateSymbolCollectorVisitor.getAggregates(query.getOrderBy(), null, null, null, windowFunctions, null);
+		}
+		if (!windowFunctions.isEmpty()) {
+			plan.setProperty(Info.HAS_WINDOW_FUNCTIONS, true);
+		}
 
 		// Attach dup removal on top
 		if(query.getSelect().isDistinct()) {

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/plantree/NodeConstants.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -98,6 +98,7 @@
         // Project node properties
         PROJECT_COLS,       // List <SingleElementSymbol>
         INTO_GROUP,         // GroupSymbol
+        HAS_WINDOW_FUNCTIONS,		// Boolean
 
         // Select node properties
         SELECT_CRITERIA,    // Criteria

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CapabilitiesUtil.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -185,6 +185,13 @@
                 return false;
             }
             break;
+        case RANK:
+        case DENSE_RANK:
+        case ROW_NUMBER:
+        	if (!caps.supportsCapability(Capability.ELEMENTARY_OLAP)) {
+        		return false;
+        	}
+        	break;
         default:
         	if (aggregate.isEnhancedNumeric()) { 
         		if (!caps.supportsCapability(Capability.QUERY_AGGREGATES_ENHANCED_NUMERIC)) {

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/CriteriaCapabilityValidatorVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -60,13 +60,12 @@
 import org.teiid.query.sql.navigator.PostOrderNavigator;
 import org.teiid.query.sql.symbol.AggregateSymbol;
 import org.teiid.query.sql.symbol.CaseExpression;
-import org.teiid.query.sql.symbol.Constant;
-import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.Function;
 import org.teiid.query.sql.symbol.QueryString;
 import org.teiid.query.sql.symbol.ScalarSubquery;
 import org.teiid.query.sql.symbol.SearchedCaseExpression;
 import org.teiid.query.sql.symbol.TextLine;
+import org.teiid.query.sql.symbol.WindowFunction;
 import org.teiid.query.sql.symbol.XMLAttributes;
 import org.teiid.query.sql.symbol.XMLElement;
 import org.teiid.query.sql.symbol.XMLForest;
@@ -165,6 +164,13 @@
         }
     }
     
+    @Override
+    public void visit(WindowFunction windowFunction) {
+    	if(! this.caps.supportsCapability(Capability.ELEMENTARY_OLAP)) {
+            markInvalid(windowFunction, "Window function not supported by source"); //$NON-NLS-1$
+        }
+    }
+    
     public void visit(CaseExpression obj) {
         if(! this.caps.supportsCapability(Capability.QUERY_CASE)) {
             markInvalid(obj, "CaseExpression pushdown not supported by source"); //$NON-NLS-1$

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RuleMergeVirtual.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -319,6 +319,10 @@
                                                  GroupSymbol virtualGroup,
                                                  PlanNode parentJoin,
                                                  QueryMetadataInterface metadata) {
+        if (projectNode.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
+        	return false;
+        }
+
         List<SingleElementSymbol> selectSymbols = (List<SingleElementSymbol>)projectNode.getProperty(NodeConstants.Info.PROJECT_COLS);
         
         HashSet<GroupSymbol> groups = new HashSet<GroupSymbol>();

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/rules/RulePushSelectCriteria.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -52,7 +52,9 @@
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 import org.teiid.query.sql.symbol.GroupSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
 import org.teiid.query.sql.util.SymbolMap;
+import org.teiid.query.sql.visitor.AggregateSymbolCollectorVisitor;
 import org.teiid.query.sql.visitor.ElementCollectorVisitor;
 import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
 import org.teiid.query.util.CommandContext;
@@ -560,17 +562,21 @@
         if(projectNode.getChildCount() == 0) {
             return false;
         }
+        List<WindowFunction> windowFunctions = null;
+        if (projectNode.hasBooleanProperty(Info.HAS_WINDOW_FUNCTIONS)) {
+        	windowFunctions = new LinkedList<WindowFunction>();
+        }
 
         Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
 
-        Boolean conversionResult = checkConversion(symbolMap, ElementCollectorVisitor.getElements(crit, true));
+        Boolean conversionResult = checkConversion(symbolMap, ElementCollectorVisitor.getElements(crit, true), windowFunctions);
         
         if (conversionResult == Boolean.FALSE) {
         	return false; //not convertable
         }
         
         if (!critNode.getSubqueryContainers().isEmpty() 
-        		&& checkConversion(symbolMap, critNode.getCorrelatedReferenceElements()) != null) {
+        		&& checkConversion(symbolMap, critNode.getCorrelatedReferenceElements(), windowFunctions) != null) {
     		return false; //not convertable, or has an aggregate for a correlated reference
         }
         
@@ -591,7 +597,7 @@
     }
 
 	private Boolean checkConversion(SymbolMap symbolMap,
-			Collection<ElementSymbol> elements) {
+			Collection<ElementSymbol> elements, List<WindowFunction> windowFunctions) {
 		Boolean result = null;
         
         for (ElementSymbol element : elements) {
@@ -609,6 +615,13 @@
             if (!ElementCollectorVisitor.getAggregates(converted, false).isEmpty()) {
                 result = Boolean.TRUE;
             }
+            
+            if (windowFunctions != null) {
+            	AggregateSymbolCollectorVisitor.getAggregates(converted, null, null, null, windowFunctions, null);
+            	if (!windowFunctions.isEmpty()) {
+            		return false;
+            	}
+            }
         }
 		return result;
 	}

Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -2250,7 +2250,8 @@
     			expression.setAggregateFunction(Type.MAX);
     		}
     	}
-    	if (rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
+    	if ((expression.getAggregateFunction() == Type.MAX || expression.getAggregateFunction() == Type.MIN) 
+    			&& rewriteAggs && expression.getExpression() != null && EvaluatableVisitor.willBecomeConstant(expression.getExpression())) {
     		return expression.getExpression();
     	}
     	if (expression.getExpression() != null && expression.getCondition() != null && !expression.respectsNulls()) {

Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/OrderByItem.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -79,7 +79,7 @@
 	 * @return true if the expression does not appear in the select clause
 	 */
 	public boolean isUnrelated() {
-		return expressionPosition != null && expressionPosition == -1;
+		return expressionPosition == null || expressionPosition == -1;
 	}
 
 	@Override

Modified: trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/symbol/AggregateSymbol.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -260,17 +260,14 @@
     		return false;
     	}
     	switch (getAggregateFunction()) {
-		case COUNT:
-		case AVG:
-		case STDDEV_POP:
-		case STDDEV_SAMP:
-		case VAR_POP:
-		case VAR_SAMP:
-		case SUM:
-		case ARRAY_AGG:
-			return true;
+		case MAX:
+		case MIN:
+		case ANY:
+		case SOME:
+		case EVERY:
+			return false;
 		}
-		return false;
+		return true;
     }
     
     public Expression getCondition() {
@@ -291,13 +288,17 @@
 	}
 	
 	public boolean respectsNulls() {
-		return this.aggregate == Type.ARRAY_AGG;
+		switch (this.aggregate) {
+		case TEXTAGG:
+		case ARRAY_AGG:
+			return true;
+		}
+		return false;
 	}
 	
 	public boolean canStage() {
 		switch (this.aggregate) {
 		case TEXTAGG:
-			return false;
 		case ARRAY_AGG:
 			return false;
 		case XMLAGG:

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/AggregateSymbolCollectorVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -25,7 +25,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 
 import org.teiid.query.sql.LanguageObject;
 import org.teiid.query.sql.LanguageVisitor;
@@ -99,7 +99,7 @@
     		Collection<? super AggregateSymbol> aggregates, 
     		Collection<? super ElementSymbol> otherElements, 
     		Collection<? super Expression> groupingColsUsed, 
-    		Collection<? super Expression> windowFunctions, 
+    		Collection<? super WindowFunction> windowFunctions, 
     		Collection<? extends Expression> groupingCols) {
         AggregateSymbolCollectorVisitor visitor = new AggregateSymbolCollectorVisitor(aggregates, otherElements);
         visitor.windowFunctions = windowFunctions;
@@ -113,7 +113,7 @@
     	}
         Collection<AggregateSymbol> aggregates = null;
         if (removeDuplicates) {
-            aggregates = new HashSet<AggregateSymbol>();
+            aggregates = new LinkedHashSet<AggregateSymbol>();
         } else {
             aggregates = new ArrayList<AggregateSymbol>();    
         }

Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -67,6 +67,7 @@
 import org.teiid.query.sql.symbol.QueryString;
 import org.teiid.query.sql.symbol.SearchedCaseExpression;
 import org.teiid.query.sql.symbol.SingleElementSymbol;
+import org.teiid.query.sql.symbol.WindowFunction;
 import org.teiid.query.sql.symbol.XMLElement;
 import org.teiid.query.sql.symbol.XMLParse;
 import org.teiid.query.sql.symbol.XMLSerialize;
@@ -448,4 +449,15 @@
     	}
     }
     
+    @Override
+    public void visit(WindowFunction windowFunction) {
+    	if (windowFunction.getPartition() == null) {
+    		return;
+    	}
+    	List<Expression> partition = windowFunction.getPartition();
+		for (int i = 0; i < partition.size(); i++) {
+    		partition.set(i, replaceExpression(partition.get(i)));
+    	}
+    }
+    
 }

Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -165,6 +165,8 @@
 	// State during validation
     private boolean isXML = false;	// only used for Query commands
     
+    private boolean inQuery;
+    
     // update procedure being validated
     private CreateUpdateProcedureCommand updateProc;
     
@@ -265,6 +267,7 @@
         	this.isXML = true;
 	        validateXMLQuery(obj);
         } else {
+        	this.inQuery = true;
             validateAggregates(obj);
 
             //if it is select with no from, should not have ScalarSubQuery
@@ -1217,6 +1220,10 @@
     
     @Override
     public void visit(AggregateSymbol obj) {
+    	if (!inQuery) {
+    		handleValidationError(QueryPlugin.Util.getString("SQLParser.Aggregate_only_top_level", obj), obj); //$NON-NLS-1$
+    		return;
+    	}
     	if (obj.getCondition() != null) {
     		Expression condition = obj.getCondition();
     		validateNoSubqueriesOrOuterReferences(condition);

Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties	2011-07-22 21:13:20 UTC (rev 3330)
@@ -259,7 +259,7 @@
 
 
 SQLParser.Unknown_join_type=Unknown join type: {0}
-SQLParser.Aggregate_only_top_level=Aggregate and window functions are not allowed in the FROM/WHERE/GROUP BY clauses: {0}
+SQLParser.Aggregate_only_top_level=Aggregate functions are only allowed HAVING/SELECT/ORDER BY clauses.  Window functions are only allowed in the SELECT/ORDER BY clauses: {0}
 SQLParser.window_only_top_level=Window functions are not allowed in the HAVING clause: {0}
 SQLParser.Unknown_agg_func=Unknown aggregate function: {0}
 SQLParser.Invalid_func=Invalid function name: [{0}]

Added: trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.query.optimizer;
+
+import static org.teiid.query.optimizer.TestOptimizer.*;
+
+import org.junit.Test;
+import org.teiid.query.optimizer.TestOptimizer.ComparisonMode;
+import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
+import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
+import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+public class TestWindowFunctions {
+
+    @Test public void testViewNotRemoved() throws Exception {
+    	BasicSourceCapabilities caps = getTypicalCapabilities();
+    	caps.setCapabilitySupport(Capability.ELEMENTARY_OLAP, true);
+    	caps.setCapabilitySupport(Capability.QUERY_FROM_INLINE_VIEWS, true);
+        ProcessorPlan plan = TestOptimizer.helpPlan("SELECT y FROM (select row_number() over (order by e1) as y from pm1.g1) as x where x.y = 10", //$NON-NLS-1$
+                                      RealMetadataFactory.example1Cached(), null, new DefaultCapabilitiesFinder(caps),
+                                      new String[] {
+                                          "SELECT v_0.c_0 FROM (SELECT ROW_NUMBER() OVER (ORDER BY g_0.e1) AS c_0 FROM pm1.g1 AS g_0) AS v_0 WHERE v_0.c_0 = 10"}, ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$
+    
+        checkNodeTypes(plan, FULL_PUSHDOWN);                                    
+    }
+	
+}


Property changes on: trunk/engine/src/test/java/org/teiid/query/optimizer/TestWindowFunctions.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/test/java/org/teiid/query/rewriter/TestQueryRewriter.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -1709,6 +1709,9 @@
         helpTestRewriteCriteria("case when 0 = pm1.g1.e2 then null else null end IS NULL", TRUE_STR); //$NON-NLS-1$ 
     }
     
+    @Test public void testRewriteConstantAgg2() throws Exception {
+    	helpTestRewriteCommand("select count(2) from pm1.g1 group by e1", "SELECT COUNT(2) FROM pm1.g1 GROUP BY e1");
+    }
     
     @Test public void testRewriteCaseExprForCase5413a() {
         helpTestRewriteCriteria("pm1.g2.e1 = case when 0 = pm1.g1.e2 then 2 else 2 end", "pm1.g2.e1 = '2'"); //$NON-NLS-1$ //$NON-NLS-2$

Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -1515,6 +1515,16 @@
         ValidatorReport report = helpValidateInModeler("pm1.vsp42", sql, metadata);  //$NON-NLS-1$ 
         assertEquals("Expected report to have no validation failures", false, report.hasItems()); //$NON-NLS-1$
     }
+    
+    @Test public void testNonQueryAgg() throws Exception{
+        String sql = "CREATE VIRTUAL PROCEDURE BEGIN IF (max(pm1.vsp42.param1) > 0) SELECT 1 AS x; ELSE SELECT 0 AS x; END"; //$NON-NLS-1$
+        
+        QueryMetadataInterface metadata = RealMetadataFactory.example1Cached();
+        
+        // Validate
+        ValidatorReport report = helpValidateInModeler("pm1.vsp42", sql, metadata);  //$NON-NLS-1$ 
+        examineReport(sql, new String[] {"MAX(pm1.vsp42.param1)"}, report);
+    }
 	
 	@Test public void testDefect14886() throws Exception{        
         String sql = "CREATE VIRTUAL PROCEDURE BEGIN END";  //$NON-NLS-1$        
@@ -1888,5 +1898,13 @@
 	@Test public void testWindowFunctionWithNestedOrdering() {
 		helpValidate("SELECT xmlagg(xmlelement(name x, e1) order by e2) over () from pm1.g1", new String[] {"XMLAGG(XMLELEMENT(NAME x, e1) ORDER BY e2)"}, RealMetadataFactory.example1Cached());		
 	}
+	
+	@Test public void testWindowFunctionWithNestedaggAllowed() {
+		helpValidate("SELECT max(e1) over (order by max(e2)) from pm1.g1 group by e1", new String[] {}, RealMetadataFactory.example1Cached());		
+	}
 
+	@Test public void testWindowFunctionWithNestedaggAllowed1() {
+		helpValidate("SELECT max(min(e1)) over (order by max(e2)) from pm1.g1 group by e1", new String[] {"MIN(e1)"}, RealMetadataFactory.example1Cached());		
+	}
+	
 }

Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestCollectorVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -22,16 +22,16 @@
 
 package org.teiid.connector.visitor.util;
 
+import static org.junit.Assert.*;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
-import junit.framework.TestCase;
-
+import org.junit.Test;
 import org.teiid.language.ColumnReference;
 import org.teiid.language.Comparison;
 import org.teiid.language.Expression;
@@ -41,25 +41,14 @@
 import org.teiid.language.Select;
 import org.teiid.language.Comparison.Operator;
 import org.teiid.language.visitor.CollectorVisitor;
-
 /**
  */
-public class TestCollectorVisitor extends TestCase {
+public class TestCollectorVisitor {
 
-    /**
-     * Constructor for TestElementCollectorVisitor.
-     * @param name
-     */
-    public TestCollectorVisitor(String name) {
-        super(name);
-    }
-
-    public Set getStringSet(Collection objs) {
-        Set strings = new HashSet();
+    public Set<String> getStringSet(Collection<? extends Object> objs) {
+        Set<String> strings = new HashSet<String>();
         
-        Iterator iter = objs.iterator();
-        while(iter.hasNext()) {
-            Object obj = iter.next();
+        for (Object obj : objs) {
             if(obj == null) {
                 strings.add(null);
             } else {
@@ -90,38 +79,38 @@
         return q;   
     }
  
-    public void testCollection1() {
+    @Test public void testCollection1() {
         helpTestCollection(example1(), ColumnReference.class, new String[] {"g1.e1", "g1.e2" }); //$NON-NLS-1$ //$NON-NLS-2$
     }
 
-    public void testCollection2() {
+    @Test public void testCollection2() {
         helpTestCollection(example1(), Function.class, new String[] {"length(g1.e2)" }); //$NON-NLS-1$
     }
 
-    public void testCollection3() {
+    @Test public void testCollection3() {
         helpTestCollection(example1(), Expression.class, new String[] {"g1.e1", "g1.e2", "length(g1.e2)" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     }
 
 
     public void helpTestElementsUsedByGroups(LanguageObject obj, String[] elements, String[] groups) {
-        Set actualElements = getStringSet(CollectorVisitor.collectElements(obj));
-        Set actualGroups = getStringSet(CollectorVisitor.collectGroupsUsedByElements(obj));
+        Set<String> actualElements = getStringSet(CollectorVisitor.collectElements(obj));
+        Set<String> actualGroups = getStringSet(CollectorVisitor.collectGroupsUsedByElements(obj));
         
-        Set expectedElements = new HashSet(Arrays.asList(elements));
-        Set expectedGroups = new HashSet(Arrays.asList(groups));
+        Set<String> expectedElements = new HashSet<String>(Arrays.asList(elements));
+        Set<String> expectedGroups = new HashSet<String>(Arrays.asList(groups));
         
         assertEquals("Did not get expected elements", expectedElements, actualElements); //$NON-NLS-1$
         assertEquals("Did not get expected groups", expectedGroups, actualGroups);         //$NON-NLS-1$
     }
     
-    public void test1() {
+    @Test public void test1() {
         NamedTable g1 = new NamedTable("g1", null, null); //$NON-NLS-1$
         ColumnReference e1 = new ColumnReference(g1, "e1", null, String.class); //$NON-NLS-1$
         
         helpTestElementsUsedByGroups(e1, new String[] {"g1.e1"}, new String[] {"g1"}); //$NON-NLS-1$ //$NON-NLS-2$
     }
     
-    public void test2() {
+    @Test public void test2() {
         NamedTable g1 = new NamedTable("g1", null, null); //$NON-NLS-1$
         ColumnReference e1 = new ColumnReference(g1, "e1", null, String.class); //$NON-NLS-1$
         ColumnReference e2 = new ColumnReference(g1, "e2", null, String.class); //$NON-NLS-1$

Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java	2011-07-22 19:03:28 UTC (rev 3329)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java	2011-07-22 21:13:20 UTC (rev 3330)
@@ -73,7 +73,7 @@
 import org.teiid.query.sql.lang.CompareCriteria;
 import org.teiid.query.sql.lang.JoinType;
 
-
+ at SuppressWarnings("nls")
 public class TestSQLStringVisitor  {
 
     public static final RuntimeMetadata metadata = TstLanguageBridgeFactory.metadataFactory;
@@ -425,5 +425,12 @@
     	Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
     	assertEquals("SELECT g_0.IntKey AS c_0 FROM SmallA AS g_0 ORDER BY c_0 NULLS FIRST", command.toString()); //$NON-NLS-1$
     }
+    
+    @Test public void testWindowFunction() throws Exception {
+    	String sql = "select max(intnum) over (order by intkey nulls first) from bqt1.smalla";
+    	
+    	Command command = FakeTranslationFactory.getInstance().getBQTTranslationUtility().parseCommand(sql, true, true);
+    	assertEquals("SELECT MAX(g_0.IntNum) OVER (ORDER BY g_0.IntKey NULLS FIRST) FROM SmallA AS g_0", command.toString()); //$NON-NLS-1$
+    }
 
 }



More information about the teiid-commits mailing list