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;
-
+@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$
+ }
}